You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

160 lines
4.6 KiB

4 years ago
  1. /*!
  2. * write <https://github.com/jonschlinkert/write>
  3. *
  4. * Copyright (c) 2014-2017, Jon Schlinkert.
  5. * Released under the MIT License.
  6. */
  7. 'use strict';
  8. var fs = require('fs');
  9. var path = require('path');
  10. var mkdirp = require('mkdirp');
  11. /**
  12. * Asynchronously writes data to a file, replacing the file if it already
  13. * exists and creating any intermediate directories if they don't already
  14. * exist. Data can be a string or a buffer. Returns a promise if a callback
  15. * function is not passed.
  16. *
  17. * ```js
  18. * var writeFile = require('write');
  19. * writeFile('foo.txt', 'This is content...', function(err) {
  20. * if (err) console.log(err);
  21. * });
  22. *
  23. * // promise
  24. * writeFile('foo.txt', 'This is content...')
  25. * .then(function() {
  26. * // do stuff
  27. * });
  28. * ```
  29. * @name writeFile
  30. * @param {string|Buffer|integer} `filepath` filepath or file descriptor.
  31. * @param {string|Buffer|Uint8Array} `data` String to write to disk.
  32. * @param {object} `options` Options to pass to [fs.writeFile][fs]{#fs_fs_writefile_file_data_options_callback} and/or [mkdirp][]
  33. * @param {Function} `callback` (optional) If no callback is provided, a promise is returned.
  34. * @api public
  35. */
  36. function writeFile(filepath, data, options, cb) {
  37. if (typeof options === 'function') {
  38. cb = options;
  39. options = {};
  40. }
  41. if (typeof cb !== 'function') {
  42. return writeFile.promise.apply(null, arguments);
  43. }
  44. if (typeof filepath !== 'string') {
  45. cb(new TypeError('expected filepath to be a string'));
  46. return;
  47. }
  48. mkdirp(path.dirname(filepath), options, function(err) {
  49. if (err) {
  50. cb(err);
  51. return;
  52. }
  53. fs.writeFile(filepath, data, options, cb);
  54. });
  55. };
  56. /**
  57. * The promise version of [writeFile](#writefile). Returns a promise.
  58. *
  59. * ```js
  60. * var writeFile = require('write');
  61. * writeFile.promise('foo.txt', 'This is content...')
  62. * .then(function() {
  63. * // do stuff
  64. * });
  65. * ```
  66. * @name .promise
  67. * @param {string|Buffer|integer} `filepath` filepath or file descriptor.
  68. * @param {string|Buffer|Uint8Array} `val` String or buffer to write to disk.
  69. * @param {object} `options` Options to pass to [fs.writeFile][fs]{#fs_fs_writefile_file_data_options_callback} and/or [mkdirp][]
  70. * @return {Promise}
  71. * @api public
  72. */
  73. writeFile.promise = function(filepath, val, options) {
  74. if (typeof filepath !== 'string') {
  75. return Promise.reject(new TypeError('expected filepath to be a string'));
  76. }
  77. return new Promise(function(resolve, reject) {
  78. mkdirp(path.dirname(filepath), options, function(err) {
  79. if (err) {
  80. reject(err);
  81. return;
  82. }
  83. fs.writeFile(filepath, val, options, function(err) {
  84. if (err) {
  85. reject(err);
  86. return;
  87. }
  88. resolve(val);
  89. });
  90. });
  91. });
  92. };
  93. /**
  94. * The synchronous version of [writeFile](#writefile). Returns undefined.
  95. *
  96. * ```js
  97. * var writeFile = require('write');
  98. * writeFile.sync('foo.txt', 'This is content...');
  99. * ```
  100. * @name .sync
  101. * @param {string|Buffer|integer} `filepath` filepath or file descriptor.
  102. * @param {string|Buffer|Uint8Array} `data` String or buffer to write to disk.
  103. * @param {object} `options` Options to pass to [fs.writeFileSync][fs]{#fs_fs_writefilesync_file_data_options} and/or [mkdirp][]
  104. * @return {undefined}
  105. * @api public
  106. */
  107. writeFile.sync = function(filepath, data, options) {
  108. if (typeof filepath !== 'string') {
  109. throw new TypeError('expected filepath to be a string');
  110. }
  111. mkdirp.sync(path.dirname(filepath), options);
  112. fs.writeFileSync(filepath, data, options);
  113. };
  114. /**
  115. * Uses `fs.createWriteStream` to write data to a file, replacing the
  116. * file if it already exists and creating any intermediate directories
  117. * if they don't already exist. Data can be a string or a buffer. Returns
  118. * a new [WriteStream](https://nodejs.org/api/fs.html#fs_class_fs_writestream)
  119. * object.
  120. *
  121. * ```js
  122. * var fs = require('fs');
  123. * var writeFile = require('write');
  124. * fs.createReadStream('README.md')
  125. * .pipe(writeFile.stream('a/b/c/other-file.md'))
  126. * .on('close', function() {
  127. * // do stuff
  128. * });
  129. * ```
  130. * @name .stream
  131. * @param {string|Buffer|integer} `filepath` filepath or file descriptor.
  132. * @param {object} `options` Options to pass to [mkdirp][] and [fs.createWriteStream][fs]{#fs_fs_createwritestream_path_options}
  133. * @return {Stream} Returns a new [WriteStream](https://nodejs.org/api/fs.html#fs_class_fs_writestream) object. (See [Writable Stream](https://nodejs.org/api/stream.html#stream_class_stream_writable)).
  134. * @api public
  135. */
  136. writeFile.stream = function(filepath, options) {
  137. mkdirp.sync(path.dirname(filepath), options);
  138. return fs.createWriteStream(filepath, options);
  139. };
  140. /**
  141. * Expose `writeFile`
  142. */
  143. module.exports = writeFile;