This commit is contained in:
2022-09-30 05:39:11 +00:00
parent 41ee9463ae
commit 4687fa49bc
11418 changed files with 1312504 additions and 0 deletions

560
buildfiles/app/node_modules/winston/CHANGELOG.md generated vendored Normal file
View File

@ -0,0 +1,560 @@
# CHANGELOG
## v3.3.3 / 2020-06-23
- [#1820] Revert [#1807] to resolve breaking changes for Typescript users.
## v3.3.2 / 2020-06-22
- [#1814] Use a fork of `diagnostics` published to NPM to avoid git dependency.
## v3.3.1 / 2020-06-21
- [#1803], [#1807] Fix TypeScript bugs.
- [#1740] Add space between `info.message` and `meta.message`.
- [#1813] Avoid indirect storage-engine dependency.
- [#1810] README updates.
## v3.3.0 / 2020-06-21
- [#1779] Fix property name in rejection handler.
- [#1768] Exclude extraneous files from NPM package.
- [#1364], [#1714] Don't remove transport from logger when transport error
occurs.
- [#1603] Expose `child` property on default logger.
- [#1777] Allow HTTP transport to pass options to request.
- [#1662] Add bearer auth capabilities to HTTP transport.
- [#1612] Remove no-op in file transport.
- [#1622], [#1623], [#1625] Typescript fixes.
- (Minor) [#1647], [#1793] Update CI settings.
- (Minor) [#1600], [#1605], [#1593], [#1610], [#1654], [#1656], [#1661],
[#1651], [#1652], [#1677], [#1683], [#1684], [#1700], [#1697], [#1650],
[#1705], [#1723], [#1737], [#1733], [#1743], [#1750], [#1754], [#1780],
[#1778] README, Transports.md, other docs changes.
- [#1672], [#1686], [#1772] Update dependencies.
## v3.2.1 / 2019-01-29
### UNBOUND PROTOTYPE AD INFINITUM EDITION
- #[1579], (@indexzero) Fallback to the "root" instance **always** created by
`createLogger` for level convenience methods (e.g. `.info()`, `.silly()`).
(Fixes [#1577]).
- [#1539], (@indexzero) Assume message is the empty string when level-helper
methods are invoked with no arguments (Fixed [#1501]).
- [#1583], (@kibertoad) Add typings for defaultMeta (Fixes [#1582])
- [#1586], (@kibertoad) Update dependencies.
## v3.2.0 / 2019-01-26
### SORRY IT TOO SO LONG EDITION
> **NOTE:** this was our first release using Github Projects. See the
> [3.2.0 Release Project](https://github.com/orgs/winstonjs/projects/3).
### New Features!
- [#1471], (@kibertoad) Implement child loggers.
- [#1462], (@drazisil) Add handleRejection support.
- [#1555], (@DABH) Add fixes from [#1355] to unhandled rejection handler.
- [#1418], (@mfrisbey) Precompile ES6 syntax before publishing to npm.
- [#1533], (@kibertoad) Update to Babel 7.
- [#1562], (@indexzero) [fix] Better handling of `new Error(string)`
throughout the pipeline(s). (Fixes [#1338], [#1486]).
### Bug Fixes
- [#1355], (@DABH) Fix issues with ExceptionHandler (Fixes [#1289]).
- [#1463], (@SerayaEryn) Bubble transport `warn` events up to logger in
addition to `error`s.
- [#1480], [#1503], (@SerayaEryn) File tailrolling fix.
- [#1483], (@soldair) Assign log levels to un-bound functions.
- [#1513], (@TilaTheHun0) Set maxListeners for Console transport.
- [#1521], (@jamesbechet) Fix Transform from `readable-stream` using CRA.
- [#1434], (@Kouzukii) Fixes logger.query function (regression from `3.0.0`)
- [#1526], (@pixtron) Log file without .gz for tailable (Fixes [#1525]).
- [#1559], (@eubnara) Fix typo related to `exitOnError`.
- [#1556], (@adoyle-h) Support to create log directory if it doesn't exist
for FileTransport.
#### New `splat` behavior
- [#1552], (@indexzero) Consistent handling of meta with (and without)
interpolation in `winston` and `logform`.
- [#1499], (@DABH) Provide all of `SPLAT` to formats (Fixes [#1485]).
- [#1485], (@mpabst) Fixing off-by-one when using both meta and splat.
Previously `splat` would have added a `meta` property for any additional
`info[SPLAT]` beyond the expected number of tokens.
**As of `logform@2.0.0`,** `format.splat` assumes additional splat paramters
(aka "metas") are objects and merges enumerable properties into the `info`.
e.g. **BE ADVISED** previous "metas" that _were not objects_ will very likely
lead to odd behavior. e.g.
``` js
const { createLogger, format, transports } = require('winston');
const { splat } = format;
const { MESSAGE, LEVEL, SPLAT } = require('triple-beam');
const logger = createLogger({
format: format.combine(
format.splat(),
format.json()
),
transports: [new transports.Console()]
});
// Expects two tokens, but four splat parameters provided.
logger.info(
'Let us %s for %j', // message
'objects', // used for %s
{ label: 'sure' }, // used for %j
'lol', ['ok', 'why'] // Multiple additional meta values
);
// winston < 3.2.0 && logform@1.x behavior:
// Added "meta" property.
//
// { level: 'info',
// message: 'Let us objects for {"label":"sure"}',
// meta: ['lol', ['ok', 'why']],
// [Symbol(level)]: 'info',
// [Symbol(message)]: 'Let us %s for %j',
// [Symbol(splat)]: [ 'objects', { label: 'sure' } ] }
// winston >= 3.2.0 && logform@2.x behavior: Enumerable properties
// assigned into `info`. Since **strings and Arrays only have NUMERIC
// enumerable properties we get this behavior!**
//
// { '0': 'ok',
// '1': 'why',
// '2': 'l',
// level: 'info',
// message: 'Let us objects for {"label":"sure"}',
// [Symbol(level)]: 'info',
// [Symbol(message)]: 'Let us %s for %j',
// [Symbol(splat)]: [ 'objects', { label: 'sure' } ] }
```
## Maintenance & Documentation
- Documentation Updates
- [#1410], (@hakanostrom) Add docs reference to transport for Cloudant.
- [#1467], (@SeryaEryn) Add fast-file-rotate transport to transport.md.
- [#1488], (@adamcohen) Fix multi logger documentation.
- [#1531], (@mapleeit) Add links to transports.
- [#1548], (@ejmartin504) Fix `README.md` for awaiting logs.
- [#1554], (@indexzero) Document the solution to [#1486] as by design.
- Other small improvements: [#1509].
- Improved TypeScript support
- [#1470], (@jd-carroll) Export all transport options (Fixes [#1469]).
- [#1474], (@jd-carroll) Correct import to avoid conflict (Fixed [#1472]).
- [#1546], (@alewiahmed) Add consoleWarnLevels field to the
`ConsoleTransportOptions` interface type definition.
- [#1557], (@negezor) Add missing `child()` method.
- Dependency management
- [#1560], (@kibertoad) Update dependencies.
- [#1512], (@SerayaEryn) Add node@11 and disallow failures on node@10.
- [#1516], (@SerayaEryn) Update `readable-stream` to `v3.0.6`.
- [#1534], (@kibertoad) Update `@types/node`, `nyc`, and `through2`.
## v3.1.0 / 2018-08-22
### RELEASES ON A PLANE EDITION
- Minor TypeScript fixes [#1362], [#1395], [#1440]
- Fix minor typos [#1359], [#1363], [#1372], [#1378], [#1390]
- [#1373], (@revik): Add `consoleWarnLevels` property to console transport options for `console.warn` browser support.
- [#1394], (@bzoz): Fix tests on Windows.
- [#1447], (@dboshardy): Support transport name option to override default names for built-in transports.
- [#1420], (@ledbit): Fix file rotation with `tailing: true` (Fixes [#1450], [#1194]).
- [#1352], (@lutovich): Add `isLevelEnabled(string)` & `isXXXEnabled()` to `Logger` class.
- Dependency management
- Regenerate `package-lock.json`.
- Upgrade to `colors@^1.3.2` (Fixes [#1439]).
- Upgrade to `logform@^1.9.1`.
- Upgrade to `diagnostics@^1.1.1`.
- Upgrade to `@types/node@^10.9.3`.
- Upgrade to `assume@^2.1.0`.
- Upgrade to `hock@^1.3.3`.
- Upgrade to `mocha@^5.2.0`.
- Upgrade to `nyc@^13.0.1`.
- Upgrade to `split2@^3.0.0`.
## v3.0.0 / 2018-06-12
### GET IN THE CHOPPA EDITION
- [#1332], (@DABH): logger.debug is sent to stderr (Fixed [#1024])
- [#1328], (@ChrisAlderson): Logger level doesn't update transports level (Fixes [#1191]).
- [#1356], (@indexzero) Move splat functionality into logform. (Fixes [#1298]).
- [#1340], (@indexzero): Check log.length when evaluating "legacyness" of transports (Fixes [#1280]).
- [#1346], (@indexzero): Implement `_final` from Node.js streams. (Related to winston-transport#24, Fixes [#1250]).
- [#1347], (@indexzero): Wrap calls to `format.transform` with try / catch (Fixes [#1261]).
- [#1357], (@indexzero): Remove paddings as we have no use for it in the current API.
- [TODO]: REMAINS OPEN, NO PR (Fixes [#1289])
- Documentation
- [#1301], (@westonpace) Cleaned up some of the documentation on `colorize`
to address concerns in [#1095].
- First pass at a heavy refactor of `docs/transports.md`.
- Dependency management
- Regenerate `package-lock.json`.
- Upgrade to `logform@^1.9.0`.
## v3.0.0-rc6 / 2018-05-30
### T-MINUS 6-DAY TO WINSTON@3 EDITION
- **Document that we are pushing for a June 5th, 2018 release of `winston@3.0.0`**
- [#1287], (@DABH) Added types for Typescript.
- [#1335] Typescript: silent is boolean.
- [#1323] Add level method to default logger.
- [#1286], (@ChrisAlderson) Migrate codebase to ES6
- [#1324], (@ChrisAlderson) Fix regression introduced by ES6 migration for
exception handling.
- [#1333], (@ChrisAlderson) Fix removing all loggers from a container.
- [#1291], [#1294], [#1318], (@indexzero, @ChrisAlderson, @mempf) Improvements
to `File` transport core functionality. Fixes [#1194].
- [#1311], (@ChrisAlderson) Add `eol` option to `Stream` transport.
- [#1297], (@ChrisAlderson) Move `winston.config` to `triple-beam`. Expose
for backwards compatibility.
- [#1320], (@ChrisAlderson) Enhance tests to run on Windows.
- Internal project maintenance
- Bump to `winston-transport@4.0.0` which may cause incompatibilities if
your custom transport does not explicitly require `winston-transport`
itself.
- [#1292], (@ChrisAlderson) Add node v10 to TravisCI build matrix.
- [#1296], (@indexzero) Improve `UPGRADE-3.0.md`. Add Github Issue Template.
- Remove "npm run report" in favor of reports being automatically generate.
- Update `logform`, `triple-beam`, and `winston-transport` to latest.
> Special thanks to our newest `winston` core team member  @ChrisAlderson for
> helping make `winston@3.0.0` a reality next week!
## v3.0.0-rc5 / 2018-04-20
### UNOFFICIAL NATIONAL HOLIDAY EDITION
- [#1281] Use `Buffer.alloc` and `Buffer.from` instead of `new Buffer`.
- Better browser support
- [#1142] Move common tailFile to a separate file
- [#1279] Use feature detection to be safer for browser usage.
- MOAR Docs!
- **Document that we are pushing for a May 29th, 2018 release of `winston@3.0.0`**
- **Add David Hyde as official contributor.**
- [#1278] Final Draft of Upgrade Guide in `UPGRADE-3.0.md`
- Merge Roadmap from `3.0.0.md` into `CONTRIBUTING.md` and other
improvements to `CONTRIBUTING.md`
- Improve & expand examples
- [#1175] Add more copy about printf formats based on issue feedback.
- [#1134] Add sampleto document timestamps more clearly as an example.
- [#1273] Add example using multiple formats.
- [#1250] Add an example illustrating the "finish" event for AWS Lambda scenarios.
- Use simple format to better show that `humanReadableUnhandledException` is now the default message format.
- Add example to illustrate that example code from winston-transport
`README.md` is correct.
- Update `devDependencies`
- Bump `assume` to `^2.0.1`.
- Bump `winston-compat` to `^0.1.1`.
## v3.0.0-rc4 / 2018-04-06
### IF A TREE FALLS IN THE FORREST DOES IT MAKE A LOG EDITION
- (@indexzero, @dabh) Add support for `{ silent }` option to
``` js
require('winston').Logger;
require('winston-transport').TransportStream;
```
- Better browser support
- [#1145], (@Jasu) Replace `isstream` with `is-stream` to make stream detection work in browser.
- [#1146], (@Jasu) Rename query to different than function name, to support Babel 6.26.
- Better Typescript support in all supporting libraries
- `logform@1.4.1`
- Update documentation
- (@indexzero) Correct link to upgrade guide. Fixes #1255.
- [#1258], (@morenoh149) Document how to colorize levels. Fixes #1135.
- [#1246], (@KlemenPlazar) Update colors argument when adding custom colors
- Update `CONTRIBUTING.md`
- [#1239], (@dabh) Add changelog entries for `v3.0.0-rc3`
- Add example showing that `{ level }` can be deleted from info objects because `Symbol.for('level')` is what `winston` uses internally. Fixes #1184.
## v3.0.0-rc3 / 2018-03-16
### I GOT NOTHING EDITION
- [#1195], (@Nilegfx) Fix type error when creating `new stream.Stream()`
- [#1109], (@vsetka) Fix file transprot bug where `self.filename` was not being updated on `ENOENT`
- [#1153], (@wizardnet972) Make prototype methods return like the original method
- [#1234], (@guiguan, @indexzero) Add tests for properly handling logging of `undefined`, `null` and `Error` values
- [#1235], (@indexzero) Add example demonstrating how `meta` objects BECOME the `info` object
- Minor fixes to docs & examples: [#1232], [#1185]
## v3.0.0-rc2 / 2018-03-09
### MAINTENANCE RESUMES EDITION
- [#1209], (@dabh) Use new version of colors, solving a number of issues.
- [#1197], (@indexzero) Roadmap & guidelines for contributors.
- [#1100] Require the package.json by its full name.
- [#1149] Updates `async` to latest (`2.6.0`)
- [#1228], (@mcollina) Always pass a function to `fs.close`.
- Minor fixes to docs & examples: [#1177], [#1182], [#1208], [#1198], [#1165], [#1110], [#1117], [#1097], [#1155], [#1084], [#1141], [#1210], [#1223].
## v3.0.0-rc1 / 2017-10-19
### OMG THEY FORGOT TO NAME IT EDITION
- Fix file transport improper binding of `_onDrain` and `_onError` [#1104](https://github.com/winstonjs/winston/pull/1104)
## v3.0.0-rc0 / 2017-10-02
### IT'S-DONE.GIF EDITION
**See [UPGRADE-3.0.md](UPGRADE-3.0.md) for a complete & living upgrade guide.**
**See [3.0.0.md](3.0.0.md) for a list of remaining RC tasks.**
- **Rewrite of core logging internals:** `Logger` & `Transport` are now implemented using Node.js `objectMode` streams.
- **Your transports _should_ not break:** Special attention has been given to ensure backwards compatibility with existing transports. You will likely see this:
```
YourTransport is a legacy winston transport. Consider upgrading to winston@3:
- Upgrade docs: https://github.com/winstonjs/winston/tree/master/UPGRADE.md
```
- **`filters`, `rewriters`, and `common.log` are now _formats_:** `winston.format` offers a simple mechanism for user-land formatting & style features. The organic & frankly messy growth of `common.log` is of the past; these feature requests can be implemented entirely outside of `winston` itself.
``` js
const { createLogger, format, transports } = require('winston');
const { combine, timestamp, label, printf } = format;
const myFormat = printf(info => {
return `${info.timestamp} [${info.label}] ${info.level}: ${info.message}`;
});
const logger = createLogger({
combine(
label({ label: 'right meow!' }),
timestamp(),
myFormat
),
transports: [new transports.Console()]
});
```
- **Increased modularity:** several subsystems are now stand-alone packages:
- [logform] exposed as `winston.format`
- [winston-transport] exposed as `winston.Transport`
- [abstract-winston-transport] used for reusable unit test suites for transport authors.
- **`2.x` branch will get little to no maintenance:** no feature requests will be accepted  only a limited number of open PRs will be merged. Hoping the [significant performance benefits][perf-bench] incentivizes folks to upgrade quickly. Don't agree? Say something!
- **No guaranteed support for `node@4` or below:** all code will be migrated to ES6 over time. This release was started when ES5 was still a hard requirement due to the current LTS needs.
## v2.4.0 / 2017-10-01
### ZOMFG WINSTON@3.0.0-RC0 EDITION
- [#1036] Container.add() 'filters' and 'rewriters' option passing to logger.
- [#1066] Fixed working of "humanReadableUnhandledException" parameter when additional data is added in meta.
- [#1040] Added filtering by log level
- [#1042] Fix regressions brought by `2.3.1`.
- Fix regression on array printing.
- Fix regression on falsy value.
- [#977] Always decycle objects before cloning.
- Fixes [#862]
- Fixes [#474]
- Fixes [#914]
- [57af38a] Missing context in `.lazyDrain` of `File` transport.
- [178935f] Suppress excessive Node warning from `fs.unlink`.
- [fcf04e1] Add `label` option to `File` transport docs.
- [7e736b4], [24300e2] Added more info about undocumented `winston.startTimer()` method.
- [#1076], [#1082], [#1029], [#989], [e1e7188] Minor grammatical & style updates to `README.md`.
## v2.3.1 / 2017-01-20
### WELCOME TO THE APOCALYPSE EDITION
- [#868](https://github.com/winstonjs/winston/pull/868), Fix 'Maximum call stack size exceeded' error with custom formatter.
## v2.3.0 / 2016-11-02
### ZOMG WHY WOULD YOU ASK EDITION
- Full `CHANGELOG.md` entry forthcoming. See [the `git` diff for `2.3.0`](https://github.com/winstonjs/winston/compare/2.2.0...2.3.0) for now.
## v2.2.0 / 2016-02-25
### LEAVING CALIFORNIA EDITION
- Full `CHANGELOG.md` entry forthcoming. See [the `git` diff for `2.2.0`](https://github.com/winstonjs/winston/compare/2.1.1...2.2.0) for now.
## v2.1.1 / 2015-11-18
### COLOR ME IMPRESSED EDITION
- [#751](https://github.com/winstonjs/winston/pull/751), Fix colors not appearing in non-tty environments. Fixes [#609](https://github.com/winstonjs/winston/issues/609), [#616](https://github.com/winstonjs/winston/issues/616), [#669](https://github.com/winstonjs/winston/issues/669), [#648](https://github.com/winstonjs/winston/issues/648) (`fiznool`).
- [#752](https://github.com/winstonjs/winston/pull/752) Correct syslog RFC number. 5424 instead of 524. (`jbenoit2011`)
## v2.1.0 / 2015-11-03
### TEST ALL THE ECOSYSTEM EDITION
- [#742](https://github.com/winstonjs/winston/pull/742), [32d52b7](https://github.com/winstonjs/winston/commit/32d52b7) Distribute common test files used by transports in the `winston` ecosystem.
## v2.0.1 / 2015-11-02
### BUGS ALWAYS HAPPEN OK EDITION
- [#739](https://github.com/winstonjs/winston/issues/739), [1f16861](https://github.com/winstonjs/winston/commit/1f16861) Ensure that `logger.log("info", undefined)` does not throw.
## v2.0.0 / 2015-10-29
### OMG IT'S MY SISTER'S BIRTHDAY EDITION
#### Breaking changes
**Most important**
- **[0f82204](https://github.com/winstonjs/winston/commit/0f82204) Move `winston.transports.DailyRotateFile` [into a separate module](https://github.com/winstonjs/winston-daily-rotate-file)**: `require('winston-daily-rotate-file');`
- **[fb9eec0](https://github.com/winstonjs/winston/commit/fb9eec0) Reverse log levels in `npm` and `cli` configs to conform to [RFC524](https://tools.ietf.org/html/rfc5424). Fixes [#424](https://github.com/winstonjs/winston/pull/424) [#406](https://github.com/winstonjs/winston/pull/406) [#290](https://github.com/winstonjs/winston/pull/290)**
- **[8cd8368](https://github.com/winstonjs/winston/commit/8cd8368) Change the method signature to a `filter` function to be consistent with `rewriter` and log functions:**
``` js
function filter (level, msg, meta, inst) {
// Filter logic goes here...
}
```
**Other breaking changes**
- [e0c9dde](https://github.com/winstonjs/winston/commit/e0c9dde) Remove `winston.transports.Webhook`. Use `winston.transports.Http` instead.
- [f71e638](https://github.com/winstonjs/winston/commit/f71e638) Remove `Logger.prototype.addRewriter` and `Logger.prototype.addFilter` since they just push to an Array of functions. Use `logger.filters.push` or `logger.rewriters.push` explicitly instead.
- [a470ab5](https://github.com/winstonjs/winston/commit/a470ab5) No longer respect the `handleExceptions` option to `new winston.Logger`. Instead just pass in the `exceptionHandlers` option itself.
- [8cb7048](https://github.com/winstonjs/winston/commit/8cb7048) Removed `Logger.prototype.extend` functionality
#### New features
- [3aa990c](https://github.com/winstonjs/winston/commit/3aa990c) Added `Logger.prototype.configure` which now contains all logic previously in the `winston.Logger` constructor function. (`indexzero`)
- [#726](https://github.com/winstonjs/winston/pull/726) Update .npmignore (`coreybutler`)
- [#700](https://github.com/winstonjs/winston/pull/700) Add an `eol` option to the `Console` transport. (`aquavitae`)
- [#731](https://github.com/winstonjs/winston/pull/731) Update `lib/transports.js` for better static analysis. (`indexzero`)
#### Fixes, refactoring, and optimizations. OH MY!
- [#632](https://github.com/winstonjs/winston/pull/632) Allow `File` transport to be an `objectMode` writable stream. (`stambata`)
- [#527](https://github.com/winstonjs/winston/issues/527), [163f4f9](https://github.com/winstonjs/winston/commit/163f4f9), [3747ccf](https://github.com/winstonjs/winston/commit/3747ccf) Performance optimizations and string interpolation edge cases (`indexzero`)
- [f0edafd](https://github.com/winstonjs/winston/commit/f0edafd) Code cleanup for reability, ad-hoc styleguide enforcement (`indexzero`)
## v1.1.1 - v1.1.2 / 2015-10
### MINOR FIXES EDITION
#### Notable changes
* [727](https://github.com/winstonjs/winston/pull/727) Fix "raw" mode (`jcrugzz`)
* [703](https://github.com/winstonjs/winston/pull/703) Do not modify Error or Date objects when logging. Fixes #610 (`harriha`).
## v1.1.0 / 2015-10-09
### GREETINGS FROM CARTAGENA EDITION
#### Notable Changes
* [#721](https://github.com/winstonjs/winston/pull/721) Fixed octal literal to work with node 4 strict mode (`wesleyeff`)
* [#630](https://github.com/winstonjs/winston/pull/630) Add stderrLevels option to Console Transport and update docs (`paulhroth`)
* [#626](https://github.com/winstonjs/winston/pull/626) Add the logger (this) in the fourth argument in the rewriters and filters functions (`christophehurpeau `)
* [#623](https://github.com/winstonjs/winston/pull/623) Fix Console Transport's align option tests (`paulhroth`, `kikobeats`)
* [#692](https://github.com/winstonjs/winston/pull/692) Adding winston-aws-cloudwatch to transport docs (`timdp`)
## v1.0.2 2015-09-25
### LET'S TALK ON GITTER EDITION
#### Notable Changes
* [de80160](https://github.com/winstonjs/winston/commit/de80160) Add Gitter badge (`The Gitter Badger`)
* [44564de](https://github.com/winstonjs/winston/commit/44564de) [fix] Correct listeners in `logException`. Fixes [#218](https://github.com/winstonjs/winston/issues/218) [#213](https://github.com/winstonjs/winston/issues/213) [#327](https://github.com/winstonjs/winston/issues/327). (`indexzero`)
* [45b1eeb](https://github.com/winstonjs/winston/commit/45b1eeb) [fix] Get `tailFile` function working on latest/all node versions (`Christopher Jeffrey`)
* [c6d45f9](https://github.com/winstonjs/winston/commit/c6d45f9) Fixed event subscription on close (`Roman Stetsyshin`)
#### Other changes
* TravisCI updates & best practices [87b97cc](https://github.com/winstonjs/winston/commit/87b97cc) [91a5bc4](https://github.com/winstonjs/winston/commit/91a5bc4), [cf24e6a](https://github.com/winstonjs/winston/commit/cf24e6a) (`indexzero`)
* [d5397e7](https://github.com/winstonjs/winston/commit/d5397e7) Bump async version (`Roderick Hsiao`)
* Documentation updates & fixes [86d7527](https://github.com/winstonjs/winston/commit/86d7527), [38254c1](https://github.com/winstonjs/winston/commit/38254c1), [04e2928](https://github.com/winstonjs/winston/commit/04e2928), [61c8a89](https://github.com/winstonjs/winston/commit/61c8a89), [c42a783](https://github.com/winstonjs/winston/commit/c42a783), [0688a22](https://github.com/winstonjs/winston/commit/0688a22), [eabc113](https://github.com/winstonjs/winston/commit/eabc113) [c9506b7](https://github.com/winstonjs/winston/commit/c9506b7), [17534d2](https://github.com/winstonjs/winston/commit/17534d2), [b575e7b](https://github.com/winstonjs/winston/commit/b575e7b) (`Stefan Thies`, `charukiewicz`, `unLucio`, `Adam Cohen`, `Denis Gorbachev`, `Frederik Ring`, `Luigi Pinca`, `jeffreypriebe`)
* Documentation refactor & cleanup [a19607e](https://github.com/winstonjs/winston/commit/a19607e), [d1932b4](https://github.com/winstonjs/winston/commit/d1932b4), [7a13132](https://github.com/winstonjs/winston/commit/7a13132) (`indexzero`)
## v1.0.1 / 2015-06-26
### YAY DOCS EDITION
* [#639](https://github.com/winstonjs/winston/pull/639) Fix for [#213](https://github.com/winstonjs/winston/issues/213): More than 10 containers triggers EventEmitter memory leak warning (`marcus`)
* Documentation and `package.json` updates [cec892c](https://github.com/winstonjs/winston/commit/cec892c), [2f13b4f](https://github.com/winstonjs/winston/commit/2f13b4f), [b246efd](https://github.com/winstonjs/winston/commit/b246efd), [22a5f5a](https://github.com/winstonjs/winston/commit/22a5f5a), [5868b78](https://github.com/winstonjs/winston/commit/5868b78), [99b6b44](https://github.com/winstonjs/winston/commit/99b6b44), [447a813](https://github.com/winstonjs/winston/commit/447a813), [7f75b48](https://github.com/winstonjs/winston/commit/7f75b48) (`peteward44`, `Gilad Peleg`, `Anton Ian Sipos`, `nimrod-becker`, `LarsTi`, `indexzero`)
## v1.0.0 / 2015-04-07
### OMG 1.0.0 FINALLY EDITION
#### Breaking Changes
* [#587](https://github.com/winstonjs/winston/pull/587) Do not extend `String` prototypes as a side effect of using `colors`. (`kenperkins`)
* [#581](https://github.com/winstonjs/winston/pull/581) File transports now emit `error` on error of the underlying streams after `maxRetries` attempts. (`ambbell`).
* [#583](https://github.com/winstonjs/winston/pull/583), [92729a](https://github.com/winstonjs/winston/commit/92729a68d71d07715501c35d94d2ac06ac03ca08) Use `os.EOL` for all file writing by default. (`Mik13`, `indexzero`)
* [#532](https://github.com/winstonjs/winston/pull/532) Delete logger instance from `Container` when `close` event is emitted. (`snater`)
* [#380](https://github.com/winstonjs/winston/pull/380) Rename `duration` to `durationMs`, which is now a number a not a string ending in `ms`. (`neoziro`)
* [#253](https://github.com/winstonjs/winston/pull/253) Do not set a default level. When `level` is falsey on any `Transport` instance, any `Logger` instance uses the configured level (instead of the Transport level) (`jstamerj`).
#### Other changes
* [b83de62](https://github.com/winstonjs/winston/commit/b83de62) Fix rendering of stack traces.
* [c899cc](https://github.com/winstonjs/winston/commit/c899cc1f0719e49b26ec933e0fa263578168ea3b) Update documentation (Fixes [#549](https://github.com/winstonjs/winston/issues/549))
* [#551](https://github.com/winstonjs/winston/pull/551) Filter metadata along with messages
* [#578](https://github.com/winstonjs/winston/pull/578) Fixes minor issue with `maxFiles` in `File` transport (Fixes [#556](https://github.com/winstonjs/winston/issues/556)).
* [#560](https://github.com/winstonjs/winston/pull/560) Added `showLevel` support to `File` transport.
* [#558](https://github.com/winstonjs/winston/pull/558) Added `showLevel` support to `Console` transport.
## v0.9.0 / 2015-02-03
* [#496](https://github.com/flatiron/winston/pull/496) Updated default option handling for CLI (`oojacoboo`).
* [f37634b](https://github.com/flatiron/winston/commit/f37634b) [dist] Only support `node >= 0.8.0`. (`indexzero`)
* [91a1e90](https://github.com/flatiron/winston/commit/91a1e90), [50163a0](https://github.com/flatiron/winston/commit/50163a0) Fix #84 [Enable a better unhandled exception experience](https://github.com/flatiron/winston/issues/84) (`samz`)
* [8b5fbcd](https://github.com/flatiron/winston/commit/8b5fbcd) #448 Added tailable option to file transport which rolls files backwards instead of creating incrementing appends. Implements #268 (`neouser99`)
* [a34f7d2](https://github.com/flatiron/winston/commit/a34f7d2) Custom log formatter functionality were added. (`Melnyk Andii`)
* [4c08191](https://github.com/flatiron/winston/commit/4c08191) Added showLevel flag to common.js, file*, memory and console transports. (`Tony Germaneri`)
* [64ed8e0](https://github.com/flatiron/winston/commit/64ed8e0) Adding custom pretty print function test. (`Alberto Pose`)
* [3872dfb](https://github.com/flatiron/winston/commit/3872dfb) Adding prettyPrint parameter as function example. (`Alberto Pose`)
* [2b96eee](https://github.com/flatiron/winston/commit/2b96eee) implemented filters #526 (`Chris Oloff`)
* [72273b1](https://github.com/flatiron/winston/commit/72273b1) Added the options to colorize only the level, only the message or all. Default behavior is kept. Using true will only colorize the level and false will not colorize anything. (`Michiel De Mey`)
* [178e8a6](https://github.com/flatiron/winston/commit/178e8a6) Prevent message from meta input being overwritten (`Leonard Martin`)
* [270be86](https://github.com/flatiron/winston/commit/270be86) [api] Allow for transports to be removed by their string name [test fix] Add test coverage for multiple transports of the same type added in #187. [doc] Document using multiple transports of the same type (`indexzero`)
* [0a848fa](https://github.com/flatiron/winston/commit/0a848fa) Add depth options for meta pretty print (`Loïc Mahieu`)
* [106b670](https://github.com/flatiron/winston/commit/106b670) Allow debug messages to be sent to stdout (`John Frizelle`)
* [ad2d5e1](https://github.com/flatiron/winston/commit/ad2d5e1) [fix] Handle Error instances in a sane way since their properties are non-enumerable __by default.__ Fixes #280. (`indexzero`)
* [5109dd0](https://github.com/flatiron/winston/commit/5109dd0) [fix] Have a default `until` before a default `from`. Fixes #478. (`indexzero`)
* [d761960](https://github.com/flatiron/winston/commit/d761960) Fix logging regular expression objects (`Chasen Le Hara`)
* [2632eb8](https://github.com/flatiron/winston/commit/2632eb8) Add option for EOL chars on FileTransport (`José F. Romaniello`)
* [bdecce7](https://github.com/flatiron/winston/commit/bdecce7) Remove duplicate logstash option (`José F. Romaniello`)
* [7a01f9a](https://github.com/flatiron/winston/commit/7a01f9a) Update declaration block according to project's style guide (`Ricardo Torres`)
* [ae27a19](https://github.com/flatiron/winston/commit/ae27a19) Fixes #306: Can't set customlevels to my loggers (RangeError: Maximum call stack size exceeded) (`Alberto Pose`)
* [1ba4f51](https://github.com/flatiron/winston/commit/1ba4f51) [fix] Call `res.resume()` in HttpTransport to get around known issues in streams2. (`indexzero`)
* [39e0258](https://github.com/flatiron/winston/commit/39e0258) Updated default option handling for CLI (`Jacob Thomason`)
* [8252801](https://github.com/flatiron/winston/commit/8252801) Added logstash support to console transport (`Ramon Snir`)
* [18aa301](https://github.com/flatiron/winston/commit/18aa301) Module isStream should be isstream (`Michael Neil`)
* [2f5f296](https://github.com/flatiron/winston/commit/2f5f296) options.prettyPrint can now be a function (`Matt Zukowski`)
* [a87a876](https://github.com/flatiron/winston/commit/a87a876) Adding rotationFormat prop to file.js (`orcaman`)
* [ff187f4](https://github.com/flatiron/winston/commit/ff187f4) Allow custom exception level (`jupiter`)
## 0.8.3 / 2014-11-04
* [fix lowercase issue (`jcrugzz`)](https://github.com/flatiron/winston/commit/b3ffaa10b5fe9d2a510af5348cf4fb3870534123)
## 0.8.2 / 2014-11-04
* [Full fix for #296 with proper streams2 detection with `isstream` for file transport (`jcrugzz`)](https://github.com/flatiron/winston/commit/5c4bd4191468570e46805ed399cad63cfb1856cc)
* [Add isstream module (`jcrugzz`)](https://github.com/flatiron/winston/commit/498b216d0199aebaef72ee4d8659a00fb737b9ae)
* [Partially fix #296 with streams2 detection for file transport (`indexzero`)](https://github.com/flatiron/winston/commit/b0227b6c27cf651ffa8b8192ef79ab24296362e3)
* [add stress test for issue #288 (`indexzero`)](https://github.com/flatiron/winston/commit/e08e504b5b3a00f0acaade75c5ba69e6439c84a6)
* [lessen timeouts to check test sanity (`indexzero`)](https://github.com/flatiron/winston/commit/e925f5bc398a88464f3e796545ff88912aff7568)
* [update winston-graylog2 documentation (`unlucio`)](https://github.com/flatiron/winston/commit/49fa86c31baf12c8ac3adced3bdba6deeea2e363)
* [fix test formatting (`indexzero`)](https://github.com/flatiron/winston/commit/8e2225799520a4598044cdf93006d216812a27f9)
* [fix so options are not redefined (`indexzero`)](https://github.com/flatiron/winston/commit/d1d146e8a5bb73dcb01579ad433f6d4f70b668ea)
* [fix self/this issue that broke `http` transport (`indexzero`)](https://github.com/flatiron/winston/commit/d10cbc07755c853b60729ab0cd14aa665da2a63b)
## 0.8.1 / 2014-10-06
* [Add label option for DailyRotateFile transport (`francoisTemasys`)](https://github.com/flatiron/winston/pull/459)
* [fix Logger#transports length check upon Logger#log (`adriano-di-giovanni`, `indexzero`)](https://github.com/flatiron/winston/pull/404)
* [err can be a string. (`gdw2`, `indexzero`)](https://github.com/flatiron/winston/pull/396)
* [Added color for pre-defined cli set. (`danilo1105`, `indexzero`)](https://github.com/flatiron/winston/pull/365)
* [Fix dates on transport test (`revington`)](https://github.com/flatiron/winston/pull/346)
* [Included the label from options to the output in JSON mode. (`arxony`)](https://github.com/flatiron/winston/pull/326)
* [Allow using logstash option with the File transport (`gmajoulet`)](https://github.com/flatiron/winston/pull/299)
* [Be more defensive when working with `query` methods from Transports. Fixes #356. (indexzero)](https://github.com/flatiron/winston/commit/b80638974057f74b521dbe6f43fef2105110afa2)
* [Catch exceptions for file transport unlinkSync (`calvinfo`)](https://github.com/flatiron/winston/pull/266)
* [Adding the 'addRewriter' to winston (`machadogj`)](https://github.com/flatiron/winston/pull/258)
* [Updates to transport documentation (`pose`)](https://github.com/flatiron/winston/pull/262)
* [fix typo in "Extending another object with Logging" section.](https://github.com/flatiron/winston/pull/281)
* [Updated README.md - Replaced properties with those listed in winston-mongodb module](https://github.com/flatiron/winston/pull/264)
## 0.8.0 / 2014-09-15
* [Fixes for HTTP Transport](https://github.com/flatiron/winston/commit/a876a012641f8eba1a976eada15b6687d4a03f82)
* Removing [jsonquest](https://github.com/flatiron/winston/commit/4f088382aeda28012b7a0498829ceb243ed74ac1) and [request](https://github.com/flatiron/winston/commit/a5676313b4e9744802cc3b8e1468e4af48830876) dependencies.
* Configuration is now [shalow cloned](https://github.com/flatiron/winston/commit/08fccc81d18536d33050496102d98bde648853f2).
* [Added logstash support](https://github.com/flatiron/winston/pull/445/files)
* Fix for ["flush" event should always fire after "flush" call bug](https://github.com/flatiron/winston/pull/446/files)
* Added tests for file: [open and stress](https://github.com/flatiron/winston/commit/47d885797a2dd0d3cd879305ca813a0bd951c378).
* [Test fixes](https://github.com/flatiron/winston/commit/9e39150e0018f43d198ca4c160acef2af9860bf4)
* [Fix ")" on string interpolation](https://github.com/flatiron/winston/pull/394/files)
## 0.6.2 / 2012-07-08
* Added prettyPrint option for console logging
* Multi-line values for conditional returns are not allowed
* Added acceptance of `stringify` option
* Fixed padding for log levels

19
buildfiles/app/node_modules/winston/LICENSE generated vendored Normal file
View File

@ -0,0 +1,19 @@
Copyright (c) 2010 Charlie Robbins
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.

1230
buildfiles/app/node_modules/winston/README.md generated vendored Normal file

File diff suppressed because it is too large Load Diff

172
buildfiles/app/node_modules/winston/dist/winston.js generated vendored Normal file
View File

@ -0,0 +1,172 @@
/**
* winston.js: Top-level include defining Winston.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
var logform = require('logform');
var _require = require('./winston/common'),
warn = _require.warn;
/**
* Setup to expose.
* @type {Object}
*/
var winston = exports;
/**
* Expose version. Use `require` method for `webpack` support.
* @type {string}
*/
winston.version = require('../package.json').version;
/**
* Include transports defined by default by winston
* @type {Array}
*/
winston.transports = require('./winston/transports');
/**
* Expose utility methods
* @type {Object}
*/
winston.config = require('./winston/config');
/**
* Hoist format-related functionality from logform.
* @type {Object}
*/
winston.addColors = logform.levels;
/**
* Hoist format-related functionality from logform.
* @type {Object}
*/
winston.format = logform.format;
/**
* Expose core Logging-related prototypes.
* @type {function}
*/
winston.createLogger = require('./winston/create-logger');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.ExceptionHandler = require('./winston/exception-handler');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.RejectionHandler = require('./winston/rejection-handler');
/**
* Expose core Logging-related prototypes.
* @type {Container}
*/
winston.Container = require('./winston/container');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.Transport = require('winston-transport');
/**
* We create and expose a default `Container` to `winston.loggers` so that the
* programmer may manage multiple `winston.Logger` instances without any
* additional overhead.
* @example
* // some-file1.js
* const logger = require('winston').loggers.get('something');
*
* // some-file2.js
* const logger = require('winston').loggers.get('something');
*/
winston.loggers = new winston.Container();
/**
* We create and expose a 'defaultLogger' so that the programmer may do the
* following without the need to create an instance of winston.Logger directly:
* @example
* const winston = require('winston');
* winston.log('info', 'some message');
* winston.error('some error');
*/
var defaultLogger = winston.createLogger(); // Pass through the target methods onto `winston.
Object.keys(winston.config.npm.levels).concat(['log', 'query', 'stream', 'add', 'remove', 'clear', 'profile', 'startTimer', 'handleExceptions', 'unhandleExceptions', 'handleRejections', 'unhandleRejections', 'configure', 'child']).forEach(function (method) {
return winston[method] = function () {
return defaultLogger[method].apply(defaultLogger, arguments);
};
});
/**
* Define getter / setter for the default logger level which need to be exposed
* by winston.
* @type {string}
*/
Object.defineProperty(winston, 'level', {
get: function get() {
return defaultLogger.level;
},
set: function set(val) {
defaultLogger.level = val;
}
});
/**
* Define getter for `exceptions` which replaces `handleExceptions` and
* `unhandleExceptions`.
* @type {Object}
*/
Object.defineProperty(winston, 'exceptions', {
get: function get() {
return defaultLogger.exceptions;
}
});
/**
* Define getters / setters for appropriate properties of the default logger
* which need to be exposed by winston.
* @type {Logger}
*/
['exitOnError'].forEach(function (prop) {
Object.defineProperty(winston, prop, {
get: function get() {
return defaultLogger[prop];
},
set: function set(val) {
defaultLogger[prop] = val;
}
});
});
/**
* The default transports and exceptionHandlers for the default winston logger.
* @type {Object}
*/
Object.defineProperty(winston, 'default', {
get: function get() {
return {
exceptionHandlers: defaultLogger.exceptionHandlers,
rejectionHandlers: defaultLogger.rejectionHandlers,
transports: defaultLogger.transports
};
}
}); // Have friendlier breakage notices for properties that were exposed by default
// on winston < 3.0.
warn.deprecated(winston, 'setLevels');
warn.forFunctions(winston, 'useFormat', ['cli']);
warn.forProperties(winston, 'useFormat', ['padLevels', 'stripColors']);
warn.forFunctions(winston, 'deprecated', ['addRewriter', 'addFilter', 'clone', 'extend']);
warn.forProperties(winston, 'deprecated', ['emitErrs', 'levelLength']); // Throw a useful error when users attempt to run `new winston.Logger`.
warn.moved(winston, 'createLogger', 'Logger');

View File

@ -0,0 +1,56 @@
/**
* common.js: Internal helper and utility functions for winston.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
var _require = require('util'),
format = _require.format;
/**
* Set of simple deprecation notices and a way to expose them for a set of
* properties.
* @type {Object}
* @private
*/
exports.warn = {
deprecated: function deprecated(prop) {
return function () {
throw new Error(format('{ %s } was removed in winston@3.0.0.', prop));
};
},
useFormat: function useFormat(prop) {
return function () {
throw new Error([format('{ %s } was removed in winston@3.0.0.', prop), 'Use a custom winston.format = winston.format(function) instead.'].join('\n'));
};
},
forFunctions: function forFunctions(obj, type, props) {
props.forEach(function (prop) {
obj[prop] = exports.warn[type](prop);
});
},
moved: function moved(obj, movedTo, prop) {
function movedNotice() {
return function () {
throw new Error([format('winston.%s was moved in winston@3.0.0.', prop), format('Use a winston.%s instead.', movedTo)].join('\n'));
};
}
Object.defineProperty(obj, prop, {
get: movedNotice,
set: movedNotice
});
},
forProperties: function forProperties(obj, type, props) {
props.forEach(function (prop) {
var notice = exports.warn[type](prop);
Object.defineProperty(obj, prop, {
get: notice,
set: notice
});
});
}
};

View File

@ -0,0 +1,37 @@
/**
* index.js: Default settings for all levels that winston knows about.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
var logform = require('logform');
var _require = require('triple-beam'),
configs = _require.configs;
/**
* Export config set for the CLI.
* @type {Object}
*/
exports.cli = logform.levels(configs.cli);
/**
* Export config set for npm.
* @type {Object}
*/
exports.npm = logform.levels(configs.npm);
/**
* Export config set for the syslog.
* @type {Object}
*/
exports.syslog = logform.levels(configs.syslog);
/**
* Hoist addColors from logform where it was refactored into in winston@3.
* @type {Object}
*/
exports.addColors = logform.levels;

View File

@ -0,0 +1,147 @@
/**
* container.js: Inversion of control container for winston logger instances.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var createLogger = require('./create-logger');
/**
* Inversion of control container for winston logger instances.
* @type {Container}
*/
module.exports = /*#__PURE__*/function () {
/**
* Constructor function for the Container object responsible for managing a
* set of `winston.Logger` instances based on string ids.
* @param {!Object} [options={}] - Default pass-thru options for Loggers.
*/
function Container() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Container);
this.loggers = new Map();
this.options = options;
}
/**
* Retreives a `winston.Logger` instance for the specified `id`. If an
* instance does not exist, one is created.
* @param {!string} id - The id of the Logger to get.
* @param {?Object} [options] - Options for the Logger instance.
* @returns {Logger} - A configured Logger instance with a specified id.
*/
_createClass(Container, [{
key: "add",
value: function add(id, options) {
var _this = this;
if (!this.loggers.has(id)) {
// Remark: Simple shallow clone for configuration options in case we pass
// in instantiated protoypal objects
options = Object.assign({}, options || this.options);
var existing = options.transports || this.options.transports; // Remark: Make sure if we have an array of transports we slice it to
// make copies of those references.
options.transports = existing ? existing.slice() : [];
var logger = createLogger(options);
logger.on('close', function () {
return _this._delete(id);
});
this.loggers.set(id, logger);
}
return this.loggers.get(id);
}
/**
* Retreives a `winston.Logger` instance for the specified `id`. If
* an instance does not exist, one is created.
* @param {!string} id - The id of the Logger to get.
* @param {?Object} [options] - Options for the Logger instance.
* @returns {Logger} - A configured Logger instance with a specified id.
*/
}, {
key: "get",
value: function get(id, options) {
return this.add(id, options);
}
/**
* Check if the container has a logger with the id.
* @param {?string} id - The id of the Logger instance to find.
* @returns {boolean} - Boolean value indicating if this instance has a
* logger with the specified `id`.
*/
}, {
key: "has",
value: function has(id) {
return !!this.loggers.has(id);
}
/**
* Closes a `Logger` instance with the specified `id` if it exists.
* If no `id` is supplied then all Loggers are closed.
* @param {?string} id - The id of the Logger instance to close.
* @returns {undefined}
*/
}, {
key: "close",
value: function close(id) {
var _this2 = this;
if (id) {
return this._removeLogger(id);
}
this.loggers.forEach(function (val, key) {
return _this2._removeLogger(key);
});
}
/**
* Remove a logger based on the id.
* @param {!string} id - The id of the logger to remove.
* @returns {undefined}
* @private
*/
}, {
key: "_removeLogger",
value: function _removeLogger(id) {
if (!this.loggers.has(id)) {
return;
}
var logger = this.loggers.get(id);
logger.close();
this._delete(id);
}
/**
* Deletes a `Logger` instance with the specified `id`.
* @param {!string} id - The id of the Logger instance to delete from
* container.
* @returns {undefined}
* @private
*/
}, {
key: "_delete",
value: function _delete(id) {
this.loggers["delete"](id);
}
}]);
return Container;
}();

View File

@ -0,0 +1,141 @@
/**
* create-logger.js: Logger factory for winston logger instances.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var _require = require('triple-beam'),
LEVEL = _require.LEVEL;
var config = require('./config');
var Logger = require('./logger');
var debug = require('@dabh/diagnostics')('winston:create-logger');
function isLevelEnabledFunctionName(level) {
return 'is' + level.charAt(0).toUpperCase() + level.slice(1) + 'Enabled';
}
/**
* Create a new instance of a winston Logger. Creates a new
* prototype for each instance.
* @param {!Object} opts - Options for the created logger.
* @returns {Logger} - A newly created logger instance.
*/
module.exports = function () {
var opts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
//
// Default levels: npm
//
opts.levels = opts.levels || config.npm.levels;
/**
* DerivedLogger to attach the logs level methods.
* @type {DerivedLogger}
* @extends {Logger}
*/
var DerivedLogger = /*#__PURE__*/function (_Logger) {
_inherits(DerivedLogger, _Logger);
var _super = _createSuper(DerivedLogger);
/**
* Create a new class derived logger for which the levels can be attached to
* the prototype of. This is a V8 optimization that is well know to increase
* performance of prototype functions.
* @param {!Object} options - Options for the created logger.
*/
function DerivedLogger(options) {
_classCallCheck(this, DerivedLogger);
return _super.call(this, options);
}
return DerivedLogger;
}(Logger);
var logger = new DerivedLogger(opts); //
// Create the log level methods for the derived logger.
//
Object.keys(opts.levels).forEach(function (level) {
debug('Define prototype method for "%s"', level);
if (level === 'log') {
// eslint-disable-next-line no-console
console.warn('Level "log" not defined: conflicts with the method "log". Use a different level name.');
return;
} //
// Define prototype methods for each log level e.g.:
// logger.log('info', msg) implies these methods are defined:
// - logger.info(msg)
// - logger.isInfoEnabled()
//
// Remark: to support logger.child this **MUST** be a function
// so it'll always be called on the instance instead of a fixed
// place in the prototype chain.
//
DerivedLogger.prototype[level] = function () {
// Prefer any instance scope, but default to "root" logger
var self = this || logger; // Optimize the hot-path which is the single object.
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (args.length === 1) {
var msg = args[0];
var info = msg && msg.message && msg || {
message: msg
};
info.level = info[LEVEL] = level;
self._addDefaultMeta(info);
self.write(info);
return this || logger;
} // When provided nothing assume the empty string
if (args.length === 0) {
self.log(level, '');
return self;
} // Otherwise build argument list which could potentially conform to
// either:
// . v3 API: log(obj)
// 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
return self.log.apply(self, [level].concat(args));
};
DerivedLogger.prototype[isLevelEnabledFunctionName(level)] = function () {
return (this || logger).isLevelEnabled(level);
};
});
return logger;
};

View File

@ -0,0 +1,288 @@
/**
* exception-handler.js: Object for handling uncaughtException events.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var os = require('os');
var asyncForEach = require('async/forEach');
var debug = require('@dabh/diagnostics')('winston:exception');
var once = require('one-time');
var stackTrace = require('stack-trace');
var ExceptionStream = require('./exception-stream');
/**
* Object for handling uncaughtException events.
* @type {ExceptionHandler}
*/
module.exports = /*#__PURE__*/function () {
/**
* TODO: add contructor description
* @param {!Logger} logger - TODO: add param description
*/
function ExceptionHandler(logger) {
_classCallCheck(this, ExceptionHandler);
if (!logger) {
throw new Error('Logger is required to handle exceptions');
}
this.logger = logger;
this.handlers = new Map();
}
/**
* Handles `uncaughtException` events for the current process by adding any
* handlers passed in.
* @returns {undefined}
*/
_createClass(ExceptionHandler, [{
key: "handle",
value: function handle() {
var _this = this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
args.forEach(function (arg) {
if (Array.isArray(arg)) {
return arg.forEach(function (handler) {
return _this._addHandler(handler);
});
}
_this._addHandler(arg);
});
if (!this.catcher) {
this.catcher = this._uncaughtException.bind(this);
process.on('uncaughtException', this.catcher);
}
}
/**
* Removes any handlers to `uncaughtException` events for the current
* process. This does not modify the state of the `this.handlers` set.
* @returns {undefined}
*/
}, {
key: "unhandle",
value: function unhandle() {
var _this2 = this;
if (this.catcher) {
process.removeListener('uncaughtException', this.catcher);
this.catcher = false;
Array.from(this.handlers.values()).forEach(function (wrapper) {
return _this2.logger.unpipe(wrapper);
});
}
}
/**
* TODO: add method description
* @param {Error} err - Error to get information about.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getAllInfo",
value: function getAllInfo(err) {
var message = err.message;
if (!message && typeof err === 'string') {
message = err;
}
return {
error: err,
// TODO (indexzero): how do we configure this?
level: 'error',
message: ["uncaughtException: ".concat(message || '(no error message)'), err.stack || ' No stack trace'].join('\n'),
stack: err.stack,
exception: true,
date: new Date().toString(),
process: this.getProcessInfo(),
os: this.getOsInfo(),
trace: this.getTrace(err)
};
}
/**
* Gets all relevant process information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getProcessInfo",
value: function getProcessInfo() {
return {
pid: process.pid,
uid: process.getuid ? process.getuid() : null,
gid: process.getgid ? process.getgid() : null,
cwd: process.cwd(),
execPath: process.execPath,
version: process.version,
argv: process.argv,
memoryUsage: process.memoryUsage()
};
}
/**
* Gets all relevant OS information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getOsInfo",
value: function getOsInfo() {
return {
loadavg: os.loadavg(),
uptime: os.uptime()
};
}
/**
* Gets a stack trace for the specified error.
* @param {mixed} err - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getTrace",
value: function getTrace(err) {
var trace = err ? stackTrace.parse(err) : stackTrace.get();
return trace.map(function (site) {
return {
column: site.getColumnNumber(),
file: site.getFileName(),
"function": site.getFunctionName(),
line: site.getLineNumber(),
method: site.getMethodName(),
"native": site.isNative()
};
});
}
/**
* Helper method to add a transport as an exception handler.
* @param {Transport} handler - The transport to add as an exception handler.
* @returns {void}
*/
}, {
key: "_addHandler",
value: function _addHandler(handler) {
if (!this.handlers.has(handler)) {
handler.handleExceptions = true;
var wrapper = new ExceptionStream(handler);
this.handlers.set(handler, wrapper);
this.logger.pipe(wrapper);
}
}
/**
* Logs all relevant information around the `err` and exits the current
* process.
* @param {Error} err - Error to handle
* @returns {mixed} - TODO: add return description.
* @private
*/
}, {
key: "_uncaughtException",
value: function _uncaughtException(err) {
var info = this.getAllInfo(err);
var handlers = this._getExceptionHandlers(); // Calculate if we should exit on this error
var doExit = typeof this.logger.exitOnError === 'function' ? this.logger.exitOnError(err) : this.logger.exitOnError;
var timeout;
if (!handlers.length && doExit) {
// eslint-disable-next-line no-console
console.warn('winston: exitOnError cannot be true with no exception handlers.'); // eslint-disable-next-line no-console
console.warn('winston: not exiting process.');
doExit = false;
}
function gracefulExit() {
debug('doExit', doExit);
debug('process._exiting', process._exiting);
if (doExit && !process._exiting) {
// Remark: Currently ignoring any exceptions from transports when
// catching uncaught exceptions.
if (timeout) {
clearTimeout(timeout);
} // eslint-disable-next-line no-process-exit
process.exit(1);
}
}
if (!handlers || handlers.length === 0) {
return process.nextTick(gracefulExit);
} // Log to all transports attempting to listen for when they are completed.
asyncForEach(handlers, function (handler, next) {
var done = once(next);
var transport = handler.transport || handler; // Debug wrapping so that we can inspect what's going on under the covers.
function onDone(event) {
return function () {
debug(event);
done();
};
}
transport._ending = true;
transport.once('finish', onDone('finished'));
transport.once('error', onDone('error'));
}, function () {
return doExit && gracefulExit();
});
this.logger.log(info); // If exitOnError is true, then only allow the logging of exceptions to
// take up to `3000ms`.
if (doExit) {
timeout = setTimeout(gracefulExit, 3000);
}
}
/**
* Returns the list of transports and exceptionHandlers for this instance.
* @returns {Array} - List of transports and exceptionHandlers for this
* instance.
* @private
*/
}, {
key: "_getExceptionHandlers",
value: function _getExceptionHandlers() {
// Remark (indexzero): since `logger.transports` returns all of the pipes
// from the _readableState of the stream we actually get the join of the
// explicit handlers and the implicit transports with
// `handleExceptions: true`
return this.logger.transports.filter(function (wrap) {
var transport = wrap.transport || wrap;
return transport.handleExceptions;
});
}
}]);
return ExceptionHandler;
}();

View File

@ -0,0 +1,94 @@
/**
* exception-stream.js: TODO: add file header handler.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var _require = require('readable-stream'),
Writable = _require.Writable;
/**
* TODO: add class description.
* @type {ExceptionStream}
* @extends {Writable}
*/
module.exports = /*#__PURE__*/function (_Writable) {
_inherits(ExceptionStream, _Writable);
var _super = _createSuper(ExceptionStream);
/**
* Constructor function for the ExceptionStream responsible for wrapping a
* TransportStream; only allowing writes of `info` objects with
* `info.exception` set to true.
* @param {!TransportStream} transport - Stream to filter to exceptions
*/
function ExceptionStream(transport) {
var _this;
_classCallCheck(this, ExceptionStream);
_this = _super.call(this, {
objectMode: true
});
if (!transport) {
throw new Error('ExceptionStream requires a TransportStream instance.');
} // Remark (indexzero): we set `handleExceptions` here because it's the
// predicate checked in ExceptionHandler.prototype.__getExceptionHandlers
_this.handleExceptions = true;
_this.transport = transport;
return _this;
}
/**
* Writes the info object to our transport instance if (and only if) the
* `exception` property is set on the info.
* @param {mixed} info - TODO: add param description.
* @param {mixed} enc - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {mixed} - TODO: add return description.
* @private
*/
_createClass(ExceptionStream, [{
key: "_write",
value: function _write(info, enc, callback) {
if (info.exception) {
return this.transport.log(info, callback);
}
callback();
return true;
}
}]);
return ExceptionStream;
}(Writable);

View File

@ -0,0 +1,752 @@
/**
* logger.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var _require = require('readable-stream'),
Stream = _require.Stream,
Transform = _require.Transform;
var asyncForEach = require('async/forEach');
var _require2 = require('triple-beam'),
LEVEL = _require2.LEVEL,
SPLAT = _require2.SPLAT;
var isStream = require('is-stream');
var ExceptionHandler = require('./exception-handler');
var RejectionHandler = require('./rejection-handler');
var LegacyTransportStream = require('winston-transport/legacy');
var Profiler = require('./profiler');
var _require3 = require('./common'),
warn = _require3.warn;
var config = require('./config');
/**
* Captures the number of format (i.e. %s strings) in a given string.
* Based on `util.format`, see Node.js source:
* https://github.com/nodejs/node/blob/b1c8f15c5f169e021f7c46eb7b219de95fe97603/lib/util.js#L201-L230
* @type {RegExp}
*/
var formatRegExp = /%[scdjifoO%]/g;
/**
* TODO: add class description.
* @type {Logger}
* @extends {Transform}
*/
var Logger = /*#__PURE__*/function (_Transform) {
_inherits(Logger, _Transform);
var _super = _createSuper(Logger);
/**
* Constructor function for the Logger object responsible for persisting log
* messages and metadata to one or more transports.
* @param {!Object} options - foo
*/
function Logger(options) {
var _this;
_classCallCheck(this, Logger);
_this = _super.call(this, {
objectMode: true
});
_this.configure(options);
return _this;
}
_createClass(Logger, [{
key: "child",
value: function child(defaultRequestMetadata) {
var logger = this;
return Object.create(logger, {
write: {
value: function value(info) {
var infoClone = Object.assign({}, defaultRequestMetadata, info); // Object.assign doesn't copy inherited Error
// properties so we have to do that explicitly
//
// Remark (indexzero): we should remove this
// since the errors format will handle this case.
//
if (info instanceof Error) {
infoClone.stack = info.stack;
infoClone.message = info.message;
}
logger.write(infoClone);
}
}
});
}
/**
* This will wholesale reconfigure this instance by:
* 1. Resetting all transports. Older transports will be removed implicitly.
* 2. Set all other options including levels, colors, rewriters, filters,
* exceptionHandlers, etc.
* @param {!Object} options - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "configure",
value: function configure() {
var _this2 = this;
var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
silent = _ref.silent,
format = _ref.format,
defaultMeta = _ref.defaultMeta,
levels = _ref.levels,
_ref$level = _ref.level,
level = _ref$level === void 0 ? 'info' : _ref$level,
_ref$exitOnError = _ref.exitOnError,
exitOnError = _ref$exitOnError === void 0 ? true : _ref$exitOnError,
transports = _ref.transports,
colors = _ref.colors,
emitErrs = _ref.emitErrs,
formatters = _ref.formatters,
padLevels = _ref.padLevels,
rewriters = _ref.rewriters,
stripColors = _ref.stripColors,
exceptionHandlers = _ref.exceptionHandlers,
rejectionHandlers = _ref.rejectionHandlers;
// Reset transports if we already have them
if (this.transports.length) {
this.clear();
}
this.silent = silent;
this.format = format || this.format || require('logform/json')();
this.defaultMeta = defaultMeta || null; // Hoist other options onto this instance.
this.levels = levels || this.levels || config.npm.levels;
this.level = level;
this.exceptions = new ExceptionHandler(this);
this.rejections = new RejectionHandler(this);
this.profilers = {};
this.exitOnError = exitOnError; // Add all transports we have been provided.
if (transports) {
transports = Array.isArray(transports) ? transports : [transports];
transports.forEach(function (transport) {
return _this2.add(transport);
});
}
if (colors || emitErrs || formatters || padLevels || rewriters || stripColors) {
throw new Error(['{ colors, emitErrs, formatters, padLevels, rewriters, stripColors } were removed in winston@3.0.0.', 'Use a custom winston.format(function) instead.', 'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'].join('\n'));
}
if (exceptionHandlers) {
this.exceptions.handle(exceptionHandlers);
}
if (rejectionHandlers) {
this.rejections.handle(rejectionHandlers);
}
}
}, {
key: "isLevelEnabled",
value: function isLevelEnabled(level) {
var _this3 = this;
var givenLevelValue = getLevelValue(this.levels, level);
if (givenLevelValue === null) {
return false;
}
var configuredLevelValue = getLevelValue(this.levels, this.level);
if (configuredLevelValue === null) {
return false;
}
if (!this.transports || this.transports.length === 0) {
return configuredLevelValue >= givenLevelValue;
}
var index = this.transports.findIndex(function (transport) {
var transportLevelValue = getLevelValue(_this3.levels, transport.level);
if (transportLevelValue === null) {
transportLevelValue = configuredLevelValue;
}
return transportLevelValue >= givenLevelValue;
});
return index !== -1;
}
/* eslint-disable valid-jsdoc */
/**
* Ensure backwards compatibility with a `log` method
* @param {mixed} level - Level the log message is written at.
* @param {mixed} msg - TODO: add param description.
* @param {mixed} meta - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*
* @example
* // Supports the existing API:
* logger.log('info', 'Hello world', { custom: true });
* logger.log('info', new Error('Yo, it\'s on fire'));
*
* // Requires winston.format.splat()
* logger.log('info', '%s %d%%', 'A string', 50, { thisIsMeta: true });
*
* // And the new API with a single JSON literal:
* logger.log({ level: 'info', message: 'Hello world', custom: true });
* logger.log({ level: 'info', message: new Error('Yo, it\'s on fire') });
*
* // Also requires winston.format.splat()
* logger.log({
* level: 'info',
* message: '%s %d%%',
* [SPLAT]: ['A string', 50],
* meta: { thisIsMeta: true }
* });
*
*/
/* eslint-enable valid-jsdoc */
}, {
key: "log",
value: function log(level, msg) {
var _Object$assign2;
for (var _len = arguments.length, splat = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
splat[_key - 2] = arguments[_key];
}
// eslint-disable-line max-params
// Optimize for the hotpath of logging JSON literals
if (arguments.length === 1) {
// Yo dawg, I heard you like levels ... seriously ...
// In this context the LHS `level` here is actually the `info` so read
// this as: info[LEVEL] = info.level;
level[LEVEL] = level.level;
this._addDefaultMeta(level);
this.write(level);
return this;
} // Slightly less hotpath, but worth optimizing for.
if (arguments.length === 2) {
var _this$write;
if (msg && _typeof(msg) === 'object') {
msg[LEVEL] = msg.level = level;
this._addDefaultMeta(msg);
this.write(msg);
return this;
}
this.write((_this$write = {}, _defineProperty(_this$write, LEVEL, level), _defineProperty(_this$write, "level", level), _defineProperty(_this$write, "message", msg), _this$write));
return this;
}
var meta = splat[0];
if (_typeof(meta) === 'object' && meta !== null) {
// Extract tokens, if none available default to empty array to
// ensure consistancy in expected results
var tokens = msg && msg.match && msg.match(formatRegExp);
if (!tokens) {
var _Object$assign;
var info = Object.assign({}, this.defaultMeta, meta, (_Object$assign = {}, _defineProperty(_Object$assign, LEVEL, level), _defineProperty(_Object$assign, SPLAT, splat), _defineProperty(_Object$assign, "level", level), _defineProperty(_Object$assign, "message", msg), _Object$assign));
if (meta.message) info.message = "".concat(info.message, " ").concat(meta.message);
if (meta.stack) info.stack = meta.stack;
this.write(info);
return this;
}
}
this.write(Object.assign({}, this.defaultMeta, (_Object$assign2 = {}, _defineProperty(_Object$assign2, LEVEL, level), _defineProperty(_Object$assign2, SPLAT, splat), _defineProperty(_Object$assign2, "level", level), _defineProperty(_Object$assign2, "message", msg), _Object$assign2)));
return this;
}
/**
* Pushes data so that it can be picked up by all of our pipe targets.
* @param {mixed} info - TODO: add param description.
* @param {mixed} enc - TODO: add param description.
* @param {mixed} callback - Continues stream processing.
* @returns {undefined}
* @private
*/
}, {
key: "_transform",
value: function _transform(info, enc, callback) {
if (this.silent) {
return callback();
} // [LEVEL] is only soft guaranteed to be set here since we are a proper
// stream. It is likely that `info` came in through `.log(info)` or
// `.info(info)`. If it is not defined, however, define it.
// This LEVEL symbol is provided by `triple-beam` and also used in:
// - logform
// - winston-transport
// - abstract-winston-transport
if (!info[LEVEL]) {
info[LEVEL] = info.level;
} // Remark: really not sure what to do here, but this has been reported as
// very confusing by pre winston@2.0.0 users as quite confusing when using
// custom levels.
if (!this.levels[info[LEVEL]] && this.levels[info[LEVEL]] !== 0) {
// eslint-disable-next-line no-console
console.error('[winston] Unknown logger level: %s', info[LEVEL]);
} // Remark: not sure if we should simply error here.
if (!this._readableState.pipes) {
// eslint-disable-next-line no-console
console.error('[winston] Attempt to write logs with no transports %j', info);
} // Here we write to the `format` pipe-chain, which on `readable` above will
// push the formatted `info` Object onto the buffer for this instance. We trap
// (and re-throw) any errors generated by the user-provided format, but also
// guarantee that the streams callback is invoked so that we can continue flowing.
try {
this.push(this.format.transform(info, this.format.options));
} catch (ex) {
throw ex;
} finally {
// eslint-disable-next-line callback-return
callback();
}
}
/**
* Delays the 'finish' event until all transport pipe targets have
* also emitted 'finish' or are already finished.
* @param {mixed} callback - Continues stream processing.
*/
}, {
key: "_final",
value: function _final(callback) {
var transports = this.transports.slice();
asyncForEach(transports, function (transport, next) {
if (!transport || transport.finished) return setImmediate(next);
transport.once('finish', next);
transport.end();
}, callback);
}
/**
* Adds the transport to this logger instance by piping to it.
* @param {mixed} transport - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*/
}, {
key: "add",
value: function add(transport) {
// Support backwards compatibility with all existing `winston < 3.x.x`
// transports which meet one of two criteria:
// 1. They inherit from winston.Transport in < 3.x.x which is NOT a stream.
// 2. They expose a log method which has a length greater than 2 (i.e. more then
// just `log(info, callback)`.
var target = !isStream(transport) || transport.log.length > 2 ? new LegacyTransportStream({
transport: transport
}) : transport;
if (!target._writableState || !target._writableState.objectMode) {
throw new Error('Transports must WritableStreams in objectMode. Set { objectMode: true }.');
} // Listen for the `error` event and the `warn` event on the new Transport.
this._onEvent('error', target);
this._onEvent('warn', target);
this.pipe(target);
if (transport.handleExceptions) {
this.exceptions.handle();
}
if (transport.handleRejections) {
this.rejections.handle();
}
return this;
}
/**
* Removes the transport from this logger instance by unpiping from it.
* @param {mixed} transport - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*/
}, {
key: "remove",
value: function remove(transport) {
if (!transport) return this;
var target = transport;
if (!isStream(transport) || transport.log.length > 2) {
target = this.transports.filter(function (match) {
return match.transport === transport;
})[0];
}
if (target) {
this.unpipe(target);
}
return this;
}
/**
* Removes all transports from this logger instance.
* @returns {Logger} - TODO: add return description.
*/
}, {
key: "clear",
value: function clear() {
this.unpipe();
return this;
}
/**
* Cleans up resources (streams, event listeners) for all transports
* associated with this instance (if necessary).
* @returns {Logger} - TODO: add return description.
*/
}, {
key: "close",
value: function close() {
this.clear();
this.emit('close');
return this;
}
/**
* Sets the `target` levels specified on this instance.
* @param {Object} Target levels to use on this instance.
*/
}, {
key: "setLevels",
value: function setLevels() {
warn.deprecated('setLevels');
}
/**
* Queries the all transports for this instance with the specified `options`.
* This will aggregate each transport's results into one object containing
* a property per transport.
* @param {Object} options - Query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
*/
}, {
key: "query",
value: function query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = options || {};
var results = {};
var queryObject = Object.assign({}, options.query || {}); // Helper function to query a single transport
function queryTransport(transport, next) {
if (options.query && typeof transport.formatQuery === 'function') {
options.query = transport.formatQuery(queryObject);
}
transport.query(options, function (err, res) {
if (err) {
return next(err);
}
if (typeof transport.formatResults === 'function') {
res = transport.formatResults(res, options.format);
}
next(null, res);
});
} // Helper function to accumulate the results from `queryTransport` into
// the `results`.
function addResults(transport, next) {
queryTransport(transport, function (err, result) {
// queryTransport could potentially invoke the callback multiple times
// since Transport code can be unpredictable.
if (next) {
result = err || result;
if (result) {
results[transport.name] = result;
} // eslint-disable-next-line callback-return
next();
}
next = null;
});
} // Iterate over the transports in parallel setting the appropriate key in
// the `results`.
asyncForEach(this.transports.filter(function (transport) {
return !!transport.query;
}), addResults, function () {
return callback(null, results);
});
}
/**
* Returns a log stream for all transports. Options object is optional.
* @param{Object} options={} - Stream options for this instance.
* @returns {Stream} - TODO: add return description.
*/
}, {
key: "stream",
value: function stream() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var out = new Stream();
var streams = [];
out._streams = streams;
out.destroy = function () {
var i = streams.length;
while (i--) {
streams[i].destroy();
}
}; // Create a list of all transports for this instance.
this.transports.filter(function (transport) {
return !!transport.stream;
}).forEach(function (transport) {
var str = transport.stream(options);
if (!str) {
return;
}
streams.push(str);
str.on('log', function (log) {
log.transport = log.transport || [];
log.transport.push(transport.name);
out.emit('log', log);
});
str.on('error', function (err) {
err.transport = err.transport || [];
err.transport.push(transport.name);
out.emit('error', err);
});
});
return out;
}
/**
* Returns an object corresponding to a specific timing. When done is called
* the timer will finish and log the duration. e.g.:
* @returns {Profile} - TODO: add return description.
* @example
* const timer = winston.startTimer()
* setTimeout(() => {
* timer.done({
* message: 'Logging message'
* });
* }, 1000);
*/
}, {
key: "startTimer",
value: function startTimer() {
return new Profiler(this);
}
/**
* Tracks the time inbetween subsequent calls to this method with the same
* `id` parameter. The second call to this method will log the difference in
* milliseconds along with the message.
* @param {string} id Unique id of the profiler
* @returns {Logger} - TODO: add return description.
*/
}, {
key: "profile",
value: function profile(id) {
var time = Date.now();
if (this.profilers[id]) {
var timeEnd = this.profilers[id];
delete this.profilers[id]; // Attempt to be kind to users if they are still using older APIs.
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
if (typeof args[args.length - 2] === 'function') {
// eslint-disable-next-line no-console
console.warn('Callback function no longer supported as of winston@3.0.0');
args.pop();
} // Set the duration property of the metadata
var info = _typeof(args[args.length - 1]) === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = time - timeEnd;
info.message = info.message || id;
return this.write(info);
}
this.profilers[id] = time;
return this;
}
/**
* Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
* @returns {undefined}
* @deprecated
*/
}, {
key: "handleExceptions",
value: function handleExceptions() {
var _this$exceptions;
// eslint-disable-next-line no-console
console.warn('Deprecated: .handleExceptions() will be removed in winston@4. Use .exceptions.handle()');
(_this$exceptions = this.exceptions).handle.apply(_this$exceptions, arguments);
}
/**
* Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
* @returns {undefined}
* @deprecated
*/
}, {
key: "unhandleExceptions",
value: function unhandleExceptions() {
var _this$exceptions2;
// eslint-disable-next-line no-console
console.warn('Deprecated: .unhandleExceptions() will be removed in winston@4. Use .exceptions.unhandle()');
(_this$exceptions2 = this.exceptions).unhandle.apply(_this$exceptions2, arguments);
}
/**
* Throw a more meaningful deprecation notice
* @throws {Error} - TODO: add throws description.
*/
}, {
key: "cli",
value: function cli() {
throw new Error(['Logger.cli() was removed in winston@3.0.0', 'Use a custom winston.formats.cli() instead.', 'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'].join('\n'));
}
/**
* Bubbles the `event` that occured on the specified `transport` up
* from this instance.
* @param {string} event - The event that occured
* @param {Object} transport - Transport on which the event occured
* @private
*/
}, {
key: "_onEvent",
value: function _onEvent(event, transport) {
function transportEvent(err) {
// https://github.com/winstonjs/winston/issues/1364
if (event === 'error' && !this.transports.includes(transport)) {
this.add(transport);
}
this.emit(event, err, transport);
}
if (!transport['__winston' + event]) {
transport['__winston' + event] = transportEvent.bind(this);
transport.on(event, transport['__winston' + event]);
}
}
}, {
key: "_addDefaultMeta",
value: function _addDefaultMeta(msg) {
if (this.defaultMeta) {
Object.assign(msg, this.defaultMeta);
}
}
}]);
return Logger;
}(Transform);
function getLevelValue(levels, level) {
var value = levels[level];
if (!value && value !== 0) {
return null;
}
return value;
}
/**
* Represents the current readableState pipe targets for this Logger instance.
* @type {Array|Object}
*/
Object.defineProperty(Logger.prototype, 'transports', {
configurable: false,
enumerable: true,
get: function get() {
var pipes = this._readableState.pipes;
return !Array.isArray(pipes) ? [pipes].filter(Boolean) : pipes;
}
});
module.exports = Logger;

View File

@ -0,0 +1,69 @@
/**
* profiler.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
/**
* TODO: add class description.
* @type {Profiler}
* @private
*/
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
module.exports = /*#__PURE__*/function () {
/**
* Constructor function for the Profiler instance used by
* `Logger.prototype.startTimer`. When done is called the timer will finish
* and log the duration.
* @param {!Logger} logger - TODO: add param description.
* @private
*/
function Profiler(logger) {
_classCallCheck(this, Profiler);
if (!logger) {
throw new Error('Logger is required for profiling.');
}
this.logger = logger;
this.start = Date.now();
}
/**
* Ends the current timer (i.e. Profiler) instance and logs the `msg` along
* with the duration since creation.
* @returns {mixed} - TODO: add return description.
* @private
*/
_createClass(Profiler, [{
key: "done",
value: function done() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
if (typeof args[args.length - 1] === 'function') {
// eslint-disable-next-line no-console
console.warn('Callback function no longer supported as of winston@3.0.0');
args.pop();
}
var info = _typeof(args[args.length - 1]) === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = Date.now() - this.start;
return this.logger.write(info);
}
}]);
return Profiler;
}();

View File

@ -0,0 +1,288 @@
/**
* exception-handler.js: Object for handling uncaughtException events.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var os = require('os');
var asyncForEach = require('async/forEach');
var debug = require('@dabh/diagnostics')('winston:rejection');
var once = require('one-time');
var stackTrace = require('stack-trace');
var ExceptionStream = require('./exception-stream');
/**
* Object for handling unhandledRejection events.
* @type {RejectionHandler}
*/
module.exports = /*#__PURE__*/function () {
/**
* TODO: add contructor description
* @param {!Logger} logger - TODO: add param description
*/
function RejectionHandler(logger) {
_classCallCheck(this, RejectionHandler);
if (!logger) {
throw new Error('Logger is required to handle rejections');
}
this.logger = logger;
this.handlers = new Map();
}
/**
* Handles `unhandledRejection` events for the current process by adding any
* handlers passed in.
* @returns {undefined}
*/
_createClass(RejectionHandler, [{
key: "handle",
value: function handle() {
var _this = this;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
args.forEach(function (arg) {
if (Array.isArray(arg)) {
return arg.forEach(function (handler) {
return _this._addHandler(handler);
});
}
_this._addHandler(arg);
});
if (!this.catcher) {
this.catcher = this._unhandledRejection.bind(this);
process.on('unhandledRejection', this.catcher);
}
}
/**
* Removes any handlers to `unhandledRejection` events for the current
* process. This does not modify the state of the `this.handlers` set.
* @returns {undefined}
*/
}, {
key: "unhandle",
value: function unhandle() {
var _this2 = this;
if (this.catcher) {
process.removeListener('unhandledRejection', this.catcher);
this.catcher = false;
Array.from(this.handlers.values()).forEach(function (wrapper) {
return _this2.logger.unpipe(wrapper);
});
}
}
/**
* TODO: add method description
* @param {Error} err - Error to get information about.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getAllInfo",
value: function getAllInfo(err) {
var message = err.message;
if (!message && typeof err === 'string') {
message = err;
}
return {
error: err,
// TODO (indexzero): how do we configure this?
level: 'error',
message: ["unhandledRejection: ".concat(message || '(no error message)'), err.stack || ' No stack trace'].join('\n'),
stack: err.stack,
exception: true,
date: new Date().toString(),
process: this.getProcessInfo(),
os: this.getOsInfo(),
trace: this.getTrace(err)
};
}
/**
* Gets all relevant process information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getProcessInfo",
value: function getProcessInfo() {
return {
pid: process.pid,
uid: process.getuid ? process.getuid() : null,
gid: process.getgid ? process.getgid() : null,
cwd: process.cwd(),
execPath: process.execPath,
version: process.version,
argv: process.argv,
memoryUsage: process.memoryUsage()
};
}
/**
* Gets all relevant OS information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getOsInfo",
value: function getOsInfo() {
return {
loadavg: os.loadavg(),
uptime: os.uptime()
};
}
/**
* Gets a stack trace for the specified error.
* @param {mixed} err - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "getTrace",
value: function getTrace(err) {
var trace = err ? stackTrace.parse(err) : stackTrace.get();
return trace.map(function (site) {
return {
column: site.getColumnNumber(),
file: site.getFileName(),
"function": site.getFunctionName(),
line: site.getLineNumber(),
method: site.getMethodName(),
"native": site.isNative()
};
});
}
/**
* Helper method to add a transport as an exception handler.
* @param {Transport} handler - The transport to add as an exception handler.
* @returns {void}
*/
}, {
key: "_addHandler",
value: function _addHandler(handler) {
if (!this.handlers.has(handler)) {
handler.handleRejections = true;
var wrapper = new ExceptionStream(handler);
this.handlers.set(handler, wrapper);
this.logger.pipe(wrapper);
}
}
/**
* Logs all relevant information around the `err` and exits the current
* process.
* @param {Error} err - Error to handle
* @returns {mixed} - TODO: add return description.
* @private
*/
}, {
key: "_unhandledRejection",
value: function _unhandledRejection(err) {
var info = this.getAllInfo(err);
var handlers = this._getRejectionHandlers(); // Calculate if we should exit on this error
var doExit = typeof this.logger.exitOnError === 'function' ? this.logger.exitOnError(err) : this.logger.exitOnError;
var timeout;
if (!handlers.length && doExit) {
// eslint-disable-next-line no-console
console.warn('winston: exitOnError cannot be true with no rejection handlers.'); // eslint-disable-next-line no-console
console.warn('winston: not exiting process.');
doExit = false;
}
function gracefulExit() {
debug('doExit', doExit);
debug('process._exiting', process._exiting);
if (doExit && !process._exiting) {
// Remark: Currently ignoring any rejections from transports when
// catching unhandled rejections.
if (timeout) {
clearTimeout(timeout);
} // eslint-disable-next-line no-process-exit
process.exit(1);
}
}
if (!handlers || handlers.length === 0) {
return process.nextTick(gracefulExit);
} // Log to all transports attempting to listen for when they are completed.
asyncForEach(handlers, function (handler, next) {
var done = once(next);
var transport = handler.transport || handler; // Debug wrapping so that we can inspect what's going on under the covers.
function onDone(event) {
return function () {
debug(event);
done();
};
}
transport._ending = true;
transport.once('finish', onDone('finished'));
transport.once('error', onDone('error'));
}, function () {
return doExit && gracefulExit();
});
this.logger.log(info); // If exitOnError is true, then only allow the logging of exceptions to
// take up to `3000ms`.
if (doExit) {
timeout = setTimeout(gracefulExit, 3000);
}
}
/**
* Returns the list of transports and exceptionHandlers for this instance.
* @returns {Array} - List of transports and exceptionHandlers for this
* instance.
* @private
*/
}, {
key: "_getRejectionHandlers",
value: function _getRejectionHandlers() {
// Remark (indexzero): since `logger.transports` returns all of the pipes
// from the _readableState of the stream we actually get the join of the
// explicit handlers and the implicit transports with
// `handleRejections: true`
return this.logger.transports.filter(function (wrap) {
var transport = wrap.transport || wrap;
return transport.handleRejections;
});
}
}]);
return RejectionHandler;
}();

View File

@ -0,0 +1,135 @@
/**
* tail-file.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
var fs = require('fs');
var _require = require('string_decoder'),
StringDecoder = _require.StringDecoder;
var _require2 = require('readable-stream'),
Stream = _require2.Stream;
/**
* Simple no-op function.
* @returns {undefined}
*/
function noop() {}
/**
* TODO: add function description.
* @param {Object} options - Options for tail.
* @param {function} iter - Iterator function to execute on every line.
* `tail -f` a file. Options must include file.
* @returns {mixed} - TODO: add return description.
*/
module.exports = function (options, iter) {
var buffer = Buffer.alloc(64 * 1024);
var decode = new StringDecoder('utf8');
var stream = new Stream();
var buff = '';
var pos = 0;
var row = 0;
if (options.start === -1) {
delete options.start;
}
stream.readable = true;
stream.destroy = function () {
stream.destroyed = true;
stream.emit('end');
stream.emit('close');
};
fs.open(options.file, 'a+', '0644', function (err, fd) {
if (err) {
if (!iter) {
stream.emit('error', err);
} else {
iter(err);
}
stream.destroy();
return;
}
(function read() {
if (stream.destroyed) {
fs.close(fd, noop);
return;
}
return fs.read(fd, buffer, 0, buffer.length, pos, function (error, bytes) {
if (error) {
if (!iter) {
stream.emit('error', error);
} else {
iter(error);
}
stream.destroy();
return;
}
if (!bytes) {
if (buff) {
// eslint-disable-next-line eqeqeq
if (options.start == null || row > options.start) {
if (!iter) {
stream.emit('line', buff);
} else {
iter(null, buff);
}
}
row++;
buff = '';
}
return setTimeout(read, 1000);
}
var data = decode.write(buffer.slice(0, bytes));
if (!iter) {
stream.emit('data', data);
}
data = (buff + data).split(/\n+/);
var l = data.length - 1;
var i = 0;
for (; i < l; i++) {
// eslint-disable-next-line eqeqeq
if (options.start == null || row > options.start) {
if (!iter) {
stream.emit('line', data[i]);
} else {
iter(null, data[i]);
}
}
row++;
}
buff = data[l];
pos += bytes;
return read();
});
})();
});
if (!iter) {
return stream;
}
return stream.destroy;
};

View File

@ -0,0 +1,166 @@
/* eslint-disable no-console */
/*
* console.js: Transport for outputting to the console.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var os = require('os');
var _require = require('triple-beam'),
LEVEL = _require.LEVEL,
MESSAGE = _require.MESSAGE;
var TransportStream = require('winston-transport');
/**
* Transport for outputting to the console.
* @type {Console}
* @extends {TransportStream}
*/
module.exports = /*#__PURE__*/function (_TransportStream) {
_inherits(Console, _TransportStream);
var _super = _createSuper(Console);
/**
* Constructor function for the Console transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
function Console() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Console);
_this = _super.call(this, options); // Expose the name of this Transport on the prototype
_this.name = options.name || 'console';
_this.stderrLevels = _this._stringArrayToSet(options.stderrLevels);
_this.consoleWarnLevels = _this._stringArrayToSet(options.consoleWarnLevels);
_this.eol = options.eol || os.EOL;
_this.setMaxListeners(30);
return _this;
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
_createClass(Console, [{
key: "log",
value: function log(info, callback) {
var _this2 = this;
setImmediate(function () {
return _this2.emit('logged', info);
}); // Remark: what if there is no raw...?
if (this.stderrLevels[info[LEVEL]]) {
if (console._stderr) {
// Node.js maps `process.stderr` to `console._stderr`.
console._stderr.write("".concat(info[MESSAGE]).concat(this.eol));
} else {
// console.error adds a newline
console.error(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
} else if (this.consoleWarnLevels[info[LEVEL]]) {
if (console._stderr) {
// Node.js maps `process.stderr` to `console._stderr`.
// in Node.js console.warn is an alias for console.error
console._stderr.write("".concat(info[MESSAGE]).concat(this.eol));
} else {
// console.warn adds a newline
console.warn(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
if (console._stdout) {
// Node.js maps `process.stdout` to `console._stdout`.
console._stdout.write("".concat(info[MESSAGE]).concat(this.eol));
} else {
// console.log adds a newline.
console.log(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
}
/**
* Returns a Set-like object with strArray's elements as keys (each with the
* value true).
* @param {Array} strArray - Array of Set-elements as strings.
* @param {?string} [errMsg] - Custom error message thrown on invalid input.
* @returns {Object} - TODO: add return description.
* @private
*/
}, {
key: "_stringArrayToSet",
value: function _stringArrayToSet(strArray, errMsg) {
if (!strArray) return {};
errMsg = errMsg || 'Cannot make set from type other than Array of string elements';
if (!Array.isArray(strArray)) {
throw new Error(errMsg);
}
return strArray.reduce(function (set, el) {
if (typeof el !== 'string') {
throw new Error(errMsg);
}
set[el] = true;
return set;
}, {});
}
}]);
return Console;
}(TransportStream);

View File

@ -0,0 +1,817 @@
/* eslint-disable complexity,max-statements */
/**
* file.js: Transport for outputting to a local log file.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var fs = require('fs');
var path = require('path');
var asyncSeries = require('async/series');
var zlib = require('zlib');
var _require = require('triple-beam'),
MESSAGE = _require.MESSAGE;
var _require2 = require('readable-stream'),
Stream = _require2.Stream,
PassThrough = _require2.PassThrough;
var TransportStream = require('winston-transport');
var debug = require('@dabh/diagnostics')('winston:file');
var os = require('os');
var tailFile = require('../tail-file');
/**
* Transport for outputting to a local log file.
* @type {File}
* @extends {TransportStream}
*/
module.exports = /*#__PURE__*/function (_TransportStream) {
_inherits(File, _TransportStream);
var _super = _createSuper(File);
/**
* Constructor function for the File transport object responsible for
* persisting log messages and metadata to one or more files.
* @param {Object} options - Options for this instance.
*/
function File() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, File);
_this = _super.call(this, options); // Expose the name of this Transport on the prototype.
_this.name = options.name || 'file'; // Helper function which throws an `Error` in the event that any of the
// rest of the arguments is present in `options`.
function throwIf(target) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
args.slice(1).forEach(function (name) {
if (options[name]) {
throw new Error("Cannot set ".concat(name, " and ").concat(target, " together"));
}
});
} // Setup the base stream that always gets piped to to handle buffering.
_this._stream = new PassThrough();
_this._stream.setMaxListeners(30); // Bind this context for listener methods.
_this._onError = _this._onError.bind(_assertThisInitialized(_this));
if (options.filename || options.dirname) {
throwIf('filename or dirname', 'stream');
_this._basename = _this.filename = options.filename ? path.basename(options.filename) : 'winston.log';
_this.dirname = options.dirname || path.dirname(options.filename);
_this.options = options.options || {
flags: 'a'
};
} else if (options.stream) {
// eslint-disable-next-line no-console
console.warn('options.stream will be removed in winston@4. Use winston.transports.Stream');
throwIf('stream', 'filename', 'maxsize');
_this._dest = _this._stream.pipe(_this._setupStream(options.stream));
_this.dirname = path.dirname(_this._dest.path); // We need to listen for drain events when write() returns false. This
// can make node mad at times.
} else {
throw new Error('Cannot log to file without filename or stream.');
}
_this.maxsize = options.maxsize || null;
_this.rotationFormat = options.rotationFormat || false;
_this.zippedArchive = options.zippedArchive || false;
_this.maxFiles = options.maxFiles || null;
_this.eol = options.eol || os.EOL;
_this.tailable = options.tailable || false; // Internal state variables representing the number of files this instance
// has created and the current size (in bytes) of the current logfile.
_this._size = 0;
_this._pendingSize = 0;
_this._created = 0;
_this._drain = false;
_this._opening = false;
_this._ending = false;
if (_this.dirname) _this._createLogDirIfNotExist(_this.dirname);
_this.open();
return _this;
}
_createClass(File, [{
key: "finishIfEnding",
value: function finishIfEnding() {
var _this2 = this;
if (this._ending) {
if (this._opening) {
this.once('open', function () {
_this2._stream.once('finish', function () {
return _this2.emit('finish');
});
setImmediate(function () {
return _this2._stream.end();
});
});
} else {
this._stream.once('finish', function () {
return _this2.emit('finish');
});
setImmediate(function () {
return _this2._stream.end();
});
}
}
}
/**
* Core logging method exposed to Winston. Metadata is optional.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "log",
value: function log(info) {
var _this3 = this;
var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
// Remark: (jcrugzz) What is necessary about this callback(null, true) now
// when thinking about 3.x? Should silent be handled in the base
// TransportStream _write method?
if (this.silent) {
callback();
return true;
} // Output stream buffer is full and has asked us to wait for the drain event
if (this._drain) {
this._stream.once('drain', function () {
_this3._drain = false;
_this3.log(info, callback);
});
return;
}
if (this._rotate) {
this._stream.once('rotate', function () {
_this3._rotate = false;
_this3.log(info, callback);
});
return;
} // Grab the raw string and append the expected EOL.
var output = "".concat(info[MESSAGE]).concat(this.eol);
var bytes = Buffer.byteLength(output); // After we have written to the PassThrough check to see if we need
// to rotate to the next file.
//
// Remark: This gets called too early and does not depict when data
// has been actually flushed to disk.
function logged() {
var _this4 = this;
this._size += bytes;
this._pendingSize -= bytes;
debug('logged %s %s', this._size, output);
this.emit('logged', info); // Do not attempt to rotate files while opening
if (this._opening) {
return;
} // Check to see if we need to end the stream and create a new one.
if (!this._needsNewFile()) {
return;
} // End the current stream, ensure it flushes and create a new one.
// This could potentially be optimized to not run a stat call but its
// the safest way since we are supporting `maxFiles`.
this._rotate = true;
this._endStream(function () {
return _this4._rotateFile();
});
} // Keep track of the pending bytes being written while files are opening
// in order to properly rotate the PassThrough this._stream when the file
// eventually does open.
this._pendingSize += bytes;
if (this._opening && !this.rotatedWhileOpening && this._needsNewFile(this._size + this._pendingSize)) {
this.rotatedWhileOpening = true;
}
var written = this._stream.write(output, logged.bind(this));
if (!written) {
this._drain = true;
this._stream.once('drain', function () {
_this3._drain = false;
callback();
});
} else {
callback(); // eslint-disable-line callback-return
}
debug('written', written, this._drain);
this.finishIfEnding();
return written;
}
/**
* Query the transport. Options object is optional.
* @param {Object} options - Loggly-like query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
* TODO: Refactor me.
*/
}, {
key: "query",
value: function query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = normalizeQuery(options);
var file = path.join(this.dirname, this.filename);
var buff = '';
var results = [];
var row = 0;
var stream = fs.createReadStream(file, {
encoding: 'utf8'
});
stream.on('error', function (err) {
if (stream.readable) {
stream.destroy();
}
if (!callback) {
return;
}
return err.code !== 'ENOENT' ? callback(err) : callback(null, results);
});
stream.on('data', function (data) {
data = (buff + data).split(/\n+/);
var l = data.length - 1;
var i = 0;
for (; i < l; i++) {
if (!options.start || row >= options.start) {
add(data[i]);
}
row++;
}
buff = data[l];
});
stream.on('close', function () {
if (buff) {
add(buff, true);
}
if (options.order === 'desc') {
results = results.reverse();
} // eslint-disable-next-line callback-return
if (callback) callback(null, results);
});
function add(buff, attempt) {
try {
var log = JSON.parse(buff);
if (check(log)) {
push(log);
}
} catch (e) {
if (!attempt) {
stream.emit('error', e);
}
}
}
function push(log) {
if (options.rows && results.length >= options.rows && options.order !== 'desc') {
if (stream.readable) {
stream.destroy();
}
return;
}
if (options.fields) {
log = options.fields.reduce(function (obj, key) {
obj[key] = log[key];
return obj;
}, {});
}
if (options.order === 'desc') {
if (results.length >= options.rows) {
results.shift();
}
}
results.push(log);
}
function check(log) {
if (!log) {
return;
}
if (_typeof(log) !== 'object') {
return;
}
var time = new Date(log.timestamp);
if (options.from && time < options.from || options.until && time > options.until || options.level && options.level !== log.level) {
return;
}
return true;
}
function normalizeQuery(options) {
options = options || {}; // limit
options.rows = options.rows || options.limit || 10; // starting row offset
options.start = options.start || 0; // now
options.until = options.until || new Date();
if (_typeof(options.until) !== 'object') {
options.until = new Date(options.until);
} // now - 24
options.from = options.from || options.until - 24 * 60 * 60 * 1000;
if (_typeof(options.from) !== 'object') {
options.from = new Date(options.from);
} // 'asc' or 'desc'
options.order = options.order || 'desc';
return options;
}
}
/**
* Returns a log stream for this transport. Options object is optional.
* @param {Object} options - Stream options for this instance.
* @returns {Stream} - TODO: add return description.
* TODO: Refactor me.
*/
}, {
key: "stream",
value: function stream() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var file = path.join(this.dirname, this.filename);
var stream = new Stream();
var tail = {
file: file,
start: options.start
};
stream.destroy = tailFile(tail, function (err, line) {
if (err) {
return stream.emit('error', err);
}
try {
stream.emit('data', line);
line = JSON.parse(line);
stream.emit('log', line);
} catch (e) {
stream.emit('error', e);
}
});
return stream;
}
/**
* Checks to see the filesize of.
* @returns {undefined}
*/
}, {
key: "open",
value: function open() {
var _this5 = this;
// If we do not have a filename then we were passed a stream and
// don't need to keep track of size.
if (!this.filename) return;
if (this._opening) return;
this._opening = true; // Stat the target file to get the size and create the stream.
this.stat(function (err, size) {
if (err) {
return _this5.emit('error', err);
}
debug('stat done: %s { size: %s }', _this5.filename, size);
_this5._size = size;
_this5._dest = _this5._createStream(_this5._stream);
_this5._opening = false;
_this5.once('open', function () {
if (_this5._stream.eventNames().includes('rotate')) {
_this5._stream.emit('rotate');
} else {
_this5._rotate = false;
}
});
});
}
/**
* Stat the file and assess information in order to create the proper stream.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "stat",
value: function stat(callback) {
var _this6 = this;
var target = this._getFile();
var fullpath = path.join(this.dirname, target);
fs.stat(fullpath, function (err, stat) {
if (err && err.code === 'ENOENT') {
debug('ENOENT ok', fullpath); // Update internally tracked filename with the new target name.
_this6.filename = target;
return callback(null, 0);
}
if (err) {
debug("err ".concat(err.code, " ").concat(fullpath));
return callback(err);
}
if (!stat || _this6._needsNewFile(stat.size)) {
// If `stats.size` is greater than the `maxsize` for this
// instance then try again.
return _this6._incFile(function () {
return _this6.stat(callback);
});
} // Once we have figured out what the filename is, set it
// and return the size.
_this6.filename = target;
callback(null, stat.size);
});
}
/**
* Closes the stream associated with this instance.
* @param {function} cb - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "close",
value: function close(cb) {
var _this7 = this;
if (!this._stream) {
return;
}
this._stream.end(function () {
if (cb) {
cb(); // eslint-disable-line callback-return
}
_this7.emit('flush');
_this7.emit('closed');
});
}
/**
* TODO: add method description.
* @param {number} size - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "_needsNewFile",
value: function _needsNewFile(size) {
size = size || this._size;
return this.maxsize && size >= this.maxsize;
}
/**
* TODO: add method description.
* @param {Error} err - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "_onError",
value: function _onError(err) {
this.emit('error', err);
}
/**
* TODO: add method description.
* @param {Stream} stream - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "_setupStream",
value: function _setupStream(stream) {
stream.on('error', this._onError);
return stream;
}
/**
* TODO: add method description.
* @param {Stream} stream - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
}, {
key: "_cleanupStream",
value: function _cleanupStream(stream) {
stream.removeListener('error', this._onError);
return stream;
}
/**
* TODO: add method description.
*/
}, {
key: "_rotateFile",
value: function _rotateFile() {
var _this8 = this;
this._incFile(function () {
return _this8.open();
});
}
/**
* Unpipe from the stream that has been marked as full and end it so it
* flushes to disk.
*
* @param {function} callback - Callback for when the current file has closed.
* @private
*/
}, {
key: "_endStream",
value: function _endStream() {
var _this9 = this;
var callback = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : function () {};
if (this._dest) {
this._stream.unpipe(this._dest);
this._dest.end(function () {
_this9._cleanupStream(_this9._dest);
callback();
});
} else {
callback(); // eslint-disable-line callback-return
}
}
/**
* Returns the WritableStream for the active file on this instance. If we
* should gzip the file then a zlib stream is returned.
*
* @param {ReadableStream} source  PassThrough to pipe to the file when open.
* @returns {WritableStream} Stream that writes to disk for the active file.
*/
}, {
key: "_createStream",
value: function _createStream(source) {
var _this10 = this;
var fullpath = path.join(this.dirname, this.filename);
debug('create stream start', fullpath, this.options);
var dest = fs.createWriteStream(fullpath, this.options) // TODO: What should we do with errors here?
.on('error', function (err) {
return debug(err);
}).on('close', function () {
return debug('close', dest.path, dest.bytesWritten);
}).on('open', function () {
debug('file open ok', fullpath);
_this10.emit('open', fullpath);
source.pipe(dest); // If rotation occured during the open operation then we immediately
// start writing to a new PassThrough, begin opening the next file
// and cleanup the previous source and dest once the source has drained.
if (_this10.rotatedWhileOpening) {
_this10._stream = new PassThrough();
_this10._stream.setMaxListeners(30);
_this10._rotateFile();
_this10.rotatedWhileOpening = false;
_this10._cleanupStream(dest);
source.end();
}
});
debug('create stream ok', fullpath);
if (this.zippedArchive) {
var gzip = zlib.createGzip();
gzip.pipe(dest);
return gzip;
}
return dest;
}
/**
* TODO: add method description.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
}, {
key: "_incFile",
value: function _incFile(callback) {
debug('_incFile', this.filename);
var ext = path.extname(this._basename);
var basename = path.basename(this._basename, ext);
if (!this.tailable) {
this._created += 1;
this._checkMaxFilesIncrementing(ext, basename, callback);
} else {
this._checkMaxFilesTailable(ext, basename, callback);
}
}
/**
* Gets the next filename to use for this instance in the case that log
* filesizes are being capped.
* @returns {string} - TODO: add return description.
* @private
*/
}, {
key: "_getFile",
value: function _getFile() {
var ext = path.extname(this._basename);
var basename = path.basename(this._basename, ext);
var isRotation = this.rotationFormat ? this.rotationFormat() : this._created; // Caveat emptor (indexzero): rotationFormat() was broken by design When
// combined with max files because the set of files to unlink is never
// stored.
var target = !this.tailable && this._created ? "".concat(basename).concat(isRotation).concat(ext) : "".concat(basename).concat(ext);
return this.zippedArchive && !this.tailable ? "".concat(target, ".gz") : target;
}
/**
* Increment the number of files created or checked by this instance.
* @param {mixed} ext - TODO: add param description.
* @param {mixed} basename - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {undefined}
* @private
*/
}, {
key: "_checkMaxFilesIncrementing",
value: function _checkMaxFilesIncrementing(ext, basename, callback) {
// Check for maxFiles option and delete file.
if (!this.maxFiles || this._created < this.maxFiles) {
return setImmediate(callback);
}
var oldest = this._created - this.maxFiles;
var isOldest = oldest !== 0 ? oldest : '';
var isZipped = this.zippedArchive ? '.gz' : '';
var filePath = "".concat(basename).concat(isOldest).concat(ext).concat(isZipped);
var target = path.join(this.dirname, filePath);
fs.unlink(target, callback);
}
/**
* Roll files forward based on integer, up to maxFiles. e.g. if base if
* file.log and it becomes oversized, roll to file1.log, and allow file.log
* to be re-used. If file is oversized again, roll file1.log to file2.log,
* roll file.log to file1.log, and so on.
* @param {mixed} ext - TODO: add param description.
* @param {mixed} basename - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {undefined}
* @private
*/
}, {
key: "_checkMaxFilesTailable",
value: function _checkMaxFilesTailable(ext, basename, callback) {
var _this12 = this;
var tasks = [];
if (!this.maxFiles) {
return;
} // const isZipped = this.zippedArchive ? '.gz' : '';
var isZipped = this.zippedArchive ? '.gz' : '';
for (var x = this.maxFiles - 1; x > 1; x--) {
tasks.push(function (i, cb) {
var _this11 = this;
var fileName = "".concat(basename).concat(i - 1).concat(ext).concat(isZipped);
var tmppath = path.join(this.dirname, fileName);
fs.exists(tmppath, function (exists) {
if (!exists) {
return cb(null);
}
fileName = "".concat(basename).concat(i).concat(ext).concat(isZipped);
fs.rename(tmppath, path.join(_this11.dirname, fileName), cb);
});
}.bind(this, x));
}
asyncSeries(tasks, function () {
fs.rename(path.join(_this12.dirname, "".concat(basename).concat(ext)), path.join(_this12.dirname, "".concat(basename, "1").concat(ext).concat(isZipped)), callback);
});
}
}, {
key: "_createLogDirIfNotExist",
value: function _createLogDirIfNotExist(dirPath) {
/* eslint-disable no-sync */
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, {
recursive: true
});
}
/* eslint-enable no-sync */
}
}]);
return File;
}(TransportStream);

View File

@ -0,0 +1,264 @@
/**
* http.js: Transport for outputting to a json-rpcserver.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var http = require('http');
var https = require('https');
var _require = require('readable-stream'),
Stream = _require.Stream;
var TransportStream = require('winston-transport');
/**
* Transport for outputting to a json-rpc server.
* @type {Stream}
* @extends {TransportStream}
*/
module.exports = /*#__PURE__*/function (_TransportStream) {
_inherits(Http, _TransportStream);
var _super = _createSuper(Http);
/**
* Constructor function for the Http transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
function Http() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Http);
_this = _super.call(this, options);
_this.options = options;
_this.name = options.name || 'http';
_this.ssl = !!options.ssl;
_this.host = options.host || 'localhost';
_this.port = options.port;
_this.auth = options.auth;
_this.path = options.path || '';
_this.agent = options.agent;
_this.headers = options.headers || {};
_this.headers['content-type'] = 'application/json';
if (!_this.port) {
_this.port = _this.ssl ? 443 : 80;
}
return _this;
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
_createClass(Http, [{
key: "log",
value: function log(info, callback) {
var _this2 = this;
this._request(info, function (err, res) {
if (res && res.statusCode !== 200) {
err = new Error("Invalid HTTP Status Code: ".concat(res.statusCode));
}
if (err) {
_this2.emit('warn', err);
} else {
_this2.emit('logged', info);
}
}); // Remark: (jcrugzz) Fire and forget here so requests dont cause buffering
// and block more requests from happening?
if (callback) {
setImmediate(callback);
}
}
/**
* Query the transport. Options object is optional.
* @param {Object} options - Loggly-like query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
* @returns {undefined}
*/
}, {
key: "query",
value: function query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = {
method: 'query',
params: this.normalizeQuery(options)
};
if (options.params.path) {
options.path = options.params.path;
delete options.params.path;
}
if (options.params.auth) {
options.auth = options.params.auth;
delete options.params.auth;
}
this._request(options, function (err, res, body) {
if (res && res.statusCode !== 200) {
err = new Error("Invalid HTTP Status Code: ".concat(res.statusCode));
}
if (err) {
return callback(err);
}
if (typeof body === 'string') {
try {
body = JSON.parse(body);
} catch (e) {
return callback(e);
}
}
callback(null, body);
});
}
/**
* Returns a log stream for this transport. Options object is optional.
* @param {Object} options - Stream options for this instance.
* @returns {Stream} - TODO: add return description
*/
}, {
key: "stream",
value: function stream() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
var stream = new Stream();
options = {
method: 'stream',
params: options
};
if (options.params.path) {
options.path = options.params.path;
delete options.params.path;
}
if (options.params.auth) {
options.auth = options.params.auth;
delete options.params.auth;
}
var buff = '';
var req = this._request(options);
stream.destroy = function () {
return req.destroy();
};
req.on('data', function (data) {
data = (buff + data).split(/\n+/);
var l = data.length - 1;
var i = 0;
for (; i < l; i++) {
try {
stream.emit('log', JSON.parse(data[i]));
} catch (e) {
stream.emit('error', e);
}
}
buff = data[l];
});
req.on('error', function (err) {
return stream.emit('error', err);
});
return stream;
}
/**
* Make a request to a winstond server or any http server which can
* handle json-rpc.
* @param {function} options - Options to sent the request.
* @param {function} callback - Continuation to respond to when complete.
*/
}, {
key: "_request",
value: function _request(options, callback) {
options = options || {};
var auth = options.auth || this.auth;
var path = options.path || this.path || '';
delete options.auth;
delete options.path; // Prepare options for outgoing HTTP request
var headers = Object.assign({}, this.headers);
if (auth && auth.bearer) {
headers.Authorization = "Bearer ".concat(auth.bearer);
}
var req = (this.ssl ? https : http).request(_objectSpread(_objectSpread({}, this.options), {}, {
method: 'POST',
host: this.host,
port: this.port,
path: "/".concat(path.replace(/^\//, '')),
headers: headers,
auth: auth && auth.username && auth.password ? "".concat(auth.username, ":").concat(auth.password) : '',
agent: this.agent
}));
req.on('error', callback);
req.on('response', function (res) {
return res.on('end', function () {
return callback(null, res);
}).resume();
});
req.end(Buffer.from(JSON.stringify(options), 'utf8'));
}
}]);
return Http;
}(TransportStream);

View File

@ -0,0 +1,55 @@
/**
* transports.js: Set of all transports Winston knows about.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
/**
* TODO: add property description.
* @type {Console}
*/
Object.defineProperty(exports, 'Console', {
configurable: true,
enumerable: true,
get: function get() {
return require('./console');
}
});
/**
* TODO: add property description.
* @type {File}
*/
Object.defineProperty(exports, 'File', {
configurable: true,
enumerable: true,
get: function get() {
return require('./file');
}
});
/**
* TODO: add property description.
* @type {Http}
*/
Object.defineProperty(exports, 'Http', {
configurable: true,
enumerable: true,
get: function get() {
return require('./http');
}
});
/**
* TODO: add property description.
* @type {Stream}
*/
Object.defineProperty(exports, 'Stream', {
configurable: true,
enumerable: true,
get: function get() {
return require('./stream');
}
});

View File

@ -0,0 +1,117 @@
/**
* stream.js: Transport for outputting to any arbitrary stream.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
var isStream = require('is-stream');
var _require = require('triple-beam'),
MESSAGE = _require.MESSAGE;
var os = require('os');
var TransportStream = require('winston-transport');
/**
* Transport for outputting to any arbitrary stream.
* @type {Stream}
* @extends {TransportStream}
*/
module.exports = /*#__PURE__*/function (_TransportStream) {
_inherits(Stream, _TransportStream);
var _super = _createSuper(Stream);
/**
* Constructor function for the Console transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
function Stream() {
var _this;
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
_classCallCheck(this, Stream);
_this = _super.call(this, options);
if (!options.stream || !isStream(options.stream)) {
throw new Error('options.stream is required.');
} // We need to listen for drain events when write() returns false. This can
// make node mad at times.
_this._stream = options.stream;
_this._stream.setMaxListeners(Infinity);
_this.isObjectMode = options.stream._writableState.objectMode;
_this.eol = options.eol || os.EOL;
return _this;
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
_createClass(Stream, [{
key: "log",
value: function log(info, callback) {
var _this2 = this;
setImmediate(function () {
return _this2.emit('logged', info);
});
if (this.isObjectMode) {
this._stream.write(info);
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
this._stream.write("".concat(info[MESSAGE]).concat(this.eol));
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
}]);
return Stream;
}(TransportStream);

193
buildfiles/app/node_modules/winston/index.d.ts generated vendored Normal file
View File

@ -0,0 +1,193 @@
// Type definitions for winston 3.0
// Project: https://github.com/winstonjs/winston
/// <reference types="node" />
import * as NodeJSStream from "stream";
import * as logform from 'logform';
import * as Transport from 'winston-transport';
import * as Config from './lib/winston/config/index';
import * as Transports from './lib/winston/transports/index';
declare namespace winston {
// Hoisted namespaces from other modules
export import format = logform.format;
export import Logform = logform;
export import config = Config;
export import transports = Transports;
export import transport = Transport;
interface ExceptionHandler {
logger: Logger;
handlers: Map<any, any>;
catcher: Function | boolean;
handle(...transports: Transport[]): void;
unhandle(...transports: Transport[]): void;
getAllInfo(err: string | Error): object;
getProcessInfo(): object;
getOsInfo(): object;
getTrace(err: Error): object;
new(logger: Logger): ExceptionHandler;
}
interface QueryOptions {
rows?: number;
limit?: number;
start?: number;
from?: Date;
until?: Date;
order?: "asc" | "desc";
fields: any;
}
interface Profiler {
logger: Logger;
start: Number;
done(info?: any): boolean;
}
type LogCallback = (error?: any, level?: string, message?: string, meta?: any) => void;
interface LogEntry {
level: string;
message: string;
[optionName: string]: any;
}
interface LogMethod {
(level: string, message: string, callback: LogCallback): Logger;
(level: string, message: string, meta: any, callback: LogCallback): Logger;
(level: string, message: string, ...meta: any[]): Logger;
(entry: LogEntry): Logger;
(level: string, message: any): Logger;
}
interface LeveledLogMethod {
(message: string, callback: LogCallback): Logger;
(message: string, meta: any, callback: LogCallback): Logger;
(message: string, ...meta: any[]): Logger;
(message: any): Logger;
(infoObject: object): Logger;
}
interface LoggerOptions {
levels?: Config.AbstractConfigSetLevels;
silent?: boolean;
format?: logform.Format;
level?: string;
exitOnError?: Function | boolean;
defaultMeta?: any;
transports?: Transport[] | Transport;
handleExceptions?: boolean;
exceptionHandlers?: any;
}
interface Logger extends NodeJSStream.Transform {
silent: boolean;
format: logform.Format;
levels: Config.AbstractConfigSetLevels;
level: string;
transports: Transport[];
exceptions: ExceptionHandler;
profilers: object;
exitOnError: Function | boolean;
defaultMeta?: any;
log: LogMethod;
add(transport: Transport): Logger;
remove(transport: Transport): Logger;
clear(): Logger;
close(): Logger;
// for cli and npm levels
error: LeveledLogMethod;
warn: LeveledLogMethod;
help: LeveledLogMethod;
data: LeveledLogMethod;
info: LeveledLogMethod;
debug: LeveledLogMethod;
prompt: LeveledLogMethod;
http: LeveledLogMethod;
verbose: LeveledLogMethod;
input: LeveledLogMethod;
silly: LeveledLogMethod;
// for syslog levels only
emerg: LeveledLogMethod;
alert: LeveledLogMethod;
crit: LeveledLogMethod;
warning: LeveledLogMethod;
notice: LeveledLogMethod;
query(options?: QueryOptions, callback?: (err: Error, results: any) => void): any;
stream(options?: any): NodeJS.ReadableStream;
startTimer(): Profiler;
profile(id: string | number, meta?: LogEntry): Logger;
configure(options: LoggerOptions): void;
child(options: Object): Logger;
isLevelEnabled(level: string): boolean;
isErrorEnabled(): boolean;
isWarnEnabled(): boolean;
isInfoEnabled(): boolean;
isVerboseEnabled(): boolean;
isDebugEnabled(): boolean;
isSillyEnabled(): boolean;
new(options?: LoggerOptions): Logger;
}
interface Container {
loggers: Map<string, Logger>;
options: LoggerOptions;
add(id: string, options?: LoggerOptions): Logger;
get(id: string, options?: LoggerOptions): Logger;
has(id: string): boolean;
close(id?: string): void;
new(options?: LoggerOptions): Container;
}
let version: string;
let ExceptionHandler: ExceptionHandler;
let Container: Container;
let loggers: Container;
let addColors: (target: Config.AbstractConfigSetColors) => any;
let createLogger: (options?: LoggerOptions) => Logger;
// Pass-through npm level methods routed to the default logger.
let error: LeveledLogMethod;
let warn: LeveledLogMethod;
let info: LeveledLogMethod;
let http: LeveledLogMethod;
let verbose: LeveledLogMethod;
let debug: LeveledLogMethod;
let silly: LeveledLogMethod;
// Other pass-through methods routed to the default logger.
let log: LogMethod;
let query: (options?: QueryOptions, callback?: (err: Error, results: any) => void) => any;
let stream: (options?: any) => NodeJS.ReadableStream;
let add: (transport: Transport) => Logger;
let remove: (transport: Transport) => Logger;
let clear: () => Logger;
let startTimer: () => Profiler;
let profile: (id: string | number) => Logger;
let configure: (options: LoggerOptions) => void;
let child: (options: Object) => Logger;
let level: string;
let exceptions: ExceptionHandler;
let exitOnError: Function | boolean;
// let default: object;
}
export = winston;

182
buildfiles/app/node_modules/winston/lib/winston.js generated vendored Normal file
View File

@ -0,0 +1,182 @@
/**
* winston.js: Top-level include defining Winston.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const logform = require('logform');
const { warn } = require('./winston/common');
/**
* Setup to expose.
* @type {Object}
*/
const winston = exports;
/**
* Expose version. Use `require` method for `webpack` support.
* @type {string}
*/
winston.version = require('../package.json').version;
/**
* Include transports defined by default by winston
* @type {Array}
*/
winston.transports = require('./winston/transports');
/**
* Expose utility methods
* @type {Object}
*/
winston.config = require('./winston/config');
/**
* Hoist format-related functionality from logform.
* @type {Object}
*/
winston.addColors = logform.levels;
/**
* Hoist format-related functionality from logform.
* @type {Object}
*/
winston.format = logform.format;
/**
* Expose core Logging-related prototypes.
* @type {function}
*/
winston.createLogger = require('./winston/create-logger');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.ExceptionHandler = require('./winston/exception-handler');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.RejectionHandler = require('./winston/rejection-handler');
/**
* Expose core Logging-related prototypes.
* @type {Container}
*/
winston.Container = require('./winston/container');
/**
* Expose core Logging-related prototypes.
* @type {Object}
*/
winston.Transport = require('winston-transport');
/**
* We create and expose a default `Container` to `winston.loggers` so that the
* programmer may manage multiple `winston.Logger` instances without any
* additional overhead.
* @example
* // some-file1.js
* const logger = require('winston').loggers.get('something');
*
* // some-file2.js
* const logger = require('winston').loggers.get('something');
*/
winston.loggers = new winston.Container();
/**
* We create and expose a 'defaultLogger' so that the programmer may do the
* following without the need to create an instance of winston.Logger directly:
* @example
* const winston = require('winston');
* winston.log('info', 'some message');
* winston.error('some error');
*/
const defaultLogger = winston.createLogger();
// Pass through the target methods onto `winston.
Object.keys(winston.config.npm.levels)
.concat([
'log',
'query',
'stream',
'add',
'remove',
'clear',
'profile',
'startTimer',
'handleExceptions',
'unhandleExceptions',
'handleRejections',
'unhandleRejections',
'configure',
'child'
])
.forEach(
method => (winston[method] = (...args) => defaultLogger[method](...args))
);
/**
* Define getter / setter for the default logger level which need to be exposed
* by winston.
* @type {string}
*/
Object.defineProperty(winston, 'level', {
get() {
return defaultLogger.level;
},
set(val) {
defaultLogger.level = val;
}
});
/**
* Define getter for `exceptions` which replaces `handleExceptions` and
* `unhandleExceptions`.
* @type {Object}
*/
Object.defineProperty(winston, 'exceptions', {
get() {
return defaultLogger.exceptions;
}
});
/**
* Define getters / setters for appropriate properties of the default logger
* which need to be exposed by winston.
* @type {Logger}
*/
['exitOnError'].forEach(prop => {
Object.defineProperty(winston, prop, {
get() {
return defaultLogger[prop];
},
set(val) {
defaultLogger[prop] = val;
}
});
});
/**
* The default transports and exceptionHandlers for the default winston logger.
* @type {Object}
*/
Object.defineProperty(winston, 'default', {
get() {
return {
exceptionHandlers: defaultLogger.exceptionHandlers,
rejectionHandlers: defaultLogger.rejectionHandlers,
transports: defaultLogger.transports
};
}
});
// Have friendlier breakage notices for properties that were exposed by default
// on winston < 3.0.
warn.deprecated(winston, 'setLevels');
warn.forFunctions(winston, 'useFormat', ['cli']);
warn.forProperties(winston, 'useFormat', ['padLevels', 'stripColors']);
warn.forFunctions(winston, 'deprecated', [
'addRewriter',
'addFilter',
'clone',
'extend'
]);
warn.forProperties(winston, 'deprecated', ['emitErrs', 'levelLength']);
// Throw a useful error when users attempt to run `new winston.Logger`.
warn.moved(winston, 'createLogger', 'Logger');

View File

@ -0,0 +1,61 @@
/**
* common.js: Internal helper and utility functions for winston.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const { format } = require('util');
/**
* Set of simple deprecation notices and a way to expose them for a set of
* properties.
* @type {Object}
* @private
*/
exports.warn = {
deprecated(prop) {
return () => {
throw new Error(format('{ %s } was removed in winston@3.0.0.', prop));
};
},
useFormat(prop) {
return () => {
throw new Error([
format('{ %s } was removed in winston@3.0.0.', prop),
'Use a custom winston.format = winston.format(function) instead.'
].join('\n'));
};
},
forFunctions(obj, type, props) {
props.forEach(prop => {
obj[prop] = exports.warn[type](prop);
});
},
moved(obj, movedTo, prop) {
function movedNotice() {
return () => {
throw new Error([
format('winston.%s was moved in winston@3.0.0.', prop),
format('Use a winston.%s instead.', movedTo)
].join('\n'));
};
}
Object.defineProperty(obj, prop, {
get: movedNotice,
set: movedNotice
});
},
forProperties(obj, type, props) {
props.forEach(prop => {
const notice = exports.warn[type](prop);
Object.defineProperty(obj, prop, {
get: notice,
set: notice
});
});
}
};

View File

@ -0,0 +1,98 @@
// Type definitions for winston 3.0
// Project: https://github.com/winstonjs/winston
/// <reference types="node" />
declare namespace winston {
interface AbstractConfigSetLevels {
[key: string]: number;
}
interface AbstractConfigSetColors {
[key: string]: string | string[];
}
interface AbstractConfigSet {
levels: AbstractConfigSetLevels;
colors: AbstractConfigSetColors;
}
interface CliConfigSetLevels extends AbstractConfigSetLevels {
error: number;
warn: number;
help: number;
data: number;
info: number;
debug: number;
prompt: number;
verbose: number;
input: number;
silly: number;
}
interface CliConfigSetColors extends AbstractConfigSetColors {
error: string | string[];
warn: string | string[];
help: string | string[];
data: string | string[];
info: string | string[];
debug: string | string[];
prompt: string | string[];
verbose: string | string[];
input: string | string[];
silly: string | string[];
}
interface NpmConfigSetLevels extends AbstractConfigSetLevels {
error: number;
warn: number;
info: number;
http: number;
verbose: number;
debug: number;
silly: number;
}
interface NpmConfigSetColors extends AbstractConfigSetColors {
error: string | string[];
warn: string | string[];
info: string | string[];
verbose: string | string[];
debug: string | string[];
silly: string | string[];
}
interface SyslogConfigSetLevels extends AbstractConfigSetLevels {
emerg: number;
alert: number;
crit: number;
error: number;
warning: number;
notice: number;
info: number;
debug: number;
}
interface SyslogConfigSetColors extends AbstractConfigSetColors {
emerg: string | string[];
alert: string | string[];
crit: string | string[];
error: string | string[];
warning: string | string[];
notice: string | string[];
info: string | string[];
debug: string | string[];
}
interface Config {
allColors: AbstractConfigSetColors;
cli: { levels: CliConfigSetLevels, colors: CliConfigSetColors };
npm: { levels: NpmConfigSetLevels, colors: NpmConfigSetColors };
syslog: { levels: SyslogConfigSetLevels, colors: SyslogConfigSetColors };
addColors(colors: AbstractConfigSetColors): void;
}
}
declare const winston: winston.Config;
export = winston;

View File

@ -0,0 +1,35 @@
/**
* index.js: Default settings for all levels that winston knows about.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const logform = require('logform');
const { configs } = require('triple-beam');
/**
* Export config set for the CLI.
* @type {Object}
*/
exports.cli = logform.levels(configs.cli);
/**
* Export config set for npm.
* @type {Object}
*/
exports.npm = logform.levels(configs.npm);
/**
* Export config set for the syslog.
* @type {Object}
*/
exports.syslog = logform.levels(configs.syslog);
/**
* Hoist addColors from logform where it was refactored into in winston@3.
* @type {Object}
*/
exports.addColors = logform.levels;

View File

@ -0,0 +1,114 @@
/**
* container.js: Inversion of control container for winston logger instances.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const createLogger = require('./create-logger');
/**
* Inversion of control container for winston logger instances.
* @type {Container}
*/
module.exports = class Container {
/**
* Constructor function for the Container object responsible for managing a
* set of `winston.Logger` instances based on string ids.
* @param {!Object} [options={}] - Default pass-thru options for Loggers.
*/
constructor(options = {}) {
this.loggers = new Map();
this.options = options;
}
/**
* Retreives a `winston.Logger` instance for the specified `id`. If an
* instance does not exist, one is created.
* @param {!string} id - The id of the Logger to get.
* @param {?Object} [options] - Options for the Logger instance.
* @returns {Logger} - A configured Logger instance with a specified id.
*/
add(id, options) {
if (!this.loggers.has(id)) {
// Remark: Simple shallow clone for configuration options in case we pass
// in instantiated protoypal objects
options = Object.assign({}, options || this.options);
const existing = options.transports || this.options.transports;
// Remark: Make sure if we have an array of transports we slice it to
// make copies of those references.
options.transports = existing ? existing.slice() : [];
const logger = createLogger(options);
logger.on('close', () => this._delete(id));
this.loggers.set(id, logger);
}
return this.loggers.get(id);
}
/**
* Retreives a `winston.Logger` instance for the specified `id`. If
* an instance does not exist, one is created.
* @param {!string} id - The id of the Logger to get.
* @param {?Object} [options] - Options for the Logger instance.
* @returns {Logger} - A configured Logger instance with a specified id.
*/
get(id, options) {
return this.add(id, options);
}
/**
* Check if the container has a logger with the id.
* @param {?string} id - The id of the Logger instance to find.
* @returns {boolean} - Boolean value indicating if this instance has a
* logger with the specified `id`.
*/
has(id) {
return !!this.loggers.has(id);
}
/**
* Closes a `Logger` instance with the specified `id` if it exists.
* If no `id` is supplied then all Loggers are closed.
* @param {?string} id - The id of the Logger instance to close.
* @returns {undefined}
*/
close(id) {
if (id) {
return this._removeLogger(id);
}
this.loggers.forEach((val, key) => this._removeLogger(key));
}
/**
* Remove a logger based on the id.
* @param {!string} id - The id of the logger to remove.
* @returns {undefined}
* @private
*/
_removeLogger(id) {
if (!this.loggers.has(id)) {
return;
}
const logger = this.loggers.get(id);
logger.close();
this._delete(id);
}
/**
* Deletes a `Logger` instance with the specified `id`.
* @param {!string} id - The id of the Logger instance to delete from
* container.
* @returns {undefined}
* @private
*/
_delete(id) {
this.loggers.delete(id);
}
};

View File

@ -0,0 +1,104 @@
/**
* create-logger.js: Logger factory for winston logger instances.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const { LEVEL } = require('triple-beam');
const config = require('./config');
const Logger = require('./logger');
const debug = require('@dabh/diagnostics')('winston:create-logger');
function isLevelEnabledFunctionName(level) {
return 'is' + level.charAt(0).toUpperCase() + level.slice(1) + 'Enabled';
}
/**
* Create a new instance of a winston Logger. Creates a new
* prototype for each instance.
* @param {!Object} opts - Options for the created logger.
* @returns {Logger} - A newly created logger instance.
*/
module.exports = function (opts = {}) {
//
// Default levels: npm
//
opts.levels = opts.levels || config.npm.levels;
/**
* DerivedLogger to attach the logs level methods.
* @type {DerivedLogger}
* @extends {Logger}
*/
class DerivedLogger extends Logger {
/**
* Create a new class derived logger for which the levels can be attached to
* the prototype of. This is a V8 optimization that is well know to increase
* performance of prototype functions.
* @param {!Object} options - Options for the created logger.
*/
constructor(options) {
super(options);
}
}
const logger = new DerivedLogger(opts);
//
// Create the log level methods for the derived logger.
//
Object.keys(opts.levels).forEach(function (level) {
debug('Define prototype method for "%s"', level);
if (level === 'log') {
// eslint-disable-next-line no-console
console.warn('Level "log" not defined: conflicts with the method "log". Use a different level name.');
return;
}
//
// Define prototype methods for each log level e.g.:
// logger.log('info', msg) implies these methods are defined:
// - logger.info(msg)
// - logger.isInfoEnabled()
//
// Remark: to support logger.child this **MUST** be a function
// so it'll always be called on the instance instead of a fixed
// place in the prototype chain.
//
DerivedLogger.prototype[level] = function (...args) {
// Prefer any instance scope, but default to "root" logger
const self = this || logger;
// Optimize the hot-path which is the single object.
if (args.length === 1) {
const [msg] = args;
const info = msg && msg.message && msg || { message: msg };
info.level = info[LEVEL] = level;
self._addDefaultMeta(info);
self.write(info);
return (this || logger);
}
// When provided nothing assume the empty string
if (args.length === 0) {
self.log(level, '');
return self;
}
// Otherwise build argument list which could potentially conform to
// either:
// . v3 API: log(obj)
// 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
return self.log(level, ...args);
};
DerivedLogger.prototype[isLevelEnabledFunctionName(level)] = function () {
return (this || logger).isLevelEnabled(level);
};
});
return logger;
};

View File

@ -0,0 +1,245 @@
/**
* exception-handler.js: Object for handling uncaughtException events.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const os = require('os');
const asyncForEach = require('async/forEach');
const debug = require('@dabh/diagnostics')('winston:exception');
const once = require('one-time');
const stackTrace = require('stack-trace');
const ExceptionStream = require('./exception-stream');
/**
* Object for handling uncaughtException events.
* @type {ExceptionHandler}
*/
module.exports = class ExceptionHandler {
/**
* TODO: add contructor description
* @param {!Logger} logger - TODO: add param description
*/
constructor(logger) {
if (!logger) {
throw new Error('Logger is required to handle exceptions');
}
this.logger = logger;
this.handlers = new Map();
}
/**
* Handles `uncaughtException` events for the current process by adding any
* handlers passed in.
* @returns {undefined}
*/
handle(...args) {
args.forEach(arg => {
if (Array.isArray(arg)) {
return arg.forEach(handler => this._addHandler(handler));
}
this._addHandler(arg);
});
if (!this.catcher) {
this.catcher = this._uncaughtException.bind(this);
process.on('uncaughtException', this.catcher);
}
}
/**
* Removes any handlers to `uncaughtException` events for the current
* process. This does not modify the state of the `this.handlers` set.
* @returns {undefined}
*/
unhandle() {
if (this.catcher) {
process.removeListener('uncaughtException', this.catcher);
this.catcher = false;
Array.from(this.handlers.values())
.forEach(wrapper => this.logger.unpipe(wrapper));
}
}
/**
* TODO: add method description
* @param {Error} err - Error to get information about.
* @returns {mixed} - TODO: add return description.
*/
getAllInfo(err) {
let { message } = err;
if (!message && typeof err === 'string') {
message = err;
}
return {
error: err,
// TODO (indexzero): how do we configure this?
level: 'error',
message: [
`uncaughtException: ${(message || '(no error message)')}`,
err.stack || ' No stack trace'
].join('\n'),
stack: err.stack,
exception: true,
date: new Date().toString(),
process: this.getProcessInfo(),
os: this.getOsInfo(),
trace: this.getTrace(err)
};
}
/**
* Gets all relevant process information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
getProcessInfo() {
return {
pid: process.pid,
uid: process.getuid ? process.getuid() : null,
gid: process.getgid ? process.getgid() : null,
cwd: process.cwd(),
execPath: process.execPath,
version: process.version,
argv: process.argv,
memoryUsage: process.memoryUsage()
};
}
/**
* Gets all relevant OS information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
getOsInfo() {
return {
loadavg: os.loadavg(),
uptime: os.uptime()
};
}
/**
* Gets a stack trace for the specified error.
* @param {mixed} err - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
getTrace(err) {
const trace = err ? stackTrace.parse(err) : stackTrace.get();
return trace.map(site => {
return {
column: site.getColumnNumber(),
file: site.getFileName(),
function: site.getFunctionName(),
line: site.getLineNumber(),
method: site.getMethodName(),
native: site.isNative()
};
});
}
/**
* Helper method to add a transport as an exception handler.
* @param {Transport} handler - The transport to add as an exception handler.
* @returns {void}
*/
_addHandler(handler) {
if (!this.handlers.has(handler)) {
handler.handleExceptions = true;
const wrapper = new ExceptionStream(handler);
this.handlers.set(handler, wrapper);
this.logger.pipe(wrapper);
}
}
/**
* Logs all relevant information around the `err` and exits the current
* process.
* @param {Error} err - Error to handle
* @returns {mixed} - TODO: add return description.
* @private
*/
_uncaughtException(err) {
const info = this.getAllInfo(err);
const handlers = this._getExceptionHandlers();
// Calculate if we should exit on this error
let doExit = typeof this.logger.exitOnError === 'function'
? this.logger.exitOnError(err)
: this.logger.exitOnError;
let timeout;
if (!handlers.length && doExit) {
// eslint-disable-next-line no-console
console.warn('winston: exitOnError cannot be true with no exception handlers.');
// eslint-disable-next-line no-console
console.warn('winston: not exiting process.');
doExit = false;
}
function gracefulExit() {
debug('doExit', doExit);
debug('process._exiting', process._exiting);
if (doExit && !process._exiting) {
// Remark: Currently ignoring any exceptions from transports when
// catching uncaught exceptions.
if (timeout) {
clearTimeout(timeout);
}
// eslint-disable-next-line no-process-exit
process.exit(1);
}
}
if (!handlers || handlers.length === 0) {
return process.nextTick(gracefulExit);
}
// Log to all transports attempting to listen for when they are completed.
asyncForEach(handlers, (handler, next) => {
const done = once(next);
const transport = handler.transport || handler;
// Debug wrapping so that we can inspect what's going on under the covers.
function onDone(event) {
return () => {
debug(event);
done();
};
}
transport._ending = true;
transport.once('finish', onDone('finished'));
transport.once('error', onDone('error'));
}, () => doExit && gracefulExit());
this.logger.log(info);
// If exitOnError is true, then only allow the logging of exceptions to
// take up to `3000ms`.
if (doExit) {
timeout = setTimeout(gracefulExit, 3000);
}
}
/**
* Returns the list of transports and exceptionHandlers for this instance.
* @returns {Array} - List of transports and exceptionHandlers for this
* instance.
* @private
*/
_getExceptionHandlers() {
// Remark (indexzero): since `logger.transports` returns all of the pipes
// from the _readableState of the stream we actually get the join of the
// explicit handlers and the implicit transports with
// `handleExceptions: true`
return this.logger.transports.filter(wrap => {
const transport = wrap.transport || wrap;
return transport.handleExceptions;
});
}
};

View File

@ -0,0 +1,54 @@
/**
* exception-stream.js: TODO: add file header handler.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const { Writable } = require('readable-stream');
/**
* TODO: add class description.
* @type {ExceptionStream}
* @extends {Writable}
*/
module.exports = class ExceptionStream extends Writable {
/**
* Constructor function for the ExceptionStream responsible for wrapping a
* TransportStream; only allowing writes of `info` objects with
* `info.exception` set to true.
* @param {!TransportStream} transport - Stream to filter to exceptions
*/
constructor(transport) {
super({ objectMode: true });
if (!transport) {
throw new Error('ExceptionStream requires a TransportStream instance.');
}
// Remark (indexzero): we set `handleExceptions` here because it's the
// predicate checked in ExceptionHandler.prototype.__getExceptionHandlers
this.handleExceptions = true;
this.transport = transport;
}
/**
* Writes the info object to our transport instance if (and only if) the
* `exception` property is set on the info.
* @param {mixed} info - TODO: add param description.
* @param {mixed} enc - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {mixed} - TODO: add return description.
* @private
*/
_write(info, enc, callback) {
if (info.exception) {
return this.transport.log(info, callback);
}
callback();
return true;
}
};

View File

@ -0,0 +1,667 @@
/**
* logger.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const { Stream, Transform } = require('readable-stream');
const asyncForEach = require('async/forEach');
const { LEVEL, SPLAT } = require('triple-beam');
const isStream = require('is-stream');
const ExceptionHandler = require('./exception-handler');
const RejectionHandler = require('./rejection-handler');
const LegacyTransportStream = require('winston-transport/legacy');
const Profiler = require('./profiler');
const { warn } = require('./common');
const config = require('./config');
/**
* Captures the number of format (i.e. %s strings) in a given string.
* Based on `util.format`, see Node.js source:
* https://github.com/nodejs/node/blob/b1c8f15c5f169e021f7c46eb7b219de95fe97603/lib/util.js#L201-L230
* @type {RegExp}
*/
const formatRegExp = /%[scdjifoO%]/g;
/**
* TODO: add class description.
* @type {Logger}
* @extends {Transform}
*/
class Logger extends Transform {
/**
* Constructor function for the Logger object responsible for persisting log
* messages and metadata to one or more transports.
* @param {!Object} options - foo
*/
constructor(options) {
super({ objectMode: true });
this.configure(options);
}
child(defaultRequestMetadata) {
const logger = this;
return Object.create(logger, {
write: {
value: function (info) {
const infoClone = Object.assign(
{},
defaultRequestMetadata,
info
);
// Object.assign doesn't copy inherited Error
// properties so we have to do that explicitly
//
// Remark (indexzero): we should remove this
// since the errors format will handle this case.
//
if (info instanceof Error) {
infoClone.stack = info.stack;
infoClone.message = info.message;
}
logger.write(infoClone);
}
}
});
}
/**
* This will wholesale reconfigure this instance by:
* 1. Resetting all transports. Older transports will be removed implicitly.
* 2. Set all other options including levels, colors, rewriters, filters,
* exceptionHandlers, etc.
* @param {!Object} options - TODO: add param description.
* @returns {undefined}
*/
configure({
silent,
format,
defaultMeta,
levels,
level = 'info',
exitOnError = true,
transports,
colors,
emitErrs,
formatters,
padLevels,
rewriters,
stripColors,
exceptionHandlers,
rejectionHandlers
} = {}) {
// Reset transports if we already have them
if (this.transports.length) {
this.clear();
}
this.silent = silent;
this.format = format || this.format || require('logform/json')();
this.defaultMeta = defaultMeta || null;
// Hoist other options onto this instance.
this.levels = levels || this.levels || config.npm.levels;
this.level = level;
this.exceptions = new ExceptionHandler(this);
this.rejections = new RejectionHandler(this);
this.profilers = {};
this.exitOnError = exitOnError;
// Add all transports we have been provided.
if (transports) {
transports = Array.isArray(transports) ? transports : [transports];
transports.forEach(transport => this.add(transport));
}
if (
colors ||
emitErrs ||
formatters ||
padLevels ||
rewriters ||
stripColors
) {
throw new Error(
[
'{ colors, emitErrs, formatters, padLevels, rewriters, stripColors } were removed in winston@3.0.0.',
'Use a custom winston.format(function) instead.',
'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'
].join('\n')
);
}
if (exceptionHandlers) {
this.exceptions.handle(exceptionHandlers);
}
if (rejectionHandlers) {
this.rejections.handle(rejectionHandlers);
}
}
isLevelEnabled(level) {
const givenLevelValue = getLevelValue(this.levels, level);
if (givenLevelValue === null) {
return false;
}
const configuredLevelValue = getLevelValue(this.levels, this.level);
if (configuredLevelValue === null) {
return false;
}
if (!this.transports || this.transports.length === 0) {
return configuredLevelValue >= givenLevelValue;
}
const index = this.transports.findIndex(transport => {
let transportLevelValue = getLevelValue(this.levels, transport.level);
if (transportLevelValue === null) {
transportLevelValue = configuredLevelValue;
}
return transportLevelValue >= givenLevelValue;
});
return index !== -1;
}
/* eslint-disable valid-jsdoc */
/**
* Ensure backwards compatibility with a `log` method
* @param {mixed} level - Level the log message is written at.
* @param {mixed} msg - TODO: add param description.
* @param {mixed} meta - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*
* @example
* // Supports the existing API:
* logger.log('info', 'Hello world', { custom: true });
* logger.log('info', new Error('Yo, it\'s on fire'));
*
* // Requires winston.format.splat()
* logger.log('info', '%s %d%%', 'A string', 50, { thisIsMeta: true });
*
* // And the new API with a single JSON literal:
* logger.log({ level: 'info', message: 'Hello world', custom: true });
* logger.log({ level: 'info', message: new Error('Yo, it\'s on fire') });
*
* // Also requires winston.format.splat()
* logger.log({
* level: 'info',
* message: '%s %d%%',
* [SPLAT]: ['A string', 50],
* meta: { thisIsMeta: true }
* });
*
*/
/* eslint-enable valid-jsdoc */
log(level, msg, ...splat) {
// eslint-disable-line max-params
// Optimize for the hotpath of logging JSON literals
if (arguments.length === 1) {
// Yo dawg, I heard you like levels ... seriously ...
// In this context the LHS `level` here is actually the `info` so read
// this as: info[LEVEL] = info.level;
level[LEVEL] = level.level;
this._addDefaultMeta(level);
this.write(level);
return this;
}
// Slightly less hotpath, but worth optimizing for.
if (arguments.length === 2) {
if (msg && typeof msg === 'object') {
msg[LEVEL] = msg.level = level;
this._addDefaultMeta(msg);
this.write(msg);
return this;
}
this.write({ [LEVEL]: level, level, message: msg });
return this;
}
const [meta] = splat;
if (typeof meta === 'object' && meta !== null) {
// Extract tokens, if none available default to empty array to
// ensure consistancy in expected results
const tokens = msg && msg.match && msg.match(formatRegExp);
if (!tokens) {
const info = Object.assign({}, this.defaultMeta, meta, {
[LEVEL]: level,
[SPLAT]: splat,
level,
message: msg
});
if (meta.message) info.message = `${info.message} ${meta.message}`;
if (meta.stack) info.stack = meta.stack;
this.write(info);
return this;
}
}
this.write(Object.assign({}, this.defaultMeta, {
[LEVEL]: level,
[SPLAT]: splat,
level,
message: msg
}));
return this;
}
/**
* Pushes data so that it can be picked up by all of our pipe targets.
* @param {mixed} info - TODO: add param description.
* @param {mixed} enc - TODO: add param description.
* @param {mixed} callback - Continues stream processing.
* @returns {undefined}
* @private
*/
_transform(info, enc, callback) {
if (this.silent) {
return callback();
}
// [LEVEL] is only soft guaranteed to be set here since we are a proper
// stream. It is likely that `info` came in through `.log(info)` or
// `.info(info)`. If it is not defined, however, define it.
// This LEVEL symbol is provided by `triple-beam` and also used in:
// - logform
// - winston-transport
// - abstract-winston-transport
if (!info[LEVEL]) {
info[LEVEL] = info.level;
}
// Remark: really not sure what to do here, but this has been reported as
// very confusing by pre winston@2.0.0 users as quite confusing when using
// custom levels.
if (!this.levels[info[LEVEL]] && this.levels[info[LEVEL]] !== 0) {
// eslint-disable-next-line no-console
console.error('[winston] Unknown logger level: %s', info[LEVEL]);
}
// Remark: not sure if we should simply error here.
if (!this._readableState.pipes) {
// eslint-disable-next-line no-console
console.error(
'[winston] Attempt to write logs with no transports %j',
info
);
}
// Here we write to the `format` pipe-chain, which on `readable` above will
// push the formatted `info` Object onto the buffer for this instance. We trap
// (and re-throw) any errors generated by the user-provided format, but also
// guarantee that the streams callback is invoked so that we can continue flowing.
try {
this.push(this.format.transform(info, this.format.options));
} catch (ex) {
throw ex;
} finally {
// eslint-disable-next-line callback-return
callback();
}
}
/**
* Delays the 'finish' event until all transport pipe targets have
* also emitted 'finish' or are already finished.
* @param {mixed} callback - Continues stream processing.
*/
_final(callback) {
const transports = this.transports.slice();
asyncForEach(
transports,
(transport, next) => {
if (!transport || transport.finished) return setImmediate(next);
transport.once('finish', next);
transport.end();
},
callback
);
}
/**
* Adds the transport to this logger instance by piping to it.
* @param {mixed} transport - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*/
add(transport) {
// Support backwards compatibility with all existing `winston < 3.x.x`
// transports which meet one of two criteria:
// 1. They inherit from winston.Transport in < 3.x.x which is NOT a stream.
// 2. They expose a log method which has a length greater than 2 (i.e. more then
// just `log(info, callback)`.
const target =
!isStream(transport) || transport.log.length > 2
? new LegacyTransportStream({ transport })
: transport;
if (!target._writableState || !target._writableState.objectMode) {
throw new Error(
'Transports must WritableStreams in objectMode. Set { objectMode: true }.'
);
}
// Listen for the `error` event and the `warn` event on the new Transport.
this._onEvent('error', target);
this._onEvent('warn', target);
this.pipe(target);
if (transport.handleExceptions) {
this.exceptions.handle();
}
if (transport.handleRejections) {
this.rejections.handle();
}
return this;
}
/**
* Removes the transport from this logger instance by unpiping from it.
* @param {mixed} transport - TODO: add param description.
* @returns {Logger} - TODO: add return description.
*/
remove(transport) {
if (!transport) return this;
let target = transport;
if (!isStream(transport) || transport.log.length > 2) {
target = this.transports.filter(
match => match.transport === transport
)[0];
}
if (target) {
this.unpipe(target);
}
return this;
}
/**
* Removes all transports from this logger instance.
* @returns {Logger} - TODO: add return description.
*/
clear() {
this.unpipe();
return this;
}
/**
* Cleans up resources (streams, event listeners) for all transports
* associated with this instance (if necessary).
* @returns {Logger} - TODO: add return description.
*/
close() {
this.clear();
this.emit('close');
return this;
}
/**
* Sets the `target` levels specified on this instance.
* @param {Object} Target levels to use on this instance.
*/
setLevels() {
warn.deprecated('setLevels');
}
/**
* Queries the all transports for this instance with the specified `options`.
* This will aggregate each transport's results into one object containing
* a property per transport.
* @param {Object} options - Query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
*/
query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = options || {};
const results = {};
const queryObject = Object.assign({}, options.query || {});
// Helper function to query a single transport
function queryTransport(transport, next) {
if (options.query && typeof transport.formatQuery === 'function') {
options.query = transport.formatQuery(queryObject);
}
transport.query(options, (err, res) => {
if (err) {
return next(err);
}
if (typeof transport.formatResults === 'function') {
res = transport.formatResults(res, options.format);
}
next(null, res);
});
}
// Helper function to accumulate the results from `queryTransport` into
// the `results`.
function addResults(transport, next) {
queryTransport(transport, (err, result) => {
// queryTransport could potentially invoke the callback multiple times
// since Transport code can be unpredictable.
if (next) {
result = err || result;
if (result) {
results[transport.name] = result;
}
// eslint-disable-next-line callback-return
next();
}
next = null;
});
}
// Iterate over the transports in parallel setting the appropriate key in
// the `results`.
asyncForEach(
this.transports.filter(transport => !!transport.query),
addResults,
() => callback(null, results)
);
}
/**
* Returns a log stream for all transports. Options object is optional.
* @param{Object} options={} - Stream options for this instance.
* @returns {Stream} - TODO: add return description.
*/
stream(options = {}) {
const out = new Stream();
const streams = [];
out._streams = streams;
out.destroy = () => {
let i = streams.length;
while (i--) {
streams[i].destroy();
}
};
// Create a list of all transports for this instance.
this.transports
.filter(transport => !!transport.stream)
.forEach(transport => {
const str = transport.stream(options);
if (!str) {
return;
}
streams.push(str);
str.on('log', log => {
log.transport = log.transport || [];
log.transport.push(transport.name);
out.emit('log', log);
});
str.on('error', err => {
err.transport = err.transport || [];
err.transport.push(transport.name);
out.emit('error', err);
});
});
return out;
}
/**
* Returns an object corresponding to a specific timing. When done is called
* the timer will finish and log the duration. e.g.:
* @returns {Profile} - TODO: add return description.
* @example
* const timer = winston.startTimer()
* setTimeout(() => {
* timer.done({
* message: 'Logging message'
* });
* }, 1000);
*/
startTimer() {
return new Profiler(this);
}
/**
* Tracks the time inbetween subsequent calls to this method with the same
* `id` parameter. The second call to this method will log the difference in
* milliseconds along with the message.
* @param {string} id Unique id of the profiler
* @returns {Logger} - TODO: add return description.
*/
profile(id, ...args) {
const time = Date.now();
if (this.profilers[id]) {
const timeEnd = this.profilers[id];
delete this.profilers[id];
// Attempt to be kind to users if they are still using older APIs.
if (typeof args[args.length - 2] === 'function') {
// eslint-disable-next-line no-console
console.warn(
'Callback function no longer supported as of winston@3.0.0'
);
args.pop();
}
// Set the duration property of the metadata
const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = time - timeEnd;
info.message = info.message || id;
return this.write(info);
}
this.profilers[id] = time;
return this;
}
/**
* Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
* @returns {undefined}
* @deprecated
*/
handleExceptions(...args) {
// eslint-disable-next-line no-console
console.warn(
'Deprecated: .handleExceptions() will be removed in winston@4. Use .exceptions.handle()'
);
this.exceptions.handle(...args);
}
/**
* Backwards compatibility to `exceptions.handle` in winston < 3.0.0.
* @returns {undefined}
* @deprecated
*/
unhandleExceptions(...args) {
// eslint-disable-next-line no-console
console.warn(
'Deprecated: .unhandleExceptions() will be removed in winston@4. Use .exceptions.unhandle()'
);
this.exceptions.unhandle(...args);
}
/**
* Throw a more meaningful deprecation notice
* @throws {Error} - TODO: add throws description.
*/
cli() {
throw new Error(
[
'Logger.cli() was removed in winston@3.0.0',
'Use a custom winston.formats.cli() instead.',
'See: https://github.com/winstonjs/winston/tree/master/UPGRADE-3.0.md'
].join('\n')
);
}
/**
* Bubbles the `event` that occured on the specified `transport` up
* from this instance.
* @param {string} event - The event that occured
* @param {Object} transport - Transport on which the event occured
* @private
*/
_onEvent(event, transport) {
function transportEvent(err) {
// https://github.com/winstonjs/winston/issues/1364
if (event === 'error' && !this.transports.includes(transport)) {
this.add(transport);
}
this.emit(event, err, transport);
}
if (!transport['__winston' + event]) {
transport['__winston' + event] = transportEvent.bind(this);
transport.on(event, transport['__winston' + event]);
}
}
_addDefaultMeta(msg) {
if (this.defaultMeta) {
Object.assign(msg, this.defaultMeta);
}
}
}
function getLevelValue(levels, level) {
const value = levels[level];
if (!value && value !== 0) {
return null;
}
return value;
}
/**
* Represents the current readableState pipe targets for this Logger instance.
* @type {Array|Object}
*/
Object.defineProperty(Logger.prototype, 'transports', {
configurable: false,
enumerable: true,
get() {
const { pipes } = this._readableState;
return !Array.isArray(pipes) ? [pipes].filter(Boolean) : pipes;
}
});
module.exports = Logger;

View File

@ -0,0 +1,51 @@
/**
* profiler.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
/**
* TODO: add class description.
* @type {Profiler}
* @private
*/
module.exports = class Profiler {
/**
* Constructor function for the Profiler instance used by
* `Logger.prototype.startTimer`. When done is called the timer will finish
* and log the duration.
* @param {!Logger} logger - TODO: add param description.
* @private
*/
constructor(logger) {
if (!logger) {
throw new Error('Logger is required for profiling.');
}
this.logger = logger;
this.start = Date.now();
}
/**
* Ends the current timer (i.e. Profiler) instance and logs the `msg` along
* with the duration since creation.
* @returns {mixed} - TODO: add return description.
* @private
*/
done(...args) {
if (typeof args[args.length - 1] === 'function') {
// eslint-disable-next-line no-console
console.warn('Callback function no longer supported as of winston@3.0.0');
args.pop();
}
const info = typeof args[args.length - 1] === 'object' ? args.pop() : {};
info.level = info.level || 'info';
info.durationMs = (Date.now()) - this.start;
return this.logger.write(info);
}
};

View File

@ -0,0 +1,251 @@
/**
* exception-handler.js: Object for handling uncaughtException events.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const os = require('os');
const asyncForEach = require('async/forEach');
const debug = require('@dabh/diagnostics')('winston:rejection');
const once = require('one-time');
const stackTrace = require('stack-trace');
const ExceptionStream = require('./exception-stream');
/**
* Object for handling unhandledRejection events.
* @type {RejectionHandler}
*/
module.exports = class RejectionHandler {
/**
* TODO: add contructor description
* @param {!Logger} logger - TODO: add param description
*/
constructor(logger) {
if (!logger) {
throw new Error('Logger is required to handle rejections');
}
this.logger = logger;
this.handlers = new Map();
}
/**
* Handles `unhandledRejection` events for the current process by adding any
* handlers passed in.
* @returns {undefined}
*/
handle(...args) {
args.forEach(arg => {
if (Array.isArray(arg)) {
return arg.forEach(handler => this._addHandler(handler));
}
this._addHandler(arg);
});
if (!this.catcher) {
this.catcher = this._unhandledRejection.bind(this);
process.on('unhandledRejection', this.catcher);
}
}
/**
* Removes any handlers to `unhandledRejection` events for the current
* process. This does not modify the state of the `this.handlers` set.
* @returns {undefined}
*/
unhandle() {
if (this.catcher) {
process.removeListener('unhandledRejection', this.catcher);
this.catcher = false;
Array.from(this.handlers.values()).forEach(wrapper =>
this.logger.unpipe(wrapper)
);
}
}
/**
* TODO: add method description
* @param {Error} err - Error to get information about.
* @returns {mixed} - TODO: add return description.
*/
getAllInfo(err) {
let { message } = err;
if (!message && typeof err === 'string') {
message = err;
}
return {
error: err,
// TODO (indexzero): how do we configure this?
level: 'error',
message: [
`unhandledRejection: ${message || '(no error message)'}`,
err.stack || ' No stack trace'
].join('\n'),
stack: err.stack,
exception: true,
date: new Date().toString(),
process: this.getProcessInfo(),
os: this.getOsInfo(),
trace: this.getTrace(err)
};
}
/**
* Gets all relevant process information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
getProcessInfo() {
return {
pid: process.pid,
uid: process.getuid ? process.getuid() : null,
gid: process.getgid ? process.getgid() : null,
cwd: process.cwd(),
execPath: process.execPath,
version: process.version,
argv: process.argv,
memoryUsage: process.memoryUsage()
};
}
/**
* Gets all relevant OS information for the currently running process.
* @returns {mixed} - TODO: add return description.
*/
getOsInfo() {
return {
loadavg: os.loadavg(),
uptime: os.uptime()
};
}
/**
* Gets a stack trace for the specified error.
* @param {mixed} err - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
getTrace(err) {
const trace = err ? stackTrace.parse(err) : stackTrace.get();
return trace.map(site => {
return {
column: site.getColumnNumber(),
file: site.getFileName(),
function: site.getFunctionName(),
line: site.getLineNumber(),
method: site.getMethodName(),
native: site.isNative()
};
});
}
/**
* Helper method to add a transport as an exception handler.
* @param {Transport} handler - The transport to add as an exception handler.
* @returns {void}
*/
_addHandler(handler) {
if (!this.handlers.has(handler)) {
handler.handleRejections = true;
const wrapper = new ExceptionStream(handler);
this.handlers.set(handler, wrapper);
this.logger.pipe(wrapper);
}
}
/**
* Logs all relevant information around the `err` and exits the current
* process.
* @param {Error} err - Error to handle
* @returns {mixed} - TODO: add return description.
* @private
*/
_unhandledRejection(err) {
const info = this.getAllInfo(err);
const handlers = this._getRejectionHandlers();
// Calculate if we should exit on this error
let doExit =
typeof this.logger.exitOnError === 'function'
? this.logger.exitOnError(err)
: this.logger.exitOnError;
let timeout;
if (!handlers.length && doExit) {
// eslint-disable-next-line no-console
console.warn('winston: exitOnError cannot be true with no rejection handlers.');
// eslint-disable-next-line no-console
console.warn('winston: not exiting process.');
doExit = false;
}
function gracefulExit() {
debug('doExit', doExit);
debug('process._exiting', process._exiting);
if (doExit && !process._exiting) {
// Remark: Currently ignoring any rejections from transports when
// catching unhandled rejections.
if (timeout) {
clearTimeout(timeout);
}
// eslint-disable-next-line no-process-exit
process.exit(1);
}
}
if (!handlers || handlers.length === 0) {
return process.nextTick(gracefulExit);
}
// Log to all transports attempting to listen for when they are completed.
asyncForEach(
handlers,
(handler, next) => {
const done = once(next);
const transport = handler.transport || handler;
// Debug wrapping so that we can inspect what's going on under the covers.
function onDone(event) {
return () => {
debug(event);
done();
};
}
transport._ending = true;
transport.once('finish', onDone('finished'));
transport.once('error', onDone('error'));
},
() => doExit && gracefulExit()
);
this.logger.log(info);
// If exitOnError is true, then only allow the logging of exceptions to
// take up to `3000ms`.
if (doExit) {
timeout = setTimeout(gracefulExit, 3000);
}
}
/**
* Returns the list of transports and exceptionHandlers for this instance.
* @returns {Array} - List of transports and exceptionHandlers for this
* instance.
* @private
*/
_getRejectionHandlers() {
// Remark (indexzero): since `logger.transports` returns all of the pipes
// from the _readableState of the stream we actually get the join of the
// explicit handlers and the implicit transports with
// `handleRejections: true`
return this.logger.transports.filter(wrap => {
const transport = wrap.transport || wrap;
return transport.handleRejections;
});
}
};

View File

@ -0,0 +1,124 @@
/**
* tail-file.js: TODO: add file header description.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const fs = require('fs');
const { StringDecoder } = require('string_decoder');
const { Stream } = require('readable-stream');
/**
* Simple no-op function.
* @returns {undefined}
*/
function noop() {}
/**
* TODO: add function description.
* @param {Object} options - Options for tail.
* @param {function} iter - Iterator function to execute on every line.
* `tail -f` a file. Options must include file.
* @returns {mixed} - TODO: add return description.
*/
module.exports = (options, iter) => {
const buffer = Buffer.alloc(64 * 1024);
const decode = new StringDecoder('utf8');
const stream = new Stream();
let buff = '';
let pos = 0;
let row = 0;
if (options.start === -1) {
delete options.start;
}
stream.readable = true;
stream.destroy = () => {
stream.destroyed = true;
stream.emit('end');
stream.emit('close');
};
fs.open(options.file, 'a+', '0644', (err, fd) => {
if (err) {
if (!iter) {
stream.emit('error', err);
} else {
iter(err);
}
stream.destroy();
return;
}
(function read() {
if (stream.destroyed) {
fs.close(fd, noop);
return;
}
return fs.read(fd, buffer, 0, buffer.length, pos, (error, bytes) => {
if (error) {
if (!iter) {
stream.emit('error', error);
} else {
iter(error);
}
stream.destroy();
return;
}
if (!bytes) {
if (buff) {
// eslint-disable-next-line eqeqeq
if (options.start == null || row > options.start) {
if (!iter) {
stream.emit('line', buff);
} else {
iter(null, buff);
}
}
row++;
buff = '';
}
return setTimeout(read, 1000);
}
let data = decode.write(buffer.slice(0, bytes));
if (!iter) {
stream.emit('data', data);
}
data = (buff + data).split(/\n+/);
const l = data.length - 1;
let i = 0;
for (; i < l; i++) {
// eslint-disable-next-line eqeqeq
if (options.start == null || row > options.start) {
if (!iter) {
stream.emit('line', data[i]);
} else {
iter(null, data[i]);
}
}
row++;
}
buff = data[l];
pos += bytes;
return read();
});
}());
});
if (!iter) {
return stream;
}
return stream.destroy;
};

View File

@ -0,0 +1,117 @@
/* eslint-disable no-console */
/*
* console.js: Transport for outputting to the console.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const os = require('os');
const { LEVEL, MESSAGE } = require('triple-beam');
const TransportStream = require('winston-transport');
/**
* Transport for outputting to the console.
* @type {Console}
* @extends {TransportStream}
*/
module.exports = class Console extends TransportStream {
/**
* Constructor function for the Console transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
constructor(options = {}) {
super(options);
// Expose the name of this Transport on the prototype
this.name = options.name || 'console';
this.stderrLevels = this._stringArrayToSet(options.stderrLevels);
this.consoleWarnLevels = this._stringArrayToSet(options.consoleWarnLevels);
this.eol = options.eol || os.EOL;
this.setMaxListeners(30);
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
log(info, callback) {
setImmediate(() => this.emit('logged', info));
// Remark: what if there is no raw...?
if (this.stderrLevels[info[LEVEL]]) {
if (console._stderr) {
// Node.js maps `process.stderr` to `console._stderr`.
console._stderr.write(`${info[MESSAGE]}${this.eol}`);
} else {
// console.error adds a newline
console.error(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
} else if (this.consoleWarnLevels[info[LEVEL]]) {
if (console._stderr) {
// Node.js maps `process.stderr` to `console._stderr`.
// in Node.js console.warn is an alias for console.error
console._stderr.write(`${info[MESSAGE]}${this.eol}`);
} else {
// console.warn adds a newline
console.warn(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
if (console._stdout) {
// Node.js maps `process.stdout` to `console._stdout`.
console._stdout.write(`${info[MESSAGE]}${this.eol}`);
} else {
// console.log adds a newline.
console.log(info[MESSAGE]);
}
if (callback) {
callback(); // eslint-disable-line callback-return
}
}
/**
* Returns a Set-like object with strArray's elements as keys (each with the
* value true).
* @param {Array} strArray - Array of Set-elements as strings.
* @param {?string} [errMsg] - Custom error message thrown on invalid input.
* @returns {Object} - TODO: add return description.
* @private
*/
_stringArrayToSet(strArray, errMsg) {
if (!strArray)
return {};
errMsg = errMsg || 'Cannot make set from type other than Array of string elements';
if (!Array.isArray(strArray)) {
throw new Error(errMsg);
}
return strArray.reduce((set, el) => {
if (typeof el !== 'string') {
throw new Error(errMsg);
}
set[el] = true;
return set;
}, {});
}
};

View File

@ -0,0 +1,695 @@
/* eslint-disable complexity,max-statements */
/**
* file.js: Transport for outputting to a local log file.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const fs = require('fs');
const path = require('path');
const asyncSeries = require('async/series');
const zlib = require('zlib');
const { MESSAGE } = require('triple-beam');
const { Stream, PassThrough } = require('readable-stream');
const TransportStream = require('winston-transport');
const debug = require('@dabh/diagnostics')('winston:file');
const os = require('os');
const tailFile = require('../tail-file');
/**
* Transport for outputting to a local log file.
* @type {File}
* @extends {TransportStream}
*/
module.exports = class File extends TransportStream {
/**
* Constructor function for the File transport object responsible for
* persisting log messages and metadata to one or more files.
* @param {Object} options - Options for this instance.
*/
constructor(options = {}) {
super(options);
// Expose the name of this Transport on the prototype.
this.name = options.name || 'file';
// Helper function which throws an `Error` in the event that any of the
// rest of the arguments is present in `options`.
function throwIf(target, ...args) {
args.slice(1).forEach(name => {
if (options[name]) {
throw new Error(`Cannot set ${name} and ${target} together`);
}
});
}
// Setup the base stream that always gets piped to to handle buffering.
this._stream = new PassThrough();
this._stream.setMaxListeners(30);
// Bind this context for listener methods.
this._onError = this._onError.bind(this);
if (options.filename || options.dirname) {
throwIf('filename or dirname', 'stream');
this._basename = this.filename = options.filename
? path.basename(options.filename)
: 'winston.log';
this.dirname = options.dirname || path.dirname(options.filename);
this.options = options.options || { flags: 'a' };
} else if (options.stream) {
// eslint-disable-next-line no-console
console.warn('options.stream will be removed in winston@4. Use winston.transports.Stream');
throwIf('stream', 'filename', 'maxsize');
this._dest = this._stream.pipe(this._setupStream(options.stream));
this.dirname = path.dirname(this._dest.path);
// We need to listen for drain events when write() returns false. This
// can make node mad at times.
} else {
throw new Error('Cannot log to file without filename or stream.');
}
this.maxsize = options.maxsize || null;
this.rotationFormat = options.rotationFormat || false;
this.zippedArchive = options.zippedArchive || false;
this.maxFiles = options.maxFiles || null;
this.eol = options.eol || os.EOL;
this.tailable = options.tailable || false;
// Internal state variables representing the number of files this instance
// has created and the current size (in bytes) of the current logfile.
this._size = 0;
this._pendingSize = 0;
this._created = 0;
this._drain = false;
this._opening = false;
this._ending = false;
if (this.dirname) this._createLogDirIfNotExist(this.dirname);
this.open();
}
finishIfEnding() {
if (this._ending) {
if (this._opening) {
this.once('open', () => {
this._stream.once('finish', () => this.emit('finish'));
setImmediate(() => this._stream.end());
});
} else {
this._stream.once('finish', () => this.emit('finish'));
setImmediate(() => this._stream.end());
}
}
}
/**
* Core logging method exposed to Winston. Metadata is optional.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
log(info, callback = () => {}) {
// Remark: (jcrugzz) What is necessary about this callback(null, true) now
// when thinking about 3.x? Should silent be handled in the base
// TransportStream _write method?
if (this.silent) {
callback();
return true;
}
// Output stream buffer is full and has asked us to wait for the drain event
if (this._drain) {
this._stream.once('drain', () => {
this._drain = false;
this.log(info, callback);
});
return;
}
if (this._rotate) {
this._stream.once('rotate', () => {
this._rotate = false;
this.log(info, callback);
});
return;
}
// Grab the raw string and append the expected EOL.
const output = `${info[MESSAGE]}${this.eol}`;
const bytes = Buffer.byteLength(output);
// After we have written to the PassThrough check to see if we need
// to rotate to the next file.
//
// Remark: This gets called too early and does not depict when data
// has been actually flushed to disk.
function logged() {
this._size += bytes;
this._pendingSize -= bytes;
debug('logged %s %s', this._size, output);
this.emit('logged', info);
// Do not attempt to rotate files while opening
if (this._opening) {
return;
}
// Check to see if we need to end the stream and create a new one.
if (!this._needsNewFile()) {
return;
}
// End the current stream, ensure it flushes and create a new one.
// This could potentially be optimized to not run a stat call but its
// the safest way since we are supporting `maxFiles`.
this._rotate = true;
this._endStream(() => this._rotateFile());
}
// Keep track of the pending bytes being written while files are opening
// in order to properly rotate the PassThrough this._stream when the file
// eventually does open.
this._pendingSize += bytes;
if (this._opening
&& !this.rotatedWhileOpening
&& this._needsNewFile(this._size + this._pendingSize)) {
this.rotatedWhileOpening = true;
}
const written = this._stream.write(output, logged.bind(this));
if (!written) {
this._drain = true;
this._stream.once('drain', () => {
this._drain = false;
callback();
});
} else {
callback(); // eslint-disable-line callback-return
}
debug('written', written, this._drain);
this.finishIfEnding();
return written;
}
/**
* Query the transport. Options object is optional.
* @param {Object} options - Loggly-like query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
* TODO: Refactor me.
*/
query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = normalizeQuery(options);
const file = path.join(this.dirname, this.filename);
let buff = '';
let results = [];
let row = 0;
const stream = fs.createReadStream(file, {
encoding: 'utf8'
});
stream.on('error', err => {
if (stream.readable) {
stream.destroy();
}
if (!callback) {
return;
}
return err.code !== 'ENOENT' ? callback(err) : callback(null, results);
});
stream.on('data', data => {
data = (buff + data).split(/\n+/);
const l = data.length - 1;
let i = 0;
for (; i < l; i++) {
if (!options.start || row >= options.start) {
add(data[i]);
}
row++;
}
buff = data[l];
});
stream.on('close', () => {
if (buff) {
add(buff, true);
}
if (options.order === 'desc') {
results = results.reverse();
}
// eslint-disable-next-line callback-return
if (callback) callback(null, results);
});
function add(buff, attempt) {
try {
const log = JSON.parse(buff);
if (check(log)) {
push(log);
}
} catch (e) {
if (!attempt) {
stream.emit('error', e);
}
}
}
function push(log) {
if (
options.rows &&
results.length >= options.rows &&
options.order !== 'desc'
) {
if (stream.readable) {
stream.destroy();
}
return;
}
if (options.fields) {
log = options.fields.reduce((obj, key) => {
obj[key] = log[key];
return obj;
}, {});
}
if (options.order === 'desc') {
if (results.length >= options.rows) {
results.shift();
}
}
results.push(log);
}
function check(log) {
if (!log) {
return;
}
if (typeof log !== 'object') {
return;
}
const time = new Date(log.timestamp);
if (
(options.from && time < options.from) ||
(options.until && time > options.until) ||
(options.level && options.level !== log.level)
) {
return;
}
return true;
}
function normalizeQuery(options) {
options = options || {};
// limit
options.rows = options.rows || options.limit || 10;
// starting row offset
options.start = options.start || 0;
// now
options.until = options.until || new Date();
if (typeof options.until !== 'object') {
options.until = new Date(options.until);
}
// now - 24
options.from = options.from || (options.until - (24 * 60 * 60 * 1000));
if (typeof options.from !== 'object') {
options.from = new Date(options.from);
}
// 'asc' or 'desc'
options.order = options.order || 'desc';
return options;
}
}
/**
* Returns a log stream for this transport. Options object is optional.
* @param {Object} options - Stream options for this instance.
* @returns {Stream} - TODO: add return description.
* TODO: Refactor me.
*/
stream(options = {}) {
const file = path.join(this.dirname, this.filename);
const stream = new Stream();
const tail = {
file,
start: options.start
};
stream.destroy = tailFile(tail, (err, line) => {
if (err) {
return stream.emit('error', err);
}
try {
stream.emit('data', line);
line = JSON.parse(line);
stream.emit('log', line);
} catch (e) {
stream.emit('error', e);
}
});
return stream;
}
/**
* Checks to see the filesize of.
* @returns {undefined}
*/
open() {
// If we do not have a filename then we were passed a stream and
// don't need to keep track of size.
if (!this.filename) return;
if (this._opening) return;
this._opening = true;
// Stat the target file to get the size and create the stream.
this.stat((err, size) => {
if (err) {
return this.emit('error', err);
}
debug('stat done: %s { size: %s }', this.filename, size);
this._size = size;
this._dest = this._createStream(this._stream);
this._opening = false;
this.once('open', () => {
if (this._stream.eventNames().includes('rotate')) {
this._stream.emit('rotate');
} else {
this._rotate = false;
}
});
});
}
/**
* Stat the file and assess information in order to create the proper stream.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
stat(callback) {
const target = this._getFile();
const fullpath = path.join(this.dirname, target);
fs.stat(fullpath, (err, stat) => {
if (err && err.code === 'ENOENT') {
debug('ENOENT ok', fullpath);
// Update internally tracked filename with the new target name.
this.filename = target;
return callback(null, 0);
}
if (err) {
debug(`err ${err.code} ${fullpath}`);
return callback(err);
}
if (!stat || this._needsNewFile(stat.size)) {
// If `stats.size` is greater than the `maxsize` for this
// instance then try again.
return this._incFile(() => this.stat(callback));
}
// Once we have figured out what the filename is, set it
// and return the size.
this.filename = target;
callback(null, stat.size);
});
}
/**
* Closes the stream associated with this instance.
* @param {function} cb - TODO: add param description.
* @returns {undefined}
*/
close(cb) {
if (!this._stream) {
return;
}
this._stream.end(() => {
if (cb) {
cb(); // eslint-disable-line callback-return
}
this.emit('flush');
this.emit('closed');
});
}
/**
* TODO: add method description.
* @param {number} size - TODO: add param description.
* @returns {undefined}
*/
_needsNewFile(size) {
size = size || this._size;
return this.maxsize && size >= this.maxsize;
}
/**
* TODO: add method description.
* @param {Error} err - TODO: add param description.
* @returns {undefined}
*/
_onError(err) {
this.emit('error', err);
}
/**
* TODO: add method description.
* @param {Stream} stream - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
_setupStream(stream) {
stream.on('error', this._onError);
return stream;
}
/**
* TODO: add method description.
* @param {Stream} stream - TODO: add param description.
* @returns {mixed} - TODO: add return description.
*/
_cleanupStream(stream) {
stream.removeListener('error', this._onError);
return stream;
}
/**
* TODO: add method description.
*/
_rotateFile() {
this._incFile(() => this.open());
}
/**
* Unpipe from the stream that has been marked as full and end it so it
* flushes to disk.
*
* @param {function} callback - Callback for when the current file has closed.
* @private
*/
_endStream(callback = () => {}) {
if (this._dest) {
this._stream.unpipe(this._dest);
this._dest.end(() => {
this._cleanupStream(this._dest);
callback();
});
} else {
callback(); // eslint-disable-line callback-return
}
}
/**
* Returns the WritableStream for the active file on this instance. If we
* should gzip the file then a zlib stream is returned.
*
* @param {ReadableStream} source  PassThrough to pipe to the file when open.
* @returns {WritableStream} Stream that writes to disk for the active file.
*/
_createStream(source) {
const fullpath = path.join(this.dirname, this.filename);
debug('create stream start', fullpath, this.options);
const dest = fs.createWriteStream(fullpath, this.options)
// TODO: What should we do with errors here?
.on('error', err => debug(err))
.on('close', () => debug('close', dest.path, dest.bytesWritten))
.on('open', () => {
debug('file open ok', fullpath);
this.emit('open', fullpath);
source.pipe(dest);
// If rotation occured during the open operation then we immediately
// start writing to a new PassThrough, begin opening the next file
// and cleanup the previous source and dest once the source has drained.
if (this.rotatedWhileOpening) {
this._stream = new PassThrough();
this._stream.setMaxListeners(30);
this._rotateFile();
this.rotatedWhileOpening = false;
this._cleanupStream(dest);
source.end();
}
});
debug('create stream ok', fullpath);
if (this.zippedArchive) {
const gzip = zlib.createGzip();
gzip.pipe(dest);
return gzip;
}
return dest;
}
/**
* TODO: add method description.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
_incFile(callback) {
debug('_incFile', this.filename);
const ext = path.extname(this._basename);
const basename = path.basename(this._basename, ext);
if (!this.tailable) {
this._created += 1;
this._checkMaxFilesIncrementing(ext, basename, callback);
} else {
this._checkMaxFilesTailable(ext, basename, callback);
}
}
/**
* Gets the next filename to use for this instance in the case that log
* filesizes are being capped.
* @returns {string} - TODO: add return description.
* @private
*/
_getFile() {
const ext = path.extname(this._basename);
const basename = path.basename(this._basename, ext);
const isRotation = this.rotationFormat
? this.rotationFormat()
: this._created;
// Caveat emptor (indexzero): rotationFormat() was broken by design When
// combined with max files because the set of files to unlink is never
// stored.
const target = !this.tailable && this._created
? `${basename}${isRotation}${ext}`
: `${basename}${ext}`;
return this.zippedArchive && !this.tailable
? `${target}.gz`
: target;
}
/**
* Increment the number of files created or checked by this instance.
* @param {mixed} ext - TODO: add param description.
* @param {mixed} basename - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {undefined}
* @private
*/
_checkMaxFilesIncrementing(ext, basename, callback) {
// Check for maxFiles option and delete file.
if (!this.maxFiles || this._created < this.maxFiles) {
return setImmediate(callback);
}
const oldest = this._created - this.maxFiles;
const isOldest = oldest !== 0 ? oldest : '';
const isZipped = this.zippedArchive ? '.gz' : '';
const filePath = `${basename}${isOldest}${ext}${isZipped}`;
const target = path.join(this.dirname, filePath);
fs.unlink(target, callback);
}
/**
* Roll files forward based on integer, up to maxFiles. e.g. if base if
* file.log and it becomes oversized, roll to file1.log, and allow file.log
* to be re-used. If file is oversized again, roll file1.log to file2.log,
* roll file.log to file1.log, and so on.
* @param {mixed} ext - TODO: add param description.
* @param {mixed} basename - TODO: add param description.
* @param {mixed} callback - TODO: add param description.
* @returns {undefined}
* @private
*/
_checkMaxFilesTailable(ext, basename, callback) {
const tasks = [];
if (!this.maxFiles) {
return;
}
// const isZipped = this.zippedArchive ? '.gz' : '';
const isZipped = this.zippedArchive ? '.gz' : '';
for (let x = this.maxFiles - 1; x > 1; x--) {
tasks.push(function (i, cb) {
let fileName = `${basename}${(i - 1)}${ext}${isZipped}`;
const tmppath = path.join(this.dirname, fileName);
fs.exists(tmppath, exists => {
if (!exists) {
return cb(null);
}
fileName = `${basename}${i}${ext}${isZipped}`;
fs.rename(tmppath, path.join(this.dirname, fileName), cb);
});
}.bind(this, x));
}
asyncSeries(tasks, () => {
fs.rename(
path.join(this.dirname, `${basename}${ext}`),
path.join(this.dirname, `${basename}1${ext}${isZipped}`),
callback
);
});
}
_createLogDirIfNotExist(dirPath) {
/* eslint-disable no-sync */
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath, { recursive: true });
}
/* eslint-enable no-sync */
}
};

View File

@ -0,0 +1,202 @@
/**
* http.js: Transport for outputting to a json-rpcserver.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const http = require('http');
const https = require('https');
const { Stream } = require('readable-stream');
const TransportStream = require('winston-transport');
/**
* Transport for outputting to a json-rpc server.
* @type {Stream}
* @extends {TransportStream}
*/
module.exports = class Http extends TransportStream {
/**
* Constructor function for the Http transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
constructor(options = {}) {
super(options);
this.options = options;
this.name = options.name || 'http';
this.ssl = !!options.ssl;
this.host = options.host || 'localhost';
this.port = options.port;
this.auth = options.auth;
this.path = options.path || '';
this.agent = options.agent;
this.headers = options.headers || {};
this.headers['content-type'] = 'application/json';
if (!this.port) {
this.port = this.ssl ? 443 : 80;
}
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {function} callback - TODO: add param description.
* @returns {undefined}
*/
log(info, callback) {
this._request(info, (err, res) => {
if (res && res.statusCode !== 200) {
err = new Error(`Invalid HTTP Status Code: ${res.statusCode}`);
}
if (err) {
this.emit('warn', err);
} else {
this.emit('logged', info);
}
});
// Remark: (jcrugzz) Fire and forget here so requests dont cause buffering
// and block more requests from happening?
if (callback) {
setImmediate(callback);
}
}
/**
* Query the transport. Options object is optional.
* @param {Object} options - Loggly-like query options for this instance.
* @param {function} callback - Continuation to respond to when complete.
* @returns {undefined}
*/
query(options, callback) {
if (typeof options === 'function') {
callback = options;
options = {};
}
options = {
method: 'query',
params: this.normalizeQuery(options)
};
if (options.params.path) {
options.path = options.params.path;
delete options.params.path;
}
if (options.params.auth) {
options.auth = options.params.auth;
delete options.params.auth;
}
this._request(options, (err, res, body) => {
if (res && res.statusCode !== 200) {
err = new Error(`Invalid HTTP Status Code: ${res.statusCode}`);
}
if (err) {
return callback(err);
}
if (typeof body === 'string') {
try {
body = JSON.parse(body);
} catch (e) {
return callback(e);
}
}
callback(null, body);
});
}
/**
* Returns a log stream for this transport. Options object is optional.
* @param {Object} options - Stream options for this instance.
* @returns {Stream} - TODO: add return description
*/
stream(options = {}) {
const stream = new Stream();
options = {
method: 'stream',
params: options
};
if (options.params.path) {
options.path = options.params.path;
delete options.params.path;
}
if (options.params.auth) {
options.auth = options.params.auth;
delete options.params.auth;
}
let buff = '';
const req = this._request(options);
stream.destroy = () => req.destroy();
req.on('data', data => {
data = (buff + data).split(/\n+/);
const l = data.length - 1;
let i = 0;
for (; i < l; i++) {
try {
stream.emit('log', JSON.parse(data[i]));
} catch (e) {
stream.emit('error', e);
}
}
buff = data[l];
});
req.on('error', err => stream.emit('error', err));
return stream;
}
/**
* Make a request to a winstond server or any http server which can
* handle json-rpc.
* @param {function} options - Options to sent the request.
* @param {function} callback - Continuation to respond to when complete.
*/
_request(options, callback) {
options = options || {};
const auth = options.auth || this.auth;
const path = options.path || this.path || '';
delete options.auth;
delete options.path;
// Prepare options for outgoing HTTP request
const headers = Object.assign({}, this.headers);
if (auth && auth.bearer) {
headers.Authorization = `Bearer ${auth.bearer}`;
}
const req = (this.ssl ? https : http).request({
...this.options,
method: 'POST',
host: this.host,
port: this.port,
path: `/${path.replace(/^\//, '')}`,
headers: headers,
auth: (auth && auth.username && auth.password) ? (`${auth.username}:${auth.password}`) : '',
agent: this.agent
});
req.on('error', callback);
req.on('response', res => (
res.on('end', () => callback(null, res)).resume()
));
req.end(Buffer.from(JSON.stringify(options), 'utf8'));
}
};

View File

@ -0,0 +1,100 @@
// Type definitions for winston 3.0
// Project: https://github.com/winstonjs/winston
/// <reference types="node" />
import {Agent} from "http";
import * as Transport from 'winston-transport';
declare namespace winston {
interface ConsoleTransportOptions extends Transport.TransportStreamOptions {
consoleWarnLevels?: string[],
stderrLevels?: string[];
debugStdout?: boolean;
eol?: string;
}
interface ConsoleTransportInstance extends Transport {
name: string;
stderrLevels: string[];
eol: string;
new(options?: ConsoleTransportOptions): ConsoleTransportInstance;
}
interface FileTransportOptions extends Transport.TransportStreamOptions {
filename?: string;
dirname?: string;
options?: object;
maxsize?: number;
stream?: NodeJS.WritableStream;
rotationFormat?: Function;
zippedArchive?: boolean;
maxFiles?: number;
eol?: string;
tailable?: boolean;
}
interface FileTransportInstance extends Transport {
name: string;
filename: string;
dirname: string;
options: object;
maxsize: number | null;
rotationFormat: Function | boolean;
zippedArchive: boolean;
maxFiles: number | null;
eol: string;
tailable: boolean;
new(options?: FileTransportOptions): FileTransportInstance;
}
interface HttpTransportOptions extends Transport.TransportStreamOptions {
ssl?: any;
host?: string;
port?: number;
auth?: { username?: string | undefined, password?: string | undefined, bearer?: string | undefined };
path?: string;
agent?: Agent;
headers?: object;
}
interface HttpTransportInstance extends Transport {
name: string;
ssl: boolean;
host: string;
port: number;
auth?: { username?: string | undefined, password?: string | undefined, bearer?: string | undefined };
path: string;
agent?: Agent | null;
new(options?: HttpTransportOptions): HttpTransportInstance;
}
interface StreamTransportOptions extends Transport.TransportStreamOptions {
stream: NodeJS.WritableStream;
eol?: string;
}
interface StreamTransportInstance extends Transport {
eol: string;
new(options?: StreamTransportOptions): StreamTransportInstance;
}
interface Transports {
FileTransportOptions: FileTransportOptions;
File: FileTransportInstance;
ConsoleTransportOptions: ConsoleTransportOptions;
Console: ConsoleTransportInstance;
HttpTransportOptions: HttpTransportOptions;
Http: HttpTransportInstance;
StreamTransportOptions: StreamTransportOptions;
Stream: StreamTransportInstance;
}
}
declare const winston: winston.Transports;
export = winston;

View File

@ -0,0 +1,56 @@
/**
* transports.js: Set of all transports Winston knows about.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
/**
* TODO: add property description.
* @type {Console}
*/
Object.defineProperty(exports, 'Console', {
configurable: true,
enumerable: true,
get() {
return require('./console');
}
});
/**
* TODO: add property description.
* @type {File}
*/
Object.defineProperty(exports, 'File', {
configurable: true,
enumerable: true,
get() {
return require('./file');
}
});
/**
* TODO: add property description.
* @type {Http}
*/
Object.defineProperty(exports, 'Http', {
configurable: true,
enumerable: true,
get() {
return require('./http');
}
});
/**
* TODO: add property description.
* @type {Stream}
*/
Object.defineProperty(exports, 'Stream', {
configurable: true,
enumerable: true,
get() {
return require('./stream');
}
});

View File

@ -0,0 +1,63 @@
/**
* stream.js: Transport for outputting to any arbitrary stream.
*
* (C) 2010 Charlie Robbins
* MIT LICENCE
*/
'use strict';
const isStream = require('is-stream');
const { MESSAGE } = require('triple-beam');
const os = require('os');
const TransportStream = require('winston-transport');
/**
* Transport for outputting to any arbitrary stream.
* @type {Stream}
* @extends {TransportStream}
*/
module.exports = class Stream extends TransportStream {
/**
* Constructor function for the Console transport object responsible for
* persisting log messages and metadata to a terminal or TTY.
* @param {!Object} [options={}] - Options for this instance.
*/
constructor(options = {}) {
super(options);
if (!options.stream || !isStream(options.stream)) {
throw new Error('options.stream is required.');
}
// We need to listen for drain events when write() returns false. This can
// make node mad at times.
this._stream = options.stream;
this._stream.setMaxListeners(Infinity);
this.isObjectMode = options.stream._writableState.objectMode;
this.eol = options.eol || os.EOL;
}
/**
* Core logging method exposed to Winston.
* @param {Object} info - TODO: add param description.
* @param {Function} callback - TODO: add param description.
* @returns {undefined}
*/
log(info, callback) {
setImmediate(() => this.emit('logged', info));
if (this.isObjectMode) {
this._stream.write(info);
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
this._stream.write(`${info[MESSAGE]}${this.eol}`);
if (callback) {
callback(); // eslint-disable-line callback-return
}
return;
}
};

View File

@ -0,0 +1,331 @@
# v3.2.0
- Fix a bug in Safari related to overwriting `func.name`
- Remove built-in browserify configuration (#1653)
- Varios doc fixes (#1688, #1703, #1704)
# v3.1.1
- Allow redefining `name` property on wrapped functions.
# v3.1.0
- Added `q.pushAsync` and `q.unshiftAsync`, analagous to `q.push` and `q.unshift`, except they always do not accept a callback, and reject if processing the task errors. (#1659)
- Promises returned from `q.push` and `q.unshift` when a callback is not passed now resolve even if an error ocurred. (#1659)
- Fixed a parsing bug in `autoInject` with complicated function bodies (#1663)
- Added ES6+ configuration for Browserify bundlers (#1653)
- Various doc fixes (#1664, #1658, #1665, #1652)
# v3.0.1
## Bug fixes
- Fixed a regression where arrays passed to `queue` and `cargo` would be completely flattened. (#1645)
- Clarified Async's browser support (#1643)
# v3.0.0
The `async`/`await` release!
There are a lot of new features and subtle breaking changes in this major version, but the biggest feature is that most Async methods return a Promise if you omit the callback, meaning you can `await` them from within an `async` function.
```js
const results = await async.mapLimit(urls, 5, async url => {
const resp = await fetch(url)
return resp.body
})
```
## Breaking Changes
- Most Async methods return a Promise when the final callback is omitted, making them `await`-able! (#1572)
- We are now making heavy use of ES2015 features, this means we have dropped out-of-the-box support for Node 4 and earlier, and many old versions of browsers. (#1541, #1553)
- In `queue`, `priorityQueue`, `cargo` and `cargoQueue`, the "event"-style methods, like `q.drain` and `q.saturated` are now methods that register a callback, rather than properties you assign a callback to. They are now of the form `q.drain(callback)`. If you do not pass a callback a Promise will be returned for the next occurrence of the event, making them `await`-able, e.g. `await q.drain()`. (#1586, #1641)
- Calling `callback(false)` will cancel an async method, preventing further iteration and callback calls. This is useful for preventing memory leaks when you break out of an async flow by calling an outer callback. (#1064, #1542)
- `during` and `doDuring` have been removed, and instead `whilst`, `doWhilst`, `until` and `doUntil` now have asynchronous `test` functions. (#850, #1557)
- `limits` of less than 1 now cause an error to be thrown in queues and collection methods. (#1249, #1552)
- `memoize` no longer memoizes errors (#1465, #1466)
- `applyEach`/`applyEachSeries` have a simpler interface, to make them more easily type-able. It always returns a function that takes in a single callback argument. If that callback is omitted, a promise is returned, making it awaitable. (#1228, #1640)
## New Features
- Async generators are now supported in all the Collection methods. (#1560)
- Added `cargoQueue`, a queue with both `concurrency` and `payload` size parameters. (#1567)
- Queue objects returned from `queue` now have a `Symbol.iterator` method, meaning they can be iterated over to inspect the current list of items in the queue. (#1459, #1556)
- A ESM-flavored `async.mjs` is included in the `async` package. This is described in the `package.json` `"module"` field, meaning it should be automatically used by Webpack and other compatible bundlers.
## Bug fixes
- Better handle arbitrary error objects in `asyncify` (#1568, #1569)
## Other
- Removed Lodash as a dependency (#1283, #1528)
- Miscellaneous docs fixes (#1393, #1501, #1540, #1543, #1558, #1563, #1564, #1579, #1581)
- Miscellaneous test fixes (#1538)
-------
# v2.6.1
- Updated lodash to prevent `npm audit` warnings. (#1532, #1533)
- Made `async-es` more optimized for webpack users (#1517)
- Fixed a stack overflow with large collections and a synchronous iterator (#1514)
- Various small fixes/chores (#1505, #1511, #1527, #1530)
# v2.6.0
- Added missing aliases for many methods. Previously, you could not (e.g.) `require('async/find')` or use `async.anyLimit`. (#1483)
- Improved `queue` performance. (#1448, #1454)
- Add missing sourcemap (#1452, #1453)
- Various doc updates (#1448, #1471, #1483)
# v2.5.0
- Added `concatLimit`, the `Limit` equivalent of [`concat`](https://caolan.github.io/async/docs.html#concat) ([#1426](https://github.com/caolan/async/issues/1426), [#1430](https://github.com/caolan/async/pull/1430))
- `concat` improvements: it now preserves order, handles falsy values and the `iteratee` callback takes a variable number of arguments ([#1437](https://github.com/caolan/async/issues/1437), [#1436](https://github.com/caolan/async/pull/1436))
- Fixed an issue in `queue` where there was a size discrepancy between `workersList().length` and `running()` ([#1428](https://github.com/caolan/async/issues/1428), [#1429](https://github.com/caolan/async/pull/1429))
- Various doc fixes ([#1422](https://github.com/caolan/async/issues/1422), [#1424](https://github.com/caolan/async/pull/1424))
# v2.4.1
- Fixed a bug preventing functions wrapped with `timeout()` from being re-used. ([#1418](https://github.com/caolan/async/issues/1418), [#1419](https://github.com/caolan/async/issues/1419))
# v2.4.0
- Added `tryEach`, for running async functions in parallel, where you only expect one to succeed. ([#1365](https://github.com/caolan/async/issues/1365), [#687](https://github.com/caolan/async/issues/687))
- Improved performance, most notably in `parallel` and `waterfall` ([#1395](https://github.com/caolan/async/issues/1395))
- Added `queue.remove()`, for removing items in a `queue` ([#1397](https://github.com/caolan/async/issues/1397), [#1391](https://github.com/caolan/async/issues/1391))
- Fixed using `eval`, preventing Async from running in pages with Content Security Policy ([#1404](https://github.com/caolan/async/issues/1404), [#1403](https://github.com/caolan/async/issues/1403))
- Fixed errors thrown in an `asyncify`ed function's callback being caught by the underlying Promise ([#1408](https://github.com/caolan/async/issues/1408))
- Fixed timing of `queue.empty()` ([#1367](https://github.com/caolan/async/issues/1367))
- Various doc fixes ([#1314](https://github.com/caolan/async/issues/1314), [#1394](https://github.com/caolan/async/issues/1394), [#1412](https://github.com/caolan/async/issues/1412))
# v2.3.0
- Added support for ES2017 `async` functions. Wherever you can pass a Node-style/CPS function that uses a callback, you can also pass an `async` function. Previously, you had to wrap `async` functions with `asyncify`. The caveat is that it will only work if `async` functions are supported natively in your environment, transpiled implementations can't be detected. ([#1386](https://github.com/caolan/async/issues/1386), [#1390](https://github.com/caolan/async/issues/1390))
- Small doc fix ([#1392](https://github.com/caolan/async/issues/1392))
# v2.2.0
- Added `groupBy`, and the `Series`/`Limit` equivalents, analogous to [`_.groupBy`](http://lodash.com/docs#groupBy) ([#1364](https://github.com/caolan/async/issues/1364))
- Fixed `transform` bug when `callback` was not passed ([#1381](https://github.com/caolan/async/issues/1381))
- Added note about `reflect` to `parallel` docs ([#1385](https://github.com/caolan/async/issues/1385))
# v2.1.5
- Fix `auto` bug when function names collided with Array.prototype ([#1358](https://github.com/caolan/async/issues/1358))
- Improve some error messages ([#1349](https://github.com/caolan/async/issues/1349))
- Avoid stack overflow case in queue
- Fixed an issue in `some`, `every` and `find` where processing would continue after the result was determined.
- Cleanup implementations of `some`, `every` and `find`
# v2.1.3
- Make bundle size smaller
- Create optimized hotpath for `filter` in array case.
# v2.1.2
- Fixed a stackoverflow bug with `detect`, `some`, `every` on large inputs ([#1293](https://github.com/caolan/async/issues/1293)).
# v2.1.0
- `retry` and `retryable` now support an optional `errorFilter` function that determines if the `task` should retry on the error ([#1256](https://github.com/caolan/async/issues/1256), [#1261](https://github.com/caolan/async/issues/1261))
- Optimized array iteration in `race`, `cargo`, `queue`, and `priorityQueue` ([#1253](https://github.com/caolan/async/issues/1253))
- Added alias documentation to doc site ([#1251](https://github.com/caolan/async/issues/1251), [#1254](https://github.com/caolan/async/issues/1254))
- Added [BootStrap scrollspy](http://getbootstrap.com/javascript/#scrollspy) to docs to highlight in the sidebar the current method being viewed ([#1289](https://github.com/caolan/async/issues/1289), [#1300](https://github.com/caolan/async/issues/1300))
- Various minor doc fixes ([#1263](https://github.com/caolan/async/issues/1263), [#1264](https://github.com/caolan/async/issues/1264), [#1271](https://github.com/caolan/async/issues/1271), [#1278](https://github.com/caolan/async/issues/1278), [#1280](https://github.com/caolan/async/issues/1280), [#1282](https://github.com/caolan/async/issues/1282), [#1302](https://github.com/caolan/async/issues/1302))
# v2.0.1
- Significantly optimized all iteration based collection methods such as `each`, `map`, `filter`, etc ([#1245](https://github.com/caolan/async/issues/1245), [#1246](https://github.com/caolan/async/issues/1246), [#1247](https://github.com/caolan/async/issues/1247)).
# v2.0.0
Lots of changes here!
First and foremost, we have a slick new [site for docs](https://caolan.github.io/async/). Special thanks to [**@hargasinski**](https://github.com/hargasinski) for his work converting our old docs to `jsdoc` format and implementing the new website. Also huge ups to [**@ivanseidel**](https://github.com/ivanseidel) for designing our new logo. It was a long process for both of these tasks, but I think these changes turned out extraordinary well.
The biggest feature is modularization. You can now `require("async/series")` to only require the `series` function. Every Async library function is available this way. You still can `require("async")` to require the entire library, like you could do before.
We also provide Async as a collection of ES2015 modules. You can now `import {each} from 'async-es'` or `import waterfall from 'async-es/waterfall'`. If you are using only a few Async functions, and are using a ES bundler such as Rollup, this can significantly lower your build size.
Major thanks to [**@Kikobeats**](github.com/Kikobeats), [**@aearly**](github.com/aearly) and [**@megawac**](github.com/megawac) for doing the majority of the modularization work, as well as [**@jdalton**](github.com/jdalton) and [**@Rich-Harris**](github.com/Rich-Harris) for advisory work on the general modularization strategy.
Another one of the general themes of the 2.0 release is standardization of what an "async" function is. We are now more strictly following the node-style continuation passing style. That is, an async function is a function that:
1. Takes a variable number of arguments
2. The last argument is always a callback
3. The callback can accept any number of arguments
4. The first argument passed to the callback will be treated as an error result, if the argument is truthy
5. Any number of result arguments can be passed after the "error" argument
6. The callback is called once and exactly once, either on the same tick or later tick of the JavaScript event loop.
There were several cases where Async accepted some functions that did not strictly have these properties, most notably `auto`, `every`, `some`, `filter`, `reject` and `detect`.
Another theme is performance. We have eliminated internal deferrals in all cases where they make sense. For example, in `waterfall` and `auto`, there was a `setImmediate` between each task -- these deferrals have been removed. A `setImmediate` call can add up to 1ms of delay. This might not seem like a lot, but it can add up if you are using many Async functions in the course of processing a HTTP request, for example. Nearly all asynchronous functions that do I/O already have some sort of deferral built in, so the extra deferral is unnecessary. The trade-off of this change is removing our built-in stack-overflow defense. Many synchronous callback calls in series can quickly overflow the JS call stack. If you do have a function that is sometimes synchronous (calling its callback on the same tick), and are running into stack overflows, wrap it with `async.ensureAsync()`.
Another big performance win has been re-implementing `queue`, `cargo`, and `priorityQueue` with [doubly linked lists](https://en.wikipedia.org/wiki/Doubly_linked_list) instead of arrays. This has lead to queues being an order of [magnitude faster on large sets of tasks](https://github.com/caolan/async/pull/1205).
## New Features
- Async is now modularized. Individual functions can be `require()`d from the main package. (`require('async/auto')`) ([#984](https://github.com/caolan/async/issues/984), [#996](https://github.com/caolan/async/issues/996))
- Async is also available as a collection of ES2015 modules in the new `async-es` package. (`import {forEachSeries} from 'async-es'`) ([#984](https://github.com/caolan/async/issues/984), [#996](https://github.com/caolan/async/issues/996))
- Added `race`, analogous to `Promise.race()`. It will run an array of async tasks in parallel and will call its callback with the result of the first task to respond. ([#568](https://github.com/caolan/async/issues/568), [#1038](https://github.com/caolan/async/issues/1038))
- Collection methods now accept ES2015 iterators. Maps, Sets, and anything that implements the iterator spec can now be passed directly to `each`, `map`, `parallel`, etc.. ([#579](https://github.com/caolan/async/issues/579), [#839](https://github.com/caolan/async/issues/839), [#1074](https://github.com/caolan/async/issues/1074))
- Added `mapValues`, for mapping over the properties of an object and returning an object with the same keys. ([#1157](https://github.com/caolan/async/issues/1157), [#1177](https://github.com/caolan/async/issues/1177))
- Added `timeout`, a wrapper for an async function that will make the task time-out after the specified time. ([#1007](https://github.com/caolan/async/issues/1007), [#1027](https://github.com/caolan/async/issues/1027))
- Added `reflect` and `reflectAll`, analagous to [`Promise.reflect()`](http://bluebirdjs.com/docs/api/reflect.html), a wrapper for async tasks that always succeeds, by gathering results and errors into an object. ([#942](https://github.com/caolan/async/issues/942), [#1012](https://github.com/caolan/async/issues/1012), [#1095](https://github.com/caolan/async/issues/1095))
- `constant` supports dynamic arguments -- it will now always use its last argument as the callback. ([#1016](https://github.com/caolan/async/issues/1016), [#1052](https://github.com/caolan/async/issues/1052))
- `setImmediate` and `nextTick` now support arguments to partially apply to the deferred function, like the node-native versions do. ([#940](https://github.com/caolan/async/issues/940), [#1053](https://github.com/caolan/async/issues/1053))
- `auto` now supports resolving cyclic dependencies using [Kahn's algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm) ([#1140](https://github.com/caolan/async/issues/1140)).
- Added `autoInject`, a relative of `auto` that automatically spreads a task's dependencies as arguments to the task function. ([#608](https://github.com/caolan/async/issues/608), [#1055](https://github.com/caolan/async/issues/1055), [#1099](https://github.com/caolan/async/issues/1099), [#1100](https://github.com/caolan/async/issues/1100))
- You can now limit the concurrency of `auto` tasks. ([#635](https://github.com/caolan/async/issues/635), [#637](https://github.com/caolan/async/issues/637))
- Added `retryable`, a relative of `retry` that wraps an async function, making it retry when called. ([#1058](https://github.com/caolan/async/issues/1058))
- `retry` now supports specifying a function that determines the next time interval, useful for exponential backoff, logging and other retry strategies. ([#1161](https://github.com/caolan/async/issues/1161))
- `retry` will now pass all of the arguments the task function was resolved with to the callback ([#1231](https://github.com/caolan/async/issues/1231)).
- Added `q.unsaturated` -- callback called when a `queue`'s number of running workers falls below a threshold. ([#868](https://github.com/caolan/async/issues/868), [#1030](https://github.com/caolan/async/issues/1030), [#1033](https://github.com/caolan/async/issues/1033), [#1034](https://github.com/caolan/async/issues/1034))
- Added `q.error` -- a callback called whenever a `queue` task calls its callback with an error. ([#1170](https://github.com/caolan/async/issues/1170))
- `applyEach` and `applyEachSeries` now pass results to the final callback. ([#1088](https://github.com/caolan/async/issues/1088))
## Breaking changes
- Calling a callback more than once is considered an error, and an error will be thrown. This had an explicit breaking change in `waterfall`. If you were relying on this behavior, you should more accurately represent your control flow as an event emitter or stream. ([#814](https://github.com/caolan/async/issues/814), [#815](https://github.com/caolan/async/issues/815), [#1048](https://github.com/caolan/async/issues/1048), [#1050](https://github.com/caolan/async/issues/1050))
- `auto` task functions now always take the callback as the last argument. If a task has dependencies, the `results` object will be passed as the first argument. To migrate old task functions, wrap them with [`_.flip`](https://lodash.com/docs#flip) ([#1036](https://github.com/caolan/async/issues/1036), [#1042](https://github.com/caolan/async/issues/1042))
- Internal `setImmediate` calls have been refactored away. This may make existing flows vulnerable to stack overflows if you use many synchronous functions in series. Use `ensureAsync` to work around this. ([#696](https://github.com/caolan/async/issues/696), [#704](https://github.com/caolan/async/issues/704), [#1049](https://github.com/caolan/async/issues/1049), [#1050](https://github.com/caolan/async/issues/1050))
- `map` used to return an object when iterating over an object. `map` now always returns an array, like in other libraries. The previous object behavior has been split out into `mapValues`. ([#1157](https://github.com/caolan/async/issues/1157), [#1177](https://github.com/caolan/async/issues/1177))
- `filter`, `reject`, `some`, `every`, `detect` and their families like `{METHOD}Series` and `{METHOD}Limit` now expect an error as the first callback argument, rather than just a simple boolean. Pass `null` as the first argument, or use `fs.access` instead of `fs.exists`. ([#118](https://github.com/caolan/async/issues/118), [#774](https://github.com/caolan/async/issues/774), [#1028](https://github.com/caolan/async/issues/1028), [#1041](https://github.com/caolan/async/issues/1041))
- `{METHOD}` and `{METHOD}Series` are now implemented in terms of `{METHOD}Limit`. This is a major internal simplification, and is not expected to cause many problems, but it does subtly affect how functions execute internally. ([#778](https://github.com/caolan/async/issues/778), [#847](https://github.com/caolan/async/issues/847))
- `retry`'s callback is now optional. Previously, omitting the callback would partially apply the function, meaning it could be passed directly as a task to `series` or `auto`. The partially applied "control-flow" behavior has been separated out into `retryable`. ([#1054](https://github.com/caolan/async/issues/1054), [#1058](https://github.com/caolan/async/issues/1058))
- The test function for `whilst`, `until`, and `during` used to be passed non-error args from the iteratee function's callback, but this led to weirdness where the first call of the test function would be passed no args. We have made it so the test function is never passed extra arguments, and only the `doWhilst`, `doUntil`, and `doDuring` functions pass iteratee callback arguments to the test function ([#1217](https://github.com/caolan/async/issues/1217), [#1224](https://github.com/caolan/async/issues/1224))
- The `q.tasks` array has been renamed `q._tasks` and is now implemented as a doubly linked list (DLL). Any code that used to interact with this array will need to be updated to either use the provided helpers or support DLLs ([#1205](https://github.com/caolan/async/issues/1205)).
- The timing of the `q.saturated()` callback in a `queue` has been modified to better reflect when tasks pushed to the queue will start queueing. ([#724](https://github.com/caolan/async/issues/724), [#1078](https://github.com/caolan/async/issues/1078))
- Removed `iterator` method in favour of [ES2015 iterator protocol](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators ) which natively supports arrays ([#1237](https://github.com/caolan/async/issues/1237))
- Dropped support for Component, Jam, SPM, and Volo ([#1175](https://github.com/caolan/async/issues/1175), #[#176](https://github.com/caolan/async/issues/176))
## Bug Fixes
- Improved handling of no dependency cases in `auto` & `autoInject` ([#1147](https://github.com/caolan/async/issues/1147)).
- Fixed a bug where the callback generated by `asyncify` with `Promises` could resolve twice ([#1197](https://github.com/caolan/async/issues/1197)).
- Fixed several documented optional callbacks not actually being optional ([#1223](https://github.com/caolan/async/issues/1223)).
## Other
- Added `someSeries` and `everySeries` for symmetry, as well as a complete set of `any`/`anyLimit`/`anySeries` and `all`/`/allLmit`/`allSeries` aliases.
- Added `find` as an alias for `detect. (as well as `findLimit` and `findSeries`).
- Various doc fixes ([#1005](https://github.com/caolan/async/issues/1005), [#1008](https://github.com/caolan/async/issues/1008), [#1010](https://github.com/caolan/async/issues/1010), [#1015](https://github.com/caolan/async/issues/1015), [#1021](https://github.com/caolan/async/issues/1021), [#1037](https://github.com/caolan/async/issues/1037), [#1039](https://github.com/caolan/async/issues/1039), [#1051](https://github.com/caolan/async/issues/1051), [#1102](https://github.com/caolan/async/issues/1102), [#1107](https://github.com/caolan/async/issues/1107), [#1121](https://github.com/caolan/async/issues/1121), [#1123](https://github.com/caolan/async/issues/1123), [#1129](https://github.com/caolan/async/issues/1129), [#1135](https://github.com/caolan/async/issues/1135), [#1138](https://github.com/caolan/async/issues/1138), [#1141](https://github.com/caolan/async/issues/1141), [#1153](https://github.com/caolan/async/issues/1153), [#1216](https://github.com/caolan/async/issues/1216), [#1217](https://github.com/caolan/async/issues/1217), [#1232](https://github.com/caolan/async/issues/1232), [#1233](https://github.com/caolan/async/issues/1233), [#1236](https://github.com/caolan/async/issues/1236), [#1238](https://github.com/caolan/async/issues/1238))
Thank you [**@aearly**](github.com/aearly) and [**@megawac**](github.com/megawac) for taking the lead on version 2 of async.
------------------------------------------
# v1.5.2
- Allow using `"constructor"` as an argument in `memoize` ([#998](https://github.com/caolan/async/issues/998))
- Give a better error messsage when `auto` dependency checking fails ([#994](https://github.com/caolan/async/issues/994))
- Various doc updates ([#936](https://github.com/caolan/async/issues/936), [#956](https://github.com/caolan/async/issues/956), [#979](https://github.com/caolan/async/issues/979), [#1002](https://github.com/caolan/async/issues/1002))
# v1.5.1
- Fix issue with `pause` in `queue` with concurrency enabled ([#946](https://github.com/caolan/async/issues/946))
- `while` and `until` now pass the final result to callback ([#963](https://github.com/caolan/async/issues/963))
- `auto` will properly handle concurrency when there is no callback ([#966](https://github.com/caolan/async/issues/966))
- `auto` will no. properly stop execution when an error occurs ([#988](https://github.com/caolan/async/issues/988), [#993](https://github.com/caolan/async/issues/993))
- Various doc fixes ([#971](https://github.com/caolan/async/issues/971), [#980](https://github.com/caolan/async/issues/980))
# v1.5.0
- Added `transform`, analogous to [`_.transform`](http://lodash.com/docs#transform) ([#892](https://github.com/caolan/async/issues/892))
- `map` now returns an object when an object is passed in, rather than array with non-numeric keys. `map` will begin always returning an array with numeric indexes in the next major release. ([#873](https://github.com/caolan/async/issues/873))
- `auto` now accepts an optional `concurrency` argument to limit the number o. running tasks ([#637](https://github.com/caolan/async/issues/637))
- Added `queue#workersList()`, to retrieve the lis. of currently running tasks. ([#891](https://github.com/caolan/async/issues/891))
- Various code simplifications ([#896](https://github.com/caolan/async/issues/896), [#904](https://github.com/caolan/async/issues/904))
- Various doc fixes :scroll: ([#890](https://github.com/caolan/async/issues/890), [#894](https://github.com/caolan/async/issues/894), [#903](https://github.com/caolan/async/issues/903), [#905](https://github.com/caolan/async/issues/905), [#912](https://github.com/caolan/async/issues/912))
# v1.4.2
- Ensure coverage files don't get published on npm ([#879](https://github.com/caolan/async/issues/879))
# v1.4.1
- Add in overlooked `detectLimit` method ([#866](https://github.com/caolan/async/issues/866))
- Removed unnecessary files from npm releases ([#861](https://github.com/caolan/async/issues/861))
- Removed usage of a reserved word to prevent :boom: in older environments ([#870](https://github.com/caolan/async/issues/870))
# v1.4.0
- `asyncify` now supports promises ([#840](https://github.com/caolan/async/issues/840))
- Added `Limit` versions of `filter` and `reject` ([#836](https://github.com/caolan/async/issues/836))
- Add `Limit` versions of `detect`, `some` and `every` ([#828](https://github.com/caolan/async/issues/828), [#829](https://github.com/caolan/async/issues/829))
- `some`, `every` and `detect` now short circuit early ([#828](https://github.com/caolan/async/issues/828), [#829](https://github.com/caolan/async/issues/829))
- Improve detection of the global object ([#804](https://github.com/caolan/async/issues/804)), enabling use in WebWorkers
- `whilst` now called with arguments from iterator ([#823](https://github.com/caolan/async/issues/823))
- `during` now gets called with arguments from iterator ([#824](https://github.com/caolan/async/issues/824))
- Code simplifications and optimizations aplenty ([diff](https://github.com/caolan/async/compare/v1.3.0...v1.4.0))
# v1.3.0
New Features:
- Added `constant`
- Added `asyncify`/`wrapSync` for making sync functions work with callbacks. ([#671](https://github.com/caolan/async/issues/671), [#806](https://github.com/caolan/async/issues/806))
- Added `during` and `doDuring`, which are like `whilst` with an async truth test. ([#800](https://github.com/caolan/async/issues/800))
- `retry` now accepts an `interval` parameter to specify a delay between retries. ([#793](https://github.com/caolan/async/issues/793))
- `async` should work better in Web Workers due to better `root` detection ([#804](https://github.com/caolan/async/issues/804))
- Callbacks are now optional in `whilst`, `doWhilst`, `until`, and `doUntil` ([#642](https://github.com/caolan/async/issues/642))
- Various internal updates ([#786](https://github.com/caolan/async/issues/786), [#801](https://github.com/caolan/async/issues/801), [#802](https://github.com/caolan/async/issues/802), [#803](https://github.com/caolan/async/issues/803))
- Various doc fixes ([#790](https://github.com/caolan/async/issues/790), [#794](https://github.com/caolan/async/issues/794))
Bug Fixes:
- `cargo` now exposes the `payload` size, and `cargo.payload` can be changed on the fly after the `cargo` is created. ([#740](https://github.com/caolan/async/issues/740), [#744](https://github.com/caolan/async/issues/744), [#783](https://github.com/caolan/async/issues/783))
# v1.2.1
Bug Fix:
- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. ([#782](https://github.com/caolan/async/issues/782))
# v1.2.0
New Features:
- Added `timesLimit` ([#743](https://github.com/caolan/async/issues/743))
- `concurrency` can be changed after initialization in `queue` by setting `q.concurrency`. The new concurrency will be reflected the next time a task is processed. ([#747](https://github.com/caolan/async/issues/747), [#772](https://github.com/caolan/async/issues/772))
Bug Fixes:
- Fixed a regression in `each` and family with empty arrays that have additional properties. ([#775](https://github.com/caolan/async/issues/775), [#777](https://github.com/caolan/async/issues/777))
# v1.1.1
Bug Fix:
- Small regression with synchronous iterator behavior in `eachSeries` with a 1-element array. Before 1.1.0, `eachSeries`'s callback was called on the same tick, which this patch restores. In 2.0.0, it will be called on the next tick. ([#782](https://github.com/caolan/async/issues/782))
# v1.1.0
New Features:
- `cargo` now supports all of the same methods and event callbacks as `queue`.
- Added `ensureAsync` - A wrapper that ensures an async function calls its callback on a later tick. ([#769](https://github.com/caolan/async/issues/769))
- Optimized `map`, `eachOf`, and `waterfall` families of functions
- Passing a `null` or `undefined` array to `map`, `each`, `parallel` and families will be treated as an empty array ([#667](https://github.com/caolan/async/issues/667)).
- The callback is now optional for the composed results of `compose` and `seq`. ([#618](https://github.com/caolan/async/issues/618))
- Reduced file size by 4kb, (minified version by 1kb)
- Added code coverage through `nyc` and `coveralls` ([#768](https://github.com/caolan/async/issues/768))
Bug Fixes:
- `forever` will no longer stack overflow with a synchronous iterator ([#622](https://github.com/caolan/async/issues/622))
- `eachLimit` and other limit functions will stop iterating once an error occurs ([#754](https://github.com/caolan/async/issues/754))
- Always pass `null` in callbacks when there is no error ([#439](https://github.com/caolan/async/issues/439))
- Ensure proper conditions when calling `drain()` after pushing an empty data set to a queue ([#668](https://github.com/caolan/async/issues/668))
- `each` and family will properly handle an empty array ([#578](https://github.com/caolan/async/issues/578))
- `eachSeries` and family will finish if the underlying array is modified during execution ([#557](https://github.com/caolan/async/issues/557))
- `queue` will throw if a non-function is passed to `q.push()` ([#593](https://github.com/caolan/async/issues/593))
- Doc fixes ([#629](https://github.com/caolan/async/issues/629), [#766](https://github.com/caolan/async/issues/766))
# v1.0.0
No known breaking changes, we are simply complying with semver from here on out.
Changes:
- Start using a changelog!
- Add `forEachOf` for iterating over Objects (or to iterate Arrays with indexes available) ([#168](https://github.com/caolan/async/issues/168) [#704](https://github.com/caolan/async/issues/704) [#321](https://github.com/caolan/async/issues/321))
- Detect deadlocks in `auto` ([#663](https://github.com/caolan/async/issues/663))
- Better support for require.js ([#527](https://github.com/caolan/async/issues/527))
- Throw if queue created with concurrency `0` ([#714](https://github.com/caolan/async/issues/714))
- Fix unneeded iteration in `queue.resume()` ([#758](https://github.com/caolan/async/issues/758))
- Guard against timer mocking overriding `setImmediate` ([#609](https://github.com/caolan/async/issues/609) [#611](https://github.com/caolan/async/issues/611))
- Miscellaneous doc fixes ([#542](https://github.com/caolan/async/issues/542) [#596](https://github.com/caolan/async/issues/596) [#615](https://github.com/caolan/async/issues/615) [#628](https://github.com/caolan/async/issues/628) [#631](https://github.com/caolan/async/issues/631) [#690](https://github.com/caolan/async/issues/690) [#729](https://github.com/caolan/async/issues/729))
- Use single noop function internally ([#546](https://github.com/caolan/async/issues/546))
- Optimize internal `_each`, `_map` and `_keys` functions.

View File

@ -0,0 +1,19 @@
Copyright (c) 2010-2018 Caolan McMahon
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.

View File

@ -0,0 +1,60 @@
![Async Logo](https://raw.githubusercontent.com/caolan/async/master/logo/async-logo_readme.jpg)
[![Build Status via Travis CI](https://travis-ci.org/caolan/async.svg?branch=master)](https://travis-ci.org/caolan/async)
[![Build Status via Azure Pipelines](https://dev.azure.com/caolanmcmahon/async/_apis/build/status/caolan.async?branchName=master)](https://dev.azure.com/caolanmcmahon/async/_build/latest?definitionId=1&branchName=master)
[![NPM version](https://img.shields.io/npm/v/async.svg)](https://www.npmjs.com/package/async)
[![Coverage Status](https://coveralls.io/repos/caolan/async/badge.svg?branch=master)](https://coveralls.io/r/caolan/async?branch=master)
[![Join the chat at https://gitter.im/caolan/async](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/caolan/async?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/async/badge?style=rounded)](https://www.jsdelivr.com/package/npm/async)
<!--
|Linux|Windows|MacOS|
|-|-|-|
|[![Linux Build Status](https://dev.azure.com/caolanmcmahon/async/_apis/build/status/caolan.async?branchName=master&jobName=Linux&configuration=Linux%20node_10_x)](https://dev.azure.com/caolanmcmahon/async/_build/latest?definitionId=1&branchName=master) | [![Windows Build Status](https://dev.azure.com/caolanmcmahon/async/_apis/build/status/caolan.async?branchName=master&jobName=Windows&configuration=Windows%20node_10_x)](https://dev.azure.com/caolanmcmahon/async/_build/latest?definitionId=1&branchName=master) | [![MacOS Build Status](https://dev.azure.com/caolanmcmahon/async/_apis/build/status/caolan.async?branchName=master&jobName=OSX&configuration=OSX%20node_10_x)](https://dev.azure.com/caolanmcmahon/async/_build/latest?definitionId=1&branchName=master)| -->
Async is a utility module which provides straight-forward, powerful functions for working with [asynchronous JavaScript](http://caolan.github.io/async/v3/global.html). Although originally designed for use with [Node.js](https://nodejs.org/) and installable via `npm i async`, it can also be used directly in the browser. A ESM/MJS version is included in the main `async` package that should automatically be used with compatible bundlers such as Webpack and Rollup.
A pure ESM version of Async is available as [`async-es`](https://www.npmjs.com/package/async-es).
For Documentation, visit <https://caolan.github.io/async/>
*For Async v1.5.x documentation, go [HERE](https://github.com/caolan/async/blob/v1.5.2/README.md)*
```javascript
// for use with Node-style callbacks...
var async = require("async");
var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
var configs = {};
async.forEachOf(obj, (value, key, callback) => {
fs.readFile(__dirname + value, "utf8", (err, data) => {
if (err) return callback(err);
try {
configs[key] = JSON.parse(data);
} catch (e) {
return callback(e);
}
callback();
});
}, err => {
if (err) console.error(err.message);
// configs is now a map of JSON data
doSomethingWith(configs);
});
```
```javascript
var async = require("async");
// ...or ES2017 async functions
async.mapLimit(urls, 5, async function(url) {
const response = await fetch(url)
return response.body
}, (err, results) => {
if (err) throw err
// results is now an array of the response bodies
console.log(results)
})
```

View File

@ -0,0 +1,54 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns `true` if every element in `coll` satisfies an async test. If any
* iteratee call returns `false`, the main `callback` is immediately called.
*
* @name every
* @static
* @memberOf module:Collections
* @method
* @alias all
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in parallel.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
* @example
*
* async.every(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, result) {
* // if result is true then every file exists
* });
*/
function every(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(every, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,46 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
*
* @name everyLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.every]{@link module:Collections.every}
* @alias allLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in parallel.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function everyLimit(coll, limit, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(everyLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,45 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfSeries = require('./eachOfSeries');
var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
*
* @name everySeries
* @static
* @memberOf module:Collections
* @method
* @see [async.every]{@link module:Collections.every}
* @alias allSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in series.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function everySeries(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOfSeries2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(everySeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,56 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns `true` if at least one element in the `coll` satisfies an async test.
* If any iteratee call returns `true`, the main `callback` is immediately
* called.
*
* @name some
* @static
* @memberOf module:Collections
* @method
* @alias any
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collections in parallel.
* The iteratee should complete with a boolean `result` value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the iteratee functions have finished.
* Result will be either `true` or `false` depending on the values of the async
* tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
* @example
*
* async.some(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, result) {
* // if result is true then at least one of the files exists
* });
*/
function some(coll, iteratee, callback) {
return (0, _createTester2.default)(Boolean, res => res)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(some, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.
*
* @name someLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.some]{@link module:Collections.some}
* @alias anyLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collections in parallel.
* The iteratee should complete with a boolean `result` value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the iteratee functions have finished.
* Result will be either `true` or `false` depending on the values of the async
* tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function someLimit(coll, limit, iteratee, callback) {
return (0, _createTester2.default)(Boolean, res => res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(someLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,46 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfSeries = require('./eachOfSeries');
var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.
*
* @name someSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.some]{@link module:Collections.some}
* @alias anySeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collections in series.
* The iteratee should complete with a boolean `result` value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the iteratee functions have finished.
* Result will be either `true` or `false` depending on the values of the async
* tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function someSeries(coll, iteratee, callback) {
return (0, _createTester2.default)(Boolean, res => res)(_eachOfSeries2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(someSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (fn, ...args) {
return (...callArgs) => fn(...args, ...callArgs);
};
module.exports = exports["default"]; /**
* Creates a continuation function with some arguments already applied.
*
* Useful as a shorthand when combined with other control flow functions. Any
* arguments passed to the returned function are added to the arguments
* originally passed to apply.
*
* @name apply
* @static
* @memberOf module:Utils
* @method
* @category Util
* @param {Function} fn - The function you want to eventually apply all
* arguments to. Invokes with (arguments...).
* @param {...*} arguments... - Any number of arguments to automatically apply
* when the continuation is called.
* @returns {Function} the partially-applied function
* @example
*
* // using apply
* async.parallel([
* async.apply(fs.writeFile, 'testfile1', 'test1'),
* async.apply(fs.writeFile, 'testfile2', 'test2')
* ]);
*
*
* // the same process without using apply
* async.parallel([
* function(callback) {
* fs.writeFile('testfile1', 'test1', callback);
* },
* function(callback) {
* fs.writeFile('testfile2', 'test2', callback);
* }
* ]);
*
* // It's possible to pass any number of additional arguments when calling the
* // continuation:
*
* node> var fn = async.apply(sys.puts, 'one');
* node> fn('two', 'three');
* one
* two
* three
*/

View File

@ -0,0 +1,57 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _applyEach = require('./internal/applyEach');
var _applyEach2 = _interopRequireDefault(_applyEach);
var _map = require('./map');
var _map2 = _interopRequireDefault(_map);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Applies the provided arguments to each function in the array, calling
* `callback` after all functions have completed. If you only provide the first
* argument, `fns`, then it will return a function which lets you pass in the
* arguments as if it were a single function call. If more arguments are
* provided, `callback` is required while `args` is still optional. The results
* for each of the applied async functions are passed to the final callback
* as an array.
*
* @name applyEach
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s
* to all call with the same arguments
* @param {...*} [args] - any number of separate arguments to pass to the
* function.
* @param {Function} [callback] - the final argument should be the callback,
* called when all functions have completed processing.
* @returns {AsyncFunction} - Returns a function that takes no args other than
* an optional callback, that is the result of applying the `args` to each
* of the functions.
* @example
*
* const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')
*
* appliedFn((err, results) => {
* // results[0] is the results for `enableSearch`
* // results[1] is the results for `updateSchema`
* });
*
* // partial application example:
* async.each(
* buckets,
* async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),
* callback
* );
*/
exports.default = (0, _applyEach2.default)(_map2.default);
module.exports = exports['default'];

View File

@ -0,0 +1,37 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _applyEach = require('./internal/applyEach');
var _applyEach2 = _interopRequireDefault(_applyEach);
var _mapSeries = require('./mapSeries');
var _mapSeries2 = _interopRequireDefault(_mapSeries);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.
*
* @name applyEachSeries
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.applyEach]{@link module:ControlFlow.applyEach}
* @category Control Flow
* @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all
* call with the same arguments
* @param {...*} [args] - any number of separate arguments to pass to the
* function.
* @param {Function} [callback] - the final argument should be the callback,
* called when all functions have completed processing.
* @returns {AsyncFunction} - A function, that when called, is the result of
* appling the `args` to the list of functions. It takes no args, other than
* a callback.
*/
exports.default = (0, _applyEach2.default)(_mapSeries2.default);
module.exports = exports['default'];

View File

@ -0,0 +1,118 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = asyncify;
var _initialParams = require('./internal/initialParams');
var _initialParams2 = _interopRequireDefault(_initialParams);
var _setImmediate = require('./internal/setImmediate');
var _setImmediate2 = _interopRequireDefault(_setImmediate);
var _wrapAsync = require('./internal/wrapAsync');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Take a sync function and make it async, passing its return value to a
* callback. This is useful for plugging sync functions into a waterfall,
* series, or other async functions. Any arguments passed to the generated
* function will be passed to the wrapped function (except for the final
* callback argument). Errors thrown will be passed to the callback.
*
* If the function passed to `asyncify` returns a Promise, that promises's
* resolved/rejected state will be used to call the callback, rather than simply
* the synchronous return value.
*
* This also means you can asyncify ES2017 `async` functions.
*
* @name asyncify
* @static
* @memberOf module:Utils
* @method
* @alias wrapSync
* @category Util
* @param {Function} func - The synchronous function, or Promise-returning
* function to convert to an {@link AsyncFunction}.
* @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be
* invoked with `(args..., callback)`.
* @example
*
* // passing a regular synchronous function
* async.waterfall([
* async.apply(fs.readFile, filename, "utf8"),
* async.asyncify(JSON.parse),
* function (data, next) {
* // data is the result of parsing the text.
* // If there was a parsing error, it would have been caught.
* }
* ], callback);
*
* // passing a function returning a promise
* async.waterfall([
* async.apply(fs.readFile, filename, "utf8"),
* async.asyncify(function (contents) {
* return db.model.create(contents);
* }),
* function (model, next) {
* // `model` is the instantiated model object.
* // If there was an error, this function would be skipped.
* }
* ], callback);
*
* // es2017 example, though `asyncify` is not needed if your JS environment
* // supports async functions out of the box
* var q = async.queue(async.asyncify(async function(file) {
* var intermediateStep = await processFile(file);
* return await somePromise(intermediateStep)
* }));
*
* q.push(files);
*/
function asyncify(func) {
if ((0, _wrapAsync.isAsync)(func)) {
return function (...args /*, callback*/) {
const callback = args.pop();
const promise = func.apply(this, args);
return handlePromise(promise, callback);
};
}
return (0, _initialParams2.default)(function (args, callback) {
var result;
try {
result = func.apply(this, args);
} catch (e) {
return callback(e);
}
// if result is Promise object
if (result && typeof result.then === 'function') {
return handlePromise(result, callback);
} else {
callback(null, result);
}
});
}
function handlePromise(promise, callback) {
return promise.then(value => {
invokeCallback(callback, null, value);
}, err => {
invokeCallback(callback, err && err.message ? err : new Error(err));
});
}
function invokeCallback(callback, error, value) {
try {
callback(error, value);
} catch (err) {
(0, _setImmediate2.default)(e => {
throw e;
}, err);
}
}
module.exports = exports['default'];

View File

@ -0,0 +1,267 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = auto;
var _once = require('./internal/once');
var _once2 = _interopRequireDefault(_once);
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _promiseCallback = require('./internal/promiseCallback');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on
* their requirements. Each function can optionally depend on other functions
* being completed first, and each function is run as soon as its requirements
* are satisfied.
*
* If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence
* will stop. Further tasks will not execute (so any other functions depending
* on it will not run), and the main `callback` is immediately called with the
* error.
*
* {@link AsyncFunction}s also receive an object containing the results of functions which
* have completed so far as the first argument, if they have dependencies. If a
* task function has no dependencies, it will only be passed a callback.
*
* @name auto
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {Object} tasks - An object. Each of its properties is either a
* function or an array of requirements, with the {@link AsyncFunction} itself the last item
* in the array. The object's key of a property serves as the name of the task
* defined by that property, i.e. can be used when specifying requirements for
* other tasks. The function receives one or two arguments:
* * a `results` object, containing the results of the previously executed
* functions, only passed if the task has any dependencies,
* * a `callback(err, result)` function, which must be called when finished,
* passing an `error` (which can be `null`) and the result of the function's
* execution.
* @param {number} [concurrency=Infinity] - An optional `integer` for
* determining the maximum number of tasks that can be run in parallel. By
* default, as many as possible.
* @param {Function} [callback] - An optional callback which is called when all
* the tasks have been completed. It receives the `err` argument if any `tasks`
* pass an error to their callback. Results are always returned; however, if an
* error occurs, no further `tasks` will be performed, and the results object
* will only contain partial results. Invoked with (err, results).
* @returns {Promise} a promise, if a callback is not passed
* @example
*
* async.auto({
* // this function will just be passed a callback
* readData: async.apply(fs.readFile, 'data.txt', 'utf-8'),
* showData: ['readData', function(results, cb) {
* // results.readData is the file's contents
* // ...
* }]
* }, callback);
*
* async.auto({
* get_data: function(callback) {
* console.log('in get_data');
* // async code to get some data
* callback(null, 'data', 'converted to array');
* },
* make_folder: function(callback) {
* console.log('in make_folder');
* // async code to create a directory to store a file in
* // this is run at the same time as getting the data
* callback(null, 'folder');
* },
* write_file: ['get_data', 'make_folder', function(results, callback) {
* console.log('in write_file', JSON.stringify(results));
* // once there is some data and the directory exists,
* // write the data to a file in the directory
* callback(null, 'filename');
* }],
* email_link: ['write_file', function(results, callback) {
* console.log('in email_link', JSON.stringify(results));
* // once the file is written let's email a link to it...
* // results.write_file contains the filename returned by write_file.
* callback(null, {'file':results.write_file, 'email':'user@example.com'});
* }]
* }, function(err, results) {
* console.log('err = ', err);
* console.log('results = ', results);
* });
*/
function auto(tasks, concurrency, callback) {
if (typeof concurrency !== 'number') {
// concurrency is optional, shift the args.
callback = concurrency;
concurrency = null;
}
callback = (0, _once2.default)(callback || (0, _promiseCallback.promiseCallback)());
var numTasks = Object.keys(tasks).length;
if (!numTasks) {
return callback(null);
}
if (!concurrency) {
concurrency = numTasks;
}
var results = {};
var runningTasks = 0;
var canceled = false;
var hasError = false;
var listeners = Object.create(null);
var readyTasks = [];
// for cycle detection:
var readyToCheck = []; // tasks that have been identified as reachable
// without the possibility of returning to an ancestor task
var uncheckedDependencies = {};
Object.keys(tasks).forEach(key => {
var task = tasks[key];
if (!Array.isArray(task)) {
// no dependencies
enqueueTask(key, [task]);
readyToCheck.push(key);
return;
}
var dependencies = task.slice(0, task.length - 1);
var remainingDependencies = dependencies.length;
if (remainingDependencies === 0) {
enqueueTask(key, task);
readyToCheck.push(key);
return;
}
uncheckedDependencies[key] = remainingDependencies;
dependencies.forEach(dependencyName => {
if (!tasks[dependencyName]) {
throw new Error('async.auto task `' + key + '` has a non-existent dependency `' + dependencyName + '` in ' + dependencies.join(', '));
}
addListener(dependencyName, () => {
remainingDependencies--;
if (remainingDependencies === 0) {
enqueueTask(key, task);
}
});
});
});
checkForDeadlocks();
processQueue();
function enqueueTask(key, task) {
readyTasks.push(() => runTask(key, task));
}
function processQueue() {
if (canceled) return;
if (readyTasks.length === 0 && runningTasks === 0) {
return callback(null, results);
}
while (readyTasks.length && runningTasks < concurrency) {
var run = readyTasks.shift();
run();
}
}
function addListener(taskName, fn) {
var taskListeners = listeners[taskName];
if (!taskListeners) {
taskListeners = listeners[taskName] = [];
}
taskListeners.push(fn);
}
function taskComplete(taskName) {
var taskListeners = listeners[taskName] || [];
taskListeners.forEach(fn => fn());
processQueue();
}
function runTask(key, task) {
if (hasError) return;
var taskCallback = (0, _onlyOnce2.default)((err, ...result) => {
runningTasks--;
if (err === false) {
canceled = true;
return;
}
if (result.length < 2) {
[result] = result;
}
if (err) {
var safeResults = {};
Object.keys(results).forEach(rkey => {
safeResults[rkey] = results[rkey];
});
safeResults[key] = result;
hasError = true;
listeners = Object.create(null);
if (canceled) return;
callback(err, safeResults);
} else {
results[key] = result;
taskComplete(key);
}
});
runningTasks++;
var taskFn = (0, _wrapAsync2.default)(task[task.length - 1]);
if (task.length > 1) {
taskFn(results, taskCallback);
} else {
taskFn(taskCallback);
}
}
function checkForDeadlocks() {
// Kahn's algorithm
// https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm
// http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html
var currentTask;
var counter = 0;
while (readyToCheck.length) {
currentTask = readyToCheck.pop();
counter++;
getDependents(currentTask).forEach(dependent => {
if (--uncheckedDependencies[dependent] === 0) {
readyToCheck.push(dependent);
}
});
}
if (counter !== numTasks) {
throw new Error('async.auto cannot execute tasks due to a recursive dependency');
}
}
function getDependents(taskName) {
var result = [];
Object.keys(tasks).forEach(key => {
const task = tasks[key];
if (Array.isArray(task) && task.indexOf(taskName) >= 0) {
result.push(key);
}
});
return result;
}
return callback[_promiseCallback.PROMISE_SYMBOL];
}
module.exports = exports['default'];

View File

@ -0,0 +1,156 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = autoInject;
var _auto = require('./auto');
var _auto2 = _interopRequireDefault(_auto);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var FN_ARGS = /^(?:async\s+)?(?:function)?\s*\w*\s*\(\s*([^)]+)\s*\)(?:\s*{)/;
var ARROW_FN_ARGS = /^(?:async\s+)?\(?\s*([^)=]+)\s*\)?(?:\s*=>)/;
var FN_ARG_SPLIT = /,/;
var FN_ARG = /(=.+)?(\s*)$/;
var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg;
function parseParams(func) {
const src = func.toString().replace(STRIP_COMMENTS, '');
let match = src.match(FN_ARGS);
if (!match) {
match = src.match(ARROW_FN_ARGS);
}
if (!match) throw new Error('could not parse args in autoInject\nSource:\n' + src);
let [, args] = match;
return args.replace(/\s/g, '').split(FN_ARG_SPLIT).map(arg => arg.replace(FN_ARG, '').trim());
}
/**
* A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent
* tasks are specified as parameters to the function, after the usual callback
* parameter, with the parameter names matching the names of the tasks it
* depends on. This can provide even more readable task graphs which can be
* easier to maintain.
*
* If a final callback is specified, the task results are similarly injected,
* specified as named parameters after the initial error parameter.
*
* The autoInject function is purely syntactic sugar and its semantics are
* otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.
*
* @name autoInject
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.auto]{@link module:ControlFlow.auto}
* @category Control Flow
* @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of
* the form 'func([dependencies...], callback). The object's key of a property
* serves as the name of the task defined by that property, i.e. can be used
* when specifying requirements for other tasks.
* * The `callback` parameter is a `callback(err, result)` which must be called
* when finished, passing an `error` (which can be `null`) and the result of
* the function's execution. The remaining parameters name other tasks on
* which the task is dependent, and the results from those tasks are the
* arguments of those parameters.
* @param {Function} [callback] - An optional callback which is called when all
* the tasks have been completed. It receives the `err` argument if any `tasks`
* pass an error to their callback, and a `results` object with any completed
* task results, similar to `auto`.
* @returns {Promise} a promise, if no callback is passed
* @example
*
* // The example from `auto` can be rewritten as follows:
* async.autoInject({
* get_data: function(callback) {
* // async code to get some data
* callback(null, 'data', 'converted to array');
* },
* make_folder: function(callback) {
* // async code to create a directory to store a file in
* // this is run at the same time as getting the data
* callback(null, 'folder');
* },
* write_file: function(get_data, make_folder, callback) {
* // once there is some data and the directory exists,
* // write the data to a file in the directory
* callback(null, 'filename');
* },
* email_link: function(write_file, callback) {
* // once the file is written let's email a link to it...
* // write_file contains the filename returned by write_file.
* callback(null, {'file':write_file, 'email':'user@example.com'});
* }
* }, function(err, results) {
* console.log('err = ', err);
* console.log('email_link = ', results.email_link);
* });
*
* // If you are using a JS minifier that mangles parameter names, `autoInject`
* // will not work with plain functions, since the parameter names will be
* // collapsed to a single letter identifier. To work around this, you can
* // explicitly specify the names of the parameters your task function needs
* // in an array, similar to Angular.js dependency injection.
*
* // This still has an advantage over plain `auto`, since the results a task
* // depends on are still spread into arguments.
* async.autoInject({
* //...
* write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {
* callback(null, 'filename');
* }],
* email_link: ['write_file', function(write_file, callback) {
* callback(null, {'file':write_file, 'email':'user@example.com'});
* }]
* //...
* }, function(err, results) {
* console.log('err = ', err);
* console.log('email_link = ', results.email_link);
* });
*/
function autoInject(tasks, callback) {
var newTasks = {};
Object.keys(tasks).forEach(key => {
var taskFn = tasks[key];
var params;
var fnIsAsync = (0, _wrapAsync.isAsync)(taskFn);
var hasNoDeps = !fnIsAsync && taskFn.length === 1 || fnIsAsync && taskFn.length === 0;
if (Array.isArray(taskFn)) {
params = [...taskFn];
taskFn = params.pop();
newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);
} else if (hasNoDeps) {
// no dependencies, use the function as-is
newTasks[key] = taskFn;
} else {
params = parseParams(taskFn);
if (taskFn.length === 0 && !fnIsAsync && params.length === 0) {
throw new Error("autoInject task functions require explicit parameters.");
}
// remove callback param
if (!fnIsAsync) params.pop();
newTasks[key] = params.concat(newTask);
}
function newTask(results, taskCb) {
var newArgs = params.map(name => results[name]);
newArgs.push(taskCb);
(0, _wrapAsync2.default)(taskFn)(...newArgs);
}
});
return (0, _auto2.default)(newTasks, callback);
}
module.exports = exports['default'];

View File

@ -0,0 +1,17 @@
{
"name": "async",
"main": "dist/async.js",
"ignore": [
"bower_components",
"lib",
"test",
"node_modules",
"perf",
"support",
"**/.*",
"*.config.js",
"*.json",
"index.js",
"Makefile"
]
}

View File

@ -0,0 +1,63 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = cargo;
var _queue = require('./internal/queue');
var _queue2 = _interopRequireDefault(_queue);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Creates a `cargo` object with the specified payload. Tasks added to the
* cargo will be processed altogether (up to the `payload` limit). If the
* `worker` is in progress, the task is queued until it becomes available. Once
* the `worker` has completed some tasks, each callback of those tasks is
* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
* for how `cargo` and `queue` work.
*
* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
* at a time, cargo passes an array of tasks to a single worker, repeating
* when the worker is finished.
*
* @name cargo
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.queue]{@link module:ControlFlow.queue}
* @category Control Flow
* @param {AsyncFunction} worker - An asynchronous function for processing an array
* of queued tasks. Invoked with `(tasks, callback)`.
* @param {number} [payload=Infinity] - An optional `integer` for determining
* how many tasks should be processed per round; if omitted, the default is
* unlimited.
* @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can
* attached as certain properties to listen for specific events during the
* lifecycle of the cargo and inner queue.
* @example
*
* // create a cargo object with payload 2
* var cargo = async.cargo(function(tasks, callback) {
* for (var i=0; i<tasks.length; i++) {
* console.log('hello ' + tasks[i].name);
* }
* callback();
* }, 2);
*
* // add some items
* cargo.push({name: 'foo'}, function(err) {
* console.log('finished processing foo');
* });
* cargo.push({name: 'bar'}, function(err) {
* console.log('finished processing bar');
* });
* await cargo.push({name: 'baz'});
* console.log('finished processing baz');
*/
function cargo(worker, payload) {
return (0, _queue2.default)(worker, 1, payload);
}
module.exports = exports['default'];

View File

@ -0,0 +1,71 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = cargo;
var _queue = require('./internal/queue');
var _queue2 = _interopRequireDefault(_queue);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Creates a `cargoQueue` object with the specified payload. Tasks added to the
* cargoQueue will be processed together (up to the `payload` limit) in `concurrency` parallel workers.
* If the all `workers` are in progress, the task is queued until one becomes available. Once
* a `worker` has completed some tasks, each callback of those tasks is
* called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)
* for how `cargo` and `queue` work.
*
* While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers
* at a time, and [`cargo`]{@link module:ControlFlow.cargo} passes an array of tasks to a single worker,
* the cargoQueue passes an array of tasks to multiple parallel workers.
*
* @name cargoQueue
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.queue]{@link module:ControlFlow.queue}
* @see [async.cargo]{@link module:ControlFLow.cargo}
* @category Control Flow
* @param {AsyncFunction} worker - An asynchronous function for processing an array
* of queued tasks. Invoked with `(tasks, callback)`.
* @param {number} [concurrency=1] - An `integer` for determining how many
* `worker` functions should be run in parallel. If omitted, the concurrency
* defaults to `1`. If the concurrency is `0`, an error is thrown.
* @param {number} [payload=Infinity] - An optional `integer` for determining
* how many tasks should be processed per round; if omitted, the default is
* unlimited.
* @returns {module:ControlFlow.QueueObject} A cargoQueue object to manage the tasks. Callbacks can
* attached as certain properties to listen for specific events during the
* lifecycle of the cargoQueue and inner queue.
* @example
*
* // create a cargoQueue object with payload 2 and concurrency 2
* var cargoQueue = async.cargoQueue(function(tasks, callback) {
* for (var i=0; i<tasks.length; i++) {
* console.log('hello ' + tasks[i].name);
* }
* callback();
* }, 2, 2);
*
* // add some items
* cargoQueue.push({name: 'foo'}, function(err) {
* console.log('finished processing foo');
* });
* cargoQueue.push({name: 'bar'}, function(err) {
* console.log('finished processing bar');
* });
* cargoQueue.push({name: 'baz'}, function(err) {
* console.log('finished processing baz');
* });
* cargoQueue.push({name: 'boo'}, function(err) {
* console.log('finished processing boo');
* });
*/
function cargo(worker, concurrency, payload) {
return (0, _queue2.default)(worker, concurrency, payload);
}
module.exports = exports['default'];

View File

@ -0,0 +1,55 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = compose;
var _seq = require('./seq');
var _seq2 = _interopRequireDefault(_seq);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Creates a function which is a composition of the passed asynchronous
* functions. Each function consumes the return value of the function that
* follows. Composing functions `f()`, `g()`, and `h()` would produce the result
* of `f(g(h()))`, only this version uses callbacks to obtain the return values.
*
* If the last argument to the composed function is not a function, a promise
* is returned when you call it.
*
* Each function is executed with the `this` binding of the composed function.
*
* @name compose
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {...AsyncFunction} functions - the asynchronous functions to compose
* @returns {Function} an asynchronous function that is the composed
* asynchronous `functions`
* @example
*
* function add1(n, callback) {
* setTimeout(function () {
* callback(null, n + 1);
* }, 10);
* }
*
* function mul3(n, callback) {
* setTimeout(function () {
* callback(null, n * 3);
* }, 10);
* }
*
* var add1mul3 = async.compose(mul3, add1);
* add1mul3(4, function (err, result) {
* // result now equals 15
* });
*/
function compose(...args) {
return (0, _seq2.default)(...args.reverse());
}
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _concatLimit = require('./concatLimit');
var _concatLimit2 = _interopRequireDefault(_concatLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Applies `iteratee` to each item in `coll`, concatenating the results. Returns
* the concatenated list. The `iteratee`s are called in parallel, and the
* results are concatenated as they return. The results array will be returned in
* the original order of `coll` passed to the `iteratee` function.
*
* @name concat
* @static
* @memberOf module:Collections
* @method
* @category Collection
* @alias flatMap
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
* which should use an array as its result. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
* @example
*
* async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
* // files is now a list of filenames that exist in the 3 directories
* });
*/
function concat(coll, iteratee, callback) {
return (0, _concatLimit2.default)(coll, Infinity, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(concat, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _mapLimit = require('./mapLimit');
var _mapLimit2 = _interopRequireDefault(_mapLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
*
* @name concatLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.concat]{@link module:Collections.concat}
* @category Collection
* @alias flatMapLimit
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
* which should use an array as its result. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
*/
function concatLimit(coll, limit, iteratee, callback) {
var _iteratee = (0, _wrapAsync2.default)(iteratee);
return (0, _mapLimit2.default)(coll, limit, (val, iterCb) => {
_iteratee(val, (err, ...args) => {
if (err) return iterCb(err);
return iterCb(err, args);
});
}, (err, mapResults) => {
var result = [];
for (var i = 0; i < mapResults.length; i++) {
if (mapResults[i]) {
result = result.concat(...mapResults[i]);
}
}
return callback(err, result);
});
}
exports.default = (0, _awaitify2.default)(concatLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,41 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _concatLimit = require('./concatLimit');
var _concatLimit2 = _interopRequireDefault(_concatLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
*
* @name concatSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.concat]{@link module:Collections.concat}
* @category Collection
* @alias flatMapSeries
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
* The iteratee should complete with an array an array of results.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
*/
function concatSeries(coll, iteratee, callback) {
return (0, _concatLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(concatSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,55 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (...args) {
return function (...ignoredArgs /*, callback*/) {
var callback = ignoredArgs.pop();
return callback(null, ...args);
};
};
module.exports = exports["default"]; /**
* Returns a function that when called, calls-back with the values provided.
* Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to
* [`auto`]{@link module:ControlFlow.auto}.
*
* @name constant
* @static
* @memberOf module:Utils
* @method
* @category Util
* @param {...*} arguments... - Any number of arguments to automatically invoke
* callback with.
* @returns {AsyncFunction} Returns a function that when invoked, automatically
* invokes the callback with the previous given arguments.
* @example
*
* async.waterfall([
* async.constant(42),
* function (value, next) {
* // value === 42
* },
* //...
* ], callback);
*
* async.waterfall([
* async.constant(filename, "utf8"),
* fs.readFile,
* function (fileData, next) {
* //...
* }
* //...
* ], callback);
*
* async.auto({
* hostname: async.constant("https://server.net/"),
* port: findFreePort,
* launchServer: ["hostname", "port", function (options, cb) {
* startServer(options, cb);
* }],
* //...
* }, callback);
*/

View File

@ -0,0 +1,61 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns the first value in `coll` that passes an async truth test. The
* `iteratee` is applied in parallel, meaning the first iteratee to return
* `true` will fire the detect `callback` with that result. That means the
* result might not be the first item in the original `coll` (in terms of order)
* that passes the test.
* If order within the original `coll` is important, then look at
* [`detectSeries`]{@link module:Collections.detectSeries}.
*
* @name detect
* @static
* @memberOf module:Collections
* @method
* @alias find
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns A Promise, if no callback is passed
* @example
*
* async.detect(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, result) {
* // result now equals the first file in the list that exists
* });
*/
function detect(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detect, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,48 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
* time.
*
* @name detectLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.detect]{@link module:Collections.detect}
* @alias findLimit
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns a Promise if no callback is passed
*/
function detectLimit(coll, limit, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detectLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
*
* @name detectSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.detect]{@link module:Collections.detect}
* @alias findSeries
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns a Promise if no callback is passed
*/
function detectSeries(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(1), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detectSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,43 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _consoleFunc = require('./internal/consoleFunc');
var _consoleFunc2 = _interopRequireDefault(_consoleFunc);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Logs the result of an [`async` function]{@link AsyncFunction} to the
* `console` using `console.dir` to display the properties of the resulting object.
* Only works in Node.js or in browsers that support `console.dir` and
* `console.error` (such as FF and Chrome).
* If multiple arguments are returned from the async function,
* `console.dir` is called on each argument in order.
*
* @name dir
* @static
* @memberOf module:Utils
* @method
* @category Util
* @param {AsyncFunction} function - The function you want to eventually apply
* all arguments to.
* @param {...*} arguments... - Any number of arguments to apply to the function.
* @example
*
* // in a module
* var hello = function(name, callback) {
* setTimeout(function() {
* callback(null, {hello: name});
* }, 1000);
* };
*
* // in the node repl
* node> async.dir(hello, 'world');
* {hello: 'world'}
*/
exports.default = (0, _consoleFunc2.default)('dir');
module.exports = exports['default'];

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,68 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
* the order of operations, the arguments `test` and `iteratee` are switched.
*
* `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
*
* @name doWhilst
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.whilst]{@link module:ControlFlow.whilst}
* @category Control Flow
* @param {AsyncFunction} iteratee - A function which is called each time `test`
* passes. Invoked with (callback).
* @param {AsyncFunction} test - asynchronous truth test to perform after each
* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
* non-error args from the previous callback of `iteratee`.
* @param {Function} [callback] - A callback which is called after the test
* function has failed and repeated execution of `iteratee` has stopped.
* `callback` will be passed an error and any arguments passed to the final
* `iteratee`'s callback. Invoked with (err, [results]);
* @returns {Promise} a promise, if no callback is passed
*/
function doWhilst(iteratee, test, callback) {
callback = (0, _onlyOnce2.default)(callback);
var _fn = (0, _wrapAsync2.default)(iteratee);
var _test = (0, _wrapAsync2.default)(test);
var results;
function next(err, ...args) {
if (err) return callback(err);
if (err === false) return;
results = args;
_test(...args, check);
}
function check(err, truth) {
if (err) return callback(err);
if (err === false) return;
if (!truth) return callback(null, ...results);
_fn(next);
}
return check(null, true);
}
exports.default = (0, _awaitify2.default)(doWhilst, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,46 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = doUntil;
var _doWhilst = require('./doWhilst');
var _doWhilst2 = _interopRequireDefault(_doWhilst);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the
* argument ordering differs from `until`.
*
* @name doUntil
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.doWhilst]{@link module:ControlFlow.doWhilst}
* @category Control Flow
* @param {AsyncFunction} iteratee - An async function which is called each time
* `test` fails. Invoked with (callback).
* @param {AsyncFunction} test - asynchronous truth test to perform after each
* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
* non-error args from the previous callback of `iteratee`
* @param {Function} [callback] - A callback which is called after the test
* function has passed and repeated execution of `iteratee` has stopped. `callback`
* will be passed an error and any arguments passed to the final `iteratee`'s
* callback. Invoked with (err, [results]);
* @returns {Promise} a promise, if no callback is passed
*/
function doUntil(iteratee, test, callback) {
const _test = (0, _wrapAsync2.default)(test);
return (0, _doWhilst2.default)(iteratee, (...args) => {
const cb = args.pop();
_test(...args, (err, truth) => cb(err, !truth));
}, callback);
}
module.exports = exports['default'];

View File

@ -0,0 +1,68 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in
* the order of operations, the arguments `test` and `iteratee` are switched.
*
* `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.
*
* @name doWhilst
* @static
* @memberOf module:ControlFlow
* @method
* @see [async.whilst]{@link module:ControlFlow.whilst}
* @category Control Flow
* @param {AsyncFunction} iteratee - A function which is called each time `test`
* passes. Invoked with (callback).
* @param {AsyncFunction} test - asynchronous truth test to perform after each
* execution of `iteratee`. Invoked with (...args, callback), where `...args` are the
* non-error args from the previous callback of `iteratee`.
* @param {Function} [callback] - A callback which is called after the test
* function has failed and repeated execution of `iteratee` has stopped.
* `callback` will be passed an error and any arguments passed to the final
* `iteratee`'s callback. Invoked with (err, [results]);
* @returns {Promise} a promise, if no callback is passed
*/
function doWhilst(iteratee, test, callback) {
callback = (0, _onlyOnce2.default)(callback);
var _fn = (0, _wrapAsync2.default)(iteratee);
var _test = (0, _wrapAsync2.default)(test);
var results;
function next(err, ...args) {
if (err) return callback(err);
if (err === false) return;
results = args;
_test(...args, check);
}
function check(err, truth) {
if (err) return callback(err);
if (err === false) return;
if (!truth) return callback(null, ...results);
_fn(next);
}
return check(null, true);
}
exports.default = (0, _awaitify2.default)(doWhilst, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,78 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when
* stopped, or an error occurs.
*
* @name whilst
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {AsyncFunction} test - asynchronous truth test to perform before each
* execution of `iteratee`. Invoked with ().
* @param {AsyncFunction} iteratee - An async function which is called each time
* `test` passes. Invoked with (callback).
* @param {Function} [callback] - A callback which is called after the test
* function has failed and repeated execution of `iteratee` has stopped. `callback`
* will be passed an error and any arguments passed to the final `iteratee`'s
* callback. Invoked with (err, [results]);
* @returns {Promise} a promise, if no callback is passed
* @example
*
* var count = 0;
* async.whilst(
* function test(cb) { cb(null, count < 5); },
* function iter(callback) {
* count++;
* setTimeout(function() {
* callback(null, count);
* }, 1000);
* },
* function (err, n) {
* // 5 seconds have passed, n = 5
* }
* );
*/
function whilst(test, iteratee, callback) {
callback = (0, _onlyOnce2.default)(callback);
var _fn = (0, _wrapAsync2.default)(iteratee);
var _test = (0, _wrapAsync2.default)(test);
var results = [];
function next(err, ...rest) {
if (err) return callback(err);
results = rest;
if (err === false) return;
_test(check);
}
function check(err, truth) {
if (err) return callback(err);
if (err === false) return;
if (!truth) return callback(null, ...results);
_fn(next);
}
return _test(check);
}
exports.default = (0, _awaitify2.default)(whilst, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,88 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _withoutIndex = require('./internal/withoutIndex');
var _withoutIndex2 = _interopRequireDefault(_withoutIndex);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Applies the function `iteratee` to each item in `coll`, in parallel.
* The `iteratee` is called with an item from the list, and a callback for when
* it has finished. If the `iteratee` passes an error to its `callback`, the
* main `callback` (for the `each` function) is immediately called with the
* error.
*
* Note, that since this function applies `iteratee` to each item in parallel,
* there is no guarantee that the iteratee functions will complete in order.
*
* @name each
* @static
* @memberOf module:Collections
* @method
* @alias forEach
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to
* each item in `coll`. Invoked with (item, callback).
* The array index is not passed to the iteratee.
* If you need the index, use `eachOf`.
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
* @example
*
* // assuming openFiles is an array of file names and saveFile is a function
* // to save the modified contents of that file:
*
* async.each(openFiles, saveFile, function(err){
* // if any of the saves produced an error, err would equal that error
* });
*
* // assuming openFiles is an array of file names
* async.each(openFiles, function(file, callback) {
*
* // Perform operation on file here.
* console.log('Processing file ' + file);
*
* if( file.length > 32 ) {
* console.log('This file name is too long');
* callback('File name too long');
* } else {
* // Do work to process file here
* console.log('File processed');
* callback();
* }
* }, function(err) {
* // if any of the file processing produced an error, err would equal that error
* if( err ) {
* // One of the iterations produced an error.
* // All processing will now stop.
* console.log('A file failed to process');
* } else {
* console.log('All files have been processed successfully');
* }
* });
*/
function eachLimit(coll, iteratee, callback) {
return (0, _eachOf2.default)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback);
}
exports.default = (0, _awaitify2.default)(eachLimit, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,50 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _withoutIndex = require('./internal/withoutIndex');
var _withoutIndex2 = _interopRequireDefault(_withoutIndex);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
*
* @name eachLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.each]{@link module:Collections.each}
* @alias forEachLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async function to apply to each item in
* `coll`.
* The array index is not passed to the iteratee.
* If you need the index, use `eachOfLimit`.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachLimit(coll, limit, iteratee, callback) {
return (0, _eachOfLimit2.default)(limit)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback);
}
exports.default = (0, _awaitify2.default)(eachLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,116 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _isArrayLike = require('./internal/isArrayLike');
var _isArrayLike2 = _interopRequireDefault(_isArrayLike);
var _breakLoop = require('./internal/breakLoop');
var _breakLoop2 = _interopRequireDefault(_breakLoop);
var _eachOfLimit = require('./eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _once = require('./internal/once');
var _once2 = _interopRequireDefault(_once);
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// eachOf implementation optimized for array-likes
function eachOfArrayLike(coll, iteratee, callback) {
callback = (0, _once2.default)(callback);
var index = 0,
completed = 0,
{ length } = coll,
canceled = false;
if (length === 0) {
callback(null);
}
function iteratorCallback(err, value) {
if (err === false) {
canceled = true;
}
if (canceled === true) return;
if (err) {
callback(err);
} else if (++completed === length || value === _breakLoop2.default) {
callback(null);
}
}
for (; index < length; index++) {
iteratee(coll[index], index, (0, _onlyOnce2.default)(iteratorCallback));
}
}
// a generic version of eachOf which can handle array, object, and iterator cases.
function eachOfGeneric(coll, iteratee, callback) {
return (0, _eachOfLimit2.default)(coll, Infinity, iteratee, callback);
}
/**
* Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
* to the iteratee.
*
* @name eachOf
* @static
* @memberOf module:Collections
* @method
* @alias forEachOf
* @category Collection
* @see [async.each]{@link module:Collections.each}
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each
* item in `coll`.
* The `key` is the item's key, or index in the case of an array.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
* @example
*
* var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
* var configs = {};
*
* async.forEachOf(obj, function (value, key, callback) {
* fs.readFile(__dirname + value, "utf8", function (err, data) {
* if (err) return callback(err);
* try {
* configs[key] = JSON.parse(data);
* } catch (e) {
* return callback(e);
* }
* callback();
* });
* }, function (err) {
* if (err) console.error(err.message);
* // configs is now a map of JSON data
* doSomethingWith(configs);
* });
*/
function eachOf(coll, iteratee, callback) {
var eachOfImplementation = (0, _isArrayLike2.default)(coll) ? eachOfArrayLike : eachOfGeneric;
return eachOfImplementation(coll, (0, _wrapAsync2.default)(iteratee), callback);
}
exports.default = (0, _awaitify2.default)(eachOf, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit2 = require('./internal/eachOfLimit');
var _eachOfLimit3 = _interopRequireDefault(_eachOfLimit2);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
* time.
*
* @name eachOfLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.eachOf]{@link module:Collections.eachOf}
* @alias forEachOfLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async function to apply to each
* item in `coll`. The `key` is the item's key, or index in the case of an
* array.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachOfLimit(coll, limit, iteratee, callback) {
return (0, _eachOfLimit3.default)(limit)(coll, (0, _wrapAsync2.default)(iteratee), callback);
}
exports.default = (0, _awaitify2.default)(eachOfLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,39 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit = require('./eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
*
* @name eachOfSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.eachOf]{@link module:Collections.eachOf}
* @alias forEachOfSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to each item in
* `coll`.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all `iteratee`
* functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachOfSeries(coll, iteratee, callback) {
return (0, _eachOfLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(eachOfSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,44 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachLimit = require('./eachLimit');
var _eachLimit2 = _interopRequireDefault(_eachLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
*
* Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
* in series and therefore the iteratee functions will complete in order.
* @name eachSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.each]{@link module:Collections.each}
* @alias forEachSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to each
* item in `coll`.
* The array index is not passed to the iteratee.
* If you need the index, use `eachOfSeries`.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachSeries(coll, iteratee, callback) {
return (0, _eachLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(eachSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,67 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = ensureAsync;
var _setImmediate = require('./internal/setImmediate');
var _setImmediate2 = _interopRequireDefault(_setImmediate);
var _wrapAsync = require('./internal/wrapAsync');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Wrap an async function and ensure it calls its callback on a later tick of
* the event loop. If the function already calls its callback on a next tick,
* no extra deferral is added. This is useful for preventing stack overflows
* (`RangeError: Maximum call stack size exceeded`) and generally keeping
* [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)
* contained. ES2017 `async` functions are returned as-is -- they are immune
* to Zalgo's corrupting influences, as they always resolve on a later tick.
*
* @name ensureAsync
* @static
* @memberOf module:Utils
* @method
* @category Util
* @param {AsyncFunction} fn - an async function, one that expects a node-style
* callback as its last argument.
* @returns {AsyncFunction} Returns a wrapped function with the exact same call
* signature as the function passed in.
* @example
*
* function sometimesAsync(arg, callback) {
* if (cache[arg]) {
* return callback(null, cache[arg]); // this would be synchronous!!
* } else {
* doSomeIO(arg, callback); // this IO would be asynchronous
* }
* }
*
* // this has a risk of stack overflows if many results are cached in a row
* async.mapSeries(args, sometimesAsync, done);
*
* // this will defer sometimesAsync's callback if necessary,
* // preventing stack overflows
* async.mapSeries(args, async.ensureAsync(sometimesAsync), done);
*/
function ensureAsync(fn) {
if ((0, _wrapAsync.isAsync)(fn)) return fn;
return function (...args /*, callback*/) {
var callback = args.pop();
var sync = true;
args.push((...innerArgs) => {
if (sync) {
(0, _setImmediate2.default)(() => callback(...innerArgs));
} else {
callback(...innerArgs);
}
});
fn.apply(this, args);
sync = false;
};
}
module.exports = exports['default'];

View File

@ -0,0 +1,54 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns `true` if every element in `coll` satisfies an async test. If any
* iteratee call returns `false`, the main `callback` is immediately called.
*
* @name every
* @static
* @memberOf module:Collections
* @method
* @alias all
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in parallel.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
* @example
*
* async.every(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, result) {
* // if result is true then every file exists
* });
*/
function every(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(every, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,46 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.
*
* @name everyLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.every]{@link module:Collections.every}
* @alias allLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in parallel.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function everyLimit(coll, limit, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(everyLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,45 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfSeries = require('./eachOfSeries');
var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.
*
* @name everySeries
* @static
* @memberOf module:Collections
* @method
* @see [async.every]{@link module:Collections.every}
* @alias allSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async truth test to apply to each item
* in the collection in series.
* The iteratee must complete with a boolean result value.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result will be either `true` or `false`
* depending on the values of the async tests. Invoked with (err, result).
* @returns {Promise} a promise, if no callback provided
*/
function everySeries(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => !bool, res => !res)(_eachOfSeries2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(everySeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,53 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _filter2 = require('./internal/filter');
var _filter3 = _interopRequireDefault(_filter2);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns a new array of all the values in `coll` which pass an async truth
* test. This operation is performed in parallel, but the results array will be
* in the same order as the original.
*
* @name filter
* @static
* @memberOf module:Collections
* @method
* @alias select
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {Function} iteratee - A truth test to apply to each item in `coll`.
* The `iteratee` is passed a `callback(err, truthValue)`, which must be called
* with a boolean argument once it has completed. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Invoked with (err, results).
* @returns {Promise} a promise, if no callback provided
* @example
*
* async.filter(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, results) {
* // results now equals an array of the existing files
* });
*/
function filter(coll, iteratee, callback) {
return (0, _filter3.default)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(filter, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,45 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _filter2 = require('./internal/filter');
var _filter3 = _interopRequireDefault(_filter2);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a
* time.
*
* @name filterLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.filter]{@link module:Collections.filter}
* @alias selectLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {Function} iteratee - A truth test to apply to each item in `coll`.
* The `iteratee` is passed a `callback(err, truthValue)`, which must be called
* with a boolean argument once it has completed. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Invoked with (err, results).
* @returns {Promise} a promise, if no callback provided
*/
function filterLimit(coll, limit, iteratee, callback) {
return (0, _filter3.default)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(filterLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,43 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _filter2 = require('./internal/filter');
var _filter3 = _interopRequireDefault(_filter2);
var _eachOfSeries = require('./eachOfSeries');
var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.
*
* @name filterSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.filter]{@link module:Collections.filter}
* @alias selectSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {Function} iteratee - A truth test to apply to each item in `coll`.
* The `iteratee` is passed a `callback(err, truthValue)`, which must be called
* with a boolean argument once it has completed. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Invoked with (err, results)
* @returns {Promise} a promise, if no callback provided
*/
function filterSeries(coll, iteratee, callback) {
return (0, _filter3.default)(_eachOfSeries2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(filterSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,61 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Returns the first value in `coll` that passes an async truth test. The
* `iteratee` is applied in parallel, meaning the first iteratee to return
* `true` will fire the detect `callback` with that result. That means the
* result might not be the first item in the original `coll` (in terms of order)
* that passes the test.
* If order within the original `coll` is important, then look at
* [`detectSeries`]{@link module:Collections.detectSeries}.
*
* @name detect
* @static
* @memberOf module:Collections
* @method
* @alias find
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns A Promise, if no callback is passed
* @example
*
* async.detect(['file1','file2','file3'], function(filePath, callback) {
* fs.access(filePath, function(err) {
* callback(null, !err)
* });
* }, function(err, result) {
* // result now equals the first file in the list that exists
* });
*/
function detect(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)(_eachOf2.default, coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detect, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,48 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a
* time.
*
* @name detectLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.detect]{@link module:Collections.detect}
* @alias findLimit
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns a Promise if no callback is passed
*/
function detectLimit(coll, limit, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(limit), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detectLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createTester = require('./internal/createTester');
var _createTester2 = _interopRequireDefault(_createTester);
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.
*
* @name detectSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.detect]{@link module:Collections.detect}
* @alias findSeries
* @category Collections
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.
* The iteratee must complete with a boolean value as its result.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called as soon as any
* iteratee returns `true`, or after all the `iteratee` functions have finished.
* Result will be the first item in the array that passes the truth test
* (iteratee) or the value `undefined` if none passed. Invoked with
* (err, result).
* @returns a Promise if no callback is passed
*/
function detectSeries(coll, iteratee, callback) {
return (0, _createTester2.default)(bool => bool, (res, item) => item)((0, _eachOfLimit2.default)(1), coll, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(detectSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _concatLimit = require('./concatLimit');
var _concatLimit2 = _interopRequireDefault(_concatLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Applies `iteratee` to each item in `coll`, concatenating the results. Returns
* the concatenated list. The `iteratee`s are called in parallel, and the
* results are concatenated as they return. The results array will be returned in
* the original order of `coll` passed to the `iteratee` function.
*
* @name concat
* @static
* @memberOf module:Collections
* @method
* @category Collection
* @alias flatMap
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
* which should use an array as its result. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
* @example
*
* async.concat(['dir1','dir2','dir3'], fs.readdir, function(err, files) {
* // files is now a list of filenames that exist in the 3 directories
* });
*/
function concat(coll, iteratee, callback) {
return (0, _concatLimit2.default)(coll, Infinity, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(concat, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,60 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _mapLimit = require('./mapLimit');
var _mapLimit2 = _interopRequireDefault(_mapLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.
*
* @name concatLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.concat]{@link module:Collections.concat}
* @category Collection
* @alias flatMapLimit
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,
* which should use an array as its result. Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
*/
function concatLimit(coll, limit, iteratee, callback) {
var _iteratee = (0, _wrapAsync2.default)(iteratee);
return (0, _mapLimit2.default)(coll, limit, (val, iterCb) => {
_iteratee(val, (err, ...args) => {
if (err) return iterCb(err);
return iterCb(err, args);
});
}, (err, mapResults) => {
var result = [];
for (var i = 0; i < mapResults.length; i++) {
if (mapResults[i]) {
result = result.concat(...mapResults[i]);
}
}
return callback(err, result);
});
}
exports.default = (0, _awaitify2.default)(concatLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,41 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _concatLimit = require('./concatLimit');
var _concatLimit2 = _interopRequireDefault(_concatLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.
*
* @name concatSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.concat]{@link module:Collections.concat}
* @category Collection
* @alias flatMapSeries
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.
* The iteratee should complete with an array an array of results.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished, or an error occurs. Results is an array
* containing the concatenated results of the `iteratee` function. Invoked with
* (err, results).
* @returns A Promise, if no callback is passed
*/
function concatSeries(coll, iteratee, callback) {
return (0, _concatLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(concatSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,77 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfSeries = require('./eachOfSeries');
var _eachOfSeries2 = _interopRequireDefault(_eachOfSeries);
var _once = require('./internal/once');
var _once2 = _interopRequireDefault(_once);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Reduces `coll` into a single value using an async `iteratee` to return each
* successive step. `memo` is the initial state of the reduction. This function
* only operates in series.
*
* For performance reasons, it may make sense to split a call to this function
* into a parallel map, and then use the normal `Array.prototype.reduce` on the
* results. This function is for situations where each step in the reduction
* needs to be async; if you can get the data before reducing it, then it's
* probably a good idea to do so.
*
* @name reduce
* @static
* @memberOf module:Collections
* @method
* @alias inject
* @alias foldl
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {*} memo - The initial state of the reduction.
* @param {AsyncFunction} iteratee - A function applied to each item in the
* array to produce the next step in the reduction.
* The `iteratee` should complete with the next state of the reduction.
* If the iteratee complete with an error, the reduction is stopped and the
* main `callback` is immediately called with the error.
* Invoked with (memo, item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result is the reduced value. Invoked with
* (err, result).
* @returns {Promise} a promise, if no callback is passed
* @example
*
* async.reduce([1,2,3], 0, function(memo, item, callback) {
* // pointless async:
* process.nextTick(function() {
* callback(null, memo + item)
* });
* }, function(err, result) {
* // result is now equal to the last value of memo, which is 6
* });
*/
function reduce(coll, memo, iteratee, callback) {
callback = (0, _once2.default)(callback);
var _iteratee = (0, _wrapAsync2.default)(iteratee);
return (0, _eachOfSeries2.default)(coll, (x, i, iterCb) => {
_iteratee(memo, x, (err, v) => {
memo = v;
iterCb(err);
});
}, err => callback(err, memo));
}
exports.default = (0, _awaitify2.default)(reduce, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,41 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = reduceRight;
var _reduce = require('./reduce');
var _reduce2 = _interopRequireDefault(_reduce);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.
*
* @name reduceRight
* @static
* @memberOf module:Collections
* @method
* @see [async.reduce]{@link module:Collections.reduce}
* @alias foldr
* @category Collection
* @param {Array} array - A collection to iterate over.
* @param {*} memo - The initial state of the reduction.
* @param {AsyncFunction} iteratee - A function applied to each item in the
* array to produce the next step in the reduction.
* The `iteratee` should complete with the next state of the reduction.
* If the iteratee complete with an error, the reduction is stopped and the
* main `callback` is immediately called with the error.
* Invoked with (memo, item, callback).
* @param {Function} [callback] - A callback which is called after all the
* `iteratee` functions have finished. Result is the reduced value. Invoked with
* (err, result).
* @returns {Promise} a promise, if no callback is passed
*/
function reduceRight(array, memo, iteratee, callback) {
var reversed = [...array].reverse();
return (0, _reduce2.default)(reversed, memo, iteratee, callback);
}
module.exports = exports['default'];

View File

@ -0,0 +1,88 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOf = require('./eachOf');
var _eachOf2 = _interopRequireDefault(_eachOf);
var _withoutIndex = require('./internal/withoutIndex');
var _withoutIndex2 = _interopRequireDefault(_withoutIndex);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Applies the function `iteratee` to each item in `coll`, in parallel.
* The `iteratee` is called with an item from the list, and a callback for when
* it has finished. If the `iteratee` passes an error to its `callback`, the
* main `callback` (for the `each` function) is immediately called with the
* error.
*
* Note, that since this function applies `iteratee` to each item in parallel,
* there is no guarantee that the iteratee functions will complete in order.
*
* @name each
* @static
* @memberOf module:Collections
* @method
* @alias forEach
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to
* each item in `coll`. Invoked with (item, callback).
* The array index is not passed to the iteratee.
* If you need the index, use `eachOf`.
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
* @example
*
* // assuming openFiles is an array of file names and saveFile is a function
* // to save the modified contents of that file:
*
* async.each(openFiles, saveFile, function(err){
* // if any of the saves produced an error, err would equal that error
* });
*
* // assuming openFiles is an array of file names
* async.each(openFiles, function(file, callback) {
*
* // Perform operation on file here.
* console.log('Processing file ' + file);
*
* if( file.length > 32 ) {
* console.log('This file name is too long');
* callback('File name too long');
* } else {
* // Do work to process file here
* console.log('File processed');
* callback();
* }
* }, function(err) {
* // if any of the file processing produced an error, err would equal that error
* if( err ) {
* // One of the iterations produced an error.
* // All processing will now stop.
* console.log('A file failed to process');
* } else {
* console.log('All files have been processed successfully');
* }
* });
*/
function eachLimit(coll, iteratee, callback) {
return (0, _eachOf2.default)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback);
}
exports.default = (0, _awaitify2.default)(eachLimit, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,50 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit = require('./internal/eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _withoutIndex = require('./internal/withoutIndex');
var _withoutIndex2 = _interopRequireDefault(_withoutIndex);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.
*
* @name eachLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.each]{@link module:Collections.each}
* @alias forEachLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async function to apply to each item in
* `coll`.
* The array index is not passed to the iteratee.
* If you need the index, use `eachOfLimit`.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachLimit(coll, limit, iteratee, callback) {
return (0, _eachOfLimit2.default)(limit)(coll, (0, _withoutIndex2.default)((0, _wrapAsync2.default)(iteratee)), callback);
}
exports.default = (0, _awaitify2.default)(eachLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,116 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _isArrayLike = require('./internal/isArrayLike');
var _isArrayLike2 = _interopRequireDefault(_isArrayLike);
var _breakLoop = require('./internal/breakLoop');
var _breakLoop2 = _interopRequireDefault(_breakLoop);
var _eachOfLimit = require('./eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _once = require('./internal/once');
var _once2 = _interopRequireDefault(_once);
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
// eachOf implementation optimized for array-likes
function eachOfArrayLike(coll, iteratee, callback) {
callback = (0, _once2.default)(callback);
var index = 0,
completed = 0,
{ length } = coll,
canceled = false;
if (length === 0) {
callback(null);
}
function iteratorCallback(err, value) {
if (err === false) {
canceled = true;
}
if (canceled === true) return;
if (err) {
callback(err);
} else if (++completed === length || value === _breakLoop2.default) {
callback(null);
}
}
for (; index < length; index++) {
iteratee(coll[index], index, (0, _onlyOnce2.default)(iteratorCallback));
}
}
// a generic version of eachOf which can handle array, object, and iterator cases.
function eachOfGeneric(coll, iteratee, callback) {
return (0, _eachOfLimit2.default)(coll, Infinity, iteratee, callback);
}
/**
* Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument
* to the iteratee.
*
* @name eachOf
* @static
* @memberOf module:Collections
* @method
* @alias forEachOf
* @category Collection
* @see [async.each]{@link module:Collections.each}
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - A function to apply to each
* item in `coll`.
* The `key` is the item's key, or index in the case of an array.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
* @example
*
* var obj = {dev: "/dev.json", test: "/test.json", prod: "/prod.json"};
* var configs = {};
*
* async.forEachOf(obj, function (value, key, callback) {
* fs.readFile(__dirname + value, "utf8", function (err, data) {
* if (err) return callback(err);
* try {
* configs[key] = JSON.parse(data);
* } catch (e) {
* return callback(e);
* }
* callback();
* });
* }, function (err) {
* if (err) console.error(err.message);
* // configs is now a map of JSON data
* doSomethingWith(configs);
* });
*/
function eachOf(coll, iteratee, callback) {
var eachOfImplementation = (0, _isArrayLike2.default)(coll) ? eachOfArrayLike : eachOfGeneric;
return eachOfImplementation(coll, (0, _wrapAsync2.default)(iteratee), callback);
}
exports.default = (0, _awaitify2.default)(eachOf, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,47 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit2 = require('./internal/eachOfLimit');
var _eachOfLimit3 = _interopRequireDefault(_eachOfLimit2);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a
* time.
*
* @name eachOfLimit
* @static
* @memberOf module:Collections
* @method
* @see [async.eachOf]{@link module:Collections.eachOf}
* @alias forEachOfLimit
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {number} limit - The maximum number of async operations at a time.
* @param {AsyncFunction} iteratee - An async function to apply to each
* item in `coll`. The `key` is the item's key, or index in the case of an
* array.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachOfLimit(coll, limit, iteratee, callback) {
return (0, _eachOfLimit3.default)(limit)(coll, (0, _wrapAsync2.default)(iteratee), callback);
}
exports.default = (0, _awaitify2.default)(eachOfLimit, 4);
module.exports = exports['default'];

View File

@ -0,0 +1,39 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachOfLimit = require('./eachOfLimit');
var _eachOfLimit2 = _interopRequireDefault(_eachOfLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.
*
* @name eachOfSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.eachOf]{@link module:Collections.eachOf}
* @alias forEachOfSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to each item in
* `coll`.
* Invoked with (item, key, callback).
* @param {Function} [callback] - A callback which is called when all `iteratee`
* functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachOfSeries(coll, iteratee, callback) {
return (0, _eachOfLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(eachOfSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,44 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _eachLimit = require('./eachLimit');
var _eachLimit2 = _interopRequireDefault(_eachLimit);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.
*
* Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item
* in series and therefore the iteratee functions will complete in order.
* @name eachSeries
* @static
* @memberOf module:Collections
* @method
* @see [async.each]{@link module:Collections.each}
* @alias forEachSeries
* @category Collection
* @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.
* @param {AsyncFunction} iteratee - An async function to apply to each
* item in `coll`.
* The array index is not passed to the iteratee.
* If you need the index, use `eachOfSeries`.
* Invoked with (item, callback).
* @param {Function} [callback] - A callback which is called when all
* `iteratee` functions have finished, or an error occurs. Invoked with (err).
* @returns {Promise} a promise, if a callback is omitted
*/
function eachSeries(coll, iteratee, callback) {
return (0, _eachLimit2.default)(coll, 1, iteratee, callback);
}
exports.default = (0, _awaitify2.default)(eachSeries, 3);
module.exports = exports['default'];

View File

@ -0,0 +1,68 @@
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _onlyOnce = require('./internal/onlyOnce');
var _onlyOnce2 = _interopRequireDefault(_onlyOnce);
var _ensureAsync = require('./ensureAsync');
var _ensureAsync2 = _interopRequireDefault(_ensureAsync);
var _wrapAsync = require('./internal/wrapAsync');
var _wrapAsync2 = _interopRequireDefault(_wrapAsync);
var _awaitify = require('./internal/awaitify');
var _awaitify2 = _interopRequireDefault(_awaitify);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Calls the asynchronous function `fn` with a callback parameter that allows it
* to call itself again, in series, indefinitely.
* If an error is passed to the callback then `errback` is called with the
* error, and execution stops, otherwise it will never be called.
*
* @name forever
* @static
* @memberOf module:ControlFlow
* @method
* @category Control Flow
* @param {AsyncFunction} fn - an async function to call repeatedly.
* Invoked with (next).
* @param {Function} [errback] - when `fn` passes an error to it's callback,
* this function will be called, and execution stops. Invoked with (err).
* @returns {Promise} a promise that rejects if an error occurs and an errback
* is not passed
* @example
*
* async.forever(
* function(next) {
* // next is suitable for passing to things that need a callback(err [, whatever]);
* // it will result in this function being called again.
* },
* function(err) {
* // if next is called with a value in its first parameter, it will appear
* // in here as 'err', and execution will stop.
* }
* );
*/
function forever(fn, errback) {
var done = (0, _onlyOnce2.default)(errback);
var task = (0, _wrapAsync2.default)((0, _ensureAsync2.default)(fn));
function next(err) {
if (err) return done(err);
if (err === false) return;
task(next);
}
return next();
}
exports.default = (0, _awaitify2.default)(forever, 2);
module.exports = exports['default'];

Some files were not shown because too many files have changed in this diff Show More