git ssb

0+

Rômulo Alves / sync



Tree: fc4f77ebcef3769ee736b18653f7712ef8169884

Files: fc4f77ebcef3769ee736b18653f7712ef8169884 / utils.js

4170 bytesRaw
1const { PassThrough } = require('stream');
2const { stat, access } = require('fs');
3const fs = require('fs-extra');
4const { createReadStream, createWriteStream, utimes } = require('fs');
5const { createCipher, createDecipher } = require('crypto');
6const { join } = require('path');
7const { createGzip, createGunzip } = require('zlib');
8
9const combiner = require('stream-combiner');
10
11/**
12 * @function getStats
13 * @description Returns the directory/file stat
14 * @param {String} path Path to verify
15 * @return {Promies<Object>} Null if an error happens or the object of stat
16 */
17const getStats = path =>
18 new Promise(resolve => {
19 return stat(path, (err, stat) => {
20 if (err) {
21 // File does not exist
22 return resolve(null);
23 }
24
25 // Return stat
26 return resolve(stat);
27 });
28 });
29
30module.exports.getStats = getStats;
31
32/**
33 * @function exists
34 * @description Returns if a path exists
35 * @param {String} path Path to verify
36 * @return {Promise<Boolean>} Returns a boolean to indicate if path exists
37 */
38module.exports.exists = path =>
39 new Promise(resolve => {
40 return access(path, err => {
41 if (err) {
42 return resolve(false);
43 }
44
45 return resolve(true);
46 });
47 });
48
49/**
50 * @function delete
51 * @description Deletes the path
52 * @param {String} path Path to delete
53 * @return {Promise} Resolves after deleted
54 */
55module.exports.delete = path =>
56 new Promise(resolve => {
57 return fs.remove(path, () => resolve());
58 });
59
60/**
61 * @function copy
62 * @description Copies the file from the source to the target path
63 * @param {String} source File path to copy
64 * @param {String} target Path to put the file
65 * @param {String} crypt The cipher algorithm and key
66 * @param {String} decrypt The decipher algorithm and key
67 * @return {Promise<Object>} Resolves if was OK or rejects with the error object
68 */
69module.exports.copy = (source, target, crypt, decrypt) =>
70 new Promise(async (resolve, reject) => {
71 const [ statSource, statTarget ] = await Promise.all([ getStats(source), getStats(target) ]);
72
73 if (!statSource) {
74 return reject(new Error('Source does not exists.'));
75 }
76
77 if (!statSource.isFile() || (statTarget && !statTarget.isFile())) {
78 return reject(new Error(`It's possible just to copy files.`));
79 }
80
81 let cryptOrDecryptFn = null;
82 let zipFn = null;
83 let unzipFn = null;
84
85 if (crypt) {
86
87 // Set function to crypt
88 cryptOrDecryptFn = createCipher(crypt.algorithm, crypt.password);
89 zipFn = createGzip();
90 unzipFn = new PassThrough();
91 } else if (decrypt) {
92
93 // Set function to decrypt
94 cryptOrDecryptFn = createDecipher(decrypt.algorithm, decrypt.password);
95 zipFn = new PassThrough();
96 unzipFn = createGunzip();
97 } else {
98
99 // Set empty stream just to pipe
100 cryptOrDecryptFn = new PassThrough();
101 zipFn = new PassThrough();
102 unzipFn = new PassThrough();
103 }
104
105 const destStream = createWriteStream(target);
106 destStream.on('finish', () => {
107
108 // Change target modificate time
109 return utimes(target, statSource.atime, statSource.mtime, () => {
110 return resolve();
111 });
112 });
113 destStream.on('error', err => reject(err));
114
115 const combinedStreams = combiner([
116 zipFn,
117 cryptOrDecryptFn,
118 unzipFn
119 ]);
120
121 // Read the file > crypt/decrypt > write to the target > resolve the promise
122 return createReadStream(source)
123 .pipe(combinedStreams)
124 .pipe(destStream);
125 });
126
127/**
128 * @function readRecursive
129 * @description Reads recursivelly a path
130 * @param {String} source Path to copy
131 * @param {String} target Target path
132 * @return {Promise<Array<Array<String>>>} Resolves with the paths if was OK or rejects with the error object
133 */
134module.exports.readRecursive = (source, target) =>
135 new Promise((resolve, reject) => {
136
137 // Read things inside dir
138 return fs.readdir(source, (err, files) => {
139 if (err) {
140 return reject(err);
141 }
142
143 // Return an array with new source and target
144 const pathsParsed = files.map(f => [
145 join(source, f),
146 join(target, f)
147 ]);
148 });
149 });

Built with git-ssb-web