cloudcmd 17.1.6 → 17.2.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/ChangeLog +10 -1
- package/HELP.md +3 -2
- package/README.md +1 -1
- package/dist/sw.js +1 -1
- package/dist-dev/sw.js +1 -1
- package/package.json +3 -2
- package/server/{cloudcmd.js → cloudcmd.mjs} +52 -48
- package/server/cloudcmd.spec.mjs +180 -0
- package/server/config.spec.mjs +105 -0
- package/server/distribute/export.spec.mjs +68 -0
- package/server/distribute/import.spec.mjs +287 -0
- package/server/markdown/index.spec.mjs +126 -0
- package/server/rest/index.js +21 -18
- package/server/route.spec.mjs +458 -0
- package/server/server.mjs +6 -6
- package/server/terminal.js +6 -2
- package/server/terminal.spec.mjs +73 -0
- package/server/{user-menu.js → user-menu.mjs} +17 -17
- package/server/user-menu.spec.mjs +74 -0
- package/server/validate.spec.mjs +104 -0
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
import {createRequire} from 'node:module';
|
|
2
|
+
import process from 'node:process';
|
|
3
|
+
import test from 'supertape';
|
|
4
|
+
import {promisify} from 'node:util';
|
|
5
|
+
import tryToCatch from 'try-to-catch';
|
|
6
|
+
import {connect} from '../../test/before.mjs';
|
|
7
|
+
import {createConfigManager} from '../cloudcmd.mjs';
|
|
8
|
+
|
|
9
|
+
const require = createRequire(import.meta.url);
|
|
10
|
+
|
|
11
|
+
const distribute = {
|
|
12
|
+
import: promisify(require('./import')),
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const config = createConfigManager();
|
|
16
|
+
|
|
17
|
+
process.on('unhandledRejection', console.log);
|
|
18
|
+
|
|
19
|
+
test('distribute: import: canceled', async (t) => {
|
|
20
|
+
const {done} = await connect({
|
|
21
|
+
config: {
|
|
22
|
+
export: false,
|
|
23
|
+
import: false,
|
|
24
|
+
importListen: false,
|
|
25
|
+
log: false,
|
|
26
|
+
},
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const {status} = await distribute.import(config);
|
|
30
|
+
|
|
31
|
+
await done();
|
|
32
|
+
|
|
33
|
+
t.equal(status, 'canceled');
|
|
34
|
+
t.end();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('distribute: import: received: no error', async (t) => {
|
|
38
|
+
const {done, port} = await connect({
|
|
39
|
+
config: {
|
|
40
|
+
import: true,
|
|
41
|
+
importListen: false,
|
|
42
|
+
export: true,
|
|
43
|
+
log: false,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
config('importUrl', `http://localhost:${port}`);
|
|
48
|
+
|
|
49
|
+
const [e] = await tryToCatch(distribute.import, config);
|
|
50
|
+
|
|
51
|
+
await done();
|
|
52
|
+
|
|
53
|
+
t.notOk(e, 'should not be error');
|
|
54
|
+
t.end();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('distribute: import: received', async (t) => {
|
|
58
|
+
const configManager = createConfigManager();
|
|
59
|
+
const {done, port} = await connect({
|
|
60
|
+
configManager,
|
|
61
|
+
config: {
|
|
62
|
+
name: 'bill',
|
|
63
|
+
import: true,
|
|
64
|
+
importToken: 'a',
|
|
65
|
+
exportToken: 'a',
|
|
66
|
+
export: true,
|
|
67
|
+
importListen: false,
|
|
68
|
+
log: false,
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
configManager('importUrl', `http://localhost:${port}`);
|
|
73
|
+
|
|
74
|
+
const {status} = await distribute.import(configManager);
|
|
75
|
+
await done();
|
|
76
|
+
|
|
77
|
+
t.equal(status, 'received');
|
|
78
|
+
t.end();
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('distribute: import: received: auth: reject', async (t) => {
|
|
82
|
+
const configManager = createConfigManager();
|
|
83
|
+
const {done, port} = await connect({
|
|
84
|
+
configManager,
|
|
85
|
+
config: {
|
|
86
|
+
name: 'bill',
|
|
87
|
+
import: true,
|
|
88
|
+
importToken: 'xxxxx',
|
|
89
|
+
exportToken: 'bbbbb',
|
|
90
|
+
export: true,
|
|
91
|
+
importListen: false,
|
|
92
|
+
log: false,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
configManager('importUrl', `http://localhost:${port}`);
|
|
97
|
+
|
|
98
|
+
const {status} = await distribute.import(configManager);
|
|
99
|
+
await done();
|
|
100
|
+
|
|
101
|
+
t.equal(status, 'reject');
|
|
102
|
+
t.end();
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
test('distribute: import: received: auth: accept', async (t) => {
|
|
106
|
+
const configManager = createConfigManager();
|
|
107
|
+
const {done, port} = await connect({
|
|
108
|
+
configManager,
|
|
109
|
+
config: {
|
|
110
|
+
name: 'bill',
|
|
111
|
+
import: true,
|
|
112
|
+
importToken: 'xxxxx',
|
|
113
|
+
exportToken: 'xxxxx',
|
|
114
|
+
export: true,
|
|
115
|
+
importListen: false,
|
|
116
|
+
log: false,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
configManager('importUrl', `http://localhost:${port}`);
|
|
121
|
+
|
|
122
|
+
const {status} = await distribute.import(configManager);
|
|
123
|
+
await done();
|
|
124
|
+
|
|
125
|
+
t.equal(status, 'received');
|
|
126
|
+
t.end();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
test('distribute: import: received: no name', async (t) => {
|
|
130
|
+
const configManager = createConfigManager();
|
|
131
|
+
const {done, port} = await connect({
|
|
132
|
+
configManager,
|
|
133
|
+
config: {
|
|
134
|
+
name: '',
|
|
135
|
+
import: true,
|
|
136
|
+
export: true,
|
|
137
|
+
importListen: false,
|
|
138
|
+
log: false,
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
configManager('importUrl', `http://localhost:${port}`);
|
|
143
|
+
|
|
144
|
+
const {status} = await distribute.import(configManager);
|
|
145
|
+
await done();
|
|
146
|
+
|
|
147
|
+
t.equal(status, 'received');
|
|
148
|
+
t.end();
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test('distribute: import: error', async (t) => {
|
|
152
|
+
const configManager = createConfigManager();
|
|
153
|
+
const {done} = await connect({
|
|
154
|
+
configManager,
|
|
155
|
+
config: {
|
|
156
|
+
import: true,
|
|
157
|
+
export: false,
|
|
158
|
+
importListen: false,
|
|
159
|
+
log: false,
|
|
160
|
+
},
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
configManager('importUrl', `http://localhost:0`);
|
|
164
|
+
|
|
165
|
+
const {status} = await distribute.import(configManager, {
|
|
166
|
+
reconnection: false,
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
await done();
|
|
170
|
+
|
|
171
|
+
t.equal(status, 'connect_error');
|
|
172
|
+
t.end();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
test('distribute: import: config:change: no export', async (t) => {
|
|
176
|
+
const configManager = createConfigManager();
|
|
177
|
+
const {done} = await connect({
|
|
178
|
+
configManager,
|
|
179
|
+
config: {
|
|
180
|
+
import: true,
|
|
181
|
+
export: false,
|
|
182
|
+
importListen: true,
|
|
183
|
+
log: false,
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
const {status} = await distribute.import(configManager, {
|
|
188
|
+
reconnection: false,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
await done();
|
|
192
|
+
|
|
193
|
+
t.equal(status, 'connect_error');
|
|
194
|
+
t.end();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('distribute: import: env', async (t) => {
|
|
198
|
+
const configManager = createConfigManager();
|
|
199
|
+
const configManagerImport = createConfigManager();
|
|
200
|
+
|
|
201
|
+
const exporter = await connect({
|
|
202
|
+
configManager,
|
|
203
|
+
config: {
|
|
204
|
+
name: 'bill',
|
|
205
|
+
import: false,
|
|
206
|
+
importListen: false,
|
|
207
|
+
export: true,
|
|
208
|
+
exportToken: 'a',
|
|
209
|
+
log: false,
|
|
210
|
+
editor: 'edward',
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
const importer = await connect({
|
|
215
|
+
configManager: configManagerImport,
|
|
216
|
+
config: {
|
|
217
|
+
name: 'jack',
|
|
218
|
+
import: true,
|
|
219
|
+
importToken: 'a',
|
|
220
|
+
export: false,
|
|
221
|
+
importListen: false,
|
|
222
|
+
log: false,
|
|
223
|
+
editor: 'deepword',
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
process.env.cloudcmd_editor = 'some editor';
|
|
228
|
+
|
|
229
|
+
configManagerImport('importUrl', `http://localhost:${exporter.port}`);
|
|
230
|
+
|
|
231
|
+
await distribute.import(configManagerImport);
|
|
232
|
+
|
|
233
|
+
await importer.done();
|
|
234
|
+
await exporter.done();
|
|
235
|
+
|
|
236
|
+
delete process.env.cloudcmd_editor;
|
|
237
|
+
|
|
238
|
+
const result = configManagerImport('editor');
|
|
239
|
+
const expected = 'deepword';
|
|
240
|
+
|
|
241
|
+
t.equal(result, expected);
|
|
242
|
+
t.end();
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
test('distribute: import: no env', async (t) => {
|
|
246
|
+
const configManager = createConfigManager();
|
|
247
|
+
const configManagerImport = createConfigManager();
|
|
248
|
+
|
|
249
|
+
const exporter = await connect({
|
|
250
|
+
configManager,
|
|
251
|
+
config: {
|
|
252
|
+
name: 'bill',
|
|
253
|
+
import: false,
|
|
254
|
+
importListen: false,
|
|
255
|
+
export: true,
|
|
256
|
+
exportToken: 'a',
|
|
257
|
+
log: false,
|
|
258
|
+
editor: 'edward',
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
const importer = await connect({
|
|
263
|
+
configManager: configManagerImport,
|
|
264
|
+
config: {
|
|
265
|
+
name: 'jack',
|
|
266
|
+
import: true,
|
|
267
|
+
importToken: 'a',
|
|
268
|
+
export: false,
|
|
269
|
+
importListen: false,
|
|
270
|
+
log: false,
|
|
271
|
+
editor: 'deepword',
|
|
272
|
+
},
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
configManagerImport('importUrl', `http://localhost:${exporter.port}`);
|
|
276
|
+
|
|
277
|
+
await distribute.import(configManagerImport);
|
|
278
|
+
|
|
279
|
+
await importer.done();
|
|
280
|
+
await exporter.done();
|
|
281
|
+
|
|
282
|
+
const result = configManagerImport('editor');
|
|
283
|
+
const expected = 'edward';
|
|
284
|
+
|
|
285
|
+
t.equal(result, expected);
|
|
286
|
+
t.end();
|
|
287
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import {join} from 'node:path';
|
|
3
|
+
import {promisify} from 'node:util';
|
|
4
|
+
import tryToCatch from 'try-to-catch';
|
|
5
|
+
import test from 'supertape';
|
|
6
|
+
import serveOnce from 'serve-once';
|
|
7
|
+
import markdown from './index.js';
|
|
8
|
+
import cloudcmd from '../cloudcmd.mjs';
|
|
9
|
+
|
|
10
|
+
const config = {
|
|
11
|
+
auth: false,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const configManager = cloudcmd.createConfigManager();
|
|
15
|
+
|
|
16
|
+
const {request} = serveOnce(cloudcmd, {
|
|
17
|
+
config,
|
|
18
|
+
configManager,
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const fixtureDir = new URL('fixture', import.meta.url).pathname;
|
|
22
|
+
|
|
23
|
+
const _markdown = promisify(markdown);
|
|
24
|
+
|
|
25
|
+
test('cloudcmd: markdown: error', async (t) => {
|
|
26
|
+
const {body} = await request.get('/api/v1/markdown/not-found');
|
|
27
|
+
|
|
28
|
+
t.match(body, 'ENOENT', 'should not found');
|
|
29
|
+
t.end();
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('cloudcmd: markdown: relative: error', async (t) => {
|
|
33
|
+
const {body} = await request.get('/api/v1/markdown/not-found?relative');
|
|
34
|
+
|
|
35
|
+
t.match(body, 'ENOENT', 'should not found');
|
|
36
|
+
t.end();
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test('cloudcmd: markdown: relative', async (t) => {
|
|
40
|
+
const {body} = await request.get('/api/v1/markdown/HELP.md?relative');
|
|
41
|
+
|
|
42
|
+
t.notOk(/ENOENT/.test(body), 'should not return error');
|
|
43
|
+
t.end();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
test('cloudcmd: markdown: put', async (t) => {
|
|
47
|
+
const md = join(fixtureDir, 'markdown.md');
|
|
48
|
+
const html = join(fixtureDir, 'markdown.html');
|
|
49
|
+
|
|
50
|
+
const mdStream = fs.createReadStream(md);
|
|
51
|
+
const htmlFile = fs.readFileSync(html, 'utf8');
|
|
52
|
+
|
|
53
|
+
const {body} = await request.put('/api/v1/markdown', {
|
|
54
|
+
body: mdStream,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
t.equal(body, htmlFile, 'should render markdown input to html');
|
|
58
|
+
t.end();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
test('cloudcmd: markdown: put: error', async (t) => {
|
|
62
|
+
const md = join(fixtureDir, 'markdown-not-exist.md');
|
|
63
|
+
|
|
64
|
+
const name = 'hello';
|
|
65
|
+
const mdStream = fs.createReadStream(md);
|
|
66
|
+
|
|
67
|
+
mdStream.url = 'http://hello.world';
|
|
68
|
+
mdStream.method = 'PUT';
|
|
69
|
+
|
|
70
|
+
const [e] = await tryToCatch(_markdown, name, '/', mdStream);
|
|
71
|
+
|
|
72
|
+
t.match(e.message, 'ENOENT: no such file or directory', 'should emit error');
|
|
73
|
+
t.end();
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test('cloudcmd: markdown: no name', async (t) => {
|
|
77
|
+
const [e] = await tryToCatch(_markdown);
|
|
78
|
+
|
|
79
|
+
t.equal(e.message, 'name should be string!', 'should throw when no name');
|
|
80
|
+
t.end();
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
test('cloudcmd: markdown: no request', async (t) => {
|
|
84
|
+
const [e] = await tryToCatch(_markdown, 'hello');
|
|
85
|
+
|
|
86
|
+
t.equal(e.message, 'request could not be empty!', 'should throw when no request');
|
|
87
|
+
t.end();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('cloudcmd: markdown', async (t) => {
|
|
91
|
+
const configManager = cloudcmd.createConfigManager();
|
|
92
|
+
const fixtureDir = new URL('fixture', import.meta.url).pathname;
|
|
93
|
+
const config = {
|
|
94
|
+
auth: false,
|
|
95
|
+
root: fixtureDir,
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
const {request} = serveOnce(cloudcmd, {
|
|
99
|
+
config,
|
|
100
|
+
configManager,
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
const {body} = await request.get('/api/v1/markdown/markdown.md');
|
|
104
|
+
|
|
105
|
+
t.equal(body, '<h1>hello</h1>\n');
|
|
106
|
+
t.end();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
test('cloudcmd: markdown: zip', async (t) => {
|
|
110
|
+
const configManager = cloudcmd.createConfigManager();
|
|
111
|
+
const fixtureDir = new URL('fixture', import.meta.url).pathname;
|
|
112
|
+
const config = {
|
|
113
|
+
auth: false,
|
|
114
|
+
root: fixtureDir,
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
const {request} = serveOnce(cloudcmd, {
|
|
118
|
+
config,
|
|
119
|
+
configManager,
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
const {body} = await request.get('/api/v1/markdown/markdown.zip/markdown.md');
|
|
123
|
+
|
|
124
|
+
t.equal(body, '<h1>hello</h1>\n');
|
|
125
|
+
t.end();
|
|
126
|
+
});
|
package/server/rest/index.js
CHANGED
|
@@ -1,16 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
const process = require('node:process');
|
|
4
|
-
const DIR = '../';
|
|
5
|
-
const DIR_COMMON = `${DIR}../common/`;
|
|
6
|
-
|
|
7
3
|
const path = require('node:path');
|
|
8
|
-
const
|
|
4
|
+
const _fs = require('node:fs');
|
|
9
5
|
|
|
10
|
-
const
|
|
11
|
-
const CloudFunc = require(`${DIR_COMMON}cloudfunc`);
|
|
12
|
-
const markdown = require(`${DIR}markdown`);
|
|
13
|
-
const info = require('./info');
|
|
6
|
+
const process = require('node:process');
|
|
14
7
|
|
|
15
8
|
const jaguar = require('jaguar');
|
|
16
9
|
const onezip = require('onezip');
|
|
@@ -22,7 +15,13 @@ const json = require('jonny');
|
|
|
22
15
|
const ponse = require('ponse');
|
|
23
16
|
|
|
24
17
|
const copymitter = require('copymitter');
|
|
25
|
-
const
|
|
18
|
+
const _moveFiles = require('@cloudcmd/move-files');
|
|
19
|
+
|
|
20
|
+
const root = require(`../root`);
|
|
21
|
+
const CloudFunc = require(`../../common/cloudfunc`);
|
|
22
|
+
const markdown = require(`../markdown/index.js`);
|
|
23
|
+
const info = require('./info');
|
|
24
|
+
|
|
26
25
|
const isString = (a) => typeof a === 'string';
|
|
27
26
|
const isFn = (a) => typeof a === 'function';
|
|
28
27
|
const swap = wraptile((fn, a, b) => fn(b, a));
|
|
@@ -37,7 +36,7 @@ const UserError = (msg) => {
|
|
|
37
36
|
return error;
|
|
38
37
|
};
|
|
39
38
|
|
|
40
|
-
module.exports = currify((config, request, response, next) => {
|
|
39
|
+
module.exports = currify(({config, fs = _fs, moveFiles = _moveFiles}, request, response, next) => {
|
|
41
40
|
const name = ponse.getPathName(request);
|
|
42
41
|
const regExp = RegExp(`^${apiURL}`);
|
|
43
42
|
const is = regExp.test(name);
|
|
@@ -45,10 +44,10 @@ module.exports = currify((config, request, response, next) => {
|
|
|
45
44
|
if (!is)
|
|
46
45
|
return next();
|
|
47
46
|
|
|
48
|
-
rest(config, request, response);
|
|
47
|
+
rest({fs, config, moveFiles}, request, response);
|
|
49
48
|
});
|
|
50
49
|
|
|
51
|
-
function rest(config, request, response) {
|
|
50
|
+
function rest({fs, config, moveFiles}, request, response) {
|
|
52
51
|
const name = ponse.getPathName(request);
|
|
53
52
|
const params = {
|
|
54
53
|
request,
|
|
@@ -56,7 +55,7 @@ function rest(config, request, response) {
|
|
|
56
55
|
name: name.replace(apiURL, '') || '/',
|
|
57
56
|
};
|
|
58
57
|
|
|
59
|
-
sendData(params, config, (error, options, data) => {
|
|
58
|
+
sendData(params, {fs, config, moveFiles}, (error, options, data) => {
|
|
60
59
|
params.gzip = !error;
|
|
61
60
|
|
|
62
61
|
if (!data) {
|
|
@@ -87,8 +86,10 @@ function rest(config, request, response) {
|
|
|
87
86
|
* getting data on method and command
|
|
88
87
|
*
|
|
89
88
|
* @param params {name, method, body, requrest, response}
|
|
89
|
+
* @param config {}
|
|
90
|
+
* @param callback
|
|
90
91
|
*/
|
|
91
|
-
function sendData(params, config, callback) {
|
|
92
|
+
function sendData(params, {fs, config, moveFiles}, callback) {
|
|
92
93
|
const p = params;
|
|
93
94
|
const isMD = p.name.startsWith('/markdown');
|
|
94
95
|
const rootDir = config('root');
|
|
@@ -107,6 +108,8 @@ function sendData(params, config, callback) {
|
|
|
107
108
|
.then((body) => {
|
|
108
109
|
onPUT({
|
|
109
110
|
name: p.name,
|
|
111
|
+
fs,
|
|
112
|
+
moveFiles,
|
|
110
113
|
config,
|
|
111
114
|
body,
|
|
112
115
|
}, callback);
|
|
@@ -185,7 +188,7 @@ const getRenameMsg = (from, to) => {
|
|
|
185
188
|
};
|
|
186
189
|
|
|
187
190
|
module.exports._onPUT = onPUT;
|
|
188
|
-
function onPUT({name, config, body}, callback) {
|
|
191
|
+
function onPUT({name, fs, moveFiles, config, body}, callback) {
|
|
189
192
|
checkPut(name, body, callback);
|
|
190
193
|
|
|
191
194
|
const cmd = getCMD(name);
|
|
@@ -221,7 +224,7 @@ function onPUT({name, config, body}, callback) {
|
|
|
221
224
|
}
|
|
222
225
|
|
|
223
226
|
case 'rename':
|
|
224
|
-
return rename(rootDir, files.from, files.to, callback);
|
|
227
|
+
return rename(rootDir, files.from, files.to, fs, callback);
|
|
225
228
|
|
|
226
229
|
case 'copy':
|
|
227
230
|
if (!files.from || !files.names || !files.to)
|
|
@@ -260,7 +263,7 @@ function onPUT({name, config, body}, callback) {
|
|
|
260
263
|
}
|
|
261
264
|
}
|
|
262
265
|
|
|
263
|
-
function rename(rootDir, from, to, callback) {
|
|
266
|
+
function rename(rootDir, from, to, fs, callback) {
|
|
264
267
|
if (!from)
|
|
265
268
|
return callback(UserError('"from" should be filled'));
|
|
266
269
|
|