commit
cc302b3247
18 changed files with 962 additions and 0 deletions
@ -0,0 +1,2 @@ |
|||
node_modules |
|||
example-piped.js |
@ -0,0 +1,12 @@ |
|||
TODO |
|||
|
|||
# Special case: Duplex streams |
|||
|
|||
In Node.js streams, there is a thing called a Duplex stream. This is basically a stream that has an independent readable and writable part, that are not connected together. Like a TCP socket, for example; you send data through the writable half and receive data through the readable half - but the data you receive is not the same data as you sent. |
|||
|
|||
Duplex streams are really just two independent streams that are stuffed into a single object, representing a single resource, like a network socket. And this is how ppstreams treats those - as two independent streams. In ppstreams, there are no Duplex streams, so when converting a Node.js Duplex stream, you will have to do the conversion twice - once for the readable part, and once for the writable part. This can be done with the `duplexRead` and `duplexWrite` methods. |
|||
|
|||
__Why does ppstreams not have Duplex streams?__ Because they're surprisingly tricky to implement. They would make the ppstreams specification a lot more complex, and make certain things impossible; for example, a sink stream (writable stream) in ppstreams can return a Promise to signify when it's completely done receiving data, but a source stream (readable stream) needs to return a Promise with the next read value! You can only return one or the other, so supporting both would involve a lot of special logic for detecting what kind of thing is being returned. |
|||
|
|||
Aside from that, they are also just difficult to work with. Developers routinely get tripped up by the difference between a Duplex and a Transform stream, and it's much simpler to reason about your streams code when a separate readable and writable stream don't pretend to be a single stream when they're really not. |
|||
|
@ -0,0 +1,43 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const fs = require("fs"); |
|||
const through2 = require("through2"); |
|||
const fromNodeStream = require("./"); |
|||
const pipe = require("@ppstreams/pipe"); |
|||
const collect = require("@ppstreams/collect"); |
|||
const rangeNumbers = require("@ppstreams/range-numbers"); |
|||
const bufferedMap = require("@ppstreams/buffered-map"); |
|||
const map = require("@ppstreams/map"); |
|||
|
|||
let transform = through2.obj((chunk, encoding, callback) => { |
|||
callback(null, chunk + 5); |
|||
}); |
|||
|
|||
return Promise.try(() => { |
|||
return pipe([ |
|||
rangeNumbers(0, 10), |
|||
fromNodeStream(transform), |
|||
collect() |
|||
]).read(); |
|||
}).then((result) => { |
|||
console.log("transform result:", result); |
|||
|
|||
return pipe([ |
|||
fromNodeStream(fs.createReadStream("example.js", { encoding: "utf8" })), |
|||
bufferedMap((line) => line.split("\n")), |
|||
collect() |
|||
]).read(); |
|||
}).then((result) => { |
|||
console.log("read result:", result); |
|||
|
|||
return pipe([ |
|||
rangeNumbers(0, 10), |
|||
map((line) => String(line) + "\n"), |
|||
fromNodeStream(fs.createWriteStream("numbers.txt", { encoding: "utf8" })) |
|||
]).read(); |
|||
}).then((result) => { |
|||
console.log("write result:", result); |
|||
console.log("numbers.txt contents:"); |
|||
console.log(fs.readFileSync("numbers.txt", { encoding: "utf8" })); |
|||
}); |
@ -0,0 +1,165 @@ |
|||
"use strict"; |
|||
|
|||
const Promise = require("bluebird"); |
|||
const simpleSource = require("@ppstreams/simple-source"); |
|||
const simpleSink = require("@ppstreams/simple-sink"); |
|||
const buffer = require("@ppstreams/buffer"); |
|||
const propagatePeek = require("@ppstreams/propagate-peek"); |
|||
const propagateAbort = require("@ppstreams/propagate-abort"); |
|||
const pipe = require("@ppstreams/pipe"); |
|||
const isEndOfStream = require("@ppstreams/is-end-of-stream"); |
|||
|
|||
const createDefer = require("./src/create-defer"); |
|||
const wireUpReadableInterface = require("./src/readable"); |
|||
const wireUpWritableInterface = require("./src/writable"); |
|||
|
|||
// FIXME: Maybe also an abstraction for 'handle queue of requests', as this is used in multiple stream implementations
|
|||
// TODO: Improve robustness of stream-end handling using https://nodejs.org/dist/latest-v14.x/docs/api/stream.html#stream_stream_finished_stream_options_callback?
|
|||
// FIXME: Sequentialize all of these?
|
|||
|
|||
// readable
|
|||
// writable
|
|||
// transform
|
|||
// duplex
|
|||
|
|||
module.exports = function convert(stream) { |
|||
// FIXME: Proper validation and tagging
|
|||
// FIXME: Wrap v1 streams
|
|||
// NOTE: Standard I/O streams are specialcased here because they may be Duplex streams; even though the other half is never actually used. We're only interested in the interface that *is* being used.
|
|||
if (stream === process.stdin) { |
|||
return fromReadable(stream); |
|||
} else if (stream === process.stdout || stream === process.stderr) { |
|||
return fromWritable(stream); |
|||
} else if (stream.writable != null) { |
|||
if (stream.readable != null) { |
|||
if (stream._transform != null) { |
|||
// transform
|
|||
return fromTransform(stream); |
|||
} else { |
|||
throw new Error(`Duplex streams cannot be converted with the auto-detection API. Instead, use 'fromReadable' and/or 'fromWritable' manually, depending on which parts of the Duplex stream you are interested in.`); |
|||
} |
|||
} else { |
|||
return fromWritable(stream); |
|||
} |
|||
} else if (stream.readable != null) { |
|||
return fromReadable(stream); |
|||
} else { |
|||
throw new Error(`Not a Node stream`); |
|||
} |
|||
}; |
|||
|
|||
// FIXME: Duplex APIs
|
|||
|
|||
|
|||
function fromReadable(stream) { |
|||
let readable = wireUpReadableInterface(stream); |
|||
|
|||
return simpleSource({ |
|||
onRequest: () => { |
|||
return readable.request(); |
|||
}, |
|||
onAbort: () => { |
|||
return readable.destroy(); |
|||
} |
|||
}); |
|||
} |
|||
|
|||
function fromWritable(stream) { |
|||
let upstreamHasEnded = false; |
|||
let mostRecentSource = { abort: function() {} }; // FIXME: Replace with a proper spec-compliant dummy stream
|
|||
|
|||
let convertedStream = simpleSink({ |
|||
onResult: (result) => { |
|||
return writable.write(result); |
|||
}, |
|||
onEnd: () => { |
|||
upstreamHasEnded = true; |
|||
return writable.end(); |
|||
}, |
|||
onAbort: (_reason) => { |
|||
return writable.destroy(); |
|||
}, |
|||
onSourceChanged: (source) => { |
|||
mostRecentSource = source; |
|||
} |
|||
}); |
|||
|
|||
// NOTE: The use of `var` is intentional, to make hoisting possible here; otherwise we'd have a broken cyclical reference
|
|||
var writable = wireUpWritableInterface(stream, { |
|||
onClose: () => { |
|||
if (!upstreamHasEnded) { |
|||
convertedStream.abort(true); |
|||
} |
|||
}, |
|||
onError: (error) => { |
|||
// Make sure we notify the pipeline, if any, by passing in the most recent source stream that we've seen.
|
|||
convertedStream.abort(mostRecentSource, error); |
|||
} |
|||
}); |
|||
|
|||
return convertedStream; |
|||
} |
|||
|
|||
function fromTransform(stream) { |
|||
let completionDefer; |
|||
let endHandled = false; |
|||
|
|||
// FIXME: we need to specifically watch for the `error` and `end` events on the readable interface, to know when the transform stream has fully completed processing
|
|||
// Respond to the EndOfStream produced by the pushbuffer in this case
|
|||
// request, destroy
|
|||
let readable = wireUpReadableInterface(stream, { |
|||
onEnd: () => { |
|||
if (completionDefer != null) { |
|||
completionDefer.resolve(); |
|||
} |
|||
}, |
|||
onError: (error) => { |
|||
if (completionDefer != null) { |
|||
completionDefer.reject(error); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
// write, end, destroy
|
|||
var writable = wireUpWritableInterface(stream); |
|||
|
|||
let convertedStream = { |
|||
_promistreamVersion: 0, |
|||
description: `converted Node.js transform stream`, |
|||
abort: propagateAbort, |
|||
peek: propagatePeek, |
|||
read: function produceValue_nodeTransformStream(source) { |
|||
return Promise.try(() => { |
|||
return source.read(); |
|||
}).then((value) => { |
|||
writable.write(value); |
|||
|
|||
// This will quite possibly return an empty buffer, but that is fine; the `buffer` stream downstream from us will just keep reading (and therefore queueing up new items to be transformed) until it gets some results.
|
|||
return readable.consumeImmediateBuffer(); |
|||
}).catch(isEndOfStream, (marker) => { |
|||
// Wait for transform stream to drain fully, `error`/`end` event, and then return whatever buffer remains.
|
|||
// FIXME: Error propagation logic is pretty shaky here. Verify that we don't end up with double error reports.
|
|||
if (endHandled === false) { |
|||
endHandled = true; |
|||
|
|||
writable.end(); |
|||
|
|||
return Promise.try(() => { |
|||
let { promise, defer } = createDefer(); |
|||
completionDefer = defer; |
|||
return promise; |
|||
}).then(() => { |
|||
return readable.consumeImmediateBuffer(); |
|||
}); |
|||
} else { |
|||
throw marker; |
|||
} |
|||
}); |
|||
} |
|||
}; |
|||
|
|||
return pipe([ |
|||
convertedStream, |
|||
buffer() |
|||
]); |
|||
} |
@ -0,0 +1,10 @@ |
|||
0 |
|||
1 |
|||
2 |
|||
3 |
|||
4 |
|||
5 |
|||
6 |
|||
7 |
|||
8 |
|||
9 |
@ -0,0 +1,21 @@ |
|||
{ |
|||
"name": "@ppstreams/from-node-stream", |
|||
"version": "0.1.0", |
|||
"main": "index.js", |
|||
"repository": "http://git.cryto.net/ppstreams/from-node-stream.git", |
|||
"author": "Sven Slootweg <admin@cryto.net>", |
|||
"license": "WTFPL OR CC0-1.0", |
|||
"dependencies": { |
|||
"@joepie91/unreachable": "^1.0.0", |
|||
"@ppstreams/buffer": "^0.1.0", |
|||
"@ppstreams/end-of-stream": "^0.1.0", |
|||
"@ppstreams/is-end-of-stream": "^0.1.0", |
|||
"@ppstreams/pipe": "^0.1.1", |
|||
"@ppstreams/propagate-abort": "^0.1.3", |
|||
"@ppstreams/propagate-peek": "^0.1.0", |
|||
"@ppstreams/simple-sink": "^0.1.0", |
|||
"@ppstreams/simple-source": "^0.1.1", |
|||
"bluebird": "^3.7.2", |
|||
"split-filter": "^1.1.3" |
|||
} |
|||
} |
@ -0,0 +1,16 @@ |
|||
"use strict"; |
|||
|
|||
const util = require("util"); |
|||
|
|||
module.exports = function assertErrorType(error) { |
|||
if (!(error instanceof Error)) { |
|||
let stack = (new Error).stack |
|||
.split("\n") |
|||
.filter((line, n) => (n > 0 || !line.startsWith("Error"))) |
|||
.join("\n"); |
|||
|
|||
console.warn(`Converted Node stream produced an error value that isn't an Error instance: ${util.inspect(error)}`); |
|||
console.warn(`Stack:`); |
|||
console.warn(stack); |
|||
} |
|||
}; |
@ -0,0 +1,19 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function createDefer() { |
|||
let resolveFunc, rejectFunc; |
|||
|
|||
// NOTE: This works because the `new Promise` callback gets executed synchronously.
|
|||
let promise = new Promise((resolve, reject) => { |
|||
resolveFunc = resolve; |
|||
rejectFunc = reject; |
|||
}); |
|||
|
|||
return { |
|||
promise: promise, |
|||
defer: { |
|||
resolve: resolveFunc, |
|||
reject: rejectFunc |
|||
} |
|||
}; |
|||
}; |
@ -0,0 +1,11 @@ |
|||
"use strict"; |
|||
|
|||
const warn = require("./warn"); |
|||
|
|||
module.exports = function destroyStream(stream) { |
|||
if (typeof stream.destroy === "function") { |
|||
stream.destroy(); |
|||
} else { |
|||
warn("The stream you are converting does not have a 'destroy' method, and could therefore not be destroyed. This may cause resource leaks!"); |
|||
} |
|||
}; |
@ -0,0 +1,5 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function isStdioStream(stream) { |
|||
return (stream._isStdio === true); |
|||
}; |
@ -0,0 +1,29 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function attachReadableStreamHandlers({ stream, onClose, onError, onData }) { |
|||
function detachEventHandlers() { |
|||
stream.removeListener("end", onCloseWrapper); |
|||
stream.removeListener("close", onCloseWrapper); |
|||
stream.removeListener("error", onErrorWrapper); |
|||
stream.removeListener("data", onData); |
|||
} |
|||
|
|||
function attachEventHandlers() { |
|||
stream.on("end", onCloseWrapper); |
|||
stream.on("close", onCloseWrapper); |
|||
stream.on("error", onErrorWrapper); |
|||
stream.on("data", onData); |
|||
} |
|||
|
|||
function onCloseWrapper() { |
|||
onClose(); |
|||
detachEventHandlers(); |
|||
} |
|||
|
|||
function onErrorWrapper(error) { |
|||
onError(error); |
|||
detachEventHandlers(); |
|||
} |
|||
|
|||
attachEventHandlers(); |
|||
}; |
@ -0,0 +1,58 @@ |
|||
"use strict"; |
|||
|
|||
const attachHandlers = require("./attach-handlers"); |
|||
const createPushBuffer = require("./push-buffer"); |
|||
const destroyStream = require("../destroy-stream"); |
|||
const assertErrorType = require("../assert-error-type"); |
|||
|
|||
module.exports = function wireUpReadableInterface(stream, { onEnd, onError } = {}) { |
|||
let pushBuffer = createPushBuffer({ |
|||
onPause: function () { |
|||
if (stream.pause != null) { |
|||
stream.pause(); |
|||
return true; // FIXME: Can we verify whether the pausing was successful, somehow? Eg. to deal with streams with `readable` event handlers attached.
|
|||
} else { |
|||
return false; |
|||
} |
|||
}, |
|||
onResume: function () { |
|||
if (stream.resume != null) { |
|||
stream.resume(); |
|||
return true; |
|||
} else { |
|||
throw new Error(`Stream was successfully paused but does not have a resume method. This should never happen!`); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
// TODO: Verify that auto-detaching all event handlers upon end/error is actually the correct thing to do!
|
|||
attachHandlers({ |
|||
stream: stream, |
|||
onData: (data) => { |
|||
pushBuffer.queueValue(data); |
|||
}, |
|||
onError: (error) => { |
|||
assertErrorType(error); |
|||
pushBuffer.queueError(error); |
|||
|
|||
if (onError != null) { |
|||
onError(error); |
|||
} |
|||
}, |
|||
onClose: () => { |
|||
pushBuffer.markEnded(); |
|||
|
|||
if (onEnd != null) { |
|||
onEnd(); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return { |
|||
request: pushBuffer.queueRequest, |
|||
consumeImmediateBuffer: pushBuffer.consumeImmediateBuffer, |
|||
destroy: () => { |
|||
return destroyStream(stream); |
|||
} |
|||
}; |
|||
}; |
@ -0,0 +1,121 @@ |
|||
"use strict"; |
|||
|
|||
// FIXME: Separate this out into its own package
|
|||
|
|||
const splitFilter = require("split-filter"); |
|||
const unreachable = require("@joepie91/unreachable")("@ppstreams/from-node-stream"); |
|||
const EndOfStream = require("@ppstreams/end-of-stream"); |
|||
|
|||
const warn = require("../warn"); |
|||
const createDefer = require("../create-defer"); |
|||
|
|||
module.exports = function createPushBuffer(options) { |
|||
let onPause = options.onPause || function pauseNotImplemented() { |
|||
return false; |
|||
}; |
|||
|
|||
let onResume = options.onResume || function resumeNotImplemented() { |
|||
return false; |
|||
}; |
|||
|
|||
let itemBuffer = []; |
|||
let requestQueue = []; |
|||
let isPaused = false; |
|||
let hasEnded = false; |
|||
|
|||
function resumeIfEmpty() { |
|||
let bufferIsEmpty = (itemBuffer.length === 0); |
|||
|
|||
if (bufferIsEmpty && isPaused) { |
|||
if (onResume() === true) { |
|||
isPaused = false; |
|||
} |
|||
} |
|||
} |
|||
|
|||
function attemptDrain() { |
|||
// NOTE: This must remain fully synchronous, if we want to avoid unnecessary pauses in the `data` handler
|
|||
|
|||
while (requestQueue.length > 0) { |
|||
let hasItems = (itemBuffer.length > 0); |
|||
let hasResponse = (hasEnded || hasItems); |
|||
|
|||
if (hasResponse) { |
|||
let defer = requestQueue.shift(); |
|||
|
|||
if (hasItems) { |
|||
// FIXME: Does this correctly deal with an error event produced as a result of an abort?
|
|||
let item = itemBuffer.shift(); |
|||
|
|||
if (item.type === "value") { |
|||
defer.resolve(item.value); |
|||
} else if (item.type === "error") { |
|||
defer.reject(item.error); |
|||
} else { |
|||
unreachable(`Unexpected item type '${item.type}'`); |
|||
} |
|||
} else if (hasEnded) { |
|||
defer.reject(new EndOfStream()); |
|||
} else { |
|||
unreachable("Invalid response state, neither has items in queue nor ended"); |
|||
} |
|||
} else { |
|||
break; |
|||
} |
|||
} |
|||
|
|||
resumeIfEmpty(); |
|||
} |
|||
|
|||
return { |
|||
queueValue: function (value) { |
|||
itemBuffer.push({ type: "value", value: value }); |
|||
attemptDrain(); |
|||
|
|||
let stillHasItemsBuffered = (itemBuffer.length > 0); |
|||
|
|||
if (stillHasItemsBuffered && !isPaused) { |
|||
if (onPause() === true) { |
|||
isPaused = true; |
|||
} else { |
|||
// FIXME: Only show this warning once?
|
|||
warn("The stream you are converting does not support pausing. This may lead to unexpectedly high memory usage!"); |
|||
} |
|||
} |
|||
}, |
|||
queueError: function (error) { |
|||
itemBuffer.push({ type: "error", error: error }); |
|||
attemptDrain(); |
|||
}, |
|||
queueRequest: function () { |
|||
let { defer, promise } = createDefer(); |
|||
requestQueue.push(defer); |
|||
attemptDrain(); |
|||
return promise; |
|||
}, |
|||
markEnded: function () { |
|||
hasEnded = true; |
|||
attemptDrain(); |
|||
}, |
|||
consumeImmediateBuffer: function () { |
|||
attemptDrain(); |
|||
|
|||
// FIXME: Only return successful items here?
|
|||
if (requestQueue.length > 0) { |
|||
// We won't ever serve up the buffer until any individual-item requests have been fulfilled.
|
|||
return []; |
|||
} else { |
|||
let [ values, errors ] = splitFilter(itemBuffer, (item) => item.type === "value"); |
|||
|
|||
if (errors.length > 0) { |
|||
itemBuffer = values; // In case we ever write code that will do something with the remaining values in the buffer
|
|||
throw errors[0].error; |
|||
} else { |
|||
itemBuffer = []; |
|||
resumeIfEmpty(); // Ensure that we haven't left the source stream in a paused state, because that would deadlock the pipeline
|
|||
return values.map((item) => item.value); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
}; |
@ -0,0 +1,5 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function warn(message) { |
|||
console.error(`[@ppstreams/from-node-stream] Warning: ${message}`); |
|||
}; |
@ -0,0 +1,27 @@ |
|||
"use strict"; |
|||
|
|||
module.exports = function attachWritableStreamHandlers({ stream, onClose, onError }) { |
|||
function detachEventHandlers() { |
|||
stream.removeListener("finish", onCloseWrapper); |
|||
stream.removeListener("close", onCloseWrapper); |
|||
stream.removeListener("error", onErrorWrapper); |
|||
} |
|||
|
|||
function attachEventHandlers() { |
|||
stream.on("finish", onCloseWrapper); |
|||
stream.on("close", onCloseWrapper); |
|||
stream.on("error", onErrorWrapper); |
|||
} |
|||
|
|||
function onCloseWrapper() { |
|||
onClose(); |
|||
detachEventHandlers(); |
|||
} |
|||
|
|||
function onErrorWrapper(error) { |
|||
onError(error); |
|||
detachEventHandlers(); |
|||
} |
|||
|
|||
attachEventHandlers(); |
|||
}; |
@ -0,0 +1,40 @@ |
|||
"use strict"; |
|||
|
|||
const attachHandlers = require("./attach-handlers"); |
|||
const writeToStream = require("./write-to-stream"); |
|||
const isStdioStream = require("../is-stdio-stream"); |
|||
const destroyStream = require("../destroy-stream"); |
|||
const assertErrorType = require("../assert-error-type"); |
|||
|
|||
module.exports = function wireUpWritableInterface(stream, { onEnd, onError } = {}) { |
|||
attachHandlers({ |
|||
stream: stream, |
|||
onClose: () => { |
|||
if (onEnd != null) { |
|||
onEnd(); |
|||
} |
|||
}, |
|||
onError: (error) => { |
|||
assertErrorType(error); |
|||
|
|||
if (onError != null) { |
|||
onError(error); |
|||
} |
|||
} |
|||
}); |
|||
|
|||
return { |
|||
write: function (value) { |
|||
return writeToStream(stream, value); |
|||
}, |
|||
end: function () { |
|||
// stdout/stderr cannot be ended like other streams
|
|||
if (!isStdioStream(stream)) { |
|||
stream.end(); |
|||
} |
|||
}, |
|||
destroy: function () { |
|||
return destroyStream(stream); |
|||
} |
|||
}; |
|||
}; |
@ -0,0 +1,25 @@ |
|||
"use strict"; |
|||
|
|||
const isStdioStream = require("../is-stdio-stream"); |
|||
|
|||
module.exports = function writeToStream(stream, value) { |
|||
if (!isStdioStream(stream)) { |
|||
let canWriteMore = stream.write(value); |
|||
|
|||
if (canWriteMore) { |
|||
return; |
|||
} else { |
|||
return new Promise((resolve, _reject) => { |
|||
stream.once("drain", () => resolve()); |
|||
}); |
|||
} |
|||
} else { |
|||
// NOTE: According to the `stream-to-pull-stream` code, stdout/stderr behave differently from normal streams, and the `drain` event doesn't work correctly there. So instead, we use the flush callback to know when to write the next bit of data.
|
|||
return new Promise((resolve, _reject) => { |
|||
stream.write(value, (_error) => { |
|||
// NOTE: We ignore any errors here, and wait for them to be thrown in the `error` event, to simplify the logic.
|
|||
resolve(); |
|||
}); |
|||
}); |
|||
} |
|||
}; |
@ -0,0 +1,353 @@ |
|||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. |
|||
# yarn lockfile v1 |
|||
|
|||
|
|||
"@joepie91/unreachable@^1.0.0": |
|||
version "1.0.0" |
|||
resolved "https://registry.yarnpkg.com/@joepie91/unreachable/-/unreachable-1.0.0.tgz#8032bb8a5813e81bbbe516cb3031d60818526687" |
|||
integrity sha512-vZRJ5UDq4mqP1vgSrcOLD3aIfS/nzwsvGFOOHv5sj5fa1Ss0dT1xnIzrXKLD9pu5EcUvF3K6n6jdaMW8uXpNEQ== |
|||
|
|||
"@ppstreams/aborted@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/aborted/-/aborted-0.1.0.tgz#0e7d89be4234403412dda522600ad991abd0c9b6" |
|||
integrity sha512-KNrfltZBVZqcTML2ix6Pg5KjKCnD0pA4hNKEYo+PX4iNfk3oaQa+ma54lvgPEhTSOB9Vq2PKdq1ekxD/UAaMMQ== |
|||
dependencies: |
|||
create-error "^0.3.1" |
|||
|
|||
"@ppstreams/buffer@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/buffer/-/buffer-0.1.0.tgz#22247ae19b84494cd916e702fae0568c2811e350" |
|||
integrity sha512-6dZoCZH9z969kzLhTLEHEbyHUhYVFtVXZA0t9vPMoTSuQFqlJJZzSO/7p3VyVpxW9okJmE5h4DxZoN8BJudVlg== |
|||
dependencies: |
|||
"@joepie91/unreachable" "^1.0.0" |
|||
"@ppstreams/propagate-abort" "^0.1.2" |
|||
bluebird "^3.5.4" |
|||
|
|||
"@ppstreams/end-of-stream@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/end-of-stream/-/end-of-stream-0.1.0.tgz#fa1d3c7cbef9c2cdfdd5132a9467221826eef0b1" |
|||
integrity sha512-Fo3ljetPOuy0cV8bDtYc9vFxtRnePr4+1hy3vVmD8uxR2/oZWTgL64R91RkJSxh2FpI33X6hstnP7qEbbSQfhQ== |
|||
dependencies: |
|||
create-error "^0.3.1" |
|||
|
|||
"@ppstreams/is-aborted@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/is-aborted/-/is-aborted-0.1.0.tgz#0beb590a663a09683898de9f335320e07cc2afd3" |
|||
integrity sha512-Y/th7e/VtLjnUUuYo/URkN+BEF9GYmUPo91kd2YS//L3wmmeeXwCy+cMuFLf1v4T3szLQqUbdX1YM6vyfXpiIg== |
|||
|
|||
"@ppstreams/is-end-of-stream@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/is-end-of-stream/-/is-end-of-stream-0.1.0.tgz#703b0530698dc920a8fbdeea9812ef63a6fdb42c" |
|||
integrity sha512-F7J7ey5oApuH/+QD/CCotePi9ID1b5Wl1h7/IAArjL7ETDOEyHuQevsi/KXIq8kY+0YArW3F0c4QqgQujjvSnQ== |
|||
|
|||
"@ppstreams/pipe@^0.1.1": |
|||
version "0.1.1" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/pipe/-/pipe-0.1.1.tgz#453079d2ed8074e8a105f572967e50b0bcb7ca53" |
|||
integrity sha512-Wn/uBJArde8UwB5NrZbS4kYvUHdJtloRaobAwUAUmVKqPYTSs5zcAOy3AmxRw0k+aB4w6UtlZ47lM57K/DV/QQ== |
|||
|
|||
"@ppstreams/propagate-abort@^0.1.2", "@ppstreams/propagate-abort@^0.1.3": |
|||
version "0.1.3" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/propagate-abort/-/propagate-abort-0.1.3.tgz#ddb6f63e9891d642e225802d690186db6a5e2245" |
|||
integrity sha512-mFG6okJF+l/3Ct6SmUAIxG75tXmQlK3P/O7w4IO9rjjciww8fa5srd66c/XWUk30qLh0gaPgR38TmvynsHS6bA== |
|||
|
|||
"@ppstreams/propagate-peek@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/propagate-peek/-/propagate-peek-0.1.0.tgz#b8d24aa611845f64cf56b8cfd84266ce443b5f24" |
|||
integrity sha512-rX3ECnMxdD70fkEB6gQPr4aFg5bgOQ2Cks1LgFZv7Fj7qbj2SIjj1jHnhlFD1Wm6OZlcGXWuH2nbQp1hKoutkg== |
|||
|
|||
"@ppstreams/simple-sink@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/simple-sink/-/simple-sink-0.1.0.tgz#add7aae3068b9130a9b74d0e840a767c8b22bd0f" |
|||
integrity sha512-JjfPW9NNZmddzX724bXeht+9COVLlmq1LqL/DmLa9r3JQ5JxhvUCHVYLEjE7ER7ab4psCwxVxkmslUPpa/7+fQ== |
|||
dependencies: |
|||
"@ppstreams/is-aborted" "^0.1.0" |
|||
"@ppstreams/is-end-of-stream" "^0.1.0" |
|||
"@ppstreams/propagate-abort" "^0.1.2" |
|||
"@ppstreams/propagate-peek" "^0.1.0" |
|||
"@validatem/core" "^0.3.11" |
|||
"@validatem/default-to" "^0.1.0" |
|||
"@validatem/is-function" "^0.1.0" |
|||
"@validatem/required" "^0.1.1" |
|||
"@validatem/wrap-value-as-option" "^0.1.0" |
|||
bluebird "^3.5.4" |
|||
|
|||
"@ppstreams/simple-source@^0.1.1": |
|||
version "0.1.1" |
|||
resolved "https://registry.yarnpkg.com/@ppstreams/simple-source/-/simple-source-0.1.1.tgz#a8f276f2b6a27632edc0f123dc64c183414c4f9e" |
|||
integrity sha512-q0jpPZSGmld9VIhM+GmMRqwE9PXRiEJSXf3jhypf5VqiEs1JfrSNENvFeLYL/OxaF5PV+Jh0Up1hRfBWVK4+Sw== |
|||
dependencies: |
|||
"@ppstreams/aborted" "^0.1.0" |
|||
"@validatem/core" "^0.3.12" |
|||
"@validatem/is-function" "^0.1.0" |
|||
"@validatem/required" "^0.1.1" |
|||
"@validatem/wrap-value-as-option" "^0.1.0" |
|||
bluebird "^3.7.2" |
|||
|
|||
"@validatem/annotate-errors@^0.1.2": |
|||
version "0.1.2" |
|||
resolved "https://registry.yarnpkg.com/@validatem/annotate-errors/-/annotate-errors-0.1.2.tgz#fa9152bb30f4f42b69496b527e38f0c31ff605a9" |
|||
integrity sha512-EuX7pzdYI/YpTmZcgdPG481Oi3elAg8JWh/LYXuE1h6MaZk3A8eP5DD33/l7EoKzrysn6y8nCsqNa1ngei562w== |
|||
dependencies: |
|||
"@validatem/match-validation-error" "^0.1.0" |
|||
|
|||
"@validatem/any-property@^0.1.0": |
|||
version "0.1.3" |
|||
resolved "https://registry.yarnpkg.com/@validatem/any-property/-/any-property-0.1.3.tgz#fc7768c1922a8bacff9369ae48913672e5350f52" |
|||
integrity sha512-jYWxif5ff9pccu7566LIQ/4+snlApXEJUimBywzAriBgS3r4eDBbz3oZFHuiPmhxNK/NNof5YUS+L6Sk3zaMfg== |
|||
dependencies: |
|||
"@validatem/annotate-errors" "^0.1.2" |
|||
"@validatem/combinator" "^0.1.0" |
|||
"@validatem/error" "^1.0.0" |
|||
"@validatem/validation-result" "^0.1.1" |
|||
"@validatem/virtual-property" "^0.1.0" |
|||
default-value "^1.0.0" |
|||
|
|||
"@validatem/combinator@^0.1.0", "@validatem/combinator@^0.1.1": |
|||
version "0.1.2" |
|||
resolved "https://registry.yarnpkg.com/@validatem/combinator/-/combinator-0.1.2.tgz#eab893d55f1643b9c6857eaf6ff7ed2a728e89ff" |
|||
integrity sha512-vE8t1tNXknmN62FlN6LxQmA2c6TwVKZ+fl/Wit3H2unFdOhu7SZj2kRPGjAXdK/ARh/3svYfUBeD75pea0j1Sw== |
|||
|
|||
"@validatem/core@^0.3.11", "@validatem/core@^0.3.12": |
|||
version "0.3.12" |
|||
resolved "https://registry.yarnpkg.com/@validatem/core/-/core-0.3.12.tgz#e4e8a566850571bf55412862e88a3b06e75c8072" |
|||
integrity sha512-ngrFk6PT/pPZntpleG6q55SByongNxRk7wJhUiCihyv4yqIqqG+bNGH4wb6yW33IHefreWxkkJ53yM1Yj9srNA== |
|||
dependencies: |
|||
"@validatem/annotate-errors" "^0.1.2" |
|||
"@validatem/any-property" "^0.1.0" |
|||
"@validatem/error" "^1.0.0" |
|||
"@validatem/match-validation-error" "^0.1.0" |
|||
"@validatem/match-versioned-special" "^0.1.0" |
|||
"@validatem/match-virtual-property" "^0.1.0" |
|||
"@validatem/normalize-rules" "^0.1.0" |
|||
"@validatem/required" "^0.1.0" |
|||
"@validatem/validation-result" "^0.1.1" |
|||
"@validatem/virtual-property" "^0.1.0" |
|||
as-expression "^1.0.0" |
|||
assure-array "^1.0.0" |
|||
create-error "^0.3.1" |
|||
default-value "^1.0.0" |
|||
execall "^2.0.0" |
|||
flatten "^1.0.3" |
|||
indent-string "^4.0.0" |
|||
is-arguments "^1.0.4" |
|||
supports-color "^7.1.0" |
|||
syncpipe "^1.0.0" |
|||
|
|||
"@validatem/default-to@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/default-to/-/default-to-0.1.0.tgz#62766a3ca24d2f61a96c713bcb629a5b3c6427c5" |
|||
integrity sha512-UE/mJ6ZcHFlBLUhX75PQHDRYf80GFFhB+vZfIcsEWduh7Nm6lTMDnCPj4MI+jd9E/A7HV5D1yCZhaRSwoWo4vg== |
|||
dependencies: |
|||
is-callable "^1.1.5" |
|||
|
|||
"@validatem/either@^0.1.9": |
|||
version "0.1.9" |
|||
resolved "https://registry.yarnpkg.com/@validatem/either/-/either-0.1.9.tgz#0d753ef8fe04486d2b7122de3dd3ac51b3acaacf" |
|||
integrity sha512-cUqlRjy02qDcZ166/D6duk8lrtqrHynHuSakU0TvMGMBiLzjWpMJ+3beAWHe+kILB5/dlXVyc68ZIjSNhBi8Kw== |
|||
dependencies: |
|||
"@validatem/combinator" "^0.1.1" |
|||
"@validatem/error" "^1.0.0" |
|||
"@validatem/match-validation-error" "^0.1.0" |
|||
"@validatem/validation-result" "^0.1.2" |
|||
flatten "^1.0.3" |
|||
|
|||
"@validatem/error@^1.0.0": |
|||
version "1.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/error/-/error-1.1.0.tgz#bef46e7066c39761b494ebe3eec2ecdc7348f4ed" |
|||
integrity sha512-gZJEoZq1COi/8/5v0fVKQ9uX54x5lb5HbV7mzIOhY6dqjmLNfxdQmpECZPQrCAOpcRkRMJ7zaFhq4UTslpY9yA== |
|||
|
|||
"@validatem/has-shape@^0.1.0": |
|||
version "0.1.8" |
|||
resolved "https://registry.yarnpkg.com/@validatem/has-shape/-/has-shape-0.1.8.tgz#dff0f0449c12b96d150091b7a980154d810ae63d" |
|||
integrity sha512-x2i8toW1uraFF2Vl6WBl4CScbBeg5alrtoCKMyXbJkHf2B5QxL/ftUh2RQRcBzx6U0i7KUb8vdShcWAa+fehRQ== |
|||
dependencies: |
|||
"@validatem/annotate-errors" "^0.1.2" |
|||
"@validatem/combinator" "^0.1.0" |
|||
"@validatem/error" "^1.0.0" |
|||
"@validatem/validation-result" "^0.1.1" |
|||
array-union "^2.1.0" |
|||
as-expression "^1.0.0" |
|||
assure-array "^1.0.0" |
|||
default-value "^1.0.0" |
|||
flatten "^1.0.3" |
|||
|
|||
"@validatem/is-function@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/is-function/-/is-function-0.1.0.tgz#15a2e95259dc5e32256e8c21872455661437d069" |
|||
integrity sha512-UtVrwTGhaIdIJ0mPG5XkAmYZUeWgRoMP1G9ZEHbKvAZJ4+SXf/prC0jPgE0pw+sPjdQG4hblsXSfo/9Bf3PGdQ== |
|||
dependencies: |
|||
"@validatem/error" "^1.0.0" |
|||
is-callable "^1.1.5" |
|||
|
|||
"@validatem/is-plain-object@^0.1.0", "@validatem/is-plain-object@^0.1.1": |
|||
version "0.1.1" |
|||
resolved "https://registry.yarnpkg.com/@validatem/is-plain-object/-/is-plain-object-0.1.1.tgz#b7a3ef8ef960882c7c41e84ed709fa0bfb932e93" |
|||
integrity sha512-aNGbNIbKRpYI0lRBczlTBbiA+nqN52ADAASdySKg2/QeSCVtYS4uOIeCNIJRAgXe/5sUnLTuL4pgq628uAl7Kw== |
|||
dependencies: |
|||
"@validatem/error" "^1.0.0" |
|||
is-plain-obj "^2.1.0" |
|||
|
|||
"@validatem/match-special@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/match-special/-/match-special-0.1.0.tgz#4e0c28f1aee5bf53c1ef30bbf8c755d4946ae0ff" |
|||
integrity sha512-TFiq9Wk/1Hoja4PK85WwNYnwBXk3+Lgoj59ZIMxm2an1qmNYp8j+BnSvkKBflba451yIn6V1laU9NJf+/NYZgw== |
|||
|
|||
"@validatem/match-validation-error@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/match-validation-error/-/match-validation-error-0.1.0.tgz#fa87f5f1836e7c1d9bf6b75b2addf0a5b21e4c1e" |
|||
integrity sha512-6akGTk7DdulOreyqDiGdikwRSixQz/AlvARSX18dcWaTFc79KxCLouL2hyoFcor9IIUhu5RTY4/i756y4T1yxA== |
|||
dependencies: |
|||
"@validatem/match-versioned-special" "^0.1.0" |
|||
|
|||
"@validatem/match-versioned-special@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/match-versioned-special/-/match-versioned-special-0.1.0.tgz#2eacc48debecdbbe7e3d02f0c0a665afaea9bedf" |
|||
integrity sha512-xoOTY0bdA2ELj+ntcDVJ8YyMEFIJpjZ4HNPL9lGcbnRFwJBhQcHUAhUpZwkMxu02zH9wkNM1FvYGHxPz40745Q== |
|||
|
|||
"@validatem/match-virtual-property@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/match-virtual-property/-/match-virtual-property-0.1.0.tgz#4de2de1075987b5f3b356d3f2bcf6c0be5b5fb83" |
|||
integrity sha512-ssd3coFgwbLuqvZftLZTy3eHN0TFST8oTS2XTViQdXJPXVoJmwEKBpFhXgwnb5Ly1CE037R/KWpjhd1TP/56kQ== |
|||
|
|||
"@validatem/normalize-rules@^0.1.0": |
|||
version "0.1.3" |
|||
resolved "https://registry.yarnpkg.com/@validatem/normalize-rules/-/normalize-rules-0.1.3.tgz#59fd6193b1091ff97b5c723b32c9bb1fe2a9dc9c" |
|||
integrity sha512-HHPceAP2ce9NWymIZrgLCTzpdwXNRBCCB5H6ZPc5ggOrbmh4STpT83fLazleHtvYNlqgXZ4GjQOvCwrjaM+qEA== |
|||
dependencies: |
|||
"@validatem/has-shape" "^0.1.0" |
|||
"@validatem/is-plain-object" "^0.1.0" |
|||
"@validatem/match-special" "^0.1.0" |
|||
assure-array "^1.0.0" |
|||
default-value "^1.0.0" |
|||
flatten "^1.0.3" |
|||
is-plain-obj "^2.1.0" |
|||
|
|||
"@validatem/required@^0.1.0", "@validatem/required@^0.1.1": |
|||
version "0.1.1" |
|||
resolved "https://registry.yarnpkg.com/@validatem/required/-/required-0.1.1.tgz#64f4a87333fc5955511634036b7f8948ed269170" |
|||
integrity sha512-vI4NzLfay4RFAzp7xyU34PHb8sAo6w/3frrNh1EY9Xjnw2zxjY5oaxwmbFP1jVevBE6QQEnKogtzUHz/Zuvh6g== |
|||
|
|||
"@validatem/validation-result@^0.1.1", "@validatem/validation-result@^0.1.2": |
|||
version "0.1.2" |
|||
resolved "https://registry.yarnpkg.com/@validatem/validation-result/-/validation-result-0.1.2.tgz#4e75cfd87305fc78f8d05ac84921a2c99a0348e0" |
|||
integrity sha512-okmP8JarIwIgfpaVcvZGuQ1yOsLKT3Egt49Ynz6h1MAeGsP/bGHXkkXtbiWOVsk5Tzku5vDVFSrFnF+5IEHKxw== |
|||
dependencies: |
|||
default-value "^1.0.0" |
|||
|
|||
"@validatem/virtual-property@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/virtual-property/-/virtual-property-0.1.0.tgz#880540dfd149f98ecf1095d93912e34443381fe4" |
|||
integrity sha512-JUUvWtdqoSkOwlsl20oB3qFHYIL05a/TAfdY4AJcs55QeVTiX5iI1b8IoQW644sIWWooBuLv+XwoxjRsQFczlQ== |
|||
|
|||
"@validatem/wrap-value-as-option@^0.1.0": |
|||
version "0.1.0" |
|||
resolved "https://registry.yarnpkg.com/@validatem/wrap-value-as-option/-/wrap-value-as-option-0.1.0.tgz#57fa8d535f6cdf40cf8c8846ad45f4dd68f44568" |
|||
integrity sha512-gWDkfyU0DOsbinE9iqvRSJ+NxuynChyueJsC+AFm3EYbe8+s7V2gRs3qkJ4mq7hOlUbEh8tgCWQfZZvr+IdVFw== |
|||
dependencies: |
|||
"@validatem/either" "^0.1.9" |
|||
"@validatem/is-plain-object" "^0.1.1" |
|||
|
|||
array-union@^2.1.0: |
|||
version "2.1.0" |
|||
resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" |
|||
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== |
|||
|
|||
as-expression@^1.0.0: |
|||
version "1.0.0" |
|||
resolved "https://registry.yarnpkg.com/as-expression/-/as-expression-1.0.0.tgz#7bc620ca4cb2fe0ee90d86729bd6add33b8fd831" |
|||
integrity sha512-Iqh4GxNUfxbJdGn6b7/XMzc8m1Dz2ZHouBQ9DDTzyMRO3VPPIAXeoY/sucRxxxXKbUtzwzWZSN6jPR3zfpYHHA== |
|||
|
|||
assure-array@^1.0.0: |
|||
version "1.0.0" |
|||
resolved "https://registry.yarnpkg.com/assure-array/-/assure-array-1.0.0.tgz#4f4ad16a87659d6200a4fb7103462033d216ec1f" |
|||
integrity sha1-T0rRaodlnWIApPtxA0YgM9IW7B8= |
|||
|
|||
bluebird@^3.5.4, bluebird@^3.7.2: |
|||
version "3.7.2" |
|||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" |
|||
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== |
|||
|
|||
clone-regexp@^2.1.0: |
|||
version "2.2.0" |
|||
resolved "https://registry.yarnpkg.com/clone-regexp/-/clone-regexp-2.2.0.tgz#7d65e00885cd8796405c35a737e7a86b7429e36f" |
|||
integrity sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q== |
|||
dependencies: |
|||
is-regexp "^2.0.0" |
|||
|
|||
create-error@^0.3.1: |
|||
version "0.3.1" |
|||
resolved "https://registry.yarnpkg.com/create-error/-/create-error-0.3.1.tgz#69810245a629e654432bf04377360003a5351a23" |
|||
integrity sha1-aYECRaYp5lRDK/BDdzYAA6U1GiM= |
|||
|
|||
default-value@^1.0.0: |
|||
version "1.0.0" |
|||
resolved "https://registry.yarnpkg.com/default-value/-/default-value-1.0.0.tgz#8c6f52a5a1193fe78fdc9f86eb71d16c9757c83a" |
|||
integrity sha1-jG9SpaEZP+eP3J+G63HRbJdXyDo= |
|||
dependencies: |
|||
es6-promise-try "0.0.1" |
|||
|
|||
es6-promise-try@0.0.1: |
|||
version "0.0.1" |
|||
resolved "https://registry.yarnpkg.com/es6-promise-try/-/es6-promise-try-0.0.1.tgz#10f140dad27459cef949973e5d21a087f7274b20" |
|||
integrity sha1-EPFA2tJ0Wc75SZc+XSGgh/cnSyA= |
|||
|
|||
execall@^2.0.0: |
|||
version "2.0.0" |
|||
resolved "https://registry.yarnpkg.com/execall/-/execall-2.0.0.tgz#16a06b5fe5099df7d00be5d9c06eecded1663b45" |
|||
integrity sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow== |
|||
dependencies: |
|||
clone-regexp "^2.1.0" |
|||
|
|||
flatten@^1.0.3: |
|||
version "1.0.3" |
|||
resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" |
|||
integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== |
|||
|
|||
has-flag@^4.0.0: |
|||
version "4.0.0" |
|||
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" |
|||
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== |
|||
|
|||
indent-string@^4.0.0: |
|||
version "4.0.0" |
|||
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" |
|||
integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== |
|||
|
|||
is-arguments@^1.0.4: |
|||
version "1.0.4" |
|||
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3" |
|||
integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA== |
|||
|
|||
is-callable@^1.1.5: |
|||
version "1.2.0" |
|||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" |
|||
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== |
|||
|
|||
is-plain-obj@^2.1.0: |
|||
version "2.1.0" |
|||
resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" |
|||
integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== |
|||
|
|||
is-regexp@^2.0.0: |
|||
version "2.1.0" |
|||
resolved "https://registry.yarnpkg.com/is-regexp/-/is-regexp-2.1.0.tgz#cd734a56864e23b956bf4e7c66c396a4c0b22c2d" |
|||
integrity sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA== |
|||
|
|||
split-filter@^1.1.3: |
|||
version "1.1.3" |
|||
resolved "https://registry.yarnpkg.com/split-filter/-/split-filter-1.1.3.tgz#c68cc598783d88f60d16e7b452dacfe95ba60539" |
|||
integrity sha512-2xXwhWeJUFrYE8CL+qoy9mCohu5/E+uglvpqL1FVXz1XbvTwivafVC6oTDeg/9ksOAxg6DvyCF44Dvf5crFU0w== |
|||
|
|||
supports-color@^7.1.0: |
|||
version "7.1.0" |
|||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" |
|||
integrity sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g== |
|||
dependencies: |
|||
has-flag "^4.0.0" |
|||
|
|||
syncpipe@^1.0.0: |
|||
version "1.0.0" |
|||
resolved "https://registry.yarnpkg.com/syncpipe/-/syncpipe-1.0.0.tgz#170340f813150bc8fcb8878b1b9c71ea0ccd3727" |
|||
integrity sha512-cdiAFTnFJRvUaNPDc2n9CqoFvtIL3+JUMJZrC3kA3FzpugHOqu0TvkgNwmnxPZ5/WjAzMcfMS3xm+AO7rg/j/w== |
|||
dependencies: |
|||
assure-array "^1.0.0" |
Loading…
Reference in new issue