249 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			249 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
// originally based off of https://github.com/gulpjs/vinyl
 | 
						|
const invariant = require('invariant');
 | 
						|
const { of, from, isObservable } = require('rxjs');
 | 
						|
const { map, switchMap } = require('rxjs/operators');
 | 
						|
 | 
						|
function isPromise(value) {
 | 
						|
  return (
 | 
						|
    value &&
 | 
						|
    typeof value.subscribe !== 'function' &&
 | 
						|
    typeof value.then === 'function'
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
function castToObservable(maybe) {
 | 
						|
  if (isObservable(maybe)) {
 | 
						|
    return maybe;
 | 
						|
  }
 | 
						|
  if (isPromise(maybe)) {
 | 
						|
    return from(maybe);
 | 
						|
  }
 | 
						|
  return of(maybe);
 | 
						|
}
 | 
						|
 | 
						|
// createFileStream(
 | 
						|
//   files: [...PolyVinyl]
 | 
						|
// ) => Observable[...Observable[...PolyVinyl]]
 | 
						|
function createFileStream(files = []) {
 | 
						|
  return of(from(files));
 | 
						|
}
 | 
						|
 | 
						|
// Observable::pipe(
 | 
						|
//  project(
 | 
						|
//    file: PolyVinyl
 | 
						|
//  ) => PolyVinyl|Observable[PolyVinyl]|Promise[PolyVinyl]
 | 
						|
// ) => Observable[...Observable[...PolyVinyl]]
 | 
						|
function pipe(project) {
 | 
						|
  const source = this;
 | 
						|
  return source.pipe(
 | 
						|
    map(files => {
 | 
						|
      return files.pipe(switchMap(file => castToObservable(project(file))));
 | 
						|
    })
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// interface PolyVinyl {
 | 
						|
//   source: String,
 | 
						|
//   contents: String,
 | 
						|
//   name: String,
 | 
						|
//   ext: String,
 | 
						|
//   path: String,
 | 
						|
//   key: String,
 | 
						|
//   head: String,
 | 
						|
//   tail: String,
 | 
						|
//   history: [...String],
 | 
						|
//   error: Null|Object|Error
 | 
						|
// }
 | 
						|
 | 
						|
// createPoly({
 | 
						|
//   name: String,
 | 
						|
//   ext: String,
 | 
						|
//   contents: String,
 | 
						|
//   history?: [...String],
 | 
						|
// }) => PolyVinyl, throws
 | 
						|
function createPoly({ name, ext, contents, history, ...rest } = {}) {
 | 
						|
  invariant(typeof name === 'string', 'name must be a string but got %s', name);
 | 
						|
 | 
						|
  invariant(typeof ext === 'string', 'ext must be a string, but was %s', ext);
 | 
						|
 | 
						|
  invariant(
 | 
						|
    typeof contents === 'string',
 | 
						|
    'contents must be a string but got %s',
 | 
						|
    contents
 | 
						|
  );
 | 
						|
 | 
						|
  return {
 | 
						|
    ...rest,
 | 
						|
    history: Array.isArray(history) ? history : [name + '.' + ext],
 | 
						|
    name,
 | 
						|
    ext,
 | 
						|
    path: name + '.' + ext,
 | 
						|
    key: name + ext,
 | 
						|
    contents,
 | 
						|
    error: null
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// isPoly(poly: Any) => Boolean
 | 
						|
function isPoly(poly) {
 | 
						|
  return (
 | 
						|
    poly &&
 | 
						|
    typeof poly.contents === 'string' &&
 | 
						|
    typeof poly.name === 'string' &&
 | 
						|
    typeof poly.ext === 'string' &&
 | 
						|
    Array.isArray(poly.history)
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// checkPoly(poly: Any) => Void, throws
 | 
						|
function checkPoly(poly) {
 | 
						|
  invariant(
 | 
						|
    isPoly(poly),
 | 
						|
    'function should receive a PolyVinyl, but got %s',
 | 
						|
    poly
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// isEmpty(poly: PolyVinyl) => Boolean, throws
 | 
						|
function isEmpty(poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  return !!poly.contents;
 | 
						|
}
 | 
						|
 | 
						|
// setContent(contents: String, poly: PolyVinyl) => PolyVinyl
 | 
						|
// setContent will loose source if set
 | 
						|
function setContent(contents, poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  return {
 | 
						|
    ...poly,
 | 
						|
    contents,
 | 
						|
    source: null
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// setExt(ext: String, poly: PolyVinyl) => PolyVinyl
 | 
						|
function setExt(ext, poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  const newPoly = {
 | 
						|
    ...poly,
 | 
						|
    ext,
 | 
						|
    path: poly.name + '.' + ext,
 | 
						|
    key: poly.name + ext
 | 
						|
  };
 | 
						|
  newPoly.history = [...poly.history, newPoly.path];
 | 
						|
  return newPoly;
 | 
						|
}
 | 
						|
 | 
						|
// setName(name: String, poly: PolyVinyl) => PolyVinyl
 | 
						|
function setName(name, poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  const newPoly = {
 | 
						|
    ...poly,
 | 
						|
    name,
 | 
						|
    path: name + '.' + poly.ext,
 | 
						|
    key: name + poly.ext
 | 
						|
  };
 | 
						|
  newPoly.history = [...poly.history, newPoly.path];
 | 
						|
  return newPoly;
 | 
						|
}
 | 
						|
 | 
						|
// setError(error: Object, poly: PolyVinyl) => PolyVinyl
 | 
						|
function setError(error, poly) {
 | 
						|
  invariant(
 | 
						|
    typeof error === 'object',
 | 
						|
    'error must be an object or null, but got %',
 | 
						|
    error
 | 
						|
  );
 | 
						|
  checkPoly(poly);
 | 
						|
  return {
 | 
						|
    ...poly,
 | 
						|
    error
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// clearHeadTail(poly: PolyVinyl) => PolyVinyl
 | 
						|
function clearHeadTail(poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  return {
 | 
						|
    ...poly,
 | 
						|
    head: '',
 | 
						|
    tail: ''
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// appendToTail (tail: String, poly: PolyVinyl) => PolyVinyl
 | 
						|
function appendToTail(tail, poly) {
 | 
						|
  checkPoly(poly);
 | 
						|
  return {
 | 
						|
    ...poly,
 | 
						|
    tail: poly.tail.concat(tail)
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
// compileHeadTail(padding: String, poly: PolyVinyl) => PolyVinyl
 | 
						|
function compileHeadTail(padding = '', poly) {
 | 
						|
  return clearHeadTail(
 | 
						|
    transformContents(
 | 
						|
      () => [poly.head, poly.contents, poly.tail].join(padding),
 | 
						|
      poly
 | 
						|
    )
 | 
						|
  );
 | 
						|
}
 | 
						|
 | 
						|
// transformContents(
 | 
						|
//   wrap: (contents: String) => String,
 | 
						|
//   poly: PolyVinyl
 | 
						|
// ) => PolyVinyl
 | 
						|
// transformContents will keep a copy of the original
 | 
						|
// code in the `source` property. If the original polyvinyl
 | 
						|
// already contains a source, this version will continue as
 | 
						|
// the source property
 | 
						|
function transformContents(wrap, poly) {
 | 
						|
  const newPoly = setContent(wrap(poly.contents), poly);
 | 
						|
  // if no source exist, set the original contents as source
 | 
						|
  newPoly.source = poly.source || poly.contents;
 | 
						|
  return newPoly;
 | 
						|
}
 | 
						|
 | 
						|
// transformHeadTailAndContents(
 | 
						|
//   wrap: (source: String) => String,
 | 
						|
//   poly: PolyVinyl
 | 
						|
// ) => PolyVinyl
 | 
						|
function transformHeadTailAndContents(wrap, poly) {
 | 
						|
  return {
 | 
						|
    ...transformContents(wrap, poly),
 | 
						|
    head: wrap(poly.head),
 | 
						|
    tail: wrap(poly.tail)
 | 
						|
  };
 | 
						|
}
 | 
						|
 | 
						|
function testContents(predicate, poly) {
 | 
						|
  return !!predicate(poly.contents);
 | 
						|
}
 | 
						|
 | 
						|
function updateFileFromSpec(spec, poly) {
 | 
						|
  return setContent(poly.contents, createPoly(spec));
 | 
						|
}
 | 
						|
 | 
						|
module.exports = {
 | 
						|
  isPromise,
 | 
						|
  castToObservable,
 | 
						|
  createFileStream,
 | 
						|
  pipe,
 | 
						|
  createPoly,
 | 
						|
  isPoly,
 | 
						|
  checkPoly,
 | 
						|
  isEmpty,
 | 
						|
  setContent,
 | 
						|
  setExt,
 | 
						|
  setName,
 | 
						|
  setError,
 | 
						|
  clearHeadTail,
 | 
						|
  appendToTail,
 | 
						|
  compileHeadTail,
 | 
						|
  transformContents,
 | 
						|
  transformHeadTailAndContents,
 | 
						|
  testContents,
 | 
						|
  updateFileFromSpec
 | 
						|
};
 |