index.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. 'use strict';
  2. var Transform = require('readable-stream/transform');
  3. var rs = require('replacestream');
  4. var istextorbinary = require('istextorbinary');
  5. module.exports = function(search, _replacement, options) {
  6. if (!options) {
  7. options = {};
  8. }
  9. if (options.skipBinary === undefined) {
  10. options.skipBinary = true;
  11. }
  12. return new Transform({
  13. objectMode: true,
  14. transform: function(file, enc, callback) {
  15. if (file.isNull()) {
  16. return callback(null, file);
  17. }
  18. var replacement = _replacement;
  19. if (typeof _replacement === 'function') {
  20. // Pass the vinyl file object as this.file
  21. replacement = _replacement.bind({ file: file });
  22. }
  23. function doReplace() {
  24. if (file.isStream()) {
  25. file.contents = file.contents.pipe(rs(search, replacement));
  26. return callback(null, file);
  27. }
  28. if (file.isBuffer()) {
  29. if (search instanceof RegExp) {
  30. file.contents = new Buffer(String(file.contents).replace(search, replacement));
  31. }
  32. else {
  33. var chunks = String(file.contents).split(search);
  34. var result;
  35. if (typeof replacement === 'function') {
  36. // Start with the first chunk already in the result
  37. // Replacements will be added thereafter
  38. // This is done to avoid checking the value of i in the loop
  39. result = [ chunks[0] ];
  40. // The replacement function should be called once for each match
  41. for (var i = 1; i < chunks.length; i++) {
  42. // Add the replacement value
  43. result.push(replacement(search));
  44. // Add the next chunk
  45. result.push(chunks[i]);
  46. }
  47. result = result.join('');
  48. }
  49. else {
  50. result = chunks.join(replacement);
  51. }
  52. file.contents = new Buffer(result);
  53. }
  54. return callback(null, file);
  55. }
  56. callback(null, file);
  57. }
  58. if (options && options.skipBinary) {
  59. istextorbinary.isText(file.path, file.contents, function(err, result) {
  60. if (err) {
  61. return callback(err, file);
  62. }
  63. if (!result) {
  64. callback(null, file);
  65. } else {
  66. doReplace();
  67. }
  68. });
  69. return;
  70. }
  71. doReplace();
  72. }
  73. });
  74. };