node-log4js-6.9.1+~cs8.4.19/000077500000000000000000000000001451773721600151525ustar00rootroot00000000000000node-log4js-6.9.1+~cs8.4.19/CHANGELOG.md000066400000000000000000000466421451773721600167770ustar00rootroot00000000000000# streamroller Changelog ## [3.1.5](https://github.com/log4js-node/streamroller/milestone/30) - [fix: tilde expansion for windows](https://github.com/log4js-node/streamroller/pull/165) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/166) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 17.3.0 to 17.4.3 - chore(deps-dev): bump @commitlint/config-conventional from 17.3.0 to 17.4.3 - chore(deps-dev): bump @types/node from 8.11.18 to 8.13.0 - chore(deps-dev): bump eslint from 8.30.0 to 8.34.0 - chore(deps-dev): bump husky from 8.0.2 to 8.0.3 - chore(deps-dev): updated package-lock.json ## [3.1.4](https://github.com/log4js-node/streamroller/milestone/29) - [fix: addressed unhandled promise rejection when a file gets deleted in midst of rolling](https://github.com/log4js-node/streamroller/pull/160) - thanks [@lamweili](https://github.com/lamweili) - [docs: updated repository url](https://github.com/log4js-node/streamroller/pull/158) - thanks [@lamweili](https://github.com/lamweili) - [ci: replaced deprecated github set-output](https://github.com/log4js-node/streamroller/pull/159) - thanks [@lamweili](https://github.com/lamweili) - [ci: added quotes](https://github.com/log4js-node/streamroller/pull/157) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/161) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @types/node from 18.11.9 to 18.11.18 - chore(deps-dev): bump eslint from 8.28.0 to 8.30.0 - chore(deps-dev): bump mocha from 10.1.0 to 10.2.0 - chore(deps-dev): updated package-lock.json - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/156) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 17.1.2 to 17.3.0 - chore(deps-dev): bump @commitlint/config-conventional from 17.1.0 to 17.3.0 - chore(deps-dev): bump @types/node from 18.7.23 to 18.11.9 - chore(deps-dev): bump eslint from 8.24.0 to 8.28.0 - chore(deps-dev): bump husky from 8.0.1 to 8.0.2 - chore(deps-dev): bump mocha from 10.0.0 to 10.1.0 - chore(deps-dev): updated package-lock.json ## [3.1.3](https://github.com/log4js-node/streamroller/milestone/28) - [ci: manually downgrade dev dependencies for older versions](https://github.com/log4js-node/streamroller/pull/153) - thanks [@lamweili](https://github.com/lamweili) - [ci: removed scheduled job from codeql and separated npm audit](https://github.com/log4js-node/streamroller/pull/152) - thanks [@lamweili](https://github.com/lamweili) - [ci: updated codeql from v1 to v2](https://github.com/log4js-node/streamroller/pull/151) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/154) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 17.0.3 to 17.1.2 - chore(deps-dev): bump @commitlint/config-conventional from 17.0.3 to 17.1.0 - chore(deps-dev): bump @types/node from 18.0.6 to 18.7.23 - chore(deps-dev): bump eslint from 6.8.0 to 8.24.0 - chore(deps-dev): bump mocha from 7.2.0 to 10.0.0 - chore(deps): bump date-format from 4.0.13 to 4.0.14 - chore(deps): updated package-lock.json ## [3.1.2](https://github.com/log4js-node/streamroller/milestone/27) - [refactor: support older Node.js versions](https://github.com/log4js-node/streamroller/pull/147) - thanks [@lamweili](https://github.com/lamweili) - [docs: renamed peteriman to lamweili](https://github.com/log4js-node/streamroller/pull/144) - thanks [@lamweili](https://github.com/lamweili) - [ci: added tests for Node.js 8.x, 10.x, 18.x](https://github.com/log4js-node/streamroller/pull/148) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): bump date-format from 4.0.11 to 4.0.13](https://github.com/log4js-node/streamroller/pull/150) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/146) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 17.0.1 to 17.0.3 - chore(deps-dev): bump @commitlint/config-conventional from 17.0.2 to 17.0.3 - chore(deps-dev): bump @types/node from 17.0.38 to 18.0.6 - chore(deps-dev): bump eslint from 8.16.0 to 8.20.0 - chore(deps-dev): updated package-lock.json - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/143) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 17.0.0 to 17.0.1 - chore(deps-dev): bump @commitlint/config-conventional 17.0.0 to 17.0.2 - chore(deps-dev): bump @types/node from 17.0.35 to 17.0.38 - chore(deps): bump date-format 4.0.10 to 4.0.11 - chore(deps): updated package-lock.json ## [3.1.1](https://github.com/log4js-node/streamroller/milestone/26) - [fix: fs.appendFileSync should use flag instead of flags](https://github.com/log4js-node/streamroller/pull/141) - thanks [@lamweili](https://github.com/lamweili) ## [3.1.0](https://github.com/log4js-node/streamroller/milestone/25) - [feat: tilde expansion for filename](https://github.com/log4js-node/streamroller/pull/135) - thanks [@lamweili](https://github.com/lamweili) - [fix: better file validation](https://github.com/log4js-node/streamroller/pull/134) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/140) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 16.3.0 to 17.0.0 - chore(deps-dev): bump @commitlint/config-conventional from 16.2.4 to 17.0.0 - chore(deps-dev): bump @types/node from 17.0.33 to 17.0.35 - chore(deps-dev): bump eslint from 8.15.0 to 8.16.0 - chore(deps): updated package-lock.json ## [3.0.9](https://github.com/log4js-node/streamroller/milestone/24) - [fix: maxSize=0 means no rolling](https://github.com/log4js-node/streamroller/pull/131) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/132) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 16.2.3 to 16.3.0 - chore(deps-dev): bump @commitlint/config-conventional from 16.2.1 to 16.2.4 - chore(deps-dev): bump @types/node from 17.0.26 to 17.0.33 - chore(deps-dev): bump eslint from 8.14.0 to 8.15.0 - chore(deps-dev): bump husky from 7.0.4 to 8.0.1 - chore(deps-dev): bump mocha from 9.2.2 to 10.0.0 - chore(deps): bump date-format from 4.0.9 to 4.0.10 - chore(deps): updated package-lock.json ## [3.0.8](https://github.com/log4js-node/streamroller/milestone/23) - [fix: concurrency issues when forked processes trying to roll same file](https://github.com/log4js-node/streamroller/pull/124) - thanks [@lamweili](https://github.com/lamweili) - [refactor: use writeStream.destroy() instead](https://github.com/log4js-node/streamroller/pull/125) - [refactor: use isCreated variable instead of e.code='EEXIST'](https://github.com/log4js-node/streamroller/pull/126) - [chore(lint): added .eslintrc and fixed linting issues](https://github.com/log4js-node/streamroller/pull/123) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/127) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @types/node from 17.0.24 to 17.0.26 - chore(deps-dev): bump eslint from 8.13.0 to 8.14.0 - chore(deps): bump date-format from 4.0.7 to 4.0.9 - chore(deps): updated package-lock.json - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/119) - thanks [@lamweili](https://github.com/lamweili) - chore(deps): bump fs-extra from 10.0.1 to 10.1.0 - chore(deps): updated package-lock.json - revert: "[chore(dep): temporary fix for fs-extra issue (to be reverted when fs-extra patches it)](https://github.com/log4js-node/streamroller/pull/116)" ## [3.0.7](https://github.com/log4js-node/streamroller/milestone/22) - [chore(deps): temporary fix for fs-extra issue (to be reverted when fs-extra patches it)](https://github.com/log4js-node/streamroller/pull/116) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/117) - thanks [@lamweili](https://github.com/lamweili) - chore(deps): bump date-format from 4.0.6 to 4.0.7 - chore(deps): updated package-lock.json - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/113) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @types/node from 17.0.23 to 17.0.24 - chore(deps-dev): updated package-lock.json - [chore(deps-dev): updated dependencies](https://github.com/log4js-node/streamroller/pull/112) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @types/node from 17.0.22 to 17.0.23 - chore(deps-dev): bump eslint from 8.11.0 to 8.13.0 - chore(deps-dev): updated package-lock.json ## [3.0.6](https://github.com/log4js-node/streamroller/milestone/21) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/110) - thanks [@lamweili](https://github.com/lamweili) - chore(deps): bump debug from 4.3.3 to 4.3.4 - chore(deps): bump date-format from 4.0.5 to 4.0.6 - chore(deps-dev): bump @types/node from 17.0.21 to 17.0.22 - chore(deps-dev): bump @commitlint/cli from 16.2.1 to 16.2.3 - chore(deps): updated package-lock.json ## [3.0.5](https://github.com/log4js-node/streamroller/milestone/20) - [fix: added filename validation](https://github.com/log4js-node/streamroller/pull/101) - thanks [@lamweili](https://github.com/lamweili) - [docs: updated README.md with badges](https://github.com/log4js-node/streamroller/pull/105) - thanks [@lamweili](https://github.com/lamweili) - [docs: updated README.md for DateRollingFileStream](https://github.com/log4js-node/streamroller/pull/106) - thanks [@lamweili](https://github.com/lamweili) - [docs: added docs for istanbul ignore](https://github.com/log4js-node/streamroller/pull/107) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/109) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): eslint from 8.10.0 to 8.11.0 - chore(deps-dev): mocha from 9.2.1 to 9.2.2 - chore(deps): date-format from 4.0.4 to 4.0.5 - chore(deps): updated package-lock.json ## [3.0.4](https://github.com/log4js-node/streamroller/milestone/19) - [test: remove test file/folder remnants](https://github.com/log4js-node/streamroller/pull/99) - thanks [@lamweili](https://github.com/lamweili) ## [3.0.3](https://github.com/log4js-node/streamroller/milestone/18) - [fix: backward compatibility for RollingFileWriteStream to recursively create directory](https://github.com/log4js-node/streamroller/pull/96) - thanks [@lamweili](https://github.com/lamweili) - [test: 100% test coverage](https://github.com/log4js-node/streamroller/pull/94) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/97) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 16.1.0 to 16.2.1 - chore(deps-dev): bump @commitlint/config-conventional from 16.0.0 to 16.2.1 - chore(deps-dev): bump @types/node from 17.0.16 to 17.0.21 - chore(deps-dev): bump eslint from 8.8.0 to 8.10.0 - chore(deps-dev): bump mocha from 9.2.0 to 9.2.1 - chore(deps): bump date-format from 4.0.3 to 4.0.4 - chore(deps): bump fs-extra from 10.0.0 to 10.0.1 - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/95) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump @commitlint/cli from 16.0.2 to 16.1.0 - chore(deps-dev): bump @types/node from 17.0.9 to 17.0.16 - chore(deps-dev): bump eslint from 8.7.0 to 8.8.0 - chore(deps-dev): bump proxyquire from 2.1.1 to 2.1.3 - chore(deps): bump debug from 4.1.1 to 4.3.3 - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/92) - thanks [@lamweili](https://github.com/lamweili) - updated package-lock.json - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/91) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump mocha from 9.1.4 to 9.2.0 ## [3.0.2](https://github.com/log4js-node/streamroller/milestone/17) - [fix: changed default file modes from 0o644 to 0o600 for better security](https://github.com/log4js-node/streamroller/pull/87) - thanks [@lamweili](https://github.com/lamweili) - [refactor: housekeeping for comments and .gitignore](https://github.com/log4js-node/streamroller/pull/89) - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): updated dependencies](https://github.com/log4js-node/streamroller/pull/88) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): bump caniuse-lite from 1.0.30001299 to 1.0.30001300 - chore(deps-dev): bump electron-to-chromium from 1.4.45 to 1.4.47 - chore(deps-dev): bump @types/node from 17.0.8 to 17.0.9 - chore(deps-dev): bump eslint from 8.6.0 to 8.7.0 - chore(deps-dev): bump mocha from 9.1.3 to 9.1.4 - chore(deps): bump date-format from 4.0.2 to 4.0.3 ## [3.0.1](https://github.com/log4js-node/streamroller/milestone/16) - [build: not to publish misc files to NPM](https://github.com/log4js-node/streamroller/pull/82) - thanks [@lamweili](https://github.com/lamweili) - chore(deps): updated dependencies - thanks [@lamweili](https://github.com/lamweili) - [chore(deps): bump date-format from 4.0.1 to 4.0.2](https://github.com/log4js-node/streamroller/pull/86) - [chore(deps-dev): bump electron-to-chromium from 1.4.44 to 1.4.45](https://github.com/log4js-node/streamroller/pull/81) ## [3.0.0](https://github.com/log4js-node/streamroller/milestone/15) - [feat: allow for 0 backups (only hot file)](https://github.com/log4js-node/streamroller/pull/74) - thanks [@lamweili](https://github.com/lamweili) - [feat: exposed fileNameSep to be configurable](https://github.com/log4js-node/streamroller/pull/67) - thanks [@laidaxian](https://github.com/laidaxian) - [fix: for fileNameSep affecting globally](https://github.com/log4js-node/streamroller/pull/79) - thanks [@lamweili](https://github.com/lamweili) - [fix: for mode to apply to compressed file](https://github.com/log4js-node/streamroller/pull/65) - thanks [@rnd-debug](https://github.com/rnd-debug) - [fix: for extra separator in filenames](https://github.com/log4js-node/streamroller/pull/75) - thanks [@lamweili](https://github.com/lamweili) - [refactor: moved to options.numBackups instead of options.daysToKeep](https://github.com/log4js-node/streamroller/pull/78) - thanks [@lamweili](https://github.com/lamweili) - [test: improved test case performance for fakeNow](https://github.com/log4js-node/streamroller/pull/76) - thanks [@lamweili](https://github.com/lamweili) - chore(deps-dev): updated dependencies - thanks @lamweili - [chore(deps-dev): updated package.json](https://github.com/log4js-node/streamroller/pull/70) - chore(deps-dev): bump @commitlint/cli from 8.1.0 to 16.0.2 - chore(deps-dev): bump @commitlint/config-conventional from 8.1.0 to 16.0.0 - chore(deps-dev): bump @type/nodes 17.0.8 - chore(deps-dev): bump eslint from 6.0.1 to 8.6.0 - chore(deps-dev): bump mocha from 6.1.4 to 9.1.3 - chore(deps-dev): bump nyc from 14.1.1 to 15.1.0 - [chore(deps-dev): updated package-lock.json](https://github.com/log4js-node/streamroller/pull/71) - chore(deps-dev): bump @babel/compat-data from 7.16.4 to 7.16.8 - chore(deps-dev): bump @babel/generator from 7.16.7 to 7.16.8 - chore(deps-dev): bump @babel/parser from 7.16.7 to 7.16.8 - chore(deps-dev): bump @babel/travers from 7.16.7 to 7.16.8 - chore(deps-dev): bump @babel/types from 7.16.7 to 7.16.8 - [chore(deps-dev): updated package-lock.json](https://github.com/log4js-node/streamroller/pull/77) - chore(deps-dev): bump caniuse-lite from 1.0.30001298 to 1.0.30001299 - chore(deps-dev): bump electron-to-chromium from 1.4.39 to 1.4.44 - [chore(deps-dev): updated package.json](https://github.com/log4js-node/streamroller/pull/80) - chore(deps): bump date-format from 3.0.0 to 4.0.1 - chore(deps-dev): bump husky from 3.0.0 to 7.0.4 - chore(deps): bump fs-extra from 8.1.0 to 10.0.0 ## [2.2.4](https://github.com/log4js-node/streamroller/milestone/14) - [Fix for incorrect filename matching](https://github.com/log4js-node/streamroller/pull/61) - thanks [@rnd-debug](https://github.com/rnd-debug) ## [2.2.3](https://github.com/log4js-node/streamroller/milestone/13) - [Fix for unhandled promise rejection during cleanup](https://github.com/log4js-node/streamroller/pull/56) ## [2.2.2](https://github.com/log4js-node/streamroller/milestone/12) - [Fix for overwriting current file when using date rotation](https://github.com/log4js-node/streamroller/pull/54) ## 2.2.1 - Fix for num to keep not working when date pattern is all digits (forgot to do a PR for this one) ## [2.2.0](https://github.com/log4js-node/streamroller/milestone/11) - [Fallback to copy and truncate when file is busy](https://github.com/log4js-node/streamroller/pull/53) ## [2.1.0](https://github.com/log4js-node/streamroller/milestone/10) - [Improve Windows support (closing streams)](https://github.com/log4js-node/streamroller/pull/52) ## [2.0.0](https://github.com/log4js-node/streamroller/milestone/9) - [Remove support for node v6](https://github.com/log4js-node/streamroller/pull/44) - [Replace lodash with native alternatives](https://github.com/log4js-node/streamroller/pull/45) - thanks [@devoto13](https://github.com/devoto13) - [Simplify filename formatting and parsing](https://github.com/log4js-node/streamroller/pull/46) - [Removed async lib from main code](https://github.com/log4js-node/streamroller/pull/47) - [Fix timezone issues in tests](https://github.com/log4js-node/streamroller/pull/48) - thanks [@devoto13](https://github.com/devoto13) - [Fix for flag values that need existing file size](https://github.com/log4js-node/streamroller/pull/49) - [Refactor for better readability](https://github.com/log4js-node/streamroller/pull/50) - [Removed async lib from test code](https://github.com/log4js-node/streamroller/pull/51) ## [1.0.6](https://github.com/log4js-node/streamroller/milestone/8) - [Fix for overwriting old backup files](https://github.com/log4js-node/streamroller/pull/43) - Updated lodash to 4.17.14 ## [1.0.5](https://github.com/log4js-node/streamroller/milestone/7) - [Updated dependencies](https://github.com/log4js-node/streamroller/pull/38) - [Fix for initial file date when appending to existing file](https://github.com/log4js-node/streamroller/pull/40) ## [1.0.4](https://github.com/log4js-node/streamroller/milestone/6) - [Fix for initial size when appending to existing file](https://github.com/log4js-node/streamroller/pull/35) ## [1.0.3](https://github.com/log4js-node/streamroller/milestone/5) - [Fix for crash when pattern is all digits](https://github.com/log4js-node/streamroller/pull/33) ## 1.0.2 - is exactly the same as 1.0.1, due to me being an idiot and not pulling before I pushed ## Previous versions Previous release details are available by browsing the [milestones](https://github.com/log4js-node/streamroller/milestones) in github. node-log4js-6.9.1+~cs8.4.19/LICENSE000066400000000000000000000020671451773721600161640ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) 2013 Gareth Jones Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. node-log4js-6.9.1+~cs8.4.19/README.md000066400000000000000000000125771451773721600164450ustar00rootroot00000000000000streamroller [![CodeQL](https://github.com/log4js-node/streamroller/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/log4js-node/streamroller/actions/workflows/codeql-analysis.yml) [![Node.js CI](https://github.com/log4js-node/streamroller/actions/workflows/node.js.yml/badge.svg)](https://github.com/log4js-node/streamroller/actions/workflows/node.js.yml) ============ [![NPM](https://nodei.co/npm/streamroller.png?downloads=true&downloadRank=true&stars=true)](https://nodei.co/npm/streamroller/) node.js file streams that roll over when they reach a maximum size, or a date/time. ```sh npm install streamroller ``` ## usage ```javascript var rollers = require('streamroller'); var stream = new rollers.RollingFileStream('myfile', 1024, 3); stream.write("stuff"); stream.end(); ``` The streams behave the same as standard node.js streams, except that when certain conditions are met they will rename the current file to a backup and start writing to a new file. ### new RollingFileStream(filename [, maxSize, numBackups, options]) * `filename` \ * `maxSize` \ - defaults to `0` - the size in bytes to trigger a rollover. If not specified or 0, then no log rolling will happen. * `numBackups` \ - defaults to `1` - the number of old files to keep (excluding the hot file) * `options` \ * `encoding` \ - defaults to `'utf8'` * `mode` \ - defaults to `0o600` (see [node.js file modes](https://nodejs.org/dist/latest-v12.x/docs/api/fs.html#fs_file_modes)) * `flags` \ - defaults to `'a'` (see [node.js file flags](https://nodejs.org/dist/latest-v12.x/docs/api/fs.html#fs_file_system_flags)) * `compress` \ - defaults to `false` - compress the backup files using gzip (backup files will have `.gz` extension) * `keepFileExt` \ - defaults to `false` - preserve the file extension when rotating log files (`file.log` becomes `file.1.log` instead of `file.log.1`). * `fileNameSep` \ - defaults to `'.'` - the filename separator when rolling. e.g.: abc.log`.`1 or abc`.`1.log (keepFileExt) This returns a `WritableStream`. When the current file being written to (given by `filename`) gets up to or larger than `maxSize`, then the current file will be renamed to `filename.1` and a new file will start being written to. Up to `numBackups` of old files are maintained, so if `numBackups` is 3 then there will be 4 files:
     filename
     filename.1
     filename.2
     filename.3
