{"id":13802809,"url":"https://github.com/rapid7/le_node","last_synced_at":"2025-05-13T13:33:03.276Z","repository":{"id":510917,"uuid":"2011301","full_name":"rapid7/le_node","owner":"rapid7","description":"Node module for logentries.com","archived":true,"fork":false,"pushed_at":"2022-09-30T14:14:22.000Z","size":442,"stargazers_count":108,"open_issues_count":13,"forks_count":63,"subscribers_count":66,"default_branch":"master","last_synced_at":"2024-05-17T21:46:08.123Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rapid7.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-07-07T09:03:52.000Z","updated_at":"2023-08-22T09:59:43.000Z","dependencies_parsed_at":"2023-01-11T15:28:15.820Z","dependency_job_id":null,"html_url":"https://github.com/rapid7/le_node","commit_stats":null,"previous_names":["logentries/le_node","rjrodger/node-logentries"],"tags_count":34,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fle_node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fle_node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fle_node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rapid7%2Fle_node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rapid7","download_url":"https://codeload.github.com/rapid7/le_node/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225229913,"owners_count":17441344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T00:01:58.269Z","updated_at":"2024-11-18T18:30:43.226Z","avatar_url":"https://github.com/rapid7.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/rapid7/le_node.svg)](https://travis-ci.org/rapid7/le_node)\n\n# DEPRECATED\n\n`le_node` has been deprecated in favour of [`r7insight_node`](https://github.com/rapid7/r7insight_node) which includes additional functionality such as the ability to specify the region to send your log data to. Please use this new library instead. New issues with the old library will no longer be addressed.\n\n# le_node: Logentries Client\n\nAllows you to send logs to your [logentries](https://www.logentries.com) account\nfrom Node or io.js.\n\n\u003e It might work with Browserify, too, but you would need to use shims for net\n\u003e and tls. Such shims do exist, based on forge, but I haven’t tested it. There’s\n\u003e a seperate client intended for use in the browser though, called\n\u003e [le_js](https://www.npmjs.com/package/le_js), which uses http and is optimized\n\u003e for browser-specific logging needs.\n\nTested in Node v0.10 + and io.js. It probably works in Node 0.8 too, but one of\nthe test libraries ([mitm](https://www.npmjs.com/package/mitm)) doesn’t, so it\nremains unconfirmed.\n\nWhat is now \"le_node\" was previously \"logentries-client\"; users of le_node\nversions before 1.0.2 should read the sections below that detail differences if\nthey wish to update.\n\n\u003c!-- MarkdownTOC autolink=true bracket=round --\u003e\n\n- [Start](#start)\n- [Options](#options)\n- [Log Levels](#log-levels)\n- [Events](#events)\n- [Log Entries](#log-entries)\n- [Methods](#methods)\n- [Buffer \u0026 Connection Issues](#buffer--connection-issues)\n- [Using as a Winston ‘Transport’](#using-as-a-winston-transport)\n- [Using with Bunyan](#using-with-bunyan)\n- [Setting Up With Logentries Itself](#setting-up-with-logentries-itself)\n- [2015-05-26: le_node \u0026 Logentries-Client](#2015-05-26-le_node--logentries-client)\n- [Changelog (Post-Merge)](#changelog-post-merge)\n- [Changelog (Old Logentries-Client)](#changelog-old-logentries-client)\n- [Changelog (Old le_node)](#changelog-old-le_node)\n\n\u003c!-- /MarkdownTOC --\u003e\n\n## Start\n\n```javascript\nvar Logger = require('le_node');\n\nvar logger = new Logger({ token: 'myAccessToken' });\n\nlogger.warning('The kittens have become alarmingly adorable.')\n```\n\n## Options\n\nThe options object you provide to the constructor only requires your access\ntoken, but you can configure its behavior further.\n\nAll of the following except `token`, `levels` and `secure` can also be\nconfigured after instantiation as settable properties on the client. They are\naccessors, though, and invalid values will be ignored.\n\n### Required\n\n - **token:** String. Authorization token for the Logentries service.\n\n### Behavior\n - **console:** If truthy, log events also get sent to `console.log`,\n   `console.warn` and `console.error` as appropriate. Default: `false`.\n - **levels**: Custom names for the 8 log levels and their corresponding\n   methods. More details on this below.\n - **minLevel**: The minimum level to actually record logs at. String or Number.\n   Defaults to 0.\n - **bufferSize**: The maximum number of log entries that may be queued in the \n   internal ring buffer for sending at a given moment. Default: `16192`.\n - **secure:** If truthy, uses a tls connection. Default: `false`.\n - **inactivityTimeout:** The time, in milliseconds, that inactivity should warrant\n   closing the connection to the host until needed again. Defaults to 15 seconds.\n - **disableTimeout**: Sets the socket timeout to 0. Should not be used with \n   inactivityTimeout option.\n - **reconnectInitialDelay**: Initial wait time in milliseconds while reconnecting. \n   Default: `1000`\n - **reconnectMaxDelay**: Maximum wait time in milliseconds while reconnecting.\n   Default: `15 * 1000`\n - **reconnectBackoffStrategy**: Backoff strategy to be used while trying to reconnect.\n   It can be either `fibonacci` or `exponential`. Default: `fibonnacci`   \n - **maxFailedAttempts:** [Removed with new connection handling]\n   The number of times to retry to reach the logentries host in case of \n   error when connecting. Default: `15`.\n - **retryTimeout:** [Removed with new connection handling] \n   Time to wait between attemps when trying to reach the logentries host. \n   Default: `15 * 60 * 1000`.\n\n### Log Processing Options`\n - **flatten**: Convert objects into a single-level object where the values of\n   interior objects become dot-notation properties of the root object. Defaults\n   to `false`. More details on this below.\n - **flattenArrays**: If `flatten` is true, you can also indicate whether arrays\n   should be subject to the same process. Defaults to `true` if `flatten` is\n   `true`; otherwise meaningless.\n - **replacer**: A custom value-transform function to be used during JSON\n   serialization. Applied before error transformation.\n - **timestamp**: If truthy, prefix entries with an ISO timestamp (if strings)\n   or add the same as a property (if objects). Default: `false`.\n - **withHostname**: Will prepend(string) or add property (object) indicating the \n   hostname from which the log was sent.\n - **withLevel**: Will prepend (string) or add property (object) indicating the\n   log level. Default: `true`.\n - **withStack**: If an object is or contains an `Error` object, setting this to\n   `true` will cause the stack trace to be included. Default: `false.`\n\n### Other\n - **host**: The host to send logs to. Normally you would not want to set this,\n   but it may be useful for mocking during tests. The value may be just the host\n   or the host with the port specified.\n - **port**: As above. This will default to 80 if `secure` is false, or 443 if\n   it’s true.\n - **debug**: Setting this to `true` will enable debug logging with a default stdout\n  logger.\n - **debugLogger**: Use this to override default stdout logger. New logger must\n  implement a `log` method.\n\n## Log Levels\n\nThe default log levels are:\n\n 0. debug\n 1. info\n 2. notice\n 3. warning\n 4. err\n 5. crit\n 6. alert\n 7. emerg\n\nYou can provision the constructor with custom names for these levels with either\nan array or an object hash:\n\n```javascript\n[ 'boring', 'yawn', 'eh', 'hey' ]\n\n{ boring: 0, yawn: 1, eh: 2, hey: 3 }\n```\n\nIn the former case, the index corresponds to the numeric level, so sparse arrays\nare valid. In either case, missing levels will be filled in with the defaults.\n\nThe `minLevel` option respects either level number (e.g. `2`) or the name (e.g.\n`'eh'`).\n\nThe level names each become methods on the client, which are just sugar for\ncalling `client.log(lvl, logentry)` with the first argument curried.\n\nSince these names will appear on the client, they can’t collide with existing\nproperties. Not that you’re particularly likely to try naming a log level\n‘hasOwnProperty’ or ‘_write’ but I figured I should mention it.\n\nSo the following three are equivalent:\n\n```javascript\nlogger.notice('my msg');\nlogger.log('notice', 'my msg');\nlogger.log(2, 'my msg');\n```\n\nIt’s also possible to forgo log levels altogether. Just call `log` with a single\nargument and it will be interpretted as the log entry. When used this way, the\n`minLevel` setting is ignored.\n\n## Events\n\n### Logger Events\n\n#### `'error'`\nThe client is an EventEmitter, so you should (as always) make sure you have a\nlistener on `'error'`. Error events can occur when there’s been a problem with\nthe connection or if a method was called with invalid parameters. Note that\nerrors that occur during instantiation, as opposed to operation, will **throw**.\n\n#### `'log'`\nTriggered when a log is about to be written to the underlying connection. The\nprepared log object or string is supplied as an argument.\n\n#### `'connected'` and `'disconnected'` and `'timed out'` \nThese indicate when a new connection to the host is established, destroyed or \ntimed out due to client side inactivity. Inactivity timeout is normal if the connection \nis inactive for a configurable period of time (see inactivityTimeout); it will \nbe reopened when needed again. Disconnection can be either a result of socket inactivity or a network failure.\n\n#### `'drain'`, `'finish'`, `'pipe'`, and `'unpipe'`\nThese are events inherited from `Writable`.\n\n#### `'connection drain'`\nDEPRECATED. Use `buffer drain` event instead.\n\n#### `'buffer drain'`\nThis event is emitted when the underlying ring buffer is fully consumed and Socket.write callback called.\nThis can be useful when it’s time for the application to terminate but you want\nto be sure any pending logs have finished writing.\n\n```javascript\n   logger.notice({ type: 'server', event: 'shutdown' });\n   logger.once('buffer drain', () =\u003e {\n      logger.closeConnection();\n      logger.on('disconnected', () =\u003e {\n        process.exit();\n      });\n   });\n```\n\n### RingBuffer Events\n\n#### `'buffer shift'`\n\nBuffer shift event is emitted when the internal buffer is shifted due to reaching `bufferSize`\nof events in the buffer. This event may be listened for security/operations related reasons as\neach time this event is emitted, a log event will be discarded and discarded log event will\nnever make it to Logentries.\n\n```javascript\nlogger.ringBuffer.on('buffer shift', () =\u003e {\n    // page devops or send an email \n});\n```\n\n## Log Entries\n\nLog entries can be strings or objects. If the log argument is an array, it will\nbe interpretted as multiple log events.\n\n### Object Serialization\n\nIn the case of objects, the native JSON.stringify serialization is augmented in\nseveral ways. In addition to handling circular references, it will automatically\ntake care of a variety of objects and primitives which otherwise wouldn’t\nserialize correctly, like Error, RegExp, Set, Map, Infinity, NaN, etc.\n\nIf you choose to set `withStack` to true, errors will include their stacktraces\nas an array (so that they are not painful to look at). Be sure to turn on\n\"expand JSON\" (meaning pretty print) in the options on logentries:\n\n![stack trace as seen in logentries app][screen1]\n\nYou can adjust this further by supplying your own custom `replacer`. This is a\nstandard argument to JSON.stringify -- See [MDN: JSON \u003e Stringify \u003e The Replacer Parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The_replacer_parameter)\nfor details. In the event that you supply a custom replacer, it is applied\nprior to the built-in replacer described above so you can override its behavior.\n\n### Optional Augmentation\n\nTwo options are available, `timestamp` and `withLevel`, which will add data to\nyour log events. For objects, these are added as properties (non-mutatively).\nFor strings, these values are prepended. If the name of a property would cause\na collision with an existing property, it will be prepended with an underscore.\n\n### Flattening Log Objects\n\nIn some cases it will end up being easier to query your data if objects aren’t\ndeeply nested. With the `flatten` and `flattenArrays` options, you can tell the\nclient to transform objects like so:\n\n  * `{ \"a\": 1, \"b\": { \"c\": 2 } }` =\u003e `{ \"a\": 1, \"b.c\": 2 }`\n\nIf `flattenArrays` has not been set to false, this transformation will apply to\narrays as well:\n\n  * `{ \"a\": [ \"b\", { \"c\": 3 } ] }` =\u003e `{ \"a.0\": \"b\", \"a.1.c\": 3 }`\n\n## Methods\n\nIn addition to `log` and its arbitrary sugary cousins, you can call\n`closeConnection` to explicitly close an open connection if one exists; you\nmight wish to do this as part of a graceful exit. The connection will reopen if\nyou log further.\n\nAlso, because the client is actually a writable stream, you can call `write`\ndirectly. This gives you lower-level access to writing entries. It is in object\nmode, but this means it expects discreet units (one call = one entry), not\nactual objects; you should pass in strings. This is useful if you want to pipe\nstdout, for example.\n\n## Buffering\n\nIf there’s a problem with the connection (network loss or congestion),\nentries will be buffered in an internal ring buffer to a max of 16192(`bufferSize`)\nentries by default. After that, internal ring buffer will `shift` records\nto keep only last `bufferSize` number of records in memory. A log that indicates the\nbuffer was full will be sent to internal logger \"once\" this happens.\nIf `console` is true, these log entries will still display there, but they will\nnot make it to LogEntries.\n\nYou can adjust the maximum size of the buffer with the `bufferSize` option.\nYou’ll want to raise it if you’re dealing with very high volume (either a high\nnumber of logs per second, or when log entries are unusually long on average).\nOutside of these situations, exceeding the max buffer size is more likely an\nindication of creating logs in a synchronous loop (which seems like a bad idea).\n\n## Connection Handling\n\nIf the connection fails, it will keep retrying with a `fibonacci` backoff by default. \nConnection retry will start with a delay of `reconnectInitialDelay` and the delay between each retry \nwill go up to a maximum of `reconnectMaxDelay` with each retry in fibonacci sequence. \nBackoff strategy can be changed to `exponential` through constructor if necessary.\n\nA connection to the host does not guarantee that your logs are transmitting\nsuccessfully. If you have a bad token, there is no feedback from the server to\nindicate this. The only way to confirm that your token is working is to check\nthe live tail on Logentries. I will investigate this further to see if there’s\nsome other means with which a token can be tested for validity.\n\n## Using as a Winston ‘Transport’\n\nIf Winston is included in your package.json dependencies, simply requiring the\nLogentries client will place the transport constructor at `winston.transports`,\neven if Winston itself hasn’t yet been required.\n\n```javascript\nvar Logger = require('le_node');\nvar winston = require('winston');\n\nassert(winston.transports.Logentries);\n```\n\nWhen adding a new Logentries transport, the options argument passed to Winston’s\n`add` method supports the usual options in addition to those which are Winston-\nspecific. If custom levels are not provided, Winston’s defaults will be used.\n\n```javascript\nwinston.add(winston.transports.Logentries, { token: myToken });\n```\n\nIn the hard-to-imagine case where you’re using Winston without including it in\npackage.json, you can explicitly provision the transport by first requiring\nWinston and then calling `Logger.provisionWinston()`.\n\n## Using with Bunyan\n\nFor Bunyan it’s like so:\n\n```javascript\nvar bunyan = require('bunyan');\n\nvar Logger = require('le_node');\n\nvar loggerDefinition = Logger.bunyanStream({ token: myToken });\n\n// One stream\nvar logger1 = bunyan.createLogger(loggerDefinition);\n\n// Multiple streams\nvar logger2 = bunyan.createLogger({\n\tname: 'whatevs',\n\tstreams: [ loggerDefinition, otherLoggerDefinition ]\n});\n```\n\nAs with Winston, the options argument takes the normal constructor options (with\nthe exception of `timestamp`, which is an option you should set on Bunyan itself\ninstead). Bunyan uses six log levels, so the seventh and eighth, if provided,\nwill be ignored; by default Bunyan’s level names will be used.\n\nThe object returned by `bunyanStream` is the Bunyan logging ‘channel’ definition\nin total. If you want to futz with this you can -- you can change its `name` or\nget the `stream` object itself from here.\n\n## Setting Up With Logentries Itself\n\nWhen you create an account at Logentries (just a standard signup form; there’s a\nfree tier), you can find the token you need. It’s shown during the initial walk-\nthrough but you can find it later under Logs/Hosts/{ the name of your host } --\non the far right, a gray TOKEN button that you can click to reveal the string.\n\nThat’s it -- once you have the token you’re set.\n\n[screen1]: docs/screen1.png\n\n## 2015-05-26: le_node \u0026 Logentries-Client \n\nPreviously, \"le_node\" and \"logentries-client\" were two different modules. The\nformer has been replaced with the latter codebase, but the le_node name is the\ncanonical repo (it’s referenced in many places). It’s still possible to get\nlogentries-client under that name on NPM, but it’s soon just going to be an\nalias for this repository, le_node.\n\nFor users of le_node from before this switch, there are some important\ndifferences to note before upgrading.\n\nThe new codebase does follow the same essential pattern. If you only used the\nclient constructor and the log methods previously, there may be no breaking\nchanges for you. But for anybody else...\n\n### Breaking Change: `client.end()`\n\nUnlike old le_node, the client is itself a writable stream (and therefore you\ncan pipe to it, for example from stdout, though note that 1 write invocation =\n1 log entry). This also means that it has standard writable stream events and\nmethods, including `.end()`. In the old le_node, `.end()` was a non-stream\nmethod that closed the underlying connection to the host.\n\nFor the functionality previously provided by `.end()`, use `.closeConnection()`.\n\n### Deprecation: `client.level()` and `client.winston()`\n\nThe old le_node had a method called `level()` for setting the minimum log level.\nThis is now a property (not a method) called `minLevel`. It can be set to either\nthe name of the level or its index. The `level()` method has been added to the\nnew codebase to facilitate migration, but will be removed at a later date.\n\nSimply requiring le_node now automatically provisions Winston, if present, with\na Logentries transport constructor. You don’t have to do anything else. The\n`winston()` method has also been added to the new codebase to prevent errors,\nbut it’s a noop and will be removed at a later date.\n\n### Other Things For Migrants to Note\n\nThe old documentation seemed to suggest that placing a listener on the client\nfor error events was an optional thing. This isn’t the case (and wasn’t the\ncase in the old client, either). An unhandled error event from an EventEmitter\nis an unhandled error period. If you don’t place a listener for error events,\nyour application will crash if the client emits an error.\n\nThe new codebase has a lot of new features, including some that are similar to,\nbut not necessarilly the same as, old features that had been removed at some\npoint or were just not documented.\n\nThe outstanding issues that exist for le_node at the time of writing are mostly\nthings which either never affected this codebase or no longer make sense in\nregard to it.\n\n - circular refs are fine\n - `time` and `level` properties will never collide with existing props and are\n   both optional\n - JSON serialization is much more robust and customizable\n - serialized objects will not be cut off at an arbitrary depth\n - the connection is closed on extended inactivity and only reopened as needed\n - errors are handled correctly\n - there is built-in support for Bunyan\n - Winston is provisioned in accord with prevailing conventions\n\nYou should assume that there are other breaking changes which I am unaware\nof. When I wrote Logentries Client I hadn’t considered that it might replace\nle_node, so unfortunately interoperability was not on my mind. You’ll wish to\ntest thoroughly before updating an existing codebase to use the new client.\n\n## Changelog (Post-Merge)\n\n### 1.1.2\n\n - Update codependency to fix vulnerable dependency\n\n### 1.1.1\n\n - Fixes handling of winston’s meta object (gcoonrod)\n\n### 1.1.0\n\n - The `.end()` method will not synchronously terminate the underlying\n   connection anymore. Instead, it waits for drain before doing so.\n\n### 1.0.15\n\n - Bubbles errors up correctly when using the Bunyan and Winston constructors\n - Serializer no longer chokes on objects created with a null prototype\n\n### 1.0.14\n\n - Allows setting port with a string instead of a number.\n\n### 1.0.13\n \n - Fixes bug with winston transport’s `level` property.\n\n### 1.0.12\n\n - Increased default buffer size\n - Made bufferSize (highWaterMark) configurable\n\n### 1.0.10\n\n - Fixes problems with setting custom host \u0026 port\n\n### 1.0.9\n\n - Fixes serialization bug in cases where the root-level object is itself\n   exotic or otherwise does not ‘have own properties,’ including directly logged\n   errors.\n\n### 1.0.8\n\n - Fixed bugged handling of Winston’s ‘meta’ parameter.\n\n### 1.0.7\n\n - Fixed nested dependency issues with shrinkwrap.\n - Various minor changes (docs, etc)\n\n### 1.0.2\n\n - Logentries Client has become the new le_node. The original logentries-client\n   module is now an alias for le\\_node, and le\\_node is now what was previously\n   called logentries-client.\n - Added `level()` and `winston()` methods with deprecation warnings so that\n   existing le_node applications do not throw TypeErrors.\n - Added events for 'connected', 'disconnected' and 'connection drain'\n\n## Changelog (Old Logentries-Client)\n\n### 1.0.0 / 1.0.1\n\n - Major overhaul -- rewrote in ES6\n - Client is now a writable stream, compatible with stdout\n - Added `withLevel` and `timeout` options\n - Exposed `host` and `port` options for testing\n - Expanded default serialization to handle more JSON-choking cases, including\n   Map, Set and Symbol\n - Added more sanity checks on instantiation\n - Made 'level' argument optional when calling `client.log`\n - BREAKING CHANGE: `client.log` method no longer accepts an arbitrary number of\n   log entry arguments (to support above case, which seems much likely to be\n   useful)\n - Added custom, informative error objects\n - Changed default `minLevel` value to zero (1 was an accident)\n - The most significant changes concern handling the connection to the host:\n   - An exponential backoff is used when connecting fails\n   - After repeated failures, a cooldown period is enforced before further tries\n   - The buffer of pending entries has a maximum now (60)\n   - Errors get emitted when these conditions occur\n\n### 0.5.0\n\n - Added `flatten` and `flattenArray` options\n - Added more special cases for the default serializer\n - Added new tests\n\n### 0.4.0\n\n - Prevented mutation of incoming log objects when adding timestamp or level\n - Turned thrown strings into proper errors (oops!)\n - Updated dependencies\n\n### 0.3.3\n\n - Switched to the new API endpoint\n\n### 0.3.1 \u0026 0.3.2\n\n - Readme updated\n\n### 0.3.0\n\n - Improved stack trace handling when `withStack` set to true\n\n### 0.2.1\n\n - Path for problems with new 0.2.0 options\n - Added new tests\n\n### 0.2.0\n\n - Added proper handling for objects with circular references\n - Added custom serialization for Error objects \u0026 `withStack` option\n - Changed lodash to `runInContext()` to prevent template string problems\n\n### 0.1.0\n\n - Initial commit\n\n## Changelog (Old le_node)\n\n(Pieced together to the best of my ability by reviewing commit history.)\n\n### 0.1.4\n\n - Cleanup (rewrite?)\n - Did not include several previously available options, including KVP mode\n\n### 0.1.3\n\n - Switched from http to net module for non-ssl connection\n - Added KVP-style flattening options \u0026 made it default\n - Added more tests and options\n\n### 0.1.0 - 0.0.2\n\n - Code cleanup, bug fixes and tests\n\n### 0.0.1\n\n - Initial commit\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fle_node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frapid7%2Fle_node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frapid7%2Fle_node/lists"}