normalize.js 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import isPlainObj from 'is-plain-obj';
  2. import {BINARY_ENCODINGS} from '../arguments/encoding-option.js';
  3. import {TRANSFORM_TYPES} from '../stdio/type.js';
  4. import {getTransformObjectModes} from './object-mode.js';
  5. // Transforms generators/duplex/TransformStream can have multiple shapes.
  6. // This normalizes it and applies default values.
  7. export const normalizeTransforms = (stdioItems, optionName, direction, options) => [
  8. ...stdioItems.filter(({type}) => !TRANSFORM_TYPES.has(type)),
  9. ...getTransforms(stdioItems, optionName, direction, options),
  10. ];
  11. const getTransforms = (stdioItems, optionName, direction, {encoding}) => {
  12. const transforms = stdioItems.filter(({type}) => TRANSFORM_TYPES.has(type));
  13. const newTransforms = Array.from({length: transforms.length});
  14. for (const [index, stdioItem] of Object.entries(transforms)) {
  15. newTransforms[index] = normalizeTransform({
  16. stdioItem,
  17. index: Number(index),
  18. newTransforms,
  19. optionName,
  20. direction,
  21. encoding,
  22. });
  23. }
  24. return sortTransforms(newTransforms, direction);
  25. };
  26. const normalizeTransform = ({stdioItem, stdioItem: {type}, index, newTransforms, optionName, direction, encoding}) => {
  27. if (type === 'duplex') {
  28. return normalizeDuplex({stdioItem, optionName});
  29. }
  30. if (type === 'webTransform') {
  31. return normalizeTransformStream({
  32. stdioItem,
  33. index,
  34. newTransforms,
  35. direction,
  36. });
  37. }
  38. return normalizeGenerator({
  39. stdioItem,
  40. index,
  41. newTransforms,
  42. direction,
  43. encoding,
  44. });
  45. };
  46. const normalizeDuplex = ({
  47. stdioItem,
  48. stdioItem: {
  49. value: {
  50. transform,
  51. transform: {writableObjectMode, readableObjectMode},
  52. objectMode = readableObjectMode,
  53. },
  54. },
  55. optionName,
  56. }) => {
  57. if (objectMode && !readableObjectMode) {
  58. throw new TypeError(`The \`${optionName}.objectMode\` option can only be \`true\` if \`new Duplex({objectMode: true})\` is used.`);
  59. }
  60. if (!objectMode && readableObjectMode) {
  61. throw new TypeError(`The \`${optionName}.objectMode\` option cannot be \`false\` if \`new Duplex({objectMode: true})\` is used.`);
  62. }
  63. return {
  64. ...stdioItem,
  65. value: {transform, writableObjectMode, readableObjectMode},
  66. };
  67. };
  68. const normalizeTransformStream = ({stdioItem, stdioItem: {value}, index, newTransforms, direction}) => {
  69. const {transform, objectMode} = isPlainObj(value) ? value : {transform: value};
  70. const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction);
  71. return ({
  72. ...stdioItem,
  73. value: {transform, writableObjectMode, readableObjectMode},
  74. });
  75. };
  76. const normalizeGenerator = ({stdioItem, stdioItem: {value}, index, newTransforms, direction, encoding}) => {
  77. const {
  78. transform,
  79. final,
  80. binary: binaryOption = false,
  81. preserveNewlines = false,
  82. objectMode,
  83. } = isPlainObj(value) ? value : {transform: value};
  84. const binary = binaryOption || BINARY_ENCODINGS.has(encoding);
  85. const {writableObjectMode, readableObjectMode} = getTransformObjectModes(objectMode, index, newTransforms, direction);
  86. return {
  87. ...stdioItem,
  88. value: {
  89. transform,
  90. final,
  91. binary,
  92. preserveNewlines,
  93. writableObjectMode,
  94. readableObjectMode,
  95. },
  96. };
  97. };
  98. const sortTransforms = (newTransforms, direction) => direction === 'input' ? newTransforms.reverse() : newTransforms;