fsd-fs 0.7.1 → 0.10.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/README.md +1 -1
- package/lib/index.js +64 -69
- package/package.json +8 -10
- package/tsconfig.json +0 -29
package/README.md
CHANGED
package/lib/index.js
CHANGED
|
@@ -3,17 +3,21 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
const util = require("util");
|
|
4
4
|
const os = require("os");
|
|
5
5
|
const Path = require("path");
|
|
6
|
-
const fs = require("
|
|
6
|
+
const fs = require("fs");
|
|
7
7
|
const isStream = require("is-stream");
|
|
8
8
|
const _glob = require("glob");
|
|
9
|
-
const
|
|
10
|
-
const _cpr = require("cpr");
|
|
9
|
+
const mapLimit = require("async/mapLimit");
|
|
11
10
|
const Debugger = require("debug");
|
|
12
|
-
const url_1 = require("url");
|
|
13
11
|
const glob = util.promisify(_glob);
|
|
14
|
-
const rimraf = util.promisify(_rimraf);
|
|
15
|
-
const cpr = util.promisify(_cpr);
|
|
16
12
|
const debug = Debugger('fsd-fs');
|
|
13
|
+
async function getStat(path) {
|
|
14
|
+
try {
|
|
15
|
+
return await fs.promises.stat(path);
|
|
16
|
+
}
|
|
17
|
+
catch (e) {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
17
21
|
class FSAdapter {
|
|
18
22
|
constructor(options) {
|
|
19
23
|
this.instanceOfFSDAdapter = true;
|
|
@@ -50,7 +54,7 @@ class FSAdapter {
|
|
|
50
54
|
});
|
|
51
55
|
return;
|
|
52
56
|
}
|
|
53
|
-
await fs.appendFile(p, data, { mode });
|
|
57
|
+
await fs.promises.appendFile(p, data, { mode });
|
|
54
58
|
}
|
|
55
59
|
async createReadStream(path, options) {
|
|
56
60
|
debug('createReadStream %s options: %o', path, options);
|
|
@@ -59,37 +63,24 @@ class FSAdapter {
|
|
|
59
63
|
}
|
|
60
64
|
async createWriteStream(path, options) {
|
|
61
65
|
debug('createWriteStream %s', path);
|
|
62
|
-
let p
|
|
66
|
+
let p;
|
|
63
67
|
if (path.startsWith('task://')) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
p = Path.join(this._options.
|
|
68
|
+
p = Path.join(this._options.tmpdir, path.replace('task://', ''));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
p = Path.join(this._options.root, path);
|
|
68
72
|
}
|
|
69
73
|
return fs.createWriteStream(p, options);
|
|
70
74
|
}
|
|
71
75
|
async unlink(path) {
|
|
72
76
|
debug('unlink %s', path);
|
|
73
77
|
let p = Path.join(this._options.root, path);
|
|
74
|
-
await
|
|
78
|
+
await fs.promises.rm(p, { recursive: true, force: true });
|
|
75
79
|
}
|
|
76
|
-
async mkdir(path,
|
|
80
|
+
async mkdir(path, recursive) {
|
|
77
81
|
debug('mkdir %s', path);
|
|
78
82
|
let fsPath = Path.join(this._options.root, path);
|
|
79
|
-
|
|
80
|
-
if (prefix && parent !== '/') {
|
|
81
|
-
try {
|
|
82
|
-
let parentFsPath = Path.join(this._options.root, parent);
|
|
83
|
-
let stat = await fs.stat(parentFsPath);
|
|
84
|
-
if (!stat.isDirectory()) {
|
|
85
|
-
await this.mkdir(parent, true);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
catch (e) {
|
|
89
|
-
await this.mkdir(parent, true);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
await fs.mkdir(fsPath);
|
|
83
|
+
await fs.promises.mkdir(fsPath, { recursive });
|
|
93
84
|
}
|
|
94
85
|
async readdir(path, recursion) {
|
|
95
86
|
debug('readdir %s', path);
|
|
@@ -101,7 +92,18 @@ class FSAdapter {
|
|
|
101
92
|
let files = await glob(pattern, {
|
|
102
93
|
cwd: p
|
|
103
94
|
});
|
|
104
|
-
return files
|
|
95
|
+
return await mapLimit(files, 20, async (name) => {
|
|
96
|
+
let filePath = Path.join(p, name);
|
|
97
|
+
let stat = await getStat(filePath);
|
|
98
|
+
let isDir = stat.isDirectory();
|
|
99
|
+
return {
|
|
100
|
+
name: isDir ? `${name}/` : name,
|
|
101
|
+
metadata: {
|
|
102
|
+
size: isDir ? 0 : stat.size,
|
|
103
|
+
lastModified: stat.mtime
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
});
|
|
105
107
|
}
|
|
106
108
|
async createUrl(path, options) {
|
|
107
109
|
debug('createUrl %s', path);
|
|
@@ -113,71 +115,58 @@ class FSAdapter {
|
|
|
113
115
|
const { root } = this._options;
|
|
114
116
|
let from = Path.join(root, path);
|
|
115
117
|
let to = Path.join(root, dest);
|
|
116
|
-
if (!(await
|
|
118
|
+
if (!(await getStat(from)))
|
|
117
119
|
throw new Error(`source file '${path}' is not exists!`);
|
|
118
|
-
|
|
119
|
-
throw new Error(`dest file '${dest}' is already exists!`);
|
|
120
|
-
await cpr(from, to);
|
|
120
|
+
await fs.promises.cp(from, to, { recursive: true, force: true });
|
|
121
121
|
}
|
|
122
122
|
async rename(path, dest) {
|
|
123
123
|
debug('rename %s to %s', path, dest);
|
|
124
124
|
let from = Path.join(this._options.root, path);
|
|
125
125
|
let to = Path.join(this._options.root, dest);
|
|
126
|
-
await fs.rename(from, to);
|
|
126
|
+
await fs.promises.rename(from, to);
|
|
127
127
|
}
|
|
128
128
|
async exists(path) {
|
|
129
129
|
debug('check exists %s', path);
|
|
130
130
|
let p = Path.join(this._options.root, path);
|
|
131
|
-
return await
|
|
131
|
+
return !!(await getStat(p));
|
|
132
132
|
}
|
|
133
133
|
async isFile(path) {
|
|
134
134
|
debug('check is file %s', path);
|
|
135
135
|
let p = Path.join(this._options.root, path);
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return stat.isFile();
|
|
139
|
-
}
|
|
140
|
-
catch (e) {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
136
|
+
let stat = await getStat(p);
|
|
137
|
+
return stat === null || stat === void 0 ? void 0 : stat.isFile();
|
|
143
138
|
}
|
|
144
139
|
async isDirectory(path) {
|
|
145
140
|
debug('check is directory %s', path);
|
|
146
141
|
let p = Path.join(this._options.root, path);
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
return stat.isDirectory();
|
|
150
|
-
}
|
|
151
|
-
catch (e) {
|
|
152
|
-
return false;
|
|
153
|
-
}
|
|
142
|
+
let stat = await getStat(p);
|
|
143
|
+
return stat === null || stat === void 0 ? void 0 : stat.isDirectory();
|
|
154
144
|
}
|
|
155
145
|
async size(path) {
|
|
156
146
|
debug('get file size %s', path);
|
|
157
147
|
let p = Path.join(this._options.root, path);
|
|
158
|
-
let stat = await
|
|
148
|
+
let stat = await getStat(p);
|
|
159
149
|
return stat.size;
|
|
160
150
|
}
|
|
161
151
|
async lastModified(path) {
|
|
162
152
|
debug('get file lastModified %s', path);
|
|
163
153
|
let p = Path.join(this._options.root, path);
|
|
164
|
-
let stat = await
|
|
154
|
+
let stat = await getStat(p);
|
|
165
155
|
return stat.mtime;
|
|
166
156
|
}
|
|
167
157
|
async initMultipartUpload(path, partCount) {
|
|
168
158
|
debug('initMultipartUpload %s, partCount: %d', path, partCount);
|
|
169
|
-
let taskId = `upload-${Math.random().toString().
|
|
159
|
+
let taskId = `upload-${Math.random().toString().substring(2)}-`;
|
|
170
160
|
let tasks = [];
|
|
171
161
|
for (let i = 1; i <= partCount; i += 1) {
|
|
172
|
-
tasks.push(`task://${taskId}${i}
|
|
162
|
+
tasks.push(`task://${taskId}${i}`);
|
|
173
163
|
}
|
|
174
164
|
return tasks;
|
|
175
165
|
}
|
|
176
166
|
async writePart(path, partTask, data) {
|
|
177
167
|
debug('writePart %s, task: %s', path, partTask);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
throw new Error('Invalid part pathname');
|
|
168
|
+
if (!partTask.startsWith('task://'))
|
|
169
|
+
throw new Error('Invalid part task id');
|
|
181
170
|
let writeStream = await this.createWriteStream(partTask);
|
|
182
171
|
await new Promise((resolve, reject) => {
|
|
183
172
|
data.pipe(writeStream).on('close', resolve).on('error', reject);
|
|
@@ -186,25 +175,31 @@ class FSAdapter {
|
|
|
186
175
|
}
|
|
187
176
|
async completeMultipartUpload(path, parts) {
|
|
188
177
|
debug('completeMultipartUpload %s', path);
|
|
189
|
-
let
|
|
178
|
+
let partPaths = [];
|
|
190
179
|
for (let part of parts) {
|
|
191
180
|
if (!part.startsWith('part://'))
|
|
192
181
|
throw new Error(`${part} is not a part file`);
|
|
193
|
-
let
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
if (info.pathname !== path)
|
|
197
|
-
throw new Error(`Invalid part link: ${part} for path: ${path}`);
|
|
198
|
-
let file = Path.join(this._options.tmpdir, info.hostname);
|
|
199
|
-
if (!(await fs.exists(file)))
|
|
182
|
+
let partPath = Path.join(this._options.tmpdir, part.replace('part://', ''));
|
|
183
|
+
let stat = await getStat(partPath);
|
|
184
|
+
if (!stat)
|
|
200
185
|
throw new Error(`part file ${part} is not exists`);
|
|
201
|
-
|
|
186
|
+
partPaths.push({ file: partPath, size: stat.size });
|
|
202
187
|
}
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
188
|
+
let p = Path.join(this._options.root, path);
|
|
189
|
+
let start = 0;
|
|
190
|
+
for (let info of partPaths) {
|
|
191
|
+
let writeStream = fs.createWriteStream(p, {
|
|
192
|
+
flags: 'a',
|
|
193
|
+
start
|
|
194
|
+
});
|
|
195
|
+
let stream = fs.createReadStream(info.file);
|
|
196
|
+
await new Promise((resolve, reject) => {
|
|
197
|
+
stream.pipe(writeStream).on('close', resolve).on('error', reject);
|
|
198
|
+
});
|
|
199
|
+
start += info.size;
|
|
200
|
+
writeStream.close();
|
|
206
201
|
}
|
|
207
|
-
|
|
202
|
+
partPaths.forEach((info) => fs.promises.rm(info.file, { force: true }));
|
|
208
203
|
}
|
|
209
204
|
}
|
|
210
205
|
exports.default = FSAdapter;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fsd-fs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "File system adapter for fsd",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "index.d.ts",
|
|
@@ -8,16 +8,14 @@
|
|
|
8
8
|
"build": "tsc",
|
|
9
9
|
"prepublish": "npm run build"
|
|
10
10
|
},
|
|
11
|
-
"repository": "https://github.com/
|
|
12
|
-
"author": "Liang <liang@
|
|
11
|
+
"repository": "https://github.com/liangxingchen/fsd/tree/master/packages/fsd-fs",
|
|
12
|
+
"author": "Liang <liang@miaomo.cc> (https://github.com/liangxingchen)",
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"dependencies": {
|
|
15
|
-
"
|
|
16
|
-
"debug": "^4.3.
|
|
17
|
-
"glob": "^7.
|
|
18
|
-
"is-stream": "^2.0.
|
|
19
|
-
"mz": "^2.7.0",
|
|
20
|
-
"rimraf": "^3.0.2"
|
|
15
|
+
"async": "*",
|
|
16
|
+
"debug": "^4.3.4",
|
|
17
|
+
"glob": "^7.2.0",
|
|
18
|
+
"is-stream": "^2.0.1"
|
|
21
19
|
},
|
|
22
|
-
"gitHead": "
|
|
20
|
+
"gitHead": "9820fd7263b6791a38e5568396bfac0f2d3e37e9"
|
|
23
21
|
}
|
package/tsconfig.json
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"module": "commonjs",
|
|
4
|
-
"allowSyntheticDefaultImports": true,
|
|
5
|
-
"noImplicitAny": true,
|
|
6
|
-
"noImplicitAny": true,
|
|
7
|
-
"removeComments": true,
|
|
8
|
-
"preserveConstEnums": true,
|
|
9
|
-
"outDir": "lib",
|
|
10
|
-
"moduleResolution": "node",
|
|
11
|
-
"baseUrl": ".",
|
|
12
|
-
"paths": {
|
|
13
|
-
"*": [
|
|
14
|
-
"../../packages/*",
|
|
15
|
-
"../../typings/*"
|
|
16
|
-
]
|
|
17
|
-
},
|
|
18
|
-
"target": "ES2017",
|
|
19
|
-
"lib": [
|
|
20
|
-
"ES2017"
|
|
21
|
-
]
|
|
22
|
-
},
|
|
23
|
-
"include": [
|
|
24
|
-
"src/**/*"
|
|
25
|
-
],
|
|
26
|
-
"exclude": [
|
|
27
|
-
"node_modules"
|
|
28
|
-
]
|
|
29
|
-
}
|