@arcsine/nodesh
Advanced tools
Comparing version 1.6.2 to 1.7.0
Changelog | ||
----------------------------- | ||
## 1.7.0 | ||
* Support reading text files with filename/line number context | ||
* Support contextual lines for $match, before/after lines. | ||
* Changed some signature to support objects, future proofing more complex configs | ||
## 1.6.2 | ||
Added in gzip/gunzip support | ||
Supports glob patterns in file matching | ||
General improvements | ||
* Added in gzip/gunzip support | ||
* Supports glob patterns in file matching | ||
* General improvements | ||
## 1.5.0 | ||
$tokens extracts now by pattern, vs separator. | ||
* $tokens extracts now by pattern, vs separator. | ||
## 1.4.1 | ||
Fixing support for Node 10 | ||
* Fixing support for Node 10 | ||
## 1.4.0 | ||
Adding in concat operator. Supporting count flag for unique operator. | ||
* Adding in concat operator. Supporting count flag for unique operator. | ||
## 1.3.0 | ||
* Standardize stream input/output, with newline support. Ensuring consistency with POSIX definition of lines. | ||
* Cleanup of streaming emissions. | ||
Standardize stream input/output, with newline support. Ensuring consistency with POSIX definition of lines. | ||
Cleanup of streaming emissions. | ||
## 1.2.2 | ||
Support for raw streams for exec and http | ||
* Support for raw streams for exec and http | ||
## 1.2.0 | ||
Enhanced HTTP support, now allows for streaming data as request payload. | ||
* Enhanced HTTP support, now allows for streaming data as request payload. | ||
## 1.1.7 | ||
Support key/value map for replace operator | ||
Patterns from replace have been externalized out to $pattern | ||
* Support key/value map for replace operator | ||
* Patterns from replace have been externalized out to $pattern | ||
## 1.1.6 | ||
Wait for streams to finish by use of setTimeout | ||
* Wait for streams to finish by use of setTimeout | ||
## 1.1.5 | ||
Minify output appropriately | ||
* Minify output appropriately | ||
## 1.1.0 | ||
Removed need for `.async`. expose operators directly on Object.prototype | ||
* Removed need for `.async`. expose operators directly on Object.prototype |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("./global"),require("./patch");const path=require("path"),fs=require("fs"),stream_1=require("stream"),register_1=require("./util/register"),helper_1=require("./helper"),stream_2=require("./util/stream");function initialize(){const a=fs.readdirSync(path.resolve(__dirname,"operator")).filter(a=>!a.endsWith(".d.ts")).map(a=>path.resolve(__dirname,"operator",a)).map(require).reduce((a,b)=>[...a,...Object.values(b)],[]);register_1.RegisterUtil.registerOperators(a,Object),register_1.RegisterUtil.registerAsyncable(Object),register_1.RegisterUtil.properties({$iterable(){return stream_2.StreamUtil.readStream(this)}},stream_1.Readable.prototype),register_1.RegisterUtil.properties({async*$iterable(){yield this}},String.prototype),register_1.RegisterUtil.properties({async*$iterable(){yield this}},Buffer.prototype);const b=Object.getOwnPropertyDescriptors(helper_1.GlobalHelpers);if(delete b.prototype,Object.defineProperties(globalThis,b),10<parseInt(process.version.replace(/^v/i,"").split(".")[0],10)){const{constructor:a}=async function*(){}();register_1.RegisterUtil.registerThenable(a)}}initialize(); | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0}),require("./global"),require("./patch");const path=require("path"),fs=require("fs"),stream_1=require("stream"),register_1=require("./util/register"),helper_1=require("./helper"),stream_2=require("./util/stream");function initialize(){const a=fs.readdirSync(path.resolve(__dirname,"operator")).filter(a=>!a.endsWith(".d.ts")).map(a=>path.resolve(__dirname,"operator",a)).map(require).reduce((a,b)=>[...a,...Object.values(b)],[]);register_1.RegisterUtil.registerOperators(a,Object),register_1.RegisterUtil.registerAsyncable(Object),register_1.RegisterUtil.properties({$iterable(){return stream_2.StreamUtil.readStream(this)}},stream_1.Readable.prototype),register_1.RegisterUtil.properties({async*$iterable(){yield this}},String.prototype),register_1.RegisterUtil.properties({async*$iterable(){yield this}},Buffer.prototype);const b=Object.getOwnPropertyDescriptors(helper_1.GlobalHelpers);delete b.prototype;for(const[a,c]of Object.entries(b))register_1.RegisterUtil.defineProperty(globalThis,a,c);if(10<parseInt(process.version.replace(/^v/i,"").split(".")[0],10)){const{constructor:a}=async function*(){}();register_1.RegisterUtil.registerThenable(a)}}initialize(); |
@@ -19,4 +19,11 @@ import { $AsyncIterable } from '../types'; | ||
* .$console | ||
* | ||
* @example | ||
* $range(1000) | ||
* .$parallel(x => doWork(x), 100) // 100 concurrent workers | ||
* .$console | ||
*/ | ||
$parallel<T, U = T>(this: AsyncIterable<T>, op: (item: T) => AsyncIterable<U> | Promise<U>, concurrent?: number): $AsyncIterable<U>; | ||
$parallel<T, U = T>(this: AsyncIterable<T>, op: (item: T) => AsyncIterable<U> | Promise<U>, config?: number | { | ||
concurrent?: number; | ||
}): $AsyncIterable<U>; | ||
} |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const os=require("os"),async_1=require("../util/async");class AdvancedOperators{async*$parallel(a,b){b=null!==b&&void 0!==b?b:os.cpus().length-1;const c=[],d=function(){const a=Promise.race(c.map(a=>a.p));return async_1.AsyncUtil.trackWithTimer(a)};for await(const e of this){const f={};c.push(f);const g=a(e);f.p=g,"$value"in g&&!(g instanceof Promise)&&(f.p=g.$value),f.p=(async()=>await f.p)().finally(()=>{c.splice(c.indexOf(f),1)}),c.length>=b&&(yield await d())}for(;c.length;)yield await d()}}exports.AdvancedOperators=AdvancedOperators; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const os=require("os"),async_1=require("../util/async");class AdvancedOperators{async*$parallel(a,b={}){var c;"number"==typeof b&&(b={concurrent:b});const d=(c=b.concurrent,null!==c&&void 0!==c?c:os.cpus().length-1),e=[],f=function(){const a=Promise.race(e.map(a=>a.p));return async_1.AsyncUtil.trackWithTimer(a)};for await(const c of this){const b={};e.push(b);const g=a(c);b.p=g,"$value"in g&&!(g instanceof Promise)&&(b.p=g.$value),b.p=(async()=>await b.p)().finally(()=>{e.splice(e.indexOf(b),1)}),e.length>=d&&(yield await f())}for(;e.length;)yield await f()}}exports.AdvancedOperators=AdvancedOperators; |
/// <reference types="node" /> | ||
import { Readable, Writable } from 'stream'; | ||
import { $AsyncIterable } from '../types'; | ||
import { $AsyncIterable, CSVConfig } from '../types'; | ||
/** | ||
@@ -20,2 +20,13 @@ * Support for dealing with specific data formats as inputs | ||
/** | ||
* CSV support, returns rows of string[], given no column information | ||
* | ||
* @example | ||
* '<file>.csv' | ||
* .$read() // Read file | ||
* .$csv({ sep: '\t' }) | ||
* // Convert to string[] from CSV (actually TSV) | ||
*/ | ||
$csv(this: AsyncIterable<string>): $AsyncIterable<string[]>; | ||
$csv(this: AsyncIterable<string>, config: Partial<CSVConfig>): $AsyncIterable<string[]>; | ||
/** | ||
* Converts the inbound CSV string into JS Object. Converts by using simple CSV support and | ||
@@ -30,4 +41,18 @@ * splitting on commas. Each value in the sequence is assumed to be a single row in the output. | ||
*/ | ||
$csv<V extends readonly string[]>(this: AsyncIterable<string>, columns: V): $AsyncIterable<Record<V[number], string>>; | ||
$csv<V extends readonly string[]>(this: AsyncIterable<string>, config: V | (Partial<CSVConfig> & { | ||
columns: V; | ||
})): $AsyncIterable<Record<V[number], string>>; | ||
/** | ||
* If using the `headerRow` configuration, you can have the key names inferred from the first line of the file | ||
* | ||
* @example | ||
* '<file>.csv' | ||
* .$read() // Read file | ||
* .$csv({ headerRow: true, sep: '\t' }) | ||
* // Convert to objects from CSV (actually TSV) | ||
*/ | ||
$csv(this: AsyncIterable<string>, config: Partial<CSVConfig> & { | ||
headerRow: true; | ||
}): $AsyncIterable<Record<string, string>>; | ||
/** | ||
* Will read string values from the input, delimited by new lines | ||
@@ -40,3 +65,6 @@ * | ||
*/ | ||
$prompt(this: AsyncIterable<string>, input?: Readable, output?: Writable): $AsyncIterable<string>; | ||
$prompt(this: AsyncIterable<string>, config?: { | ||
input?: Readable; | ||
output?: Writable; | ||
}): $AsyncIterable<string>; | ||
/** | ||
@@ -43,0 +71,0 @@ * Compresses inbound binary/text data into compressed stream of Buffers |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const readline=require("readline"),zlib=require("zlib"),stream_1=require("../util/stream");class DataOperators{$json(a=!0){return(a?this.$toString():this).$map(a=>JSON.parse(a))}$csv(a){return this.$columns({names:a,sep:/,/})}async*$prompt(a=process.stdin,b=process.stdout){let c;try{c=readline.createInterface({input:a,output:b});for await(const a of this)yield await new Promise(b=>c.question(`${a}\n`,b))}finally{c.close()}}async*$gzip(){const a=zlib.createGzip(),b=this.$stream("binary");yield*stream_1.StreamUtil.readStream(b.pipe(a),{mode:"binary"})}async*$gunzip(a){const b=zlib.createGunzip(),c=this.$stream("binary"),d=c.pipe(b);yield*stream_1.StreamUtil.readStream(d,{mode:a})}}exports.DataOperators=DataOperators; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const readline=require("readline"),zlib=require("zlib"),stream_1=require("../util/stream"),data_1=require("../util/data");class DataOperators{$json(a=!0){return(a?this.$toString():this).$map(a=>JSON.parse(a))}async*$csv(a={}){var b,c;Array.isArray(a)&&(a={columns:a});const d=this[Symbol.asyncIterator]();let e=a.columns;const f={sep:(b=a.sep,null!==b&&void 0!==b?b:","),quote:(c=a.quote,null!==c&&void 0!==c?c:"\"")};if(a.headerRow){const a=(await d.next()).value;e=data_1.DataUtil.parseCSVLine(a,f)}for(let b;!(b=await d.next()).done;)yield data_1.DataUtil.parseCSVLine(b.value,f,e)}async*$prompt(a={}){const b={input:process.stdin,output:process.stdout,...a};let c;try{c=readline.createInterface(b);for await(const a of this)yield await new Promise(b=>c.question(`${a}\n`,b))}finally{c.close()}}async*$gzip(){const a=zlib.createGzip(),b=this.$stream("binary");yield*stream_1.StreamUtil.readStream(b.pipe(a),{mode:"binary"})}async*$gunzip(a){const b=zlib.createGunzip(),c=this.$stream("binary"),d=c.pipe(b);yield*stream_1.StreamUtil.readStream(d,{mode:a})}}exports.DataOperators=DataOperators; |
import * as fs from 'fs'; | ||
import { ScanEntry } from '../util/file'; | ||
import { $AsyncIterable, ReadDirConfig, ReadStreamConfig } from '../types'; | ||
import { $AsyncIterable, ReadDirConfig, ReadStreamConfig, ReadTextLineConfig } from '../types'; | ||
declare type Line = { | ||
text: string; | ||
number: number; | ||
file: string; | ||
}; | ||
/** | ||
@@ -13,2 +18,30 @@ * Some of the most common shell operations are iterating through files, | ||
/** | ||
* This operator will read a text file as a series of `Line` objects, which include the file name, | ||
* line number, and associated text. | ||
* | ||
* When `mode` is `text` or undefined, the result will be a series of string in the format `{{file}}:{{number}} {{text}}` | ||
* When `mode` is 'object', the result will be the raw `Line` objects | ||
* | ||
* When in `text` mode, the line number, and file name can be toggled off as needed by passing in additional config. | ||
* | ||
* @example | ||
* '<file>' | ||
* .$readLines({ number:false }) // Read as a series of lines, without numbering | ||
* | ||
* @example | ||
* '<file>' | ||
* .$readLines({ mode:'object' }) // Read as a series of line objects | ||
* .$filter(line => line.number === 5) // Read only 5th line | ||
* | ||
* @example | ||
* '.js' | ||
* .$dir() | ||
* .$readLines() // Read as a series of lines, with filename, line number prepended | ||
*/ | ||
$readLines(this: AsyncIterable<string>, config: ReadTextLineConfig<'text'>): $AsyncIterable<string>; | ||
$readLines(this: AsyncIterable<string>, config: { | ||
mode: 'object'; | ||
}): $AsyncIterable<Line>; | ||
$readLines(this: AsyncIterable<string>): $AsyncIterable<string>; | ||
/** | ||
* This operator will treat the inbound string sequence as file names, and will convert the filename (based on IOType) | ||
@@ -23,3 +56,3 @@ * * `text` (default) - The sequence will produce as series of lines of text | ||
* '<file>' | ||
* .$read('binary') // Read as a series of buffers | ||
* .$read({ mode: 'binary' }) // Read as a series of buffers | ||
* .$reduce((acc, buffer) => { | ||
@@ -31,5 +64,4 @@ * return acc + buffer.length; | ||
* '<file>' | ||
* .$read('binary', true) // Read as a single buffer | ||
* .$read({ mode:'binary', singleValue: true }) // Read as a single buffer | ||
* .$map(buffer => buffer.length) // Count number of bytes in file | ||
* | ||
*/ | ||
@@ -64,1 +96,2 @@ $read(this: AsyncIterable<string>, config?: Omit<ReadStreamConfig, 'mode'>): $AsyncIterable<string>; | ||
} | ||
export {}; |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const path=require("path"),picomatch=require("picomatch"),stream_1=require("../util/stream"),file_1=require("../util/file");class FileOperators{async*$read(a={}){for await(const b of this)yield*stream_1.StreamUtil.readStream(b,a)}async*$dir(a={base:process.cwd()}){a.base=path.resolve(process.cwd(),a.base||"");for await(const b of this){const c="string"==typeof b?/^[.][a-zA-Z0-9]+$/.test(b)?picomatch(`**/*${b}`):picomatch(b):b.test.bind(b);yield*file_1.FileUtil.scanDir({testFile:a=>c(a)},a.base).$map(b=>a.full?b:b.file)}}}exports.FileOperators=FileOperators; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const path=require("path"),stream_1=require("../util/stream"),file_1=require("../util/file");class FileOperators{async*$readLines(a={}){for await(const b of this){let c=0;const d=stream_1.StreamUtil.readStream(b,{mode:"text"}).$map(d=>({number:++c,file:a.base?b.replace(a.base,"."):b,text:d}));"object"===a.mode?yield*d:yield*d.$map(b=>{let c="";if(!1!==a.number){const a=100<=b.number?"":10<=b.number?" ":" ";c=`${a}${b.number}`}return!1!==a.file&&(c=`${b.file} ${c}`),`${c}: ${b.text}`})}}async*$read(a={}){for await(const b of this)yield*stream_1.StreamUtil.readStream(b,a)}async*$dir(a={base:process.cwd()}){a.base=path.resolve(process.cwd(),a.base||"");for await(const b of this){const c=file_1.FileUtil.getFileMatcher(b);yield*file_1.FileUtil.scanDir({testFile:c},a.base).$map(b=>a.full?b:b.file)}}}exports.FileOperators=FileOperators; |
@@ -7,2 +7,8 @@ import { $AsyncIterable, Pattern } from '../types'; | ||
}; | ||
declare type MatchConfig = { | ||
negate: true; | ||
} | { | ||
before?: number; | ||
after?: number; | ||
}; | ||
/** | ||
@@ -57,5 +63,6 @@ * Support for common textual operations. | ||
* | ||
* Additionally, mode will determine what is emitted when a match is found (within a single line): | ||
* * `undefined` - (default) Return entire line | ||
* * `'negate'` - Return only lines that do not match | ||
* Additionally, the config provides standard functionality, commensurate with grep: | ||
* * `negate` - Return only lines that do not match | ||
* * `before` - The number of lines to return before a match | ||
* * `after` - The number of lines to return after a match | ||
* | ||
@@ -65,3 +72,9 @@ * @example | ||
* .$read() | ||
* .$match(/(FIXME|TODO)/, 'negate') | ||
* .$match('TODO') | ||
* // All lines with TODO in them | ||
* | ||
* @example | ||
* '<file>' | ||
* .$read() | ||
* .$match(/(FIXME|TODO)/, { negate:true }) | ||
* // Exclude all lines that include FIXME or TODO | ||
@@ -72,6 +85,6 @@ * | ||
* .$read() | ||
* .$match(/\d{3}(-)?\d{3}(-)?\d{4}/) | ||
* .$match(/\d{3}(-)?\d{3}(-)?\d{4}/, { after:1, before:1 }) | ||
* // Match all lines with phone numbers | ||
*/ | ||
$match(this: AsyncIterable<string>, regex: Pattern, mode?: 'negate'): $AsyncIterable<string>; | ||
$match(this: AsyncIterable<string>, pattern: Pattern, config?: MatchConfig): $AsyncIterable<string>; | ||
/** | ||
@@ -78,0 +91,0 @@ * `$replace` behaves identically to `String.prototype.replace`, but will only operate |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const text_1=require("../util/text");function isIter(a){return!!a[Symbol.iterator]}class TextOperators{async*$columns(a){var b;let c=!a||"string"==typeof a||a instanceof RegExp?{sep:a}:Array.isArray(a)?{names:a}:a;const d=text_1.TextUtil.createRegExp((b=c.sep,null!==b&&void 0!==b?b:/\s+/),"");for await(const b of this){const a=b.split(d),{names:e}=c;if(e){const b=Math.min(a.length,e.length),c={};for(let d=0;d<b;d++)c[e[d]]=a[d];yield c}else yield a}}async*$tokens(a=/\S+/){a=text_1.TextUtil.createRegExp(a,"g");for await(const b of this){const c=[];b.replace(a,a=>c.push(a)?"":""),yield*c}}async*$match(a,b){a=text_1.TextUtil.createRegExp(a,"");for await(const c of this)"negate"===b?a.test(c)||(yield c):a.test(c)&&(yield c)}$replace(a,b){if("string"==typeof a||a instanceof RegExp||isIter(a)){const c=text_1.TextUtil.createRegExp(a,"g");return this.$map(a=>a.replace(c,b))}else{const b=text_1.TextUtil.createRegExp(Object.keys(a));return this.$map(c=>c.replace(b,b=>a[b]))}}$trim(){return this.$map(a=>a.trim())}$toString(){return this.$collect().$map(a=>a.join(""))}}exports.TextOperators=TextOperators; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const text_1=require("../util/text");function isIter(a){return!!a[Symbol.iterator]}class TextOperators{async*$columns(a){var b;let c=!a||"string"==typeof a||a instanceof RegExp?{sep:a}:Array.isArray(a)?{names:a}:a;const d=text_1.TextUtil.createRegExp((b=c.sep,null!==b&&void 0!==b?b:/\s+/),"");for await(const b of this){const a=b.split(d),{names:e}=c;if(e){const b=Math.min(a.length,e.length),c={};for(let d=0;d<b;d++)c[e[d]]=a[d];yield c}else yield a}}async*$tokens(a=/\S+/){a=text_1.TextUtil.createRegExp(a,"g");for await(const b of this){const c=[];b.replace(a,a=>c.push(a)?"":""),yield*c}}async*$match(a,b={}){var c,d;const e=text_1.TextUtil.createRegExp(a,""),f=!!("negate"in b)&&b.negate,g=(c="before"in b?b.before:0,null!==c&&void 0!==c?c:0),h=(d="after"in b?b.after:0,null!==d&&void 0!==d?d:0);if(f)for await(const a of this)e.test(a)||(yield a);else{let a=[],b=0;for await(const c of this)e.test(c)?(g&&a.length&&(yield*a,a=[]),yield c,h&&(b=h)):b?(yield c,b-=1):g&&(a.push(c),a.length>g&&a.shift())}}$replace(a,b){if("string"==typeof a||a instanceof RegExp||isIter(a)){const c=text_1.TextUtil.createRegExp(a,"g");return this.$map(a=>a.replace(c,b))}else{const b=text_1.TextUtil.createRegExp(Object.keys(a));return this.$map(c=>c.replace(b,b=>a[b]))}}$trim(){return this.$map(a=>a.trim())}$toString(){return this.$collect().$map(a=>a.join(""))}}exports.TextOperators=TextOperators; |
@@ -17,2 +17,8 @@ /// <reference types="node" /> | ||
}; | ||
export declare type ReadTextLineConfig<M = 'text' | 'object'> = { | ||
number?: boolean; | ||
file?: boolean; | ||
mode?: M; | ||
base?: string; | ||
}; | ||
export declare type ExecConfig<M = IOType> = ReadStreamConfig<M> & { | ||
@@ -31,2 +37,6 @@ input?: IOType; | ||
}; | ||
export declare type CSVConfig = { | ||
sep: string; | ||
quote: string; | ||
}; | ||
export declare type Pattern = string | Iterable<string> | RegExp; | ||
@@ -33,0 +43,0 @@ export declare type CompletableStream<T extends Readable = Readable> = { |
@@ -17,2 +17,6 @@ /// <reference types="node" /> | ||
static scanDir(handler: ScanHandler, base: string, entry?: ScanEntry, visited?: Set<string>): AsyncGenerator<ScanEntry>; | ||
/** | ||
* Generates a matcher for file names, given the input string | ||
*/ | ||
static getFileMatcher(pattern: string | RegExp): (name: string) => boolean; | ||
} |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const fs=require("fs"),path=require("path");class FileUtil{static async*scanDir(a,b,c,d=new Set){var e;c=(e=c,null!==e&&void 0!==e?e:{file:b});for(const e of fs.readdirSync(c.file)){if(e.startsWith("."))continue;const f=path.resolve(c.file,e),g=fs.lstatSync(f),h={stats:g,file:f,relative:f.replace(`${b}/`,"")};if(h.stats.isDirectory()||h.stats.isSymbolicLink()){if(h.stats.isSymbolicLink()){const a=fs.realpathSync(f);if(!d.has(a))yield h,d.add(a);else continue}(!a.testDir||a.testDir(h.relative,h))&&(yield*FileUtil.scanDir(a,b,h,d))}else(!a.testFile||a.testFile(h.relative,h))&&(yield h)}}}exports.FileUtil=FileUtil; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const fs=require("fs"),path=require("path");class FileUtil{static async*scanDir(a,b,c,d=new Set){var e;c=(e=c,null!==e&&void 0!==e?e:{file:b});for(const e of fs.readdirSync(c.file)){if(e.startsWith("."))continue;const f=path.resolve(c.file,e),g=fs.lstatSync(f),h={stats:g,file:f,relative:f.replace(`${b}/`,"")};if(h.stats.isDirectory()||h.stats.isSymbolicLink()){if(h.stats.isSymbolicLink()){const a=fs.realpathSync(f);if(!d.has(a))yield h,d.add(a);else continue}(!a.testDir||a.testDir(h.relative,h))&&(yield*FileUtil.scanDir(a,b,h,d))}else(!a.testFile||a.testFile(h.relative,h))&&(yield h)}}static getFileMatcher(a){if(a instanceof RegExp)return a.test.bind(a);if(/[?*{}\[\]]/.test(a)){const b=require("picomatch"),c=b(a);return a=>c(a)}return b=>b.endsWith(a)}}exports.FileUtil=FileUtil; |
@@ -11,2 +11,3 @@ export declare class RegisterUtil { | ||
static registerThenable(t: Function): void; | ||
static defineProperty(obj: any, key: string | symbol, desc: PropertyDescriptor): void; | ||
/** | ||
@@ -13,0 +14,0 @@ * Define properties on prototype |
@@ -1,1 +0,1 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const async_1=require("./async");class RegisterUtil{static registerAsyncable(a){RegisterUtil.properties({$iterable:function(){var a,b;const c=this;return(null===(a=this)||void 0===a?void 0:a[Symbol.asyncIterator])?this:(null===(b=this)||void 0===b?void 0:b[Symbol.iterator])?async function*(){yield*c}():async function*(){yield c}()}},a.prototype)}static registerThenable(a){RegisterUtil.properties({then:{get(){const a=this.$values;return a.then.bind(a)},configurable:!0}},a.prototype)}static properties(a,b){for(const c of Object.keys(a)){let d=a[c];"apply"in d&&(d={get:d}),d.configurable=!0,Object.defineProperty(b,c,d)}}static createOperator(a){return function(...b){const c=a.call(this.$iterable,...b);return c instanceof Promise&&async_1.AsyncUtil.trackWithTimer(c),c}}static registerOperators(a,b=Object){Array.isArray(a)||(a=[a]);for(const{name:c,prototype:d}of a)if(c)for(const a of Object.getOwnPropertyNames(d)){if("constructor"===a)continue;let c=Object.getOwnPropertyDescriptor(d,a);c.get||(c={get(){return RegisterUtil.createOperator(d[a])}}),Object.defineProperty(b.prototype,a,{...c,configurable:!0})}}}exports.RegisterUtil=RegisterUtil; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});const async_1=require("./async");class RegisterUtil{static registerAsyncable(a){RegisterUtil.properties({$iterable:function(){var a,b;const c=this;return(null===(a=this)||void 0===a?void 0:a[Symbol.asyncIterator])?this:(null===(b=this)||void 0===b?void 0:b[Symbol.iterator])?async function*(){yield*c}():async function*(){yield c}()}},a.prototype)}static registerThenable(a){RegisterUtil.properties({then:{get(){const a=this.$values;return a.then.bind(a)}}},a.prototype)}static defineProperty(a,b,c){Object.defineProperty(a,b,{...c,configurable:!0})}static properties(a,b){for(const c of Object.keys(a)){let d=a[c];"apply"in d&&(d={get:d}),this.defineProperty(b,c,d)}}static createOperator(a){return function(...b){const c=a.call(this.$iterable,...b);return c instanceof Promise&&async_1.AsyncUtil.trackWithTimer(c),c}}static registerOperators(a,b=Object){Array.isArray(a)||(a=[a]);for(const{name:c,prototype:d}of a)if(c)for(const a of Object.getOwnPropertyNames(d)){if("constructor"===a)continue;let c=Object.getOwnPropertyDescriptor(d,a);c.get||(c={get(){return RegisterUtil.createOperator(d[a])}}),this.defineProperty(b.prototype,a,c)}}}exports.RegisterUtil=RegisterUtil; |
{ | ||
"name": "@arcsine/nodesh", | ||
"version": "1.6.2", | ||
"version": "1.7.0", | ||
"description": "A node-based library, providing Unix shell-like functionality", | ||
@@ -5,0 +5,0 @@ "scripts": { |
@@ -480,2 +480,38 @@ <h1> | ||
#### $readLines | ||
This operator will read a text file as a series of `Line` objects, which include the file name, | ||
line number, and associated text. | ||
When `mode` is `text` or undefined, the result will be a series of string in the format `{{file}}:{{number}} {{text}}` | ||
When `mode` is 'object', the result will be the raw `Line` objects | ||
When in `text` mode, the line number, and file name can be toggled off as needed by passing in additional config. | ||
```typescript | ||
$readLines(this: AsyncIterable<string>, config: ReadTextLineConfig<'text'>): $AsyncIterable<string>; | ||
$readLines(this: AsyncIterable<string>, config: {mode: 'object';}): $AsyncIterable<Line>; | ||
$readLines(this: AsyncIterable<string>): $AsyncIterable<string>; | ||
``` | ||
Example | ||
```javascript | ||
'<file>' | ||
.$readLines({ number:false }) // Read as a series of lines, without numbering | ||
``` | ||
```javascript | ||
'<file>' | ||
.$readLines({ mode:'object' }) // Read as a series of line objects | ||
.$filter(line => line.number === 5) // Read only 5th line | ||
``` | ||
```javascript | ||
'.js' | ||
.$dir() | ||
.$readLines() // Read as a series of lines, with filename, line number prepended | ||
``` | ||
#### $read | ||
@@ -499,3 +535,3 @@ | ||
'<file>' | ||
.$read('binary') // Read as a series of buffers | ||
.$read({ mode: 'binary' }) // Read as a series of buffers | ||
.$reduce((acc, buffer) => { | ||
@@ -509,6 +545,5 @@ return acc + buffer.length; | ||
'<file>' | ||
.$read('binary', true) // Read as a single buffer | ||
.$read({ mode:'binary', singleValue: true }) // Read as a single buffer | ||
.$map(buffer => buffer.length) // Count number of bytes in file | ||
``` | ||
@@ -789,8 +824,9 @@ | ||
Additionally, mode will determine what is emitted when a match is found (within a single line): | ||
* `undefined` - (default) Return entire line | ||
* `'negate'` - Return only lines that do not match | ||
Additionally, the config provides standard functionality, commensurate with grep: | ||
* `negate` - Return only lines that do not match | ||
* `before` - The number of lines to return before a match | ||
* `after` - The number of lines to return after a match | ||
```typescript | ||
$match(this: AsyncIterable<string>, regex: Pattern, mode?: 'negate'): $AsyncIterable<string>; | ||
$match(this: AsyncIterable<string>, pattern: Pattern, config?: MatchConfig): $AsyncIterable<string>; | ||
``` | ||
@@ -801,3 +837,11 @@ Example | ||
.$read() | ||
.$match(/(FIXME|TODO)/, 'negate') | ||
.$match('TODO') | ||
// All lines with TODO in them | ||
``` | ||
```javascript | ||
'<file>' | ||
.$read() | ||
.$match(/(FIXME|TODO)/, { negate:true }) | ||
// Exclude all lines that include FIXME or TODO | ||
@@ -810,3 +854,3 @@ | ||
.$read() | ||
.$match(/\d{3}(-)?\d{3}(-)?\d{4}/) | ||
.$match(/\d{3}(-)?\d{3}(-)?\d{4}/, { after:1, before:1 }) | ||
// Match all lines with phone numbers | ||
@@ -1168,3 +1212,3 @@ | ||
```typescript | ||
$parallel<T, U = T>(this: AsyncIterable<T>, op: (item: T) => AsyncIterable<U> | Promise<U>, concurrent?: number): $AsyncIterable<U>; | ||
$parallel<T, U = T>(this: AsyncIterable<T>, op: (item: T) => AsyncIterable<U> | Promise<U>, config?: number | {concurrent?: number;}): $AsyncIterable<U>; | ||
``` | ||
@@ -1179,1 +1223,8 @@ Example | ||
```javascript | ||
$range(1000) | ||
.$parallel(x => doWork(x), 100) // 100 concurrent workers | ||
.$console | ||
``` | ||
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 2 instances in 1 package
Minified code
QualityThis package contains minified code. This may be harmless in some cases where minified code is included in packaged libraries, however packages on npm should not minify code.
Found 3 instances in 1 package
115462
56
1334
1223