UNPKG

2.96 kBJavaScriptView Raw
1"use strict";
2
3const pathUtil = require("path");
4const fs = require("./utils/fs");
5const validate = require("./utils/validate");
6const dir = require("./dir");
7const exists = require("./exists");
8
9const validateInput = (methodName, from, to) => {
10 const methodSignature = `${methodName}(from, to)`;
11 validate.argument(methodSignature, "from", from, ["string"]);
12 validate.argument(methodSignature, "to", to, ["string"]);
13};
14
15const generateSourceDoesntExistError = path => {
16 const err = new Error(`Path to move doesn't exist ${path}`);
17 err.code = "ENOENT";
18 return err;
19};
20
21// ---------------------------------------------------------
22// Sync
23// ---------------------------------------------------------
24
25const moveSync = (from, to) => {
26 try {
27 fs.renameSync(from, to);
28 } catch (err) {
29 if (err.code !== "ENOENT") {
30 // We can't make sense of this error. Rethrow it.
31 throw err;
32 } else {
33 // Ok, source or destination path doesn't exist.
34 // Must do more investigation.
35 if (!exists.sync(from)) {
36 throw generateSourceDoesntExistError(from);
37 }
38 if (!exists.sync(to)) {
39 // Some parent directory doesn't exist. Create it.
40 dir.createSync(pathUtil.dirname(to));
41 // Retry the attempt
42 fs.renameSync(from, to);
43 }
44 }
45 }
46};
47
48// ---------------------------------------------------------
49// Async
50// ---------------------------------------------------------
51
52const ensureDestinationPathExistsAsync = to => {
53 return new Promise((resolve, reject) => {
54 const destDir = pathUtil.dirname(to);
55 exists
56 .async(destDir)
57 .then(dstExists => {
58 if (!dstExists) {
59 dir.createAsync(destDir).then(resolve, reject);
60 } else {
61 // Hah, no idea.
62 reject();
63 }
64 })
65 .catch(reject);
66 });
67};
68
69const moveAsync = (from, to) => {
70 return new Promise((resolve, reject) => {
71 fs.rename(from, to)
72 .then(resolve)
73 .catch(err => {
74 if (err.code !== "ENOENT") {
75 // Something unknown. Rethrow original error.
76 reject(err);
77 } else {
78 // Ok, source or destination path doesn't exist.
79 // Must do more investigation.
80 exists
81 .async(from)
82 .then(srcExists => {
83 if (!srcExists) {
84 reject(generateSourceDoesntExistError(from));
85 } else {
86 ensureDestinationPathExistsAsync(to)
87 .then(() => {
88 // Retry the attempt
89 return fs.rename(from, to);
90 })
91 .then(resolve, reject);
92 }
93 })
94 .catch(reject);
95 }
96 });
97 });
98};
99
100// ---------------------------------------------------------
101// API
102// ---------------------------------------------------------
103
104exports.validateInput = validateInput;
105exports.sync = moveSync;
106exports.async = moveAsync;