When filename size >= maxSize then:
     filename -> filename.1
     filename.1 -> filename.2
     filename.2 -> filename.3
     filename.3 gets overwritten
     filename is a new file
### new DateRollingFileStream(filename [, pattern, options]) * `filename` \ * `pattern` \ - defaults to `yyyy-MM-dd` - the date pattern to trigger rolling (see below) * `options` \ * `encoding` \ - defaults to `'utf8'` * `mode` \ - defaults to `0o600` (see [node.js file modes](https://nodejs.org/dist/latest-v12.x/docs/api/fs.html#fs_file_modes)) * `flags` \ - defaults to `'a'` (see [node.js file flags](https://nodejs.org/dist/latest-v12.x/docs/api/fs.html#fs_file_system_flags)) * `compress` \ - defaults to `false` - compress the backup files using gzip (backup files will have `.gz` extension) * `keepFileExt` \ - defaults to `false` - preserve the file extension when rotating log files (`file.log` becomes `file.2017-05-30.log` instead of `file.log.2017-05-30`). * `fileNameSep` \ - defaults to `'.'` - the filename separator when rolling. e.g.: abc.log`.`2013-08-30 or abc`.`2013-08-30.log (keepFileExt) * `alwaysIncludePattern` \ - defaults to `false` - extend the initial file with the pattern * `daysToKeep` `numBackups` \ - defaults to `1` - the number of old files that matches the pattern to keep (excluding the hot file) * `maxSize` \ - defaults to `0` - the size in bytes to trigger a rollover. If not specified or 0, then no log rolling will happen. This returns a `WritableStream`. When the current time, formatted as `pattern`, changes then the current file will be renamed to `filename.formattedDate` where `formattedDate` is the result of processing the date through the pattern, and a new file will begin to be written. Streamroller uses [date-format](http://github.com/nomiddlename/date-format) to format dates, and the `pattern` should use the date-format format. e.g. with a `pattern` of `"yyyy-MM-dd"`, and assuming today is August 29, 2013 then writing to the stream today will just write to `filename`. At midnight (or more precisely, at the next file write after midnight), `filename` will be renamed to `filename.2013-08-29` and a new `filename` will be created. If `options.alwaysIncludePattern` is true, then the initial file will be `filename.2013-08-29` and no renaming will occur at midnight, but a new file will be written to with the name `filename.2013-08-30`. If `maxSize` is populated, when the current file being written to (given by `filename`) gets up to or larger than `maxSize`, then the current file will be renamed to `filename.pattern.1` and a new file will start being written to. Up to `numBackups` of old files are maintained, so if `numBackups` is 3 then there will be 4 files:
     filename
     filename.20220131.1
     filename.20220131.2
     filename.20220131.3
