UNPKG

3.23 kBJavaScriptView Raw
1'use strict';
2
3var _ = require('lodash'),
4 fs = require('fs'),
5 path = require('path');
6
7/** Used to indicate if running in Windows. */
8var isWindows = process.platform == 'win32';
9
10/**
11 * The escaped path separator used for inclusion in RegExp strings.
12 *
13 * @memberOf util.path
14 * @type string
15 */
16var sepEscaped = _.escapeRegExp(path.sep);
17
18/** Used to determine if a path is prefixed with a drive letter or dot-slash. */
19var rePrefixed = RegExp('^(?:' + (isWindows ? '[a-zA-Z]:|' : '') + '\\.?)' + sepEscaped);
20
21/*----------------------------------------------------------------------------*/
22
23/**
24 * Creates a hash object. If a `properties` object is provided, its own
25 * enumerable properties are assigned to the created object.
26 *
27 * @memberOf util
28 * @param {Object} [properties] The properties to assign to the object.
29 * @returns {Object} Returns the new hash object.
30 */
31function Hash(properties) {
32 return _.transform(properties, function(result, value, key) {
33 result[key] = (_.isPlainObject(value) && !(value instanceof Hash))
34 ? new Hash(value)
35 : value;
36 }, this);
37}
38
39Hash.prototype = Object.create(null);
40
41/**
42 * Makes the given `dirname` directory, without throwing errors for existing
43 * directories and making parent directories as needed.
44 *
45 * @memberOf util.fs
46 * @param {string} dirname The path of the directory.
47 * @param {number|string} [mode='0777'] The permission mode.
48 */
49function mkdirpSync(dirname, mode) {
50 var sep = path.sep;
51 dirname = path.normalize(dirname);
52
53 // Ensure relative paths are prefixed with `./`.
54 if (!rePrefixed.test(dirname)) {
55 dirname = '.' + sep + dirname;
56 }
57 dirname.split(sep).reduce(function(currPath, segment) {
58 currPath += sep + segment;
59 try {
60 currPath = fs.realpathSync(currPath);
61 } catch (e) {
62 fs.mkdirSync(currPath, mode);
63 }
64 return currPath;
65 });
66}
67
68/**
69 * Removes files or directories and their contents recursively.
70 *
71 * @memberOf util.fs
72 * @param {string} pathname The path of the file or directory.
73 */
74function rmrfSync(pathname) {
75 var sep = path.sep;
76 pathname = path.normalize(pathname);
77
78 // Safety first! Limit to modifying lodash-cli.
79 if (!_.startsWith(pathname, path.dirname(__dirname) + sep)) {
80 return;
81 }
82 try {
83 pathname = fs.realpathSync(pathname);
84 } catch (e) {
85 return;
86 }
87 if (!fs.statSync(pathname).isDirectory()) {
88 fs.unlinkSync(pathname);
89 return;
90 }
91 _.each(fs.readdirSync(pathname), function(identifier) {
92 var currPath = path.join(pathname, identifier);
93 if (fs.statSync(currPath).isDirectory()) {
94 rmrfSync(currPath);
95 } else {
96 fs.unlinkSync(currPath);
97 }
98 });
99 fs.rmdirSync(pathname);
100}
101
102/*----------------------------------------------------------------------------*/
103
104/**
105 * The utility object.
106 *
107 * @type Object
108 */
109var util = {
110
111 'Hash': Hash,
112
113 /**
114 * The file system object.
115 *
116 * @memberOf util
117 * @type Object
118 */
119 'fs': _.defaults(_.cloneDeep(fs), {
120 'mkdirpSync': mkdirpSync,
121 'rmrfSync': rmrfSync
122 }),
123
124 /**
125 * The path object.
126 *
127 * @memberOf util
128 * @type Object
129 */
130 'path': _.defaults(_.cloneDeep(path), {
131 'sepEscaped': sepEscaped
132 })
133};
134
135module.exports = util;