1. 1 : /* eslint max-params: [1, 5] */
  2. 2 : const assert = require('assert');
  3. 3 :
  4. 4 : /**
  5. 5 : * @mixin
  6. 6 : * @alias actions/fs
  7. 7 : */
  8. 8 : const fs = module.exports;
  9. 9 :
  10. 10 : const renderEachTemplate = (template, templateData, context, callback) => {
  11. 11 : if (template.when && !template.when(templateData, context)) {
  12. 12 : return;
  13. 13 : }
  14. 14 :
  15. 15 : const {source, destination, templateOptions, copyOptions} = template;
  16. 16 : return callback(
  17. 17 : source,
  18. 18 : destination,
  19. 19 : templateData,
  20. 20 : templateOptions,
  21. 21 : copyOptions
  22. 22 : );
  23. 23 : };
  24. 24 :
  25. 25 : /**
  26. 26 : * Read file from templates folder.
  27. 27 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  28. 28 : * Shortcut for this.fs.read(this.templatePath(filepath))
  29. 29 : *
  30. 30 : * @param {String} filepath - absolute file path or relative to templates folder.
  31. 31 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  32. 32 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  33. 33 : */
  34. 34 : fs.readTemplate = function (filepath, ...args) {
  35. 35 : return this.fs.read(this.templatePath(filepath), ...args);
  36. 36 : };
  37. 37 :
  38. 38 : /**
  39. 39 : * Copy file from templates folder to destination folder.
  40. 40 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  41. 41 : * Shortcut for this.fs.copy(this.templatePath(from), this.destinationPath(to))
  42. 42 : *
  43. 43 : * @param {String} from - absolute file path or relative to templates folder.
  44. 44 : * @param {String} to - absolute file path or relative to destination folder.
  45. 45 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  46. 46 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  47. 47 : */
  48. 48 : fs.copyTemplate = function (from, to, ...args) {
  49. 49 : return this.fs.copy(
  50. 50 : this.templatePath(from),
  51. 51 : this.destinationPath(to),
  52. 52 : ...args
  53. 53 : );
  54. 54 : };
  55. 55 :
  56. 56 : /**
  57. 57 : * Copy file from templates folder to destination folder.
  58. 58 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  59. 59 : * Shortcut for this.fs.copy(this.templatePath(from), this.destinationPath(to))
  60. 60 : *
  61. 61 : * @param {String} from - absolute file path or relative to templates folder.
  62. 62 : * @param {String} to - absolute file path or relative to destination folder.
  63. 63 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  64. 64 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  65. 65 : */
  66. 66 : fs.copyTemplateAsync = function (from, to, ...args) {
  67. 67 : this.checkEnvironmentVersion('mem-fs-editor', '9.0.0');
  68. 68 : return this.fs.copyAsync(
  69. 69 : this.templatePath(from),
  70. 70 : this.destinationPath(to),
  71. 71 : ...args
  72. 72 : );
  73. 73 : };
  74. 74 :
  75. 75 : /**
  76. 76 : * Read file from destination folder
  77. 77 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  78. 78 : * Shortcut for this.fs.read(this.destinationPath(filepath)).
  79. 79 : *
  80. 80 : * @param {String} filepath - absolute file path or relative to destination folder.
  81. 81 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  82. 82 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  83. 83 : */
  84. 84 : fs.readDestination = function (filepath, ...args) {
  85. 85 : return this.fs.read(this.destinationPath(filepath), ...args);
  86. 86 : };
  87. 87 :
  88. 88 : /**
  89. 89 : * Read JSON file from destination folder
  90. 90 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  91. 91 : * Shortcut for this.fs.readJSON(this.destinationPath(filepath)).
  92. 92 : *
  93. 93 : * @param {String} filepath - absolute file path or relative to destination folder.
  94. 94 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  95. 95 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  96. 96 : */
  97. 97 : fs.readDestinationJSON = function (filepath, ...args) {
  98. 98 : return this.fs.readJSON(this.destinationPath(filepath), ...args);
  99. 99 : };
  100. 100 :
  101. 101 : /**
  102. 102 : * Write file to destination folder
  103. 103 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  104. 104 : * Shortcut for this.fs.write(this.destinationPath(filepath)).
  105. 105 : *
  106. 106 : * @param {String} filepath - absolute file path or relative to destination folder.
  107. 107 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  108. 108 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  109. 109 : */
  110. 110 : fs.writeDestination = function (filepath, ...args) {
  111. 111 : return this.fs.write(this.destinationPath(filepath), ...args);
  112. 112 : };
  113. 113 :
  114. 114 : /**
  115. 115 : * Write json file to destination folder
  116. 116 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  117. 117 : * Shortcut for this.fs.writeJSON(this.destinationPath(filepath)).
  118. 118 : *
  119. 119 : * @param {String} filepath - absolute file path or relative to destination folder.
  120. 120 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  121. 121 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  122. 122 : */
  123. 123 : fs.writeDestinationJSON = function (filepath, ...args) {
  124. 124 : return this.fs.writeJSON(this.destinationPath(filepath), ...args);
  125. 125 : };
  126. 126 :
  127. 127 : /**
  128. 128 : * Delete file from destination folder
  129. 129 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  130. 130 : * Shortcut for this.fs.delete(this.destinationPath(filepath)).
  131. 131 : *
  132. 132 : * @param {String} filepath - absolute file path or relative to destination folder.
  133. 133 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  134. 134 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  135. 135 : */
  136. 136 : fs.deleteDestination = function (filepath, ...args) {
  137. 137 : return this.fs.delete(this.destinationPath(filepath), ...args);
  138. 138 : };
  139. 139 :
  140. 140 : /**
  141. 141 : * Copy file from destination folder to another destination folder.
  142. 142 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  143. 143 : * Shortcut for this.fs.copy(this.destinationPath(from), this.destinationPath(to)).
  144. 144 : *
  145. 145 : * @param {String} from - absolute file path or relative to destination folder.
  146. 146 : * @param {String} to - absolute file path or relative to destination folder.
  147. 147 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  148. 148 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  149. 149 : */
  150. 150 : fs.copyDestination = function (from, to, ...args) {
  151. 151 : return this.fs.copy(
  152. 152 : this.destinationPath(from),
  153. 153 : this.destinationPath(to),
  154. 154 : ...args
  155. 155 : );
  156. 156 : };
  157. 157 :
  158. 158 : /**
  159. 159 : * Move file from destination folder to another destination folder.
  160. 160 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  161. 161 : * Shortcut for this.fs.move(this.destinationPath(from), this.destinationPath(to)).
  162. 162 : *
  163. 163 : * @param {String} from - absolute file path or relative to destination folder.
  164. 164 : * @param {String} to - absolute file path or relative to destination folder.
  165. 165 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  166. 166 : */
  167. 167 : fs.moveDestination = function (from, to, ...args) {
  168. 168 : return this.fs.move(
  169. 169 : this.destinationPath(from),
  170. 170 : this.destinationPath(to),
  171. 171 : ...args
  172. 172 : );
  173. 173 : };
  174. 174 :
  175. 175 : /**
  176. 176 : * Exists file on destination folder.
  177. 177 : * mem-fs-editor method's shortcut, for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}.
  178. 178 : * Shortcut for this.fs.exists(this.destinationPath(filepath)).
  179. 179 : *
  180. 180 : * @param {String} filepath - absolute file path or relative to destination folder.
  181. 181 : * @param {...*} args - for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  182. 182 : * @returns {*} for more information see [mem-fs-editor]{@link https://github.com/SBoudrias/mem-fs-editor}
  183. 183 : */
  184. 184 : fs.existsDestination = function (filepath, ...args) {
  185. 185 : return this.fs.exists(this.destinationPath(filepath), ...args);
  186. 186 : };
  187. 187 :
  188. 188 : /**
  189. 189 : * Copy a template from templates folder to the destination.
  190. 190 : *
  191. 191 : * @param {String|Array} source - template file, absolute or relative to templatePath().
  192. 192 : * @param {String|Array} [destination] - destination, absolute or relative to destinationPath().
  193. 193 : * @param {Object} [templateData] - ejs data
  194. 194 : * @param {Object} [templateOptions] - ejs options
  195. 195 : * @param {Object} [copyOptions] - mem-fs-editor copy options
  196. 196 : */
  197. 197 : fs.renderTemplate = function (
  198. 198 : source = '',
  199. 199 : destination = source,
  200. 200 : templateData = this._templateData(),
  201. 201 : templateOptions,
  202. 202 : copyOptions
  203. 203 : ) {
  204. 204 : if (typeof templateData === 'string') {
  205. 205 : templateData = this._templateData(templateData);
  206. 206 : }
  207. 207 :
  208. 208 : templateOptions = {context: this, ...templateOptions};
  209. 209 :
  210. 210 : source = Array.isArray(source) ? source : [source];
  211. 211 : const templatePath = this.templatePath(...source);
  212. 212 : destination = Array.isArray(destination) ? destination : [destination];
  213. 213 : const destinationPath = this.destinationPath(...destination);
  214. 214 :
  215. 215 : this.fs.copyTpl(
  216. 216 : templatePath,
  217. 217 : destinationPath,
  218. 218 : templateData,
  219. 219 : templateOptions,
  220. 220 : copyOptions
  221. 221 : );
  222. 222 : };
  223. 223 :
  224. 224 : /**
  225. 225 : * Copy a template from templates folder to the destination.
  226. 226 : *
  227. 227 : * @param {String|Array} source - template file, absolute or relative to templatePath().
  228. 228 : * @param {String|Array} [destination] - destination, absolute or relative to destinationPath().
  229. 229 : * @param {Object} [templateData] - ejs data
  230. 230 : * @param {Object} [templateOptions] - ejs options
  231. 231 : * @param {Object} [copyOptions] - mem-fs-editor copy options
  232. 232 : */
  233. 233 : fs.renderTemplateAsync = function (
  234. 234 : source = '',
  235. 235 : destination = source,
  236. 236 : templateData = this._templateData(),
  237. 237 : templateOptions,
  238. 238 : copyOptions
  239. 239 : ) {
  240. 240 : this.checkEnvironmentVersion('mem-fs-editor', '9.0.0');
  241. 241 : if (typeof templateData === 'string') {
  242. 242 : templateData = this._templateData(templateData);
  243. 243 : }
  244. 244 :
  245. 245 : templateOptions = {context: this, ...templateOptions};
  246. 246 :
  247. 247 : source = Array.isArray(source) ? source : [source];
  248. 248 : const templatePath = this.templatePath(...source);
  249. 249 : destination = Array.isArray(destination) ? destination : [destination];
  250. 250 : const destinationPath = this.destinationPath(...destination);
  251. 251 :
  252. 252 : return this.fs.copyTplAsync(
  253. 253 : templatePath,
  254. 254 : destinationPath,
  255. 255 : templateData,
  256. 256 : templateOptions,
  257. 257 : copyOptions
  258. 258 : );
  259. 259 : };
  260. 260 :
  261. 261 : /**
  262. 262 : * Copy templates from templates folder to the destination.
  263. 263 : *
  264. 264 : * @param {Array} templates - template file, absolute or relative to templatePath().
  265. 265 : * @param {function} [templates.when] - conditional if the template should be written.
  266. 266 : * First argument is the templateData, second is the generator.
  267. 267 : * @param {String|Array} templates.source - template file, absolute or relative to templatePath().
  268. 268 : * @param {String|Array} [templates.destination] - destination, absolute or relative to destinationPath().
  269. 269 : * @param {Object} [templates.templateOptions] - ejs options
  270. 270 : * @param {Object} [templates.copyOptions] - mem-fs-editor copy options
  271. 271 : * @param {Object} [templateData] - ejs data
  272. 272 : */
  273. 273 : fs.renderTemplates = function (templates, templateData = this._templateData()) {
  274. 274 : assert(Array.isArray(templates), 'Templates must an array');
  275. 275 : if (typeof templateData === 'string') {
  276. 276 : templateData = this._templateData(templateData);
  277. 277 : }
  278. 278 :
  279. 279 : for (const template of templates)
  280. 280 : renderEachTemplate(template, templateData, this, (...args) =>
  281. 281 : this.renderTemplate(...args)
  282. 282 : );
  283. 283 : };
  284. 284 :
  285. 285 : /**
  286. 286 : * Copy templates from templates folder to the destination.
  287. 287 : *
  288. 288 : * @param {Array} templates - template file, absolute or relative to templatePath().
  289. 289 : * @param {function} [templates.when] - conditional if the template should be written.
  290. 290 : * First argument is the templateData, second is the generator.
  291. 291 : * @param {String|Array} templates.source - template file, absolute or relative to templatePath().
  292. 292 : * @param {String|Array} [templates.destination] - destination, absolute or relative to destinationPath().
  293. 293 : * @param {Object} [templates.templateOptions] - ejs options
  294. 294 : * @param {Object} [templates.copyOptions] - mem-fs-editor copy options
  295. 295 : * @param {Object} [templateData] - ejs data
  296. 296 : */
  297. 297 : fs.renderTemplatesAsync = function (
  298. 298 : templates,
  299. 299 : templateData = this._templateData()
  300. 300 : ) {
  301. 301 : assert(Array.isArray(templates), 'Templates must an array');
  302. 302 : this.checkEnvironmentVersion('mem-fs-editor', '9.0.0');
  303. 303 : if (typeof templateData === 'string') {
  304. 304 : templateData = this._templateData(templateData);
  305. 305 : }
  306. 306 :
  307. 307 : return Promise.all(
  308. 308 : templates.map((template) =>
  309. 309 : renderEachTemplate(template, templateData, this, (...args) =>
  310. 310 : this.renderTemplateAsync(...args)
  311. 311 : )
  312. 312 : )
  313. 313 : );
  314. 314 : };
  315. 315 :
  316. 316 : /**
  317. 317 : * Utility method to get a formatted data for templates.
  318. 318 : *
  319. 319 : * @param {String} path - path to the storage key.
  320. 320 : * @return {Object} data to be passed to the templates.
  321. 321 : */
  322. 322 : fs._templateData = function (path) {
  323. 323 : if (path) {
  324. 324 : return this.config.getPath(path);
  325. 325 : }
  326. 326 :
  327. 327 : const allConfig = this.config.getAll();
  328. 328 : if (this.generatorConfig) {
  329. 329 : Object.assign(allConfig, this.generatorConfig.getAll());
  330. 330 : }
  331. 331 :
  332. 332 : if (this.instanceConfig) {
  333. 333 : Object.assign(allConfig, this.instanceConfig.getAll());
  334. 334 : }
  335. 335 :
  336. 336 : return allConfig;
  337. 337 : };