node-log4js-6.9.1+~cs8.4.19/lib/000077500000000000000000000000001451773721600157205ustar00rootroot00000000000000node-log4js-6.9.1+~cs8.4.19/lib/DateRollingFileStream.js000066400000000000000000000022341451773721600224370ustar00rootroot00000000000000const RollingFileWriteStream = require('./RollingFileWriteStream'); // just to adapt the previous version class DateRollingFileStream extends RollingFileWriteStream { constructor(filename, pattern, options) { if (pattern && typeof(pattern) === 'object') { options = pattern; pattern = null; } if (!options) { options = {}; } if (!pattern) { pattern = 'yyyy-MM-dd'; } options.pattern = pattern; if (!options.numBackups && options.numBackups !== 0) { if (!options.daysToKeep && options.daysToKeep !== 0) { options.daysToKeep = 1; } else { process.emitWarning( "options.daysToKeep is deprecated due to the confusion it causes when used " + "together with file size rolling. Please use options.numBackups instead.", "DeprecationWarning", "streamroller-DEP0001" ); } options.numBackups = options.daysToKeep; } else { options.daysToKeep = options.numBackups; } super(filename, options); this.mode = this.options.mode; } get theStream() { return this.currentFileStream; } } module.exports = DateRollingFileStream; node-log4js-6.9.1+~cs8.4.19/lib/RollingFileStream.js000066400000000000000000000012641451773721600216430ustar00rootroot00000000000000const RollingFileWriteStream = require('./RollingFileWriteStream'); // just to adapt the previous version class RollingFileStream extends RollingFileWriteStream { constructor(filename, size, backups, options) { if (!options) { options = {}; } if (size) { options.maxSize = size; } if (!options.numBackups && options.numBackups !== 0) { if (!backups && backups !== 0) { backups = 1; } options.numBackups = backups; } super(filename, options); this.backups = options.numBackups; this.size = this.options.maxSize; } get theStream() { return this.currentFileStream; } } module.exports = RollingFileStream; node-log4js-6.9.1+~cs8.4.19/lib/RollingFileWriteStream.js000066400000000000000000000255051451773721600226620ustar00rootroot00000000000000const debug = require("debug")("streamroller:RollingFileWriteStream"); const fs = require("fs-extra"); const path = require("path"); const os = require("os"); const newNow = require("./now"); const format = require("date-format"); const { Writable } = require("stream"); const fileNameFormatter = require("./fileNameFormatter"); const fileNameParser = require("./fileNameParser"); const moveAndMaybeCompressFile = require("./moveAndMaybeCompressFile"); const deleteFiles = fileNames => { debug(`deleteFiles: files to delete: ${fileNames}`); return Promise.all(fileNames.map(f => fs.unlink(f).catch((e) => { debug(`deleteFiles: error when unlinking ${f}, ignoring. Error was ${e}`); }))); }; /** * RollingFileWriteStream is mainly used when writing to a file rolling by date or size. * RollingFileWriteStream inherits from stream.Writable */ class RollingFileWriteStream extends Writable { /** * Create a RollingFileWriteStream * @constructor * @param {string} filePath - The file path to write. * @param {object} options - The extra options * @param {number} options.numToKeep - The max numbers of files to keep. * @param {number} options.maxSize - The maxSize one file can reach. Unit is Byte. * This should be more than 1024. The default is 0. * If not specified or 0, then no log rolling will happen. * @param {string} options.mode - The mode of the files. The default is '0600'. Refer to stream.writable for more. * @param {string} options.flags - The default is 'a'. Refer to stream.flags for more. * @param {boolean} options.compress - Whether to compress backup files. * @param {boolean} options.keepFileExt - Whether to keep the file extension. * @param {string} options.pattern - The date string pattern in the file name. * @param {boolean} options.alwaysIncludePattern - Whether to add date to the name of the first file. */ constructor(filePath, options) { debug(`constructor: creating RollingFileWriteStream. path=${filePath}`); if (typeof filePath !== "string" || filePath.length === 0) { throw new Error(`Invalid filename: ${filePath}`); } else if (filePath.endsWith(path.sep)) { throw new Error(`Filename is a directory: ${filePath}`); } else if (filePath.indexOf(`~${path.sep}`) === 0) { // handle ~ expansion: https://github.com/nodejs/node/issues/684 // exclude ~ and ~filename as these can be valid files filePath = filePath.replace("~", os.homedir()); } super(options); this.options = this._parseOption(options); this.fileObject = path.parse(filePath); if (this.fileObject.dir === "") { this.fileObject = path.parse(path.join(process.cwd(), filePath)); } this.fileFormatter = fileNameFormatter({ file: this.fileObject, alwaysIncludeDate: this.options.alwaysIncludePattern, needsIndex: this.options.maxSize < Number.MAX_SAFE_INTEGER, compress: this.options.compress, keepFileExt: this.options.keepFileExt, fileNameSep: this.options.fileNameSep }); this.fileNameParser = fileNameParser({ file: this.fileObject, keepFileExt: this.options.keepFileExt, pattern: this.options.pattern, fileNameSep: this.options.fileNameSep }); this.state = { currentSize: 0 }; if (this.options.pattern) { this.state.currentDate = format(this.options.pattern, newNow()); } this.filename = this.fileFormatter({ index: 0, date: this.state.currentDate }); if (["a", "a+", "as", "as+"].includes(this.options.flags)) { this._setExistingSizeAndDate(); } debug( `constructor: create new file ${this.filename}, state=${JSON.stringify( this.state )}` ); this._renewWriteStream(); } _setExistingSizeAndDate() { try { const stats = fs.statSync(this.filename); this.state.currentSize = stats.size; if (this.options.pattern) { this.state.currentDate = format(this.options.pattern, stats.mtime); } } catch (e) { //file does not exist, that's fine - move along return; } } _parseOption(rawOptions) { const defaultOptions = { maxSize: 0, numToKeep: Number.MAX_SAFE_INTEGER, encoding: "utf8", mode: parseInt("0600", 8), flags: "a", compress: false, keepFileExt: false, alwaysIncludePattern: false }; const options = Object.assign({}, defaultOptions, rawOptions); if (!options.maxSize) { delete options.maxSize; } else if (options.maxSize <= 0) { throw new Error(`options.maxSize (${options.maxSize}) should be > 0`); } // options.numBackups will supercede options.numToKeep if (options.numBackups || options.numBackups === 0) { if (options.numBackups < 0) { throw new Error(`options.numBackups (${options.numBackups}) should be >= 0`); } else if (options.numBackups >= Number.MAX_SAFE_INTEGER) { // to cater for numToKeep (include the hot file) at Number.MAX_SAFE_INTEGER throw new Error(`options.numBackups (${options.numBackups}) should be < Number.MAX_SAFE_INTEGER`); } else { options.numToKeep = options.numBackups + 1; } } else if (options.numToKeep <= 0) { throw new Error(`options.numToKeep (${options.numToKeep}) should be > 0`); } debug( `_parseOption: creating stream with option=${JSON.stringify(options)}` ); return options; } _final(callback) { this.currentFileStream.end("", this.options.encoding, callback); } _write(chunk, encoding, callback) { this._shouldRoll().then(() => { debug( `_write: writing chunk. ` + `file=${this.currentFileStream.path} ` + `state=${JSON.stringify(this.state)} ` + `chunk=${chunk}` ); this.currentFileStream.write(chunk, encoding, e => { this.state.currentSize += chunk.length; callback(e); }); }); } async _shouldRoll() { if (this._dateChanged() || this._tooBig()) { debug( `_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}` ); await this._roll(); } } _dateChanged() { return ( this.state.currentDate && this.state.currentDate !== format(this.options.pattern, newNow()) ); } _tooBig() { return this.state.currentSize >= this.options.maxSize; } _roll() { debug(`_roll: closing the current stream`); return new Promise((resolve, reject) => { this.currentFileStream.end("", this.options.encoding, () => { this._moveOldFiles() .then(resolve) .catch(reject); }); }); } async _moveOldFiles() { const files = await this._getExistingFiles(); const todaysFiles = this.state.currentDate ? files.filter(f => f.date === this.state.currentDate) : files; for (let i = todaysFiles.length; i >= 0; i--) { debug(`_moveOldFiles: i = ${i}`); const sourceFilePath = this.fileFormatter({ date: this.state.currentDate, index: i }); const targetFilePath = this.fileFormatter({ date: this.state.currentDate, index: i + 1 }); const moveAndCompressOptions = { compress: this.options.compress && i === 0, mode: this.options.mode }; await moveAndMaybeCompressFile( sourceFilePath, targetFilePath, moveAndCompressOptions ); } this.state.currentSize = 0; this.state.currentDate = this.state.currentDate ? format(this.options.pattern, newNow()) : null; debug( `_moveOldFiles: finished rolling files. state=${JSON.stringify( this.state )}` ); this._renewWriteStream(); // wait for the file to be open before cleaning up old ones, // otherwise the daysToKeep calculations can be off await new Promise((resolve, reject) => { this.currentFileStream.write("", "utf8", () => { this._clean() .then(resolve) .catch(reject); }); }); } // Sorted from the oldest to the latest async _getExistingFiles() { const files = await fs.readdir(this.fileObject.dir) .catch( /* istanbul ignore next: will not happen on windows */ () => []); debug(`_getExistingFiles: files=${files}`); const existingFileDetails = files .map(n => this.fileNameParser(n)) .filter(n => n); const getKey = n => (n.timestamp ? n.timestamp : newNow().getTime()) - n.index; existingFileDetails.sort((a, b) => getKey(a) - getKey(b)); return existingFileDetails; } _renewWriteStream() { const filePath = this.fileFormatter({ date: this.state.currentDate, index: 0 }); // attempt to create the directory const mkdir = (dir) => { try { return fs.mkdirSync(dir, { recursive: true }); } // backward-compatible fs.mkdirSync for nodejs pre-10.12.0 (without recursive option) catch (e) { // recursive creation of parent first if (e.code === "ENOENT") { mkdir(path.dirname(dir)); return mkdir(dir); } // throw error for all except EEXIST and EROFS (read-only filesystem) if (e.code !== "EEXIST" && e.code !== "EROFS") { throw e; } // EEXIST: throw if file and not directory // EROFS : throw if directory not found else { try { if (fs.statSync(dir).isDirectory()) { return dir; } throw e; } catch (err) { throw e; } } } }; mkdir(this.fileObject.dir); const ops = { flags: this.options.flags, encoding: this.options.encoding, mode: this.options.mode }; const renameKey = function(obj, oldKey, newKey) { obj[newKey] = obj[oldKey]; delete obj[oldKey]; return obj; }; // try to throw EISDIR, EROFS, EACCES fs.appendFileSync(filePath, "", renameKey({ ...ops }, "flags", "flag")); this.currentFileStream = fs.createWriteStream(filePath, ops); this.currentFileStream.on("error", e => { this.emit("error", e); }); } async _clean() { const existingFileDetails = await this._getExistingFiles(); debug( `_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${existingFileDetails.length}` ); debug("_clean: existing files are: ", existingFileDetails); if (this._tooManyFiles(existingFileDetails.length)) { const fileNamesToRemove = existingFileDetails .slice(0, existingFileDetails.length - this.options.numToKeep) .map(f => path.format({ dir: this.fileObject.dir, base: f.filename })); await deleteFiles(fileNamesToRemove); } } _tooManyFiles(numFiles) { return this.options.numToKeep > 0 && numFiles > this.options.numToKeep; } } module.exports = RollingFileWriteStream; node-log4js-6.9.1+~cs8.4.19/lib/fileNameFormatter.js000066400000000000000000000017041451773721600216640ustar00rootroot00000000000000const debug = require("debug")("streamroller:fileNameFormatter"); const path = require("path"); const ZIP_EXT = ".gz"; const DEFAULT_FILENAME_SEP = "."; module.exports = ({ file, keepFileExt, needsIndex, alwaysIncludeDate, compress, fileNameSep }) => { let FILENAME_SEP = fileNameSep || DEFAULT_FILENAME_SEP; const dirAndName = path.join(file.dir, file.name); const ext = f => f + file.ext; const index = (f, i, d) => (needsIndex || !d) && i ? f + FILENAME_SEP + i : f; const date = (f, i, d) => { return (i > 0 || alwaysIncludeDate) && d ? f + FILENAME_SEP + d : f; }; const gzip = (f, i) => (i && compress ? f + ZIP_EXT : f); const parts = keepFileExt ? [date, index, ext, gzip] : [ext, date, index, gzip]; return ({ date, index }) => { debug(`_formatFileName: date=${date}, index=${index}`); return parts.reduce( (filename, part) => part(filename, index, date), dirAndName ); }; }; node-log4js-6.9.1+~cs8.4.19/lib/fileNameParser.js000066400000000000000000000056241451773721600211620ustar00rootroot00000000000000const debug = require("debug")("streamroller:fileNameParser"); const ZIP_EXT = ".gz"; const format = require("date-format"); const DEFAULT_FILENAME_SEP = "."; module.exports = ({ file, keepFileExt, pattern, fileNameSep }) => { let FILENAME_SEP = fileNameSep || DEFAULT_FILENAME_SEP; // All these functions take two arguments: f, the filename, and p, the result placeholder // They return the filename with any matching parts removed. // The "zip" function, for instance, removes the ".gz" part of the filename (if present) const zip = (f, p) => { if (f.endsWith(ZIP_EXT)) { debug("it is gzipped"); p.isCompressed = true; return f.slice(0, -1 * ZIP_EXT.length); } return f; }; const __NOT_MATCHING__ = "__NOT_MATCHING__"; const extAtEnd = f => { if (f.startsWith(file.name) && f.endsWith(file.ext)) { debug("it starts and ends with the right things"); return f.slice(file.name.length + 1, -1 * file.ext.length); } return __NOT_MATCHING__; }; const extInMiddle = f => { if (f.startsWith(file.base)) { debug("it starts with the right things"); return f.slice(file.base.length + 1); } return __NOT_MATCHING__; }; const dateAndIndex = (f, p) => { const items = f.split(FILENAME_SEP); let indexStr = items[items.length - 1]; debug("items: ", items, ", indexStr: ", indexStr); let dateStr = f; if (indexStr !== undefined && indexStr.match(/^\d+$/)) { dateStr = f.slice(0, -1 * (indexStr.length + 1)); debug(`dateStr is ${dateStr}`); if (pattern && !dateStr) { dateStr = indexStr; indexStr = "0"; } } else { indexStr = "0"; } try { // Two arguments for new Date() are intentional. This will set other date // components to minimal values in the current timezone instead of UTC, // as new Date(0) will do. const date = format.parse(pattern, dateStr, new Date(0, 0)); if (format.asString(pattern, date) !== dateStr) return f; p.index = parseInt(indexStr, 10); p.date = dateStr; p.timestamp = date.getTime(); return ""; } catch (e) { //not a valid date, don't panic. debug(`Problem parsing ${dateStr} as ${pattern}, error was: `, e); return f; } }; const index = (f, p) => { if (f.match(/^\d+$/)) { debug("it has an index"); p.index = parseInt(f, 10); return ""; } return f; }; let parts = [ zip, keepFileExt ? extAtEnd : extInMiddle, pattern ? dateAndIndex : index ]; return filename => { let result = { filename, index: 0, isCompressed: false }; // pass the filename through each of the file part parsers let whatsLeftOver = parts.reduce( (remains, part) => part(remains, result), filename ); // if there's anything left after parsing, then it wasn't a valid filename return whatsLeftOver ? null : result; }; }; node-log4js-6.9.1+~cs8.4.19/lib/index.js000066400000000000000000000003061451773721600173640ustar00rootroot00000000000000module.exports = { RollingFileWriteStream: require('./RollingFileWriteStream'), RollingFileStream: require('./RollingFileStream'), DateRollingFileStream: require('./DateRollingFileStream') }; node-log4js-6.9.1+~cs8.4.19/lib/moveAndMaybeCompressFile.js000066400000000000000000000102241451773721600231400ustar00rootroot00000000000000const debug = require('debug')('streamroller:moveAndMaybeCompressFile'); const fs = require('fs-extra'); const zlib = require('zlib'); const _parseOption = function(rawOptions){ const defaultOptions = { mode: parseInt("0600", 8), compress: false, }; const options = Object.assign({}, defaultOptions, rawOptions); debug(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(options)}`); return options; }; const moveAndMaybeCompressFile = async ( sourceFilePath, targetFilePath, options ) => { options = _parseOption(options); if (sourceFilePath === targetFilePath) { debug(`moveAndMaybeCompressFile: source and target are the same, not doing anything`); return; } if (await fs.pathExists(sourceFilePath)) { debug( `moveAndMaybeCompressFile: moving file from ${sourceFilePath} to ${targetFilePath} ${ options.compress ? "with" : "without" } compress` ); if (options.compress) { await new Promise((resolve, reject) => { let isCreated = false; // to avoid concurrency, the forked process which can create the file will proceed (using flags wx) const writeStream = fs.createWriteStream(targetFilePath, { mode: options.mode, flags: "wx" }) // wait until writable stream is valid before proceeding to read .on("open", () => { isCreated = true; const readStream = fs.createReadStream(sourceFilePath) // wait until readable stream is valid before piping .on("open", () => { readStream.pipe(zlib.createGzip()).pipe(writeStream); }) .on("error", (e) => { debug(`moveAndMaybeCompressFile: error reading ${sourceFilePath}`, e); // manually close writable: https://nodejs.org/api/stream.html#readablepipedestination-options writeStream.destroy(e); }); }) .on("finish", () => { debug(`moveAndMaybeCompressFile: finished compressing ${targetFilePath}, deleting ${sourceFilePath}`); // delete sourceFilePath fs.unlink(sourceFilePath) .then(resolve) .catch((e) => { debug(`moveAndMaybeCompressFile: error deleting ${sourceFilePath}, truncating instead`, e); // fallback to truncate fs.truncate(sourceFilePath) .then(resolve) .catch((e) => { debug(`moveAndMaybeCompressFile: error truncating ${sourceFilePath}`, e); reject(e); }); }); }) .on("error", (e) => { if (!isCreated) { debug(`moveAndMaybeCompressFile: error creating ${targetFilePath}`, e); // do not do anything if handled by another forked process reject(e); } else { debug(`moveAndMaybeCompressFile: error writing ${targetFilePath}, deleting`, e); // delete targetFilePath (taking as nothing happened) fs.unlink(targetFilePath) .then(() => { reject(e); }) .catch((e) => { debug(`moveAndMaybeCompressFile: error deleting ${targetFilePath}`, e); reject(e); }); } }); }).catch(() => {}); } else { debug(`moveAndMaybeCompressFile: renaming ${sourceFilePath} to ${targetFilePath}`); try { await fs.move(sourceFilePath, targetFilePath, { overwrite: true }); } catch (e) { debug(`moveAndMaybeCompressFile: error renaming ${sourceFilePath} to ${targetFilePath}`, e); /* istanbul ignore else: no need to do anything if file does not exist */ if (e.code !== "ENOENT") { debug(`moveAndMaybeCompressFile: trying copy+truncate instead`); try { await fs.copy(sourceFilePath, targetFilePath, { overwrite: true }); await fs.truncate(sourceFilePath); } catch (e) { debug(`moveAndMaybeCompressFile: error copy+truncate`, e); } } } } } }; module.exports = moveAndMaybeCompressFile; node-log4js-6.9.1+~cs8.4.19/lib/now.js000066400000000000000000000001171451773721600170600ustar00rootroot00000000000000// allows us to inject a mock date in tests module.exports = () => new Date(); node-log4js-6.9.1+~cs8.4.19/package.json000066400000000000000000000035331451773721600174440ustar00rootroot00000000000000{ "name": "streamroller", "version": "3.1.5", "description": "file streams that roll over when size limits, or dates are reached", "main": "lib/index.js", "files": [ "lib", "CHANGELOG.md" ], "directories": { "test": "test" }, "scripts": { "codecheck": "eslint \"lib/*.js\" \"test/*.js\"", "prepublishOnly": "npm test", "pretest": "npm run codecheck", "clean": "rm -rf node_modules/", "test": "nyc --check-coverage mocha", "html-report": "nyc report --reporter=html" }, "repository": { "type": "git", "url": "https://github.com/log4js-node/streamroller.git" }, "keywords": [ "stream", "rolling" ], "author": "Gareth Jones , Huang Yichao ", "license": "MIT", "readmeFilename": "README.md", "gitHead": "ece35d7d86c87c04ff09e8604accae81cf36a0ce", "devDependencies": { "@commitlint/cli": "^17.4.3", "@commitlint/config-conventional": "^17.4.3", "@types/node": "^18.13.0", "eslint": "^8.34.0", "husky": "^8.0.3", "mocha": "^10.2.0", "nyc": "^15.1.0", "proxyquire": "^2.1.3", "should": "^13.2.3" }, "dependencies": { "date-format": "^4.0.14", "debug": "^4.3.4", "fs-extra": "^8.1.0" }, "engines": { "node": ">=8.0" }, "commitlint": { "extends": [ "@commitlint/config-conventional" ] }, "eslintConfig": { "env": { "browser": false, "node": true, "es6": true, "mocha": true }, "parserOptions": { "ecmaVersion": 2018 }, "extends": "eslint:recommended", "rules": { "no-console": "off" } }, "husky": { "hooks": { "commit-msg": "commitlint -e $HUSKY_GIT_PARAMS" } }, "nyc": { "include": [ "lib/**" ], "branches": 100, "lines": 100, "functions": 100 } }