| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  | // originally based off of https://github.com/gulpjs/vinyl
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | const invariant = require('invariant'); | 
					
						
							|  |  |  | const { of, from, isObservable } = require('rxjs'); | 
					
						
							|  |  |  | const { map, switchMap } = require('rxjs/operators'); | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function isPromise(value) { | 
					
						
							|  |  |  |   return ( | 
					
						
							|  |  |  |     value && | 
					
						
							|  |  |  |     typeof value.subscribe !== 'function' && | 
					
						
							|  |  |  |     typeof value.then === 'function' | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function castToObservable(maybe) { | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |   if (isObservable(maybe)) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |     return maybe; | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   if (isPromise(maybe)) { | 
					
						
							| 
									
										
										
										
											2018-10-06 02:36:38 +03:00
										 |  |  |     return from(maybe); | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |   return of(maybe); | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // createFileStream(
 | 
					
						
							|  |  |  | //   files: [...PolyVinyl]
 | 
					
						
							|  |  |  | // ) => Observable[...Observable[...PolyVinyl]]
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function createFileStream(files = []) { | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |   return of(from(files)); | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Observable::pipe(
 | 
					
						
							|  |  |  | //  project(
 | 
					
						
							|  |  |  | //    file: PolyVinyl
 | 
					
						
							|  |  |  | //  ) => PolyVinyl|Observable[PolyVinyl]|Promise[PolyVinyl]
 | 
					
						
							|  |  |  | // ) => Observable[...Observable[...PolyVinyl]]
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function pipe(project) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   const source = this; | 
					
						
							| 
									
										
										
										
											2018-09-30 11:37:19 +01:00
										 |  |  |   return source.pipe( | 
					
						
							|  |  |  |     map(files => { | 
					
						
							|  |  |  |       return files.pipe(switchMap(file => castToObservable(project(file)))); | 
					
						
							|  |  |  |     }) | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 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
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function createPoly({ name, ext, contents, history, ...rest } = {}) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   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, | 
					
						
							| 
									
										
										
										
											2019-01-09 03:39:05 +03:00
										 |  |  |     history: Array.isArray(history) ? history : [name + '.' + ext], | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |     name, | 
					
						
							|  |  |  |     ext, | 
					
						
							|  |  |  |     path: name + '.' + ext, | 
					
						
							|  |  |  |     key: name + ext, | 
					
						
							|  |  |  |     contents, | 
					
						
							|  |  |  |     error: null | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // isPoly(poly: Any) => Boolean
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function isPoly(poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   return ( | 
					
						
							|  |  |  |     poly && | 
					
						
							|  |  |  |     typeof poly.contents === 'string' && | 
					
						
							|  |  |  |     typeof poly.name === 'string' && | 
					
						
							|  |  |  |     typeof poly.ext === 'string' && | 
					
						
							|  |  |  |     Array.isArray(poly.history) | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // checkPoly(poly: Any) => Void, throws
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function checkPoly(poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   invariant( | 
					
						
							|  |  |  |     isPoly(poly), | 
					
						
							|  |  |  |     'function should receive a PolyVinyl, but got %s', | 
					
						
							|  |  |  |     poly | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // isEmpty(poly: PolyVinyl) => Boolean, throws
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function isEmpty(poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   checkPoly(poly); | 
					
						
							|  |  |  |   return !!poly.contents; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // setContent(contents: String, poly: PolyVinyl) => PolyVinyl
 | 
					
						
							|  |  |  | // setContent will loose source if set
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function setContent(contents, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   checkPoly(poly); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     ...poly, | 
					
						
							|  |  |  |     contents, | 
					
						
							|  |  |  |     source: null | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // setExt(ext: String, poly: PolyVinyl) => PolyVinyl
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function setExt(ext, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function setName(name, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function setError(error, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   invariant( | 
					
						
							|  |  |  |     typeof error === 'object', | 
					
						
							|  |  |  |     'error must be an object or null, but got %', | 
					
						
							|  |  |  |     error | 
					
						
							|  |  |  |   ); | 
					
						
							|  |  |  |   checkPoly(poly); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     ...poly, | 
					
						
							|  |  |  |     error | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // clearHeadTail(poly: PolyVinyl) => PolyVinyl
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function clearHeadTail(poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   checkPoly(poly); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     ...poly, | 
					
						
							|  |  |  |     head: '', | 
					
						
							|  |  |  |     tail: '' | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // appendToTail (tail: String, poly: PolyVinyl) => PolyVinyl
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function appendToTail(tail, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   checkPoly(poly); | 
					
						
							|  |  |  |   return { | 
					
						
							|  |  |  |     ...poly, | 
					
						
							|  |  |  |     tail: poly.tail.concat(tail) | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // compileHeadTail(padding: String, poly: PolyVinyl) => PolyVinyl
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function compileHeadTail(padding = '', poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function transformContents(wrap, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   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
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function transformHeadTailAndContents(wrap, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   return { | 
					
						
							|  |  |  |     ...transformContents(wrap, poly), | 
					
						
							|  |  |  |     head: wrap(poly.head), | 
					
						
							|  |  |  |     tail: wrap(poly.tail) | 
					
						
							|  |  |  |   }; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function testContents(predicate, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   return !!predicate(poly.contents); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | function updateFileFromSpec(spec, poly) { | 
					
						
							| 
									
										
										
										
											2018-04-06 14:51:52 +01:00
										 |  |  |   return setContent(poly.contents, createPoly(spec)); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2020-06-13 11:27:15 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | module.exports = { | 
					
						
							|  |  |  |   isPromise, | 
					
						
							|  |  |  |   castToObservable, | 
					
						
							|  |  |  |   createFileStream, | 
					
						
							|  |  |  |   pipe, | 
					
						
							|  |  |  |   createPoly, | 
					
						
							|  |  |  |   isPoly, | 
					
						
							|  |  |  |   checkPoly, | 
					
						
							|  |  |  |   isEmpty, | 
					
						
							|  |  |  |   setContent, | 
					
						
							|  |  |  |   setExt, | 
					
						
							|  |  |  |   setName, | 
					
						
							|  |  |  |   setError, | 
					
						
							|  |  |  |   clearHeadTail, | 
					
						
							|  |  |  |   appendToTail, | 
					
						
							|  |  |  |   compileHeadTail, | 
					
						
							|  |  |  |   transformContents, | 
					
						
							|  |  |  |   transformHeadTailAndContents, | 
					
						
							|  |  |  |   testContents, | 
					
						
							|  |  |  |   updateFileFromSpec | 
					
						
							|  |  |  | }; |