freeCodeCamp/common/utils/polyvinyl.js

209 lines
4.5 KiB
JavaScript
Raw Normal View History

// originally based off of https://github.com/gulpjs/vinyl
2016-05-11 06:38:11 +00:00
import invariant from 'invariant';
import { Observable } from 'rx';
import castToObservable from '../app/utils/cast-to-observable.js';
// createFileStream(
// files: Dictionary[Path, PolyVinyl]
// ) => Observable[...Observable[...PolyVinyl]]
export function createFileStream(files = {}) {
return Observable.of(
Observable.from(Object.keys(files).map(key => files[key]))
);
}
// Observable::pipe(
// project(
// file: PolyVinyl
// ) => PolyVinyl|Observable[PolyVinyl]|Promise[PolyVinyl]
// ) => Observable[...Observable[...PolyVinyl]]
export function pipe(project) {
const source = this;
return source.map(
files => files.flatMap(file => castToObservable(project(file)))
);
}
2016-05-11 06:38:11 +00:00
// interface PolyVinyl {
// source: String,
2016-05-11 06:38:11 +00:00
// contents: String,
2016-05-20 19:42:26 +00:00
// name: String,
// ext: String,
2016-05-11 06:38:11 +00:00
// path: String,
2016-05-20 19:42:26 +00:00
// key: String,
// head: String,
// tail: String,
2016-05-11 06:38:11 +00:00
// history: [...String],
// error: Null|Object|Error
2016-05-11 06:38:11 +00:00
// }
2016-05-11 06:38:11 +00:00
// createPoly({
2016-05-20 19:42:26 +00:00
// name: String,
// ext: String,
2016-05-11 06:38:11 +00:00
// contents: String,
// history?: [...String],
// }) => PolyVinyl, throws
2016-05-20 19:42:26 +00:00
export function createPoly({
name,
ext,
contents,
history,
...rest
} = {}) {
invariant(
typeof name === 'string',
'name must be a string but got %s',
name
);
2016-05-11 06:38:11 +00:00
invariant(
2016-05-20 19:42:26 +00:00
typeof ext === 'string',
'ext must be a string, but was %s',
ext
2016-05-11 06:38:11 +00:00
);
2016-05-11 06:38:11 +00:00
invariant(
typeof contents === 'string',
'contents must be a string but got %s',
contents
);
2016-05-11 06:38:11 +00:00
return {
2016-05-14 23:46:20 +00:00
...rest,
2016-05-20 19:42:26 +00:00
history: Array.isArray(history) ? history : [ name + ext ],
name,
ext,
path: name + '.' + ext,
key: name + ext,
contents,
2016-05-11 06:38:11 +00:00
error: null
};
}
2016-05-11 06:38:11 +00:00
// isPoly(poly: Any) => Boolean
export function isPoly(poly) {
return poly &&
typeof poly.contents === 'string' &&
2016-05-20 19:42:26 +00:00
typeof poly.name === 'string' &&
typeof poly.ext === 'string' &&
2016-05-11 06:38:11 +00:00
Array.isArray(poly.history);
}
2016-05-11 06:38:11 +00:00
// checkPoly(poly: Any) => Void, throws
export function checkPoly(poly) {
invariant(
isPoly(poly),
'function should receive a PolyVinyl, but got %s',
poly
);
}
2016-05-11 06:38:11 +00:00
// isEmpty(poly: PolyVinyl) => Boolean, throws
export function isEmpty(poly) {
checkPoly(poly);
return !!poly.contents;
}
// setContent(contents: String, poly: PolyVinyl) => PolyVinyl
// setContent will loose source if set
export function setContent(contents, poly) {
2016-05-11 06:38:11 +00:00
checkPoly(poly);
return {
...poly,
contents,
source: null
2016-05-11 06:38:11 +00:00
};
}
// setExt(contents: String, poly: PolyVinyl) => PolyVinyl
2016-05-20 19:42:26 +00:00
export function setExt(ext, poly) {
2016-05-11 06:38:11 +00:00
checkPoly(poly);
2016-05-20 19:42:26 +00:00
const newPoly = {
...poly,
ext,
path: poly.name + '.' + ext,
key: poly.name + ext
};
newPoly.history = [ ...poly.history, newPoly.path ];
return newPoly;
2016-05-11 06:38:11 +00:00
}
// setName(contents: String, poly: PolyVinyl) => PolyVinyl
2016-05-20 19:42:26 +00:00
export function setName(name, poly) {
checkPoly(poly);
2016-05-11 06:38:11 +00:00
const newPoly = {
...poly,
2016-05-20 19:42:26 +00:00
name,
path: name + '.' + poly.ext,
key: name + poly.ext
2016-05-11 06:38:11 +00:00
};
newPoly.history = [ ...poly.history, newPoly.path ];
return newPoly;
}
// setError(contents: String, poly: PolyVinyl) => PolyVinyl
2016-05-11 06:38:11 +00:00
export 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
export function clearHeadTail(poly) {
checkPoly(poly);
return {
...poly,
head: '',
tail: ''
};
}
// compileHeadTail(contents: String, poly: PolyVinyl) => PolyVinyl
export function compileHeadTail(padding = '', poly) {
return clearHeadTail(setContent(
[ 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
export function transformContents(wrap, poly) {
const newPoly = setContent(
wrap(poly.contents),
poly
);
// if no source exist, set the original contents as source
newPoly.source = poly.contents || poly.contents;
return newPoly;
}
// transformHeadTailAndContents(
// wrap: (source: String) => String,
// poly: PolyVinyl
// ) => PolyVinyl
export function transformHeadTailAndContents(wrap, poly) {
return {
...setContent(
wrap(poly.contents),
poly
),
head: wrap(poly.head),
tail: wrap(poly.tail)
};
}