Comparing version 3.5.1 to 3.6.0
@@ -5,3 +5,3 @@ const { Transform } = require('stream'); | ||
* Create a Transform stream which will maintain a buffer with data received from a Readable stream and write data when the buffer can be matched against the regex. It will push the whole match object (or objects when the g flag is used) returned by `/regex/.exec(buffer)`. | ||
* @param {RegExp} regex Regular expression to execute | ||
* @param {!RegExp} regex The regular expression to execute. | ||
*/ | ||
@@ -11,2 +11,3 @@ function createRegexTransformStream(regex) { | ||
/** @suppress {checkTypes} */ | ||
const ts = new Transform({ | ||
@@ -48,10 +49,27 @@ transform(chunk, encoding, next) { | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Replacer} Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {function(this:*, ...string): string} _restream.Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.AsyncReplacer} AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {function(this:*, ...string): !Promise<string>} _restream.AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Rule} Rule A replacement rule. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.Rule A replacement rule. | ||
* @prop {!RegExp} re The regular expression to match input against. | ||
* @prop {!(string|_restream.Replacer|_restream.AsyncReplacer)} replacement The replacement string, or the replacer function. | ||
*/ | ||
@@ -58,0 +76,0 @@ |
@@ -22,9 +22,13 @@ const SyncReplaceable = require('../SyncReplaceable'); | ||
* @param {string} name The name of the matcher, used in the doc marker. | ||
* @param {RegExp} re The regular expression used for detection. | ||
* @return {Marker} The marker. | ||
* @param {!RegExp} re The regular expression used for detection. | ||
* @param {!_restream.MakeMarkersConfig} [conf] Additional configuration. | ||
* @param {function(string, number): string} [conf.getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @param {function(string): !RegExp} [conf.getRegex] The function used to create a RegExp to detect replaced chunks. | ||
* @return {!_restream.Marker} The marker. | ||
*/ | ||
const makeMarker = (name, re, { | ||
getReplacement = getDefaultReplacement, | ||
getRegex = getDefaultRegExp, | ||
} = {}) => { | ||
const makeMarker = (name, re, conf) => { | ||
const { | ||
getReplacement = getDefaultReplacement, | ||
getRegex = getDefaultRegExp, | ||
} = conf || {} | ||
const regExp = getRegex(name) | ||
@@ -43,7 +47,7 @@ return { | ||
* Make markers from a configuration object. | ||
* @param {Object.<string, RegExp>} matchers An object with types of markers to create as keys and their detection regexes as values. | ||
* @param {MakeMarkersConfig} [config] Additional configuration. | ||
* @param {(name: string, index: number) => string} [config.getReplacement] A function used to create a replacement when some text needs to be cut. | ||
* @param {(name: string) => RegExp} [config.getRegex] A function used to create a RegExp to detect replaced chunks. | ||
* @returns {Object.<string, Marker>} An object with markers for each requested type. | ||
* @param {!Object.<string, !RegExp>} matchers An object with types of markers to create as keys and their detection regexes as values. | ||
* @param {!_restream.MakeMarkersConfig} [config] Additional configuration. | ||
* @param {function(string, number): string} [config.getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @param {function(string): !RegExp} [config.getRegex] The function used to create a RegExp to detect replaced chunks. | ||
* @returns {!Object.<string, !_restream.Marker>} An object with markers for each requested type. | ||
*/ | ||
@@ -65,5 +69,5 @@ const makeMarkers = (matchers, config) => { | ||
* Make a rule for pasting markers back. | ||
* @param {Marker} marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @param {(Rule|Array<Rule>)} [pipeRules] Any additional rules to replace the value of the marker before pasting it. | ||
* @returns {Rule} A rule to paste previously replaced chunks. | ||
* @param {!_restream.Marker} marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @param {!(_restream.Rule|Array<!_restream.Rule>)} [pipeRules] Any additional rules to replace the value of the marker before pasting it. | ||
* @returns {!_restream.Rule} A rule to paste previously replaced chunks. | ||
*/ | ||
@@ -87,4 +91,4 @@ const makePasteRule = (marker, pipeRules = []) => { | ||
* Make a rule for initial replacement of markers. | ||
* @param {Marker} marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @returns {Rule} A rule to cut matched chunks. | ||
* @param {!_restream.Marker} marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @returns {!_restream.Rule} A rule to cut matched chunks. | ||
*/ | ||
@@ -107,3 +111,4 @@ const makeCutRule = (marker) => { | ||
/** | ||
* @typedef {import('..').Rule} Rule | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ | ||
@@ -113,14 +118,25 @@ | ||
/** | ||
* @typedef {Object} Marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @prop {string} type Type of the marker. | ||
* @prop {(index) => string} getMarker A function to generate markers which can be then found. | ||
* @prop {RegExp} re A regular expression used for detection of the match. | ||
* @prop {RegExp} regExp A generated regular expression to replace the marker back to its original value. | ||
* @prop {object} map A map which holds detected matches at their indexes. | ||
* @prop {number} lastIndex An index of the last inserted element. Starts with 0. | ||
* | ||
* @typedef {Object} MakeMarkersConfig Additional configuration. | ||
* @prop {(name: string, index: number) => string} [getReplacement] A function used to create a replacement when some text needs to be cut. | ||
* @prop {(name: string) => RegExp} [getRegex] A function used to create a RegExp to detect replaced chunks. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Marker} Marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.Marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @prop {string} name The name of the marker for annotation purposes. | ||
* @prop {function(string, number): string} getReplacement The function to generate marker placeholders which can be then found, e.g., for (name: `marker`, index: `10`) by default _Restream_ will generate `%%_RESTREAM_MARKER_REPLACEMENT_10_%%`, but can be overriden with this method. | ||
* @prop {!RegExp} re The regular expression used for detection of the match. | ||
* @prop {!RegExp} regExp The generated regular expression to replace the marker back to its original value. | ||
* @prop {!Object<number, string>} map The map which holds detected matches at their indexes. | ||
* @prop {number} lastIndex The index of the last inserted element. Starts with 0. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.MakeMarkersConfig} MakeMarkersConfig Additional configuration. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.MakeMarkersConfig Additional configuration. | ||
* @prop {function(string, number): string} [getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @prop {function(string): !RegExp} [getRegex] The function used to create a RegExp to detect replaced chunks. | ||
*/ | ||
@@ -127,0 +143,0 @@ |
const { Transform } = require('stream'); | ||
let cleanStack = require('@artdeco/clean-stack'); if (cleanStack && cleanStack.__esModule) cleanStack = cleanStack.default; | ||
const { checkRule, hideStack } = require('./lib'); | ||
let cleanStack = require('@artdeco/clean-stack'); if (cleanStack && cleanStack.__esModule) cleanStack = cleanStack.default; | ||
@@ -8,13 +8,15 @@ class Replaceable extends Transform { | ||
* Replaceable class that extends Transform and pushes data when it's done replacing each incoming chunk. If the replacement is passed as a function, it will work in the same way as the replacer for `string.replace` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), taking the `match` as the first argument, and matched `p1`, `p2`, _etc_ parameters as following arguments. The replacer can also be an async function. | ||
* @param {(Rule|Array<Rule>)} rules A single replacement rule, or multiple rules. | ||
* @param {TransformOptions=} [options] The options for the transform stream. | ||
* @param {!(_restream.Rule|Array<!_restream.Rule>)} rules A single replacement rule, or multiple rules. | ||
* @param {!stream.TransformOptions} [options] The options for the transform stream. | ||
* @example | ||
* | ||
* // markdown __ to html emphasize implementation | ||
* const stream = replaceStream({ | ||
* re: /__(\S+)__/g, | ||
* replacement(match, p1) { | ||
* return `<em>${p1}</em>` | ||
* }, | ||
* }) | ||
``` | ||
// markdown __ to html <em> implementation | ||
const stream = replaceStream({ | ||
re: /__(\S+)__/g, | ||
replacement(match, p1) { | ||
return `<em>${p1}</em>` | ||
}, | ||
}) | ||
``` | ||
*/ | ||
@@ -26,2 +28,7 @@ constructor(rules, options) { | ||
this.rules = fr | ||
/** | ||
* Whether the _Replaceable_ will not apply any more rules. | ||
* @type {boolean} | ||
*/ | ||
this._broke = false | ||
} | ||
@@ -46,4 +53,2 @@ | ||
} else { | ||
/** @type {(Replacer|AsyncReplacer)} */ | ||
const R = replacement.bind(this) | ||
const promises = [] | ||
@@ -55,3 +60,3 @@ let commonError | ||
if (this._broke) return match | ||
const p = R(match, ...args) | ||
const p = replacement.call(this, match, ...args) | ||
if (p instanceof Promise) { | ||
@@ -81,2 +86,6 @@ promises.push(p) | ||
} | ||
/** | ||
* @suppress {checkTypes} | ||
* @returns {!Promise} | ||
*/ | ||
async _transform(chunk, _, next) { | ||
@@ -100,3 +109,3 @@ try { | ||
/** | ||
* @param {(Rule|Array<Rule>)} rules | ||
* @param {!(_restream.Rule|Array<_restream.Rule>)} rules | ||
*/ | ||
@@ -115,18 +124,19 @@ constructor(rules) { | ||
/** | ||
* @typedef {import('stream').TransformOptions} TransformOptions | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ | ||
/* documentary types/rules.xml */ | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').AsyncReplacer} _restream.AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Replacer} _restream.Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('stream').TransformOptions} stream.TransformOptions | ||
*/ | ||
module.exports = Replaceable | ||
module.exports.SerialAsyncReplaceable = SerialAsyncReplaceable |
const { checkRule, hideStack } = require('./lib'); | ||
/** | ||
* SyncReplaceable function receives the whole string and returns the result of transforms which are of interface `{ re: /reg-(exp)/, replacement(m, t) { return `transform-${t}` } }` | ||
* If the replacement is passed as a function, it will work in the same way as the replacer for `string.replace` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), taking the `match` as the first argument, and matched `p1`, `p2`, _etc_ parameters as following arguments. The replacer can also be an async function. | ||
* @param {string|Buffer} input The string or buffer to transform synchronously using the replacements. Does not support asynchronous replacements. | ||
* @param {Rule[]} rules An array with rules. | ||
* _SyncReplaceable_ function receives the whole string and returns the result of transform rules which are either sync function replacers or string replacements (see https://github.com/artdecocode/restream#rule-type for more info). This is not a class and just a function. | ||
* @param {string|!Buffer} input The string or buffer to transform synchronously using the replacements. Does not support asynchronous replacements. | ||
* @param {!Array<!_restream.Rule>} rules An array with rules. | ||
* @return {string} | ||
* @example | ||
* | ||
* // markdown __ to html emphasise implementation | ||
* const stream = SyncReplaceable('__hello world__', { | ||
* --re: /__(\S+)__/g, | ||
* --replacement(match, p1) { | ||
* ----return `<em>${p1}</em>` | ||
* --}, | ||
* }) | ||
``` | ||
// markdown __ to html <em> implementation | ||
const stream = SyncReplaceable('__hello world__', { | ||
re: /__(\S+)__/g, | ||
replacement(match, p1) { | ||
return `<em>${p1}</em>` | ||
}, | ||
}) | ||
``` | ||
*/ | ||
const SyncReplaceable = (input, rules) => { | ||
const fr = rules.filter(checkRule) | ||
const s = fr.reduce((acc, { re, replacement }) => { | ||
/** @type {string} */ | ||
let Acc = acc | ||
if (this._broke) return Acc | ||
function SyncReplaceable(input, rules) { | ||
/** | ||
* @suppress {globalThis} | ||
*/ | ||
function replace() { | ||
const fr = rules.filter(checkRule) | ||
const s = fr.reduce((acc, { re, replacement }) => { | ||
/** @type {string} */ | ||
let Acc = acc | ||
if (this._broke) return Acc | ||
if (typeof replacement == 'string') { | ||
Acc = Acc.replace(re, replacement) | ||
} else { | ||
/** @type {function} */ | ||
const R = replacement.bind(this) | ||
let commonError | ||
const t = Acc.replace(re, (match, ...args) => { | ||
commonError = new Error() | ||
try { | ||
if (this._broke) return match | ||
const p = R(match, ...args) | ||
return p | ||
} catch (e) { // hide stack for sync stack traces | ||
hideStack(commonError, e) | ||
} | ||
}) | ||
return t | ||
} | ||
}, `${input}`) | ||
return s | ||
if (typeof replacement == 'string') { | ||
Acc = Acc.replace(re, replacement) | ||
} else { | ||
let commonError | ||
const t = Acc.replace(re, (match, ...args) => { | ||
commonError = new Error() | ||
try { | ||
if (this._broke) return match | ||
const p = replacement.call(this, match, ...args) | ||
return p | ||
} catch (e) { // hide stack for sync stack traces | ||
hideStack(commonError, e) | ||
} | ||
}) | ||
return t | ||
} | ||
}, `${input}`) | ||
return s | ||
} | ||
replace.brake = () => { replace._broke = true } | ||
return replace.call(replace) | ||
} | ||
@@ -49,11 +55,5 @@ | ||
/* documentary types/rules.xml */ | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
*/ | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ |
@@ -0,4 +1,13 @@ | ||
## 10 April 2019 | ||
### [3.6.0](https://github.com/artdecocode/restream/compare/v3.5.1...v3.6.0) | ||
- [externs] Provide externs for _Google Closure Compiler_ via _Depack_. | ||
- [fix] Fix _SyncReplaceable_ using global context. | ||
- [doc] Use `_restream_` namespace, markdown in examples. | ||
- [deps] Update and unlock dependencies. | ||
## 28 March 2019 | ||
### [3.5.1](git+https://github.com/artdecocode/restream/compare/v3.5.0...v3.5.1) | ||
### [3.5.1](https://github.com/artdecocode/restream/compare/v3.5.0...v3.5.1) | ||
@@ -5,0 +14,0 @@ - [fix] Allow to pass options to the _Transform_ constructor from _Replaceable_. |
@@ -0,16 +1,25 @@ | ||
/* typal types/markers.xml */ | ||
/** @const */ | ||
var _restream = {} | ||
/** | ||
* @typedef {function(string, ...string): string} Replacer | ||
* @typedef {{ name: string, getReplacement: function(string, number): string, re: !RegExp, regExp: !RegExp, map: !Object<number, string>, lastIndex: number }} | ||
*/ | ||
var Replacer | ||
_restream.Marker | ||
/** | ||
* @typedef {function(string, ...string): Promise<string>} AsyncReplacer | ||
* @typedef {{ getReplacement: (function(string, number): string|undefined), getRegex: (function(string): !RegExp|undefined) }} | ||
*/ | ||
var AsyncReplacer | ||
_restream.MakeMarkersConfig | ||
/* typal types/rules.xml */ | ||
/** | ||
* @typedef {Object} Rule | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {(string|Replacer|AsyncReplacer)} replacement A replacement string, or a replacement string function. | ||
* @typedef {function(this:*, ...string): string} | ||
*/ | ||
var Rule | ||
_restream.Replacer | ||
/** | ||
* @typedef {function(this:*, ...string): !Promise<string>} | ||
*/ | ||
_restream.AsyncReplacer | ||
/** | ||
* @typedef {{ re: !RegExp, replacement: !(string|_restream.Replacer|_restream.AsyncReplacer) }} | ||
*/ | ||
_restream.Rule |
{ | ||
"name": "restream", | ||
"version": "3.5.1", | ||
"version": "3.6.0", | ||
"description": "Regular Expression Detection & Replacement streams.", | ||
@@ -14,8 +14,4 @@ "main": "build/index.js", | ||
"b": "alamode src -o build -s", | ||
"d1": "NODE_DEBUG=doc doc src/index.js -g", | ||
"d2": "NODE_DEBUG=doc doc src/lib/markers.js -g", | ||
"d3": "NODE_DEBUG=doc doc src/Replaceable.js -g", | ||
"d4": "NODE_DEBUG=doc doc src/SyncReplaceable.js -g", | ||
"d5": "NODE_DEBUG=doc doc externs.js -g", | ||
"d": "yarn-s d1 d2 d3 d4 d5", | ||
"externs": "typal externs.js -e", | ||
"d": "typal src -c", | ||
"e": "node example", | ||
@@ -40,3 +36,3 @@ "doc": "NODE_DEBUG=doc doc documentary -o README.md", | ||
"type": "git", | ||
"url": "git+https://github.com/artdecocode/restream.git" | ||
"url": "https://github.com/artdecocode/restream.git" | ||
}, | ||
@@ -64,13 +60,13 @@ "keywords": [ | ||
"devDependencies": { | ||
"alamode": "1.8.6", | ||
"catchment": "3.2.2", | ||
"documentary": "1.23.0", | ||
"alamode": "^1.9.2", | ||
"catchment": "^3.3.0", | ||
"documentary": "^1.23.4", | ||
"eslint-config-artdeco": "1.0.1", | ||
"spawncommand": "2.1.1", | ||
"spawncommand": "^2.1.2", | ||
"yarn-s": "1.1.0", | ||
"zoroaster": "3.11.1" | ||
"zoroaster": "^3.11.4" | ||
}, | ||
"dependencies": { | ||
"@artdeco/clean-stack": "1.0.1" | ||
"@artdeco/clean-stack": "^1.1.1" | ||
} | ||
} |
@@ -64,2 +64,4 @@ # restream | ||
The types and [externs](externs.js) for _Google Closure Compiler_ via [**_Depack_**](https://github.com/dpck/depack) are defined in the `_restream` namespace. | ||
<p align="center"><a href="#table-of-contents"><img src=".documentary/section-breaks/2.svg?sanitize=true"></a></p> | ||
@@ -268,3 +270,3 @@ | ||
Author: <strong>John</strong> | ||
on <em>2019-3-28 13:40:38</em> | ||
on <em>2019-4-10 22:05:57</em> | ||
``` | ||
@@ -532,5 +534,5 @@ | ||
``` | ||
Test: serial 114ms, parallel 425ms, | ||
Example: serial 216ms, parallel 425ms, | ||
Total: serial 320ms, parallel 425ms, | ||
Test: serial 114ms, parallel 423ms, | ||
Example: serial 217ms, parallel 423ms, | ||
Total: serial 321ms, parallel 423ms, | ||
``` | ||
@@ -730,6 +732,6 @@ | ||
| Name | Type | Description | | ||
| -------------- | -------------------------------------------- | ----------------------------------------------------------------------- | | ||
| getReplacement | _(name: string, index: number) => string_ | A function used to create a replacement when some text needs to be cut. | | ||
| getRegex | _(name: string) => RegExp_ | A function used to create a RegExp to detect replaced chunks. | | ||
| Name | Type | Description | | ||
| -------------- | -------------------------------------------- | ------------------------------------------------------------------------- | | ||
| getReplacement | _(name: string, index: number) => string_ | The function used to create a replacement when some text needs to be cut. | | ||
| getRegex | _(name: string) => !RegExp_ | The function used to create a RegExp to detect replaced chunks. | | ||
@@ -736,0 +738,0 @@ By default, `%%_RESTREAM_${name.toUpperCase()}_REPLACEMENT_${index}_%%` replacement is used with <code>new RegExp(`%%_RESTREAM_${name.toUpperCase()}_REPLACEMENT_(\\d+)_%%`, 'g')</code> regex to detect it and restore the original value. |
@@ -5,3 +5,3 @@ import { Transform } from 'stream' | ||
* Create a Transform stream which will maintain a buffer with data received from a Readable stream and write data when the buffer can be matched against the regex. It will push the whole match object (or objects when the g flag is used) returned by `/regex/.exec(buffer)`. | ||
* @param {RegExp} regex Regular expression to execute | ||
* @param {!RegExp} regex The regular expression to execute. | ||
*/ | ||
@@ -11,2 +11,3 @@ export default function createRegexTransformStream(regex) { | ||
/** @suppress {checkTypes} */ | ||
const ts = new Transform({ | ||
@@ -48,9 +49,26 @@ transform(chunk, encoding, next) { | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Replacer} Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {function(this:*, ...string): string} _restream.Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.AsyncReplacer} AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {function(this:*, ...string): !Promise<string>} _restream.AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Rule} Rule A replacement rule. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.Rule A replacement rule. | ||
* @prop {!RegExp} re The regular expression to match input against. | ||
* @prop {!(string|_restream.Replacer|_restream.AsyncReplacer)} replacement The replacement string, or the replacer function. | ||
*/ |
@@ -22,9 +22,13 @@ import SyncReplaceable from '../SyncReplaceable' | ||
* @param {string} name The name of the matcher, used in the doc marker. | ||
* @param {RegExp} re The regular expression used for detection. | ||
* @return {Marker} The marker. | ||
* @param {!RegExp} re The regular expression used for detection. | ||
* @param {!_restream.MakeMarkersConfig} [conf] Additional configuration. | ||
* @param {function(string, number): string} [conf.getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @param {function(string): !RegExp} [conf.getRegex] The function used to create a RegExp to detect replaced chunks. | ||
* @return {!_restream.Marker} The marker. | ||
*/ | ||
const makeMarker = (name, re, { | ||
getReplacement = getDefaultReplacement, | ||
getRegex = getDefaultRegExp, | ||
} = {}) => { | ||
const makeMarker = (name, re, conf) => { | ||
const { | ||
getReplacement = getDefaultReplacement, | ||
getRegex = getDefaultRegExp, | ||
} = conf || {} | ||
const regExp = getRegex(name) | ||
@@ -43,7 +47,7 @@ return { | ||
* Make markers from a configuration object. | ||
* @param {Object.<string, RegExp>} matchers An object with types of markers to create as keys and their detection regexes as values. | ||
* @param {MakeMarkersConfig} [config] Additional configuration. | ||
* @param {(name: string, index: number) => string} [config.getReplacement] A function used to create a replacement when some text needs to be cut. | ||
* @param {(name: string) => RegExp} [config.getRegex] A function used to create a RegExp to detect replaced chunks. | ||
* @returns {Object.<string, Marker>} An object with markers for each requested type. | ||
* @param {!Object.<string, !RegExp>} matchers An object with types of markers to create as keys and their detection regexes as values. | ||
* @param {!_restream.MakeMarkersConfig} [config] Additional configuration. | ||
* @param {function(string, number): string} [config.getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @param {function(string): !RegExp} [config.getRegex] The function used to create a RegExp to detect replaced chunks. | ||
* @returns {!Object.<string, !_restream.Marker>} An object with markers for each requested type. | ||
*/ | ||
@@ -65,5 +69,5 @@ export const makeMarkers = (matchers, config) => { | ||
* Make a rule for pasting markers back. | ||
* @param {Marker} marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @param {(Rule|Array<Rule>)} [pipeRules] Any additional rules to replace the value of the marker before pasting it. | ||
* @returns {Rule} A rule to paste previously replaced chunks. | ||
* @param {!_restream.Marker} marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @param {!(_restream.Rule|Array<!_restream.Rule>)} [pipeRules] Any additional rules to replace the value of the marker before pasting it. | ||
* @returns {!_restream.Rule} A rule to paste previously replaced chunks. | ||
*/ | ||
@@ -87,4 +91,4 @@ export const makePasteRule = (marker, pipeRules = []) => { | ||
* Make a rule for initial replacement of markers. | ||
* @param {Marker} marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @returns {Rule} A rule to cut matched chunks. | ||
* @param {!_restream.Marker} marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @returns {!_restream.Rule} A rule to cut matched chunks. | ||
*/ | ||
@@ -107,3 +111,4 @@ export const makeCutRule = (marker) => { | ||
/** | ||
* @typedef {import('..').Rule} Rule | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ | ||
@@ -113,13 +118,24 @@ | ||
/** | ||
* @typedef {Object} Marker A marker used to cut and paste portions of text to exclude them from processing by other rules. | ||
* @prop {string} type Type of the marker. | ||
* @prop {(index) => string} getMarker A function to generate markers which can be then found. | ||
* @prop {RegExp} re A regular expression used for detection of the match. | ||
* @prop {RegExp} regExp A generated regular expression to replace the marker back to its original value. | ||
* @prop {object} map A map which holds detected matches at their indexes. | ||
* @prop {number} lastIndex An index of the last inserted element. Starts with 0. | ||
* | ||
* @typedef {Object} MakeMarkersConfig Additional configuration. | ||
* @prop {(name: string, index: number) => string} [getReplacement] A function used to create a replacement when some text needs to be cut. | ||
* @prop {(name: string) => RegExp} [getRegex] A function used to create a RegExp to detect replaced chunks. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.Marker} Marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.Marker A marker is used to cut and paste portions of text to exclude them from processing by other rules. Markers should be created using the `makeMarker` factory method that will assign their properties. | ||
* @prop {string} name The name of the marker for annotation purposes. | ||
* @prop {function(string, number): string} getReplacement The function to generate marker placeholders which can be then found, e.g., for (name: `marker`, index: `10`) by default _Restream_ will generate `%%_RESTREAM_MARKER_REPLACEMENT_10_%%`, but can be overriden with this method. | ||
* @prop {!RegExp} re The regular expression used for detection of the match. | ||
* @prop {!RegExp} regExp The generated regular expression to replace the marker back to its original value. | ||
* @prop {!Object<number, string>} map The map which holds detected matches at their indexes. | ||
* @prop {number} lastIndex The index of the last inserted element. Starts with 0. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {_restream.MakeMarkersConfig} MakeMarkersConfig Additional configuration. | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {Object} _restream.MakeMarkersConfig Additional configuration. | ||
* @prop {function(string, number): string} [getReplacement] The function used to create a replacement when some text needs to be cut. | ||
* @prop {function(string): !RegExp} [getRegex] The function used to create a RegExp to detect replaced chunks. | ||
*/ |
import { Transform } from 'stream' | ||
import cleanStack from '@artdeco/clean-stack' | ||
import { checkRule, hideStack } from './lib' | ||
import cleanStack from '@artdeco/clean-stack' | ||
@@ -8,13 +8,15 @@ export default class Replaceable extends Transform { | ||
* Replaceable class that extends Transform and pushes data when it's done replacing each incoming chunk. If the replacement is passed as a function, it will work in the same way as the replacer for `string.replace` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), taking the `match` as the first argument, and matched `p1`, `p2`, _etc_ parameters as following arguments. The replacer can also be an async function. | ||
* @param {(Rule|Array<Rule>)} rules A single replacement rule, or multiple rules. | ||
* @param {TransformOptions=} [options] The options for the transform stream. | ||
* @param {!(_restream.Rule|Array<!_restream.Rule>)} rules A single replacement rule, or multiple rules. | ||
* @param {!stream.TransformOptions} [options] The options for the transform stream. | ||
* @example | ||
* | ||
* // markdown __ to html emphasize implementation | ||
* const stream = replaceStream({ | ||
* re: /__(\S+)__/g, | ||
* replacement(match, p1) { | ||
* return `<em>${p1}</em>` | ||
* }, | ||
* }) | ||
``` | ||
// markdown __ to html <em> implementation | ||
const stream = replaceStream({ | ||
re: /__(\S+)__/g, | ||
replacement(match, p1) { | ||
return `<em>${p1}</em>` | ||
}, | ||
}) | ||
``` | ||
*/ | ||
@@ -26,2 +28,7 @@ constructor(rules, options) { | ||
this.rules = fr | ||
/** | ||
* Whether the _Replaceable_ will not apply any more rules. | ||
* @type {boolean} | ||
*/ | ||
this._broke = false | ||
} | ||
@@ -46,4 +53,2 @@ | ||
} else { | ||
/** @type {(Replacer|AsyncReplacer)} */ | ||
const R = replacement.bind(this) | ||
const promises = [] | ||
@@ -55,3 +60,3 @@ let commonError | ||
if (this._broke) return match | ||
const p = R(match, ...args) | ||
const p = replacement.call(this, match, ...args) | ||
if (p instanceof Promise) { | ||
@@ -81,2 +86,6 @@ promises.push(p) | ||
} | ||
/** | ||
* @suppress {checkTypes} | ||
* @returns {!Promise} | ||
*/ | ||
async _transform(chunk, _, next) { | ||
@@ -100,3 +109,3 @@ try { | ||
/** | ||
* @param {(Rule|Array<Rule>)} rules | ||
* @param {!(_restream.Rule|Array<_restream.Rule>)} rules | ||
*/ | ||
@@ -115,14 +124,16 @@ constructor(rules) { | ||
/** | ||
* @typedef {import('stream').TransformOptions} TransformOptions | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ | ||
/* documentary types/rules.xml */ | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').AsyncReplacer} _restream.AsyncReplacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Replacer} _restream.Replacer | ||
*/ | ||
/** | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('stream').TransformOptions} stream.TransformOptions | ||
*/ |
import { checkRule, hideStack } from './lib' | ||
/** | ||
* SyncReplaceable function receives the whole string and returns the result of transforms which are of interface `{ re: /reg-(exp)/, replacement(m, t) { return `transform-${t}` } }` | ||
* If the replacement is passed as a function, it will work in the same way as the replacer for `string.replace` method (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace), taking the `match` as the first argument, and matched `p1`, `p2`, _etc_ parameters as following arguments. The replacer can also be an async function. | ||
* @param {string|Buffer} input The string or buffer to transform synchronously using the replacements. Does not support asynchronous replacements. | ||
* @param {Rule[]} rules An array with rules. | ||
* _SyncReplaceable_ function receives the whole string and returns the result of transform rules which are either sync function replacers or string replacements (see https://github.com/artdecocode/restream#rule-type for more info). This is not a class and just a function. | ||
* @param {string|!Buffer} input The string or buffer to transform synchronously using the replacements. Does not support asynchronous replacements. | ||
* @param {!Array<!_restream.Rule>} rules An array with rules. | ||
* @return {string} | ||
* @example | ||
* | ||
* // markdown __ to html emphasise implementation | ||
* const stream = SyncReplaceable('__hello world__', { | ||
* --re: /__(\S+)__/g, | ||
* --replacement(match, p1) { | ||
* ----return `<em>${p1}</em>` | ||
* --}, | ||
* }) | ||
``` | ||
// markdown __ to html <em> implementation | ||
const stream = SyncReplaceable('__hello world__', { | ||
re: /__(\S+)__/g, | ||
replacement(match, p1) { | ||
return `<em>${p1}</em>` | ||
}, | ||
}) | ||
``` | ||
*/ | ||
const SyncReplaceable = (input, rules) => { | ||
const fr = rules.filter(checkRule) | ||
const s = fr.reduce((acc, { re, replacement }) => { | ||
/** @type {string} */ | ||
let Acc = acc | ||
if (this._broke) return Acc | ||
function SyncReplaceable(input, rules) { | ||
/** | ||
* @suppress {globalThis} | ||
*/ | ||
function replace() { | ||
const fr = rules.filter(checkRule) | ||
const s = fr.reduce((acc, { re, replacement }) => { | ||
/** @type {string} */ | ||
let Acc = acc | ||
if (this._broke) return Acc | ||
if (typeof replacement == 'string') { | ||
Acc = Acc.replace(re, replacement) | ||
} else { | ||
/** @type {function} */ | ||
const R = replacement.bind(this) | ||
let commonError | ||
const t = Acc.replace(re, (match, ...args) => { | ||
commonError = new Error() | ||
try { | ||
if (this._broke) return match | ||
const p = R(match, ...args) | ||
return p | ||
} catch (e) { // hide stack for sync stack traces | ||
hideStack(commonError, e) | ||
} | ||
}) | ||
return t | ||
} | ||
}, `${input}`) | ||
return s | ||
if (typeof replacement == 'string') { | ||
Acc = Acc.replace(re, replacement) | ||
} else { | ||
let commonError | ||
const t = Acc.replace(re, (match, ...args) => { | ||
commonError = new Error() | ||
try { | ||
if (this._broke) return match | ||
const p = replacement.call(this, match, ...args) | ||
return p | ||
} catch (e) { // hide stack for sync stack traces | ||
hideStack(commonError, e) | ||
} | ||
}) | ||
return t | ||
} | ||
}, `${input}`) | ||
return s | ||
} | ||
replace.brake = () => { replace._broke = true } | ||
return replace.call(replace) | ||
} | ||
@@ -49,11 +55,5 @@ | ||
/* documentary types/rules.xml */ | ||
/** | ||
* @typedef {(match: string, ...params: string[]) => string} Replacer | ||
* | ||
* @typedef {(match: string, ...params: string[]) => Promise.<string>} AsyncReplacer | ||
* | ||
* @typedef {Object} Rule A replacement rule. | ||
* @prop {RegExp} re A Regular expression to match against. | ||
* @prop {string|Replacer|AsyncReplacer} replacement A replacement string, or a replacement string function. | ||
*/ | ||
* @suppress {nonStandardJsDocs} | ||
* @typedef {import('..').Rule} _restream.Rule | ||
*/ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
66195
806
951
+ Added@artdeco/clean-stack@1.2.1(transitive)
- Removed@artdeco/clean-stack@1.0.1(transitive)
Updated@artdeco/clean-stack@^1.1.1