├── .eslintrc.json ├── .gitignore ├── .npmignore ├── .travis.yml ├── LICENSE ├── README.md ├── package-lock.json ├── package.json ├── src └── index.js ├── sumologic-function └── handler.template.js ├── test └── plugin.spec.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true 7 | }, 8 | "parserOptions": { 9 | "ecmaFeatures": { 10 | "jsx": true 11 | }, 12 | "sourceType": "module" 13 | }, 14 | "rules": { 15 | "no-const-assign": "warn", 16 | "no-this-before-super": "warn", 17 | "no-undef": "warn", 18 | "no-unreachable": "warn", 19 | "no-unused-vars": "warn", 20 | "constructor-super": "warn", 21 | "valid-typeof": "warn" 22 | } 23 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | 6 | # Runtime data 7 | pids 8 | *.pid 9 | *.seed 10 | 11 | # Directory for instrumented libs generated by jscoverage/JSCover 12 | lib-cov 13 | 14 | # Coverage directory used by tools like istanbul 15 | coverage 16 | 17 | # nyc test coverage 18 | .nyc_output 19 | 20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 21 | .grunt 22 | 23 | # node-waf configuration 24 | .lock-wscript 25 | 26 | # Compiled binary addons (http://nodejs.org/api/addons.html) 27 | build/Release 28 | 29 | # Dependency directories 30 | node_modules 31 | jspm_packages 32 | 33 | # Optional npm cache directory 34 | .npm 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # CI Configuration 2 | .travis.yml -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - 4 4 | deploy: 5 | provider: npm 6 | email: accounts@acloud.guru 7 | api_key: 8 | secure: Gyt/F8ljOSeGVPuihbGFBGNuMxB9c/QQBlKWmHNpGl59I/cHMNSn4bXw2HehLNlh5Wzj3wky2QEJxAyswAW8btH+BJSCQ2P4I8oBqk1Fw0DahfETQK2ut70VP3SUs2KlmQXxpYgxo6amMDKSgTUhqJiQ0zqZxcQTa1f/bc2ArliUu0SElfbjXE13pX6wu8zPR/LTJhYjtRTn4Duy/jLRAFHSEuPHcEHSQ2W/nkHCtZ6LlSTy19Jfwpn4gpgRSw5ldNTO+1MQrTA+W6zGGL9h7T4FmEV5l7mUhncHjmAf6plSnIzYMY9IqjWv0rRPZpZwB/miJdEWOcsb5xr+js/sBOgda3nU5b5nFwxzQsP+/FGQMF3Y16ttxbAwg9KHWc/1aBkHisdKTfkaDeq3jZDJSrvF7eXdx/Zy3vTmykL/5+SUw7ZyqzgrVh1xNiU8T2F7PDOdvOdNIwaaM91eoa5FQdFh29eE6lSCF89niBCbXTwnVzn6/m3EIQ9hOgholGZmPmpyWUHyNmmC1jZqbE6B9pO4pxMFdFPZmnqCCzPJKPTGgb13ax8060A8Y0gy5FRCv2gDGcvR1ZLq0kbnf/kXfqW9O6zxnMjhawq3BBTBJiR25235jLL6d/k1WeoUTLghtoV0+tvUsRJSNmJYPcVltAj56wil0IPIzZnyisnEWw0= 9 | on: 10 | tags: true 11 | repo: ACloudGuru/serverless-plugin-cloudwatch-sumologic 12 | branch: master 13 | notifications: 14 | slack: 15 | secure: SaUa30/K66GlD/kNcluWwnLjg3yWgYYNehi9kIZLzXsvnTEVuv6YJasbTGuOojrBQKQqAJLutmPedvec0AG4bbC4ltlIunvKpUCW+klOs3v0Dmi7mpwvWSJJwxIYCdwzJdqB7IiQtQfZtBbJTx+cL2fSsy1LvBEiOZiYLd+xjpiP6YpWgQocVln3nrsPqUFfFetZWy5hR6O6yPNPYjIjt0xe6OV5Ku9SIJx6EZXrJBZMDK0BXT06qYnYHJEpw3WBGOJ2M78+EBs2Ibd3NuvCzzq1pUUTdICrEy5bYjHR0i7Dtw3Vaf/LdA2QHTRnjmu8HJrA3SOUyIwubrYSMhQq3j0MQW446XUkyPDNTDAfkP2vdJOdOS8l3btZPtLB+Kgw9g6IUFc3QV+h2inXooRc7+1S4Gxi/0fiStCFwP4mY954E+GgIK+hBewh/On76YHawSX6X5HDl9L+gJEnU9kHvdo1sFzMIDvJz/eTMYo9TN3RHtRokc2pWz46C5QwB9iGkP4OptA1ri6pzdKTe3w94cZ5+fIoLnt7LACzrKp3PUCzWa6bnA5zgl5TKv994lfs02Cg3hJJn6mfTTDVN18FpD+8xQEzfOrsipyuvTWCvWfsce8t6SSs8a09mk1Kb/rDpcp5v6vcC7xGBwwaOzKpAQZNvXA7J45VonDOWocyvDU= 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 A Cloud Guru 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # serverless-plugin-cloudwatch-sumologic [![Build Status](https://travis-ci.org/ACloudGuru/serverless-plugin-cloudwatch-sumologic.svg?branch=master)](https://travis-ci.org/ACloudGuru/serverless-plugin-cloudwatch-sumologic) 2 | Plugin which auto-subscribes a log delivery lambda function to lambda log groups created by Serverless 3 | 4 | # Installation 5 | `npm install --save-dev serverless-plugin-cloudwatch-sumologic` 6 | 7 | # Configuration 8 | 1. First follow [this guide](https://help.sumologic.com/Send_Data/Sources/HTTP_Source) to create a new collector and http source on Sumologic. 9 | 2. Add the following custom variables to your `serverless.yml` file. 10 | 11 | ```yaml 12 | plugins: 13 | - serverless-plugin-cloudwatch-sumologic 14 | 15 | custom: 16 | shipLogs: 17 | # Required 18 | arn: existing cloudwatch logs ARN 19 | # OR 20 | collectorUrl: Paste your url from step 1. here 21 | 22 | # Optional, default pattern is "[timestamp=*Z, request_id=\"*-*\", event]" 23 | filterPattern: "[timestamp=*Z, request_id=\"*-*\", correlation_id=\"*-*\", event]" 24 | role: ARN of IAM role to use 25 | ``` 26 | 27 | # How it works 28 | This plugin automates the process described in the [readme](https://github.com/SumoLogic/sumologic-aws-lambda/tree/master/cloudwatchlogs/README.md) provided by Sumologic. 29 | 30 | Upon running `sls deploy` it will... 31 | 32 | 1. if no existing cloudwatch function is specified 33 | 1. Create a temporary function in the root of your serverless project 34 | 2. Add that function to the in-memory CloudFormation script created by the serverless framework 35 | 2. Iterate through all the functions (except for the sumologic one) and generate: 36 | 1. CloudFormation Subscription Filter Resource linking the log groups created by serverless framework to the sumologic lambda function. 37 | 2. Permissions to Invoke the logging function, as a Resource. 38 | 3. Wait for the stack creation/update to complete and then delete the temporarily created function source directory. 39 | 40 | # Caveats 41 | You must be running serverless 1.25.0 or higher. 42 | 43 | # Contribute 44 | Please fork this repo to make changes and then issue a pull request back to this repo. 45 | No unit tests are included at this time. Unit tests will be added before this goes into version 1.0.0 46 | 47 | # Testing 48 | Tests are written using Mocha, Sinon, Chai, using Rewire 49 | 50 | Run with `npm test` 51 | 52 | # Contributors 53 | [Daniel Parker (@rlgod)](https://github.com/rlgod) 54 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-plugin-cloudwatch-sumologic", 3 | "version": "0.0.10", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@sinonjs/formatio": { 8 | "version": "2.0.0", 9 | "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-2.0.0.tgz", 10 | "integrity": "sha512-ls6CAMA6/5gG+O/IdsBcblvnd8qcO/l1TYoNeAzp3wcISOxlPXQEus0mLcdwazEkWjaBdaJ3TaxmNgCLWwvWzg==", 11 | "dev": true, 12 | "requires": { 13 | "samsam": "1.3.0" 14 | } 15 | }, 16 | "ansi-regex": { 17 | "version": "2.1.1", 18 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 19 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", 20 | "dev": true 21 | }, 22 | "ansi-styles": { 23 | "version": "2.2.1", 24 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", 25 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", 26 | "dev": true 27 | }, 28 | "assertion-error": { 29 | "version": "1.1.0", 30 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 31 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 32 | "dev": true 33 | }, 34 | "babel-code-frame": { 35 | "version": "6.26.0", 36 | "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", 37 | "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", 38 | "dev": true, 39 | "requires": { 40 | "chalk": "1.1.3", 41 | "esutils": "2.0.2", 42 | "js-tokens": "3.0.2" 43 | } 44 | }, 45 | "babel-core": { 46 | "version": "6.26.0", 47 | "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz", 48 | "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=", 49 | "dev": true, 50 | "requires": { 51 | "babel-code-frame": "6.26.0", 52 | "babel-generator": "6.26.1", 53 | "babel-helpers": "6.24.1", 54 | "babel-messages": "6.23.0", 55 | "babel-register": "6.26.0", 56 | "babel-runtime": "6.26.0", 57 | "babel-template": "6.26.0", 58 | "babel-traverse": "6.26.0", 59 | "babel-types": "6.26.0", 60 | "babylon": "6.18.0", 61 | "convert-source-map": "1.5.1", 62 | "debug": "2.6.9", 63 | "json5": "0.5.1", 64 | "lodash": "4.17.5", 65 | "minimatch": "3.0.4", 66 | "path-is-absolute": "1.0.1", 67 | "private": "0.1.8", 68 | "slash": "1.0.0", 69 | "source-map": "0.5.7" 70 | }, 71 | "dependencies": { 72 | "debug": { 73 | "version": "2.6.9", 74 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 75 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 76 | "dev": true, 77 | "requires": { 78 | "ms": "2.0.0" 79 | } 80 | } 81 | } 82 | }, 83 | "babel-generator": { 84 | "version": "6.26.1", 85 | "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", 86 | "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", 87 | "dev": true, 88 | "requires": { 89 | "babel-messages": "6.23.0", 90 | "babel-runtime": "6.26.0", 91 | "babel-types": "6.26.0", 92 | "detect-indent": "4.0.0", 93 | "jsesc": "1.3.0", 94 | "lodash": "4.17.5", 95 | "source-map": "0.5.7", 96 | "trim-right": "1.0.1" 97 | } 98 | }, 99 | "babel-helpers": { 100 | "version": "6.24.1", 101 | "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", 102 | "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", 103 | "dev": true, 104 | "requires": { 105 | "babel-runtime": "6.26.0", 106 | "babel-template": "6.26.0" 107 | } 108 | }, 109 | "babel-messages": { 110 | "version": "6.23.0", 111 | "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", 112 | "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", 113 | "dev": true, 114 | "requires": { 115 | "babel-runtime": "6.26.0" 116 | } 117 | }, 118 | "babel-plugin-transform-es2015-block-scoping": { 119 | "version": "6.26.0", 120 | "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", 121 | "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", 122 | "dev": true, 123 | "requires": { 124 | "babel-runtime": "6.26.0", 125 | "babel-template": "6.26.0", 126 | "babel-traverse": "6.26.0", 127 | "babel-types": "6.26.0", 128 | "lodash": "4.17.5" 129 | } 130 | }, 131 | "babel-register": { 132 | "version": "6.26.0", 133 | "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", 134 | "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", 135 | "dev": true, 136 | "requires": { 137 | "babel-core": "6.26.0", 138 | "babel-runtime": "6.26.0", 139 | "core-js": "2.5.3", 140 | "home-or-tmp": "2.0.0", 141 | "lodash": "4.17.5", 142 | "mkdirp": "0.5.1", 143 | "source-map-support": "0.4.18" 144 | } 145 | }, 146 | "babel-runtime": { 147 | "version": "6.26.0", 148 | "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", 149 | "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", 150 | "dev": true, 151 | "requires": { 152 | "core-js": "2.5.3", 153 | "regenerator-runtime": "0.11.1" 154 | } 155 | }, 156 | "babel-template": { 157 | "version": "6.26.0", 158 | "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", 159 | "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", 160 | "dev": true, 161 | "requires": { 162 | "babel-runtime": "6.26.0", 163 | "babel-traverse": "6.26.0", 164 | "babel-types": "6.26.0", 165 | "babylon": "6.18.0", 166 | "lodash": "4.17.5" 167 | } 168 | }, 169 | "babel-traverse": { 170 | "version": "6.26.0", 171 | "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", 172 | "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", 173 | "dev": true, 174 | "requires": { 175 | "babel-code-frame": "6.26.0", 176 | "babel-messages": "6.23.0", 177 | "babel-runtime": "6.26.0", 178 | "babel-types": "6.26.0", 179 | "babylon": "6.18.0", 180 | "debug": "2.6.9", 181 | "globals": "9.18.0", 182 | "invariant": "2.2.3", 183 | "lodash": "4.17.5" 184 | }, 185 | "dependencies": { 186 | "debug": { 187 | "version": "2.6.9", 188 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 189 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 190 | "dev": true, 191 | "requires": { 192 | "ms": "2.0.0" 193 | } 194 | } 195 | } 196 | }, 197 | "babel-types": { 198 | "version": "6.26.0", 199 | "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", 200 | "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", 201 | "dev": true, 202 | "requires": { 203 | "babel-runtime": "6.26.0", 204 | "esutils": "2.0.2", 205 | "lodash": "4.17.5", 206 | "to-fast-properties": "1.0.3" 207 | } 208 | }, 209 | "babylon": { 210 | "version": "6.18.0", 211 | "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", 212 | "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", 213 | "dev": true 214 | }, 215 | "balanced-match": { 216 | "version": "1.0.0", 217 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 218 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 219 | "dev": true 220 | }, 221 | "brace-expansion": { 222 | "version": "1.1.11", 223 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 224 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 225 | "dev": true, 226 | "requires": { 227 | "balanced-match": "1.0.0", 228 | "concat-map": "0.0.1" 229 | } 230 | }, 231 | "browser-stdout": { 232 | "version": "1.3.0", 233 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", 234 | "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", 235 | "dev": true 236 | }, 237 | "chai": { 238 | "version": "4.1.2", 239 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz", 240 | "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", 241 | "dev": true, 242 | "requires": { 243 | "assertion-error": "1.1.0", 244 | "check-error": "1.0.2", 245 | "deep-eql": "3.0.1", 246 | "get-func-name": "2.0.0", 247 | "pathval": "1.1.0", 248 | "type-detect": "4.0.8" 249 | } 250 | }, 251 | "chalk": { 252 | "version": "1.1.3", 253 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", 254 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", 255 | "dev": true, 256 | "requires": { 257 | "ansi-styles": "2.2.1", 258 | "escape-string-regexp": "1.0.5", 259 | "has-ansi": "2.0.0", 260 | "strip-ansi": "3.0.1", 261 | "supports-color": "2.0.0" 262 | }, 263 | "dependencies": { 264 | "supports-color": { 265 | "version": "2.0.0", 266 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", 267 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", 268 | "dev": true 269 | } 270 | } 271 | }, 272 | "check-error": { 273 | "version": "1.0.2", 274 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 275 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 276 | "dev": true 277 | }, 278 | "commander": { 279 | "version": "2.11.0", 280 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", 281 | "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", 282 | "dev": true 283 | }, 284 | "concat-map": { 285 | "version": "0.0.1", 286 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 287 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 288 | "dev": true 289 | }, 290 | "convert-source-map": { 291 | "version": "1.5.1", 292 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", 293 | "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", 294 | "dev": true 295 | }, 296 | "core-js": { 297 | "version": "2.5.3", 298 | "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz", 299 | "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=", 300 | "dev": true 301 | }, 302 | "debug": { 303 | "version": "3.1.0", 304 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 305 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 306 | "dev": true, 307 | "requires": { 308 | "ms": "2.0.0" 309 | } 310 | }, 311 | "deep-eql": { 312 | "version": "3.0.1", 313 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 314 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 315 | "dev": true, 316 | "requires": { 317 | "type-detect": "4.0.8" 318 | } 319 | }, 320 | "detect-indent": { 321 | "version": "4.0.0", 322 | "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", 323 | "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", 324 | "dev": true, 325 | "requires": { 326 | "repeating": "2.0.1" 327 | } 328 | }, 329 | "diff": { 330 | "version": "3.3.1", 331 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", 332 | "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", 333 | "dev": true 334 | }, 335 | "escape-string-regexp": { 336 | "version": "1.0.5", 337 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 338 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 339 | "dev": true 340 | }, 341 | "esutils": { 342 | "version": "2.0.2", 343 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 344 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 345 | "dev": true 346 | }, 347 | "fs.realpath": { 348 | "version": "1.0.0", 349 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 350 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 351 | "dev": true 352 | }, 353 | "get-func-name": { 354 | "version": "2.0.0", 355 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 356 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 357 | "dev": true 358 | }, 359 | "glob": { 360 | "version": "7.1.2", 361 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 362 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 363 | "dev": true, 364 | "requires": { 365 | "fs.realpath": "1.0.0", 366 | "inflight": "1.0.6", 367 | "inherits": "2.0.3", 368 | "minimatch": "3.0.4", 369 | "once": "1.4.0", 370 | "path-is-absolute": "1.0.1" 371 | } 372 | }, 373 | "globals": { 374 | "version": "9.18.0", 375 | "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", 376 | "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", 377 | "dev": true 378 | }, 379 | "growl": { 380 | "version": "1.10.3", 381 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", 382 | "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", 383 | "dev": true 384 | }, 385 | "has-ansi": { 386 | "version": "2.0.0", 387 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", 388 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", 389 | "dev": true, 390 | "requires": { 391 | "ansi-regex": "2.1.1" 392 | } 393 | }, 394 | "has-flag": { 395 | "version": "2.0.0", 396 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", 397 | "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", 398 | "dev": true 399 | }, 400 | "he": { 401 | "version": "1.1.1", 402 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 403 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 404 | "dev": true 405 | }, 406 | "home-or-tmp": { 407 | "version": "2.0.0", 408 | "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", 409 | "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", 410 | "dev": true, 411 | "requires": { 412 | "os-homedir": "1.0.2", 413 | "os-tmpdir": "1.0.2" 414 | } 415 | }, 416 | "inflight": { 417 | "version": "1.0.6", 418 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 419 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 420 | "dev": true, 421 | "requires": { 422 | "once": "1.4.0", 423 | "wrappy": "1.0.2" 424 | } 425 | }, 426 | "inherits": { 427 | "version": "2.0.3", 428 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 429 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 430 | "dev": true 431 | }, 432 | "invariant": { 433 | "version": "2.2.3", 434 | "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.3.tgz", 435 | "integrity": "sha512-7Z5PPegwDTyjbaeCnV0efcyS6vdKAU51kpEmS7QFib3P4822l8ICYyMn7qvJnc+WzLoDsuI9gPMKbJ8pCu8XtA==", 436 | "dev": true, 437 | "requires": { 438 | "loose-envify": "1.3.1" 439 | } 440 | }, 441 | "is-finite": { 442 | "version": "1.0.2", 443 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", 444 | "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", 445 | "dev": true, 446 | "requires": { 447 | "number-is-nan": "1.0.1" 448 | } 449 | }, 450 | "isarray": { 451 | "version": "0.0.1", 452 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 453 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", 454 | "dev": true 455 | }, 456 | "js-tokens": { 457 | "version": "3.0.2", 458 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", 459 | "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", 460 | "dev": true 461 | }, 462 | "jsesc": { 463 | "version": "1.3.0", 464 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", 465 | "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", 466 | "dev": true 467 | }, 468 | "json5": { 469 | "version": "0.5.1", 470 | "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", 471 | "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", 472 | "dev": true 473 | }, 474 | "just-extend": { 475 | "version": "1.1.27", 476 | "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-1.1.27.tgz", 477 | "integrity": "sha512-mJVp13Ix6gFo3SBAy9U/kL+oeZqzlYYYLQBwXVBlVzIsZwBqGREnOro24oC/8s8aox+rJhtZ2DiQof++IrkA+g==", 478 | "dev": true 479 | }, 480 | "lodash": { 481 | "version": "4.17.5", 482 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz", 483 | "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw==", 484 | "dev": true 485 | }, 486 | "lodash.assignin": { 487 | "version": "4.2.0", 488 | "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", 489 | "integrity": "sha1-uo31+4QesKPoBEIysOJjqNxqKKI=" 490 | }, 491 | "lodash.clonedeep": { 492 | "version": "4.5.0", 493 | "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", 494 | "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" 495 | }, 496 | "lodash.get": { 497 | "version": "4.4.2", 498 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", 499 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", 500 | "dev": true 501 | }, 502 | "lodash.startcase": { 503 | "version": "4.4.0", 504 | "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz", 505 | "integrity": "sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg=" 506 | }, 507 | "lolex": { 508 | "version": "2.3.2", 509 | "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.3.2.tgz", 510 | "integrity": "sha512-A5pN2tkFj7H0dGIAM6MFvHKMJcPnjZsOMvR7ujCjfgW5TbV6H9vb1PgxLtHvjqNZTHsUolz+6/WEO0N1xNx2ng==", 511 | "dev": true 512 | }, 513 | "loose-envify": { 514 | "version": "1.3.1", 515 | "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", 516 | "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", 517 | "dev": true, 518 | "requires": { 519 | "js-tokens": "3.0.2" 520 | } 521 | }, 522 | "minimatch": { 523 | "version": "3.0.4", 524 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 525 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 526 | "dev": true, 527 | "requires": { 528 | "brace-expansion": "1.1.11" 529 | } 530 | }, 531 | "minimist": { 532 | "version": "0.0.8", 533 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 534 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 535 | "dev": true 536 | }, 537 | "mkdirp": { 538 | "version": "0.5.1", 539 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 540 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 541 | "dev": true, 542 | "requires": { 543 | "minimist": "0.0.8" 544 | } 545 | }, 546 | "mocha": { 547 | "version": "5.0.1", 548 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.0.1.tgz", 549 | "integrity": "sha512-SpwyojlnE/WRBNGtvJSNfllfm5PqEDFxcWluSIgLeSBJtXG4DmoX2NNAeEA7rP5kK+79VgtVq8nG6HskaL1ykg==", 550 | "dev": true, 551 | "requires": { 552 | "browser-stdout": "1.3.0", 553 | "commander": "2.11.0", 554 | "debug": "3.1.0", 555 | "diff": "3.3.1", 556 | "escape-string-regexp": "1.0.5", 557 | "glob": "7.1.2", 558 | "growl": "1.10.3", 559 | "he": "1.1.1", 560 | "mkdirp": "0.5.1", 561 | "supports-color": "4.4.0" 562 | } 563 | }, 564 | "ms": { 565 | "version": "2.0.0", 566 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 567 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 568 | "dev": true 569 | }, 570 | "nise": { 571 | "version": "1.2.5", 572 | "resolved": "https://registry.npmjs.org/nise/-/nise-1.2.5.tgz", 573 | "integrity": "sha512-Es4hGuq3lpip5PckrB+Qpuma282M0UJANJ+jxAgI+0wWTL9X6MtNv+M385JgqsAE8hv6NvD3lv8CQtXgEnvlpQ==", 574 | "dev": true, 575 | "requires": { 576 | "@sinonjs/formatio": "2.0.0", 577 | "just-extend": "1.1.27", 578 | "lolex": "2.3.2", 579 | "path-to-regexp": "1.7.0", 580 | "text-encoding": "0.6.4" 581 | } 582 | }, 583 | "number-is-nan": { 584 | "version": "1.0.1", 585 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 586 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", 587 | "dev": true 588 | }, 589 | "once": { 590 | "version": "1.4.0", 591 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 592 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 593 | "dev": true, 594 | "requires": { 595 | "wrappy": "1.0.2" 596 | } 597 | }, 598 | "os-homedir": { 599 | "version": "1.0.2", 600 | "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", 601 | "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", 602 | "dev": true 603 | }, 604 | "os-tmpdir": { 605 | "version": "1.0.2", 606 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 607 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 608 | "dev": true 609 | }, 610 | "path-is-absolute": { 611 | "version": "1.0.1", 612 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 613 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 614 | "dev": true 615 | }, 616 | "path-to-regexp": { 617 | "version": "1.7.0", 618 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", 619 | "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", 620 | "dev": true, 621 | "requires": { 622 | "isarray": "0.0.1" 623 | } 624 | }, 625 | "pathval": { 626 | "version": "1.1.0", 627 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 628 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 629 | "dev": true 630 | }, 631 | "private": { 632 | "version": "0.1.8", 633 | "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", 634 | "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", 635 | "dev": true 636 | }, 637 | "regenerator-runtime": { 638 | "version": "0.11.1", 639 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", 640 | "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", 641 | "dev": true 642 | }, 643 | "repeating": { 644 | "version": "2.0.1", 645 | "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", 646 | "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", 647 | "dev": true, 648 | "requires": { 649 | "is-finite": "1.0.2" 650 | } 651 | }, 652 | "rewire": { 653 | "version": "3.0.2", 654 | "resolved": "https://registry.npmjs.org/rewire/-/rewire-3.0.2.tgz", 655 | "integrity": "sha512-ejkkt3qYnsQ38ifc9llAAzuHiGM7kR8N5/mL3aHWgmWwet0OMFcmJB8aTsMV2PBHCWxNVTLCeRfBpEa8X2+1fw==", 656 | "dev": true, 657 | "requires": { 658 | "babel-core": "6.26.0", 659 | "babel-plugin-transform-es2015-block-scoping": "6.26.0" 660 | } 661 | }, 662 | "samsam": { 663 | "version": "1.3.0", 664 | "resolved": "https://registry.npmjs.org/samsam/-/samsam-1.3.0.tgz", 665 | "integrity": "sha512-1HwIYD/8UlOtFS3QO3w7ey+SdSDFE4HRNLZoZRYVQefrOY3l17epswImeB1ijgJFQJodIaHcwkp3r/myBjFVbg==", 666 | "dev": true 667 | }, 668 | "sinon": { 669 | "version": "4.3.0", 670 | "resolved": "https://registry.npmjs.org/sinon/-/sinon-4.3.0.tgz", 671 | "integrity": "sha512-pmf05hFgEZUS52AGJcsVjOjqAyJW2yo14cOwVYvzCyw7+inv06YXkLyW75WG6X6p951lzkoKh51L2sNbR9CDvw==", 672 | "dev": true, 673 | "requires": { 674 | "@sinonjs/formatio": "2.0.0", 675 | "diff": "3.3.1", 676 | "lodash.get": "4.4.2", 677 | "lolex": "2.3.2", 678 | "nise": "1.2.5", 679 | "supports-color": "5.2.0", 680 | "type-detect": "4.0.8" 681 | }, 682 | "dependencies": { 683 | "has-flag": { 684 | "version": "3.0.0", 685 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 686 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 687 | "dev": true 688 | }, 689 | "supports-color": { 690 | "version": "5.2.0", 691 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.2.0.tgz", 692 | "integrity": "sha512-F39vS48la4YvTZUPVeTqsjsFNrvcMwrV3RLZINsmHo+7djCvuUzSIeXOnZ5hmjef4bajL1dNccN+tg5XAliO5Q==", 693 | "dev": true, 694 | "requires": { 695 | "has-flag": "3.0.0" 696 | } 697 | } 698 | } 699 | }, 700 | "slash": { 701 | "version": "1.0.0", 702 | "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", 703 | "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", 704 | "dev": true 705 | }, 706 | "source-map": { 707 | "version": "0.5.7", 708 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", 709 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", 710 | "dev": true 711 | }, 712 | "source-map-support": { 713 | "version": "0.4.18", 714 | "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", 715 | "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", 716 | "dev": true, 717 | "requires": { 718 | "source-map": "0.5.7" 719 | } 720 | }, 721 | "strip-ansi": { 722 | "version": "3.0.1", 723 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 724 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 725 | "dev": true, 726 | "requires": { 727 | "ansi-regex": "2.1.1" 728 | } 729 | }, 730 | "supports-color": { 731 | "version": "4.4.0", 732 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", 733 | "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", 734 | "dev": true, 735 | "requires": { 736 | "has-flag": "2.0.0" 737 | } 738 | }, 739 | "text-encoding": { 740 | "version": "0.6.4", 741 | "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", 742 | "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", 743 | "dev": true 744 | }, 745 | "to-fast-properties": { 746 | "version": "1.0.3", 747 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", 748 | "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", 749 | "dev": true 750 | }, 751 | "trim-right": { 752 | "version": "1.0.1", 753 | "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", 754 | "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", 755 | "dev": true 756 | }, 757 | "type-detect": { 758 | "version": "4.0.8", 759 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 760 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 761 | "dev": true 762 | }, 763 | "wrappy": { 764 | "version": "1.0.2", 765 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 766 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 767 | "dev": true 768 | } 769 | } 770 | } 771 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "serverless-plugin-cloudwatch-sumologic", 3 | "version": "0.0.11", 4 | "description": "Serverless Plugin to enable log delivery from cloudwatch to sumologic via a lambda function and log group subscriptions", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "mocha" 8 | }, 9 | "repository": { 10 | "url": "https://github.com/ACloudGuru/serverless-plugin-cloudwatch-sumologic.git", 11 | "type": "git" 12 | }, 13 | "author": "Daniel Parker ", 14 | "license": "MIT", 15 | "dependencies": { 16 | "lodash.assignin": "^4.2.0", 17 | "lodash.clonedeep": "^4.5.0", 18 | "lodash.startcase": "^4.4.0" 19 | }, 20 | "peerDependencies": { 21 | "serverless": "^1.6.0" 22 | }, 23 | "devDependencies": { 24 | "chai": "^4.1.2", 25 | "mocha": "^5.0.1", 26 | "rewire": "^3.0.2", 27 | "sinon": "^4.3.0" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | 6 | const assignin = require('lodash.assignin'); 7 | const cloneDeep = require('lodash.clonedeep'); 8 | const startCase = require('lodash.startcase'); 9 | 10 | 11 | const fnGetAtt = logicalId => ({ "Fn::GetAtt": [ logicalId, "Arn" ] }); 12 | const fnGetRef = logicalId => ({ Ref: logicalId }); 13 | 14 | const normalizeName = name => name && `${startCase(name).split(' ').join('')}`; 15 | 16 | const getNormalizedFunctionName = functionName => 17 | normalizeName(functionName.replace(/[-_]/g, ' ')); 18 | 19 | const getLogGroupLogicalId = functionName => 20 | `${getNormalizedFunctionName(functionName)}LogGroup`; 21 | 22 | 23 | class Plugin { 24 | constructor(serverless, options) { 25 | this.serverless = serverless; 26 | this.options = options; 27 | this.provider = this.serverless.getProvider('aws'); 28 | this.sumoFnName = 'sumologic-shipping-function' 29 | 30 | this.hooks = { 31 | 'before:deploy:createDeploymentArtifacts': this.beforeDeployCreateDeploymentArtifacts.bind(this), 32 | 'deploy:compileEvents': this.deployCompileEvents.bind(this), 33 | 'after:deploy:deploy': this.afterDeployDeploy.bind(this) 34 | }; 35 | } 36 | 37 | getEnvFilePath() { 38 | return path.join(this.serverless.config.servicePath, `${this.sumoFnName}`); 39 | } 40 | 41 | beforeDeployCreateDeploymentArtifacts() { 42 | if (!!this.serverless.service.custom.shipLogs.arn) { 43 | //use existing specified handler ARN 44 | return; 45 | } 46 | 47 | this.serverless.cli.log('Adding Cloudwatch to Sumologic lambda function'); 48 | const functionPath = this.getEnvFilePath(); 49 | 50 | if (!fs.existsSync(functionPath)) { 51 | fs.mkdirSync(functionPath); 52 | } 53 | 54 | const templatePath = path.resolve(__dirname, '../sumologic-function/handler.template.js'); 55 | 56 | const templateFile = fs.readFileSync(templatePath, 'utf-8'); 57 | 58 | const collectorUrl = this.serverless.service.custom.shipLogs.collectorUrl; 59 | 60 | const handlerFunction = templateFile.replace('%collectorUrl%', collectorUrl); 61 | 62 | const customRole = this.serverless.service.custom.shipLogs.role; 63 | 64 | fs.writeFileSync(path.join(functionPath, 'handler.js'), handlerFunction); 65 | 66 | this.serverless.service.functions.sumologicShipping = { 67 | handler: `${this.sumoFnName}/handler.handler`, 68 | events: [] 69 | }; 70 | 71 | if (!!customRole) { 72 | this.serverless.service.functions.sumologicShipping.role = customRole 73 | } 74 | } 75 | 76 | deployCompileEvents() { 77 | this.serverless.cli.log('Generating subscription filters'); 78 | const filterPattern = !!this.serverless.service.custom.shipLogs.filterPattern 79 | ? this.serverless.service.custom.shipLogs.filterPattern 80 | : "[timestamp=*Z, request_id=\"*-*\", event]"; 81 | const principal = `logs.${this.serverless.service.provider.region}.amazonaws.com`; 82 | const slsResources = this.serverless.service.provider.compiledCloudFormationTemplate.Resources; 83 | 84 | let destinationArn = null; 85 | if (!!this.serverless.service.custom.shipLogs.arn) { 86 | destinationArn = this.serverless.service.custom.shipLogs.arn; 87 | } else { 88 | destinationArn = fnGetAtt("SumologicShippingLambdaFunction"); 89 | } 90 | 91 | const filterBaseStatement = { 92 | Type: "AWS::Logs::SubscriptionFilter", 93 | Properties: { 94 | DestinationArn: destinationArn, 95 | FilterPattern: filterPattern 96 | }, 97 | DependsOn: [] 98 | }; 99 | 100 | const cloudwatchLogsLambdaPermission = { 101 | Type: "AWS::Lambda::Permission", 102 | Properties: { 103 | FunctionName: destinationArn, 104 | Action: "lambda:InvokeFunction", 105 | Principal: principal, 106 | SourceAccount: fnGetRef("AWS::AccountId"), 107 | } 108 | }; 109 | 110 | 111 | this.serverless.service.getAllFunctions().forEach(fnName => { 112 | if (fnName !== 'sumologicShipping') { 113 | // console.log(fnName) 114 | const functionName = getNormalizedFunctionName(fnName); 115 | // console.log(functionName) 116 | const logGroupLogicalId = getLogGroupLogicalId(functionName) 117 | this.serverless.cli.log(logGroupLogicalId) 118 | 119 | const filterStatement = cloneDeep(filterBaseStatement); 120 | const filterStatementName = functionName + 'SubscriptionFilter'; 121 | const logGroupPermissions = cloneDeep(cloudwatchLogsLambdaPermission); 122 | const logGroupPermissionName = functionName + 'InvokePermission'; 123 | 124 | filterStatement.Properties.LogGroupName = fnGetRef(logGroupLogicalId); 125 | filterStatement.DependsOn.push(logGroupPermissionName); 126 | logGroupPermissions.Properties.SourceArn = fnGetAtt(logGroupLogicalId); 127 | 128 | const newFilterStatement = { 129 | [`${filterStatementName}`]: filterStatement 130 | }; 131 | const newLogGroupPermissions = { 132 | [`${logGroupPermissionName}`]: logGroupPermissions 133 | } 134 | 135 | assignin(slsResources, newLogGroupPermissions, newFilterStatement); 136 | } 137 | }); 138 | } 139 | 140 | afterDeployDeploy() { 141 | this.serverless.cli.log('Removing temporary Cloudwatch to Sumologic lambda function'); 142 | let functionPath = this.getEnvFilePath(); 143 | 144 | try { 145 | if (fs.existsSync(functionPath)) { 146 | if (fs.existsSync(path.join(functionPath, 'handler.js'))) { 147 | fs.unlinkSync(path.join(functionPath, 'handler.js')); 148 | } 149 | fs.rmdirSync(functionPath); 150 | } 151 | } catch (err) { 152 | throw new Error(err); 153 | } 154 | } 155 | } 156 | 157 | module.exports = Plugin; 158 | -------------------------------------------------------------------------------- /sumologic-function/handler.template.js: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 2 | // Remember to change the hostname and path to match your collection API and specific HTTP-source endpoint 3 | // See more at: https://help.sumologic.com/APIs/01Collector_Management_API 4 | /////////////////////////////////////////////////////////////////////////////////////////////////////////// 5 | var sumoEndpoint = '%collectorUrl%'; 6 | 7 | var https = require('https'); 8 | var zlib = require('zlib'); 9 | var url = require('url'); 10 | 11 | exports.handler = function (event, context) { 12 | var urlObject = url.parse(sumoEndpoint); 13 | 14 | var options = { 15 | 'hostname': urlObject.hostname, 16 | 'path': urlObject.pathname, 17 | 'method': 'POST' 18 | }; 19 | 20 | var zippedInput = new Buffer(event.awslogs.data, 'base64'); 21 | 22 | zlib.gunzip(zippedInput, function (e, buffer) { 23 | if (e) { context.fail(e); } 24 | 25 | var awslogsData = JSON.parse(buffer.toString('ascii')); 26 | 27 | console.log(awslogsData); 28 | 29 | if (awslogsData.messageType === "CONTROL_MESSAGE") { 30 | console.log("Control message"); 31 | context.succeed("Success"); 32 | } 33 | 34 | var requestsSent = 0; 35 | var requestsFailed = 0; 36 | var finalizeContext = function () { 37 | var tot = requestsSent + requestsFailed; 38 | if (tot == awslogsData.logEvents.length) { 39 | if (requestsFailed > 0) { 40 | context.fail(requestsFailed + " / " + tot + " events failed"); 41 | } else { 42 | context.succeed(requestsSent + " requests sent"); 43 | } 44 | } 45 | }; 46 | 47 | var re = new RegExp(/(?:RequestId:|Z)\s+([\w\d\-]+)/); 48 | var lastRequestID = null; 49 | awslogsData.logEvents.forEach(function (val, idx, arr) { 50 | var req = https.request(options, function (res) { 51 | var body = ''; 52 | console.log('Status:', res.statusCode); 53 | res.setEncoding('utf8'); 54 | res.on('data', function (chunk) { body += chunk; }); 55 | res.on('end', function () { 56 | console.log('Successfully processed HTTPS response'); 57 | requestsSent++; 58 | finalizeContext(); 59 | }); 60 | }); 61 | 62 | req.on('error', function (e) { 63 | console.log(e.message) 64 | requestsFailed++; 65 | finalizeContext(); 66 | }); 67 | 68 | var stream = awslogsData.logStream; 69 | var group = awslogsData.logGroup; 70 | var rs = re.exec(val.message); 71 | if (rs !== null) { 72 | lastRequestID = rs[1]; 73 | } 74 | val.requestID = lastRequestID; 75 | val.logStream = stream; 76 | val.logGroup = group; 77 | req.end(JSON.stringify(val)); 78 | }); 79 | 80 | }); 81 | }; 82 | -------------------------------------------------------------------------------- /test/plugin.spec.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const chai = require('chai'); 3 | const assert = chai.assert; 4 | const expect = chai.expect; 5 | const cloneDeep = require('lodash.clonedeep'); 6 | const rewire = require('rewire'); 7 | const sinon = require('sinon'); 8 | 9 | const Plugin = rewire('../src'); 10 | 11 | const mockCollectorUrl = 'https://not-real.not-really-sumologic.com/12345' 12 | const mockFn = 'mock-fn'; 13 | const mockFs = { 14 | existsSync: sinon.stub().returns(true), 15 | readFileSync: sinon.stub().returns('%collectorUrl%'), 16 | writeFileSync: sinon.spy() 17 | }; 18 | const mockLogArn = 'arn:aws:lambda:region:account-id:function:mock-log-fn'; 19 | const mockOptions = { test: true }; 20 | const mockProvider = {}; 21 | const mockServerless = { 22 | cli: { 23 | log: sinon.spy() 24 | }, 25 | config: { 26 | servicePath: 'mock-service-path' 27 | }, 28 | getProvider: sinon.stub().returns(mockProvider), 29 | service: { 30 | custom: { 31 | shipLogs: { 32 | arn: mockLogArn, 33 | collectorUrl: mockCollectorUrl, 34 | filterPattern: false 35 | } 36 | }, 37 | functions: {}, 38 | getAllFunctions: sinon.stub().returns([mockFn, `${mockFn}_2`]), 39 | provider: { 40 | compiledCloudFormationTemplate: { Resources: {} }, 41 | region: 'us-east-1', 42 | } 43 | } 44 | }; 45 | 46 | 47 | 48 | describe("Plugin correctly updates CF template", () => { 49 | describe('constructor', () => { 50 | let myMockServerless, myMockOptions; 51 | beforeEach(() => { 52 | myMockServerless = cloneDeep(mockServerless); 53 | myMockOptions = cloneDeep(mockOptions); 54 | }); 55 | 56 | it('Makes serverless and the opts available to itself', () => { 57 | const plugin = new Plugin(myMockServerless, myMockOptions) 58 | 59 | expect(plugin.serverless).to.deep.equal(mockServerless); 60 | expect(plugin.options).to.deep.equal(mockOptions); 61 | }); 62 | 63 | }); 64 | 65 | describe('getEnvFilePath', () => { 66 | let myMockServerless, myMockOptions; 67 | beforeEach(() => { 68 | myMockServerless = cloneDeep(mockServerless); 69 | myMockOptions = cloneDeep(mockOptions); 70 | }); 71 | 72 | it('Gets the ENV file path', () => { 73 | const plugin = new Plugin(myMockServerless, myMockOptions) 74 | const envFilePath = plugin.getEnvFilePath(); 75 | 76 | expect(envFilePath).to.include( 77 | myMockServerless.config.servicePath, 78 | '/', 79 | plugin.sumoFnName 80 | ); 81 | }); 82 | }); 83 | 84 | describe('beforeDeployCreateDeploymentArtifacts', () => { 85 | let myMockServerless, myMockOptions, revertFs; 86 | beforeEach(() => { 87 | revertFs = Plugin.__set__('fs', mockFs) 88 | myMockServerless = cloneDeep(mockServerless); 89 | myMockOptions = cloneDeep(mockOptions); 90 | }); 91 | 92 | afterEach(() => { 93 | revertFs(); 94 | }); 95 | 96 | it('Skips creating a Sumologic Lambda Function if an ARN is passed', () => { 97 | const plugin = new Plugin(myMockServerless, myMockOptions) 98 | const sumoFn = plugin.beforeDeployCreateDeploymentArtifacts() 99 | 100 | expect(sumoFn).to.be.an('undefined'); 101 | }); 102 | 103 | it('Creates a Sumologic Lambda Function if no ARN is passed', () => { 104 | delete myMockServerless.service.custom.shipLogs.arn; 105 | 106 | const plugin = new Plugin(myMockServerless, myMockOptions) 107 | const pluginFs = Plugin.__get__('fs'); 108 | plugin.beforeDeployCreateDeploymentArtifacts() 109 | 110 | expect(myMockServerless.service.functions.sumologicShipping).to.be.an('object'); 111 | expect(myMockServerless.service.functions.sumologicShipping.handler).to.include(plugin.sumoFnName); 112 | expect(pluginFs.existsSync.callCount).to.equal(1); 113 | expect(pluginFs.readFileSync.callCount).to.equal(1); 114 | expect(pluginFs.writeFileSync.callCount).to.equal(1); 115 | expect(pluginFs.writeFileSync.firstCall.args).to.include(mockCollectorUrl); 116 | }); 117 | 118 | }); 119 | 120 | describe('deployCompileEvents', () => { 121 | let myMockServerless, myMockOptions, 122 | fnGetAttSpy, fnGetAtt, 123 | fnGetRefSpy, fnGetRef, 124 | normalizeNameSpy, normalizeName, 125 | getNormalizedFunctionNameSpy, getNormalizedFunctionName, 126 | getLogGroupLogicalIdSpy, getLogGroupLogicalId; 127 | 128 | beforeEach(() => { 129 | myMockServerless = cloneDeep(mockServerless); 130 | myMockOptions = cloneDeep(mockOptions); 131 | 132 | fnGetAttSpy = Plugin.__set__('fnGetAtt', 133 | sinon.spy(Plugin.__get__('fnGetAtt'))); 134 | fnGetRefSpy = Plugin.__set__('fnGetRef', 135 | sinon.spy(Plugin.__get__('fnGetRef'))); 136 | normalizeNameSpy = Plugin.__set__('normalizeName', 137 | sinon.spy(Plugin.__get__('normalizeName'))); 138 | getNormalizedFunctionNameSpy = Plugin.__set__('getNormalizedFunctionName', 139 | sinon.spy(Plugin.__get__('getNormalizedFunctionName'))); 140 | getLogGroupLogicalIdSpy = Plugin.__set__('getLogGroupLogicalId', 141 | sinon.spy(Plugin.__get__('getLogGroupLogicalId'))); 142 | 143 | fnGetAtt = Plugin.__get__('fnGetAtt'); 144 | fnGetRef = Plugin.__get__('fnGetRef'); 145 | normalizeName = Plugin.__get__('normalizeName'); 146 | getNormalizedFunctionName = Plugin.__get__('getNormalizedFunctionName'); 147 | getLogGroupLogicalId = Plugin.__get__('getLogGroupLogicalId'); 148 | }); 149 | 150 | afterEach(() => { 151 | fnGetAttSpy() 152 | fnGetRefSpy() 153 | normalizeNameSpy() 154 | getNormalizedFunctionNameSpy() 155 | getLogGroupLogicalIdSpy() 156 | myMockServerless.cli.log.resetHistory() 157 | myMockServerless.service.getAllFunctions.resetHistory() 158 | }); 159 | 160 | it('Gets all serverless functions', () => { 161 | const plugin = new Plugin(myMockServerless, myMockOptions) 162 | plugin.deployCompileEvents(); 163 | 164 | expect(plugin.serverless.service.getAllFunctions.callCount).to.equal(1); 165 | expect(getNormalizedFunctionName.callCount).to.equal(4); 166 | expect(getLogGroupLogicalId.callCount).to.equal(2); 167 | }); 168 | 169 | it('Normalizes function names', () => { 170 | const plugin = new Plugin(myMockServerless, myMockOptions) 171 | plugin.deployCompileEvents(); 172 | 173 | expect(getNormalizedFunctionName.callCount).to.equal(4); 174 | expect(getLogGroupLogicalId.firstCall.args).not.to.include('-'); 175 | expect(getLogGroupLogicalId.firstCall.args).to.include('MockFn'); 176 | }); 177 | 178 | it('Gets LogGroupLogicalIds', () => { 179 | const plugin = new Plugin(myMockServerless, myMockOptions) 180 | plugin.deployCompileEvents(); 181 | 182 | expect(plugin.serverless.cli.log.callCount).to.equal(3); 183 | expect(plugin.serverless.cli.log.secondCall.args).to.include('MockFnLogGroup'); 184 | expect(plugin.serverless.cli.log.thirdCall.args).to.include('MockFn2LogGroup'); 185 | }); 186 | 187 | /** 188 | * Low hanging fruit 189 | * 190 | * Make this its own Describe, and actually check each aspect of the objects 191 | * that we expect it to add for the right props, etc. 192 | */ 193 | 194 | it('Updates Resources with new permissions & subscription filters', () => { 195 | const plugin = new Plugin(myMockServerless, myMockOptions) 196 | 197 | const slsResources = plugin.serverless.service.provider.compiledCloudFormationTemplate.Resources; 198 | expect(Object.keys(slsResources).length).to.equal(0); 199 | plugin.deployCompileEvents(); 200 | expect(Object.keys(slsResources).length).to.equal(4); 201 | expect(Object.keys(slsResources)).to.include( 202 | 'MockFnSubscriptionFilter', 'MockFnInvokePermission', 203 | 'MockFn2SubscriptionFilter', 'MockFn2InvokePermission' 204 | ); 205 | }) 206 | }) 207 | }); 208 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@sinonjs/formatio@^2.0.0": 6 | version "2.0.0" 7 | resolved "https://registry.yarnpkg.com/@sinonjs/formatio/-/formatio-2.0.0.tgz#84db7e9eb5531df18a8c5e0bfb6e449e55e654b2" 8 | dependencies: 9 | samsam "1.3.0" 10 | 11 | ansi-regex@^2.0.0: 12 | version "2.1.1" 13 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 14 | 15 | ansi-styles@^2.2.1: 16 | version "2.2.1" 17 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" 18 | 19 | assertion-error@^1.0.1: 20 | version "1.1.0" 21 | resolved "https://registry.yarnpkg.com/assertion-error/-/assertion-error-1.1.0.tgz#e60b6b0e8f301bd97e5375215bda406c85118c0b" 22 | 23 | babel-code-frame@^6.26.0: 24 | version "6.26.0" 25 | resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" 26 | dependencies: 27 | chalk "^1.1.3" 28 | esutils "^2.0.2" 29 | js-tokens "^3.0.2" 30 | 31 | babel-core@^6.26.0: 32 | version "6.26.0" 33 | resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" 34 | dependencies: 35 | babel-code-frame "^6.26.0" 36 | babel-generator "^6.26.0" 37 | babel-helpers "^6.24.1" 38 | babel-messages "^6.23.0" 39 | babel-register "^6.26.0" 40 | babel-runtime "^6.26.0" 41 | babel-template "^6.26.0" 42 | babel-traverse "^6.26.0" 43 | babel-types "^6.26.0" 44 | babylon "^6.18.0" 45 | convert-source-map "^1.5.0" 46 | debug "^2.6.8" 47 | json5 "^0.5.1" 48 | lodash "^4.17.4" 49 | minimatch "^3.0.4" 50 | path-is-absolute "^1.0.1" 51 | private "^0.1.7" 52 | slash "^1.0.0" 53 | source-map "^0.5.6" 54 | 55 | babel-generator@^6.26.0: 56 | version "6.26.1" 57 | resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" 58 | dependencies: 59 | babel-messages "^6.23.0" 60 | babel-runtime "^6.26.0" 61 | babel-types "^6.26.0" 62 | detect-indent "^4.0.0" 63 | jsesc "^1.3.0" 64 | lodash "^4.17.4" 65 | source-map "^0.5.7" 66 | trim-right "^1.0.1" 67 | 68 | babel-helpers@^6.24.1: 69 | version "6.24.1" 70 | resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" 71 | dependencies: 72 | babel-runtime "^6.22.0" 73 | babel-template "^6.24.1" 74 | 75 | babel-messages@^6.23.0: 76 | version "6.23.0" 77 | resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" 78 | dependencies: 79 | babel-runtime "^6.22.0" 80 | 81 | babel-plugin-transform-es2015-block-scoping@^6.26.0: 82 | version "6.26.0" 83 | resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" 84 | dependencies: 85 | babel-runtime "^6.26.0" 86 | babel-template "^6.26.0" 87 | babel-traverse "^6.26.0" 88 | babel-types "^6.26.0" 89 | lodash "^4.17.4" 90 | 91 | babel-register@^6.26.0: 92 | version "6.26.0" 93 | resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" 94 | dependencies: 95 | babel-core "^6.26.0" 96 | babel-runtime "^6.26.0" 97 | core-js "^2.5.0" 98 | home-or-tmp "^2.0.0" 99 | lodash "^4.17.4" 100 | mkdirp "^0.5.1" 101 | source-map-support "^0.4.15" 102 | 103 | babel-runtime@^6.22.0, babel-runtime@^6.26.0: 104 | version "6.26.0" 105 | resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" 106 | dependencies: 107 | core-js "^2.4.0" 108 | regenerator-runtime "^0.11.0" 109 | 110 | babel-template@^6.24.1, babel-template@^6.26.0: 111 | version "6.26.0" 112 | resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" 113 | dependencies: 114 | babel-runtime "^6.26.0" 115 | babel-traverse "^6.26.0" 116 | babel-types "^6.26.0" 117 | babylon "^6.18.0" 118 | lodash "^4.17.4" 119 | 120 | babel-traverse@^6.26.0: 121 | version "6.26.0" 122 | resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" 123 | dependencies: 124 | babel-code-frame "^6.26.0" 125 | babel-messages "^6.23.0" 126 | babel-runtime "^6.26.0" 127 | babel-types "^6.26.0" 128 | babylon "^6.18.0" 129 | debug "^2.6.8" 130 | globals "^9.18.0" 131 | invariant "^2.2.2" 132 | lodash "^4.17.4" 133 | 134 | babel-types@^6.26.0: 135 | version "6.26.0" 136 | resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" 137 | dependencies: 138 | babel-runtime "^6.26.0" 139 | esutils "^2.0.2" 140 | lodash "^4.17.4" 141 | to-fast-properties "^1.0.3" 142 | 143 | babylon@^6.18.0: 144 | version "6.18.0" 145 | resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" 146 | 147 | balanced-match@^1.0.0: 148 | version "1.0.0" 149 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 150 | 151 | brace-expansion@^1.1.7: 152 | version "1.1.11" 153 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 154 | dependencies: 155 | balanced-match "^1.0.0" 156 | concat-map "0.0.1" 157 | 158 | browser-stdout@1.3.0: 159 | version "1.3.0" 160 | resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f" 161 | 162 | chai@^4.1.2: 163 | version "4.1.2" 164 | resolved "https://registry.yarnpkg.com/chai/-/chai-4.1.2.tgz#0f64584ba642f0f2ace2806279f4f06ca23ad73c" 165 | dependencies: 166 | assertion-error "^1.0.1" 167 | check-error "^1.0.1" 168 | deep-eql "^3.0.0" 169 | get-func-name "^2.0.0" 170 | pathval "^1.0.0" 171 | type-detect "^4.0.0" 172 | 173 | chalk@^1.1.3: 174 | version "1.1.3" 175 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" 176 | dependencies: 177 | ansi-styles "^2.2.1" 178 | escape-string-regexp "^1.0.2" 179 | has-ansi "^2.0.0" 180 | strip-ansi "^3.0.0" 181 | supports-color "^2.0.0" 182 | 183 | check-error@^1.0.1: 184 | version "1.0.2" 185 | resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" 186 | 187 | commander@2.11.0: 188 | version "2.11.0" 189 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.11.0.tgz#157152fd1e7a6c8d98a5b715cf376df928004563" 190 | 191 | concat-map@0.0.1: 192 | version "0.0.1" 193 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 194 | 195 | convert-source-map@^1.5.0: 196 | version "1.5.1" 197 | resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" 198 | 199 | core-js@^2.4.0, core-js@^2.5.0: 200 | version "2.5.3" 201 | resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.3.tgz#8acc38345824f16d8365b7c9b4259168e8ed603e" 202 | 203 | debug@3.1.0: 204 | version "3.1.0" 205 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" 206 | dependencies: 207 | ms "2.0.0" 208 | 209 | debug@^2.6.8: 210 | version "2.6.9" 211 | resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 212 | dependencies: 213 | ms "2.0.0" 214 | 215 | deep-eql@^3.0.0: 216 | version "3.0.1" 217 | resolved "https://registry.yarnpkg.com/deep-eql/-/deep-eql-3.0.1.tgz#dfc9404400ad1c8fe023e7da1df1c147c4b444df" 218 | dependencies: 219 | type-detect "^4.0.0" 220 | 221 | detect-indent@^4.0.0: 222 | version "4.0.0" 223 | resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" 224 | dependencies: 225 | repeating "^2.0.0" 226 | 227 | diff@3.3.1: 228 | version "3.3.1" 229 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.1.tgz#aa8567a6eed03c531fc89d3f711cd0e5259dec75" 230 | 231 | diff@^3.1.0: 232 | version "3.4.0" 233 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.4.0.tgz#b1d85507daf3964828de54b37d0d73ba67dda56c" 234 | 235 | escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2: 236 | version "1.0.5" 237 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 238 | 239 | esutils@^2.0.2: 240 | version "2.0.2" 241 | resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" 242 | 243 | fs.realpath@^1.0.0: 244 | version "1.0.0" 245 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 246 | 247 | get-func-name@^2.0.0: 248 | version "2.0.0" 249 | resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" 250 | 251 | glob@7.1.2: 252 | version "7.1.2" 253 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" 254 | dependencies: 255 | fs.realpath "^1.0.0" 256 | inflight "^1.0.4" 257 | inherits "2" 258 | minimatch "^3.0.4" 259 | once "^1.3.0" 260 | path-is-absolute "^1.0.0" 261 | 262 | globals@^9.18.0: 263 | version "9.18.0" 264 | resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" 265 | 266 | growl@1.10.3: 267 | version "1.10.3" 268 | resolved "https://registry.yarnpkg.com/growl/-/growl-1.10.3.tgz#1926ba90cf3edfe2adb4927f5880bc22c66c790f" 269 | 270 | has-ansi@^2.0.0: 271 | version "2.0.0" 272 | resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" 273 | dependencies: 274 | ansi-regex "^2.0.0" 275 | 276 | has-flag@^2.0.0: 277 | version "2.0.0" 278 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" 279 | 280 | has-flag@^3.0.0: 281 | version "3.0.0" 282 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" 283 | 284 | he@1.1.1: 285 | version "1.1.1" 286 | resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd" 287 | 288 | home-or-tmp@^2.0.0: 289 | version "2.0.0" 290 | resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" 291 | dependencies: 292 | os-homedir "^1.0.0" 293 | os-tmpdir "^1.0.1" 294 | 295 | inflight@^1.0.4: 296 | version "1.0.6" 297 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 298 | dependencies: 299 | once "^1.3.0" 300 | wrappy "1" 301 | 302 | inherits@2: 303 | version "2.0.3" 304 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 305 | 306 | invariant@^2.2.2: 307 | version "2.2.3" 308 | resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.3.tgz#1a827dfde7dcbd7c323f0ca826be8fa7c5e9d688" 309 | dependencies: 310 | loose-envify "^1.0.0" 311 | 312 | is-finite@^1.0.0: 313 | version "1.0.2" 314 | resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" 315 | dependencies: 316 | number-is-nan "^1.0.0" 317 | 318 | isarray@0.0.1: 319 | version "0.0.1" 320 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" 321 | 322 | js-tokens@^3.0.0, js-tokens@^3.0.2: 323 | version "3.0.2" 324 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" 325 | 326 | jsesc@^1.3.0: 327 | version "1.3.0" 328 | resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" 329 | 330 | json5@^0.5.1: 331 | version "0.5.1" 332 | resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" 333 | 334 | just-extend@^1.1.27: 335 | version "1.1.27" 336 | resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-1.1.27.tgz#ec6e79410ff914e472652abfa0e603c03d60e905" 337 | 338 | lodash.assignin@^4.2.0: 339 | version "4.2.0" 340 | resolved "https://registry.yarnpkg.com/lodash.assignin/-/lodash.assignin-4.2.0.tgz#ba8df5fb841eb0a3e8044232b0e263a8dc6a28a2" 341 | 342 | lodash.clonedeep@^4.5.0: 343 | version "4.5.0" 344 | resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 345 | 346 | lodash.get@^4.4.2: 347 | version "4.4.2" 348 | resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" 349 | 350 | lodash.startcase@^4.4.0: 351 | version "4.4.0" 352 | resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" 353 | 354 | lodash@^4.17.4: 355 | version "4.17.5" 356 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511" 357 | 358 | lolex@^2.2.0, lolex@^2.3.2: 359 | version "2.3.2" 360 | resolved "https://registry.yarnpkg.com/lolex/-/lolex-2.3.2.tgz#85f9450425103bf9e7a60668ea25dc43274ca807" 361 | 362 | loose-envify@^1.0.0: 363 | version "1.3.1" 364 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" 365 | dependencies: 366 | js-tokens "^3.0.0" 367 | 368 | minimatch@^3.0.4: 369 | version "3.0.4" 370 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 371 | dependencies: 372 | brace-expansion "^1.1.7" 373 | 374 | minimist@0.0.8: 375 | version "0.0.8" 376 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 377 | 378 | mkdirp@0.5.1, mkdirp@^0.5.1: 379 | version "0.5.1" 380 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 381 | dependencies: 382 | minimist "0.0.8" 383 | 384 | mocha@^5.0.1: 385 | version "5.0.1" 386 | resolved "https://registry.yarnpkg.com/mocha/-/mocha-5.0.1.tgz#759b62c836b0732382a62b6b1fb245ec1bc943ac" 387 | dependencies: 388 | browser-stdout "1.3.0" 389 | commander "2.11.0" 390 | debug "3.1.0" 391 | diff "3.3.1" 392 | escape-string-regexp "1.0.5" 393 | glob "7.1.2" 394 | growl "1.10.3" 395 | he "1.1.1" 396 | mkdirp "0.5.1" 397 | supports-color "4.4.0" 398 | 399 | ms@2.0.0: 400 | version "2.0.0" 401 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" 402 | 403 | nise@^1.2.0: 404 | version "1.2.5" 405 | resolved "https://registry.yarnpkg.com/nise/-/nise-1.2.5.tgz#a143371b65014b6807d3a6e6b4556063f3a53363" 406 | dependencies: 407 | "@sinonjs/formatio" "^2.0.0" 408 | just-extend "^1.1.27" 409 | lolex "^2.3.2" 410 | path-to-regexp "^1.7.0" 411 | text-encoding "^0.6.4" 412 | 413 | number-is-nan@^1.0.0: 414 | version "1.0.1" 415 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 416 | 417 | once@^1.3.0: 418 | version "1.4.0" 419 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 420 | dependencies: 421 | wrappy "1" 422 | 423 | os-homedir@^1.0.0: 424 | version "1.0.2" 425 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 426 | 427 | os-tmpdir@^1.0.1: 428 | version "1.0.2" 429 | resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" 430 | 431 | path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: 432 | version "1.0.1" 433 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 434 | 435 | path-to-regexp@^1.7.0: 436 | version "1.7.0" 437 | resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.7.0.tgz#59fde0f435badacba103a84e9d3bc64e96b9937d" 438 | dependencies: 439 | isarray "0.0.1" 440 | 441 | pathval@^1.0.0: 442 | version "1.1.0" 443 | resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.0.tgz#b942e6d4bde653005ef6b71361def8727d0645e0" 444 | 445 | private@^0.1.7: 446 | version "0.1.8" 447 | resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" 448 | 449 | regenerator-runtime@^0.11.0: 450 | version "0.11.1" 451 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" 452 | 453 | repeating@^2.0.0: 454 | version "2.0.1" 455 | resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" 456 | dependencies: 457 | is-finite "^1.0.0" 458 | 459 | rewire@^3.0.2: 460 | version "3.0.2" 461 | resolved "https://registry.yarnpkg.com/rewire/-/rewire-3.0.2.tgz#25e5413c4f1676eb3247d1884198b3a265408bbd" 462 | dependencies: 463 | babel-core "^6.26.0" 464 | babel-plugin-transform-es2015-block-scoping "^6.26.0" 465 | 466 | samsam@1.3.0: 467 | version "1.3.0" 468 | resolved "https://registry.yarnpkg.com/samsam/-/samsam-1.3.0.tgz#8d1d9350e25622da30de3e44ba692b5221ab7c50" 469 | 470 | sinon@^4.3.0: 471 | version "4.3.0" 472 | resolved "https://registry.yarnpkg.com/sinon/-/sinon-4.3.0.tgz#cec9b27d5f4e2c63c1a79c9dc1c05d34bb088234" 473 | dependencies: 474 | "@sinonjs/formatio" "^2.0.0" 475 | diff "^3.1.0" 476 | lodash.get "^4.4.2" 477 | lolex "^2.2.0" 478 | nise "^1.2.0" 479 | supports-color "^5.1.0" 480 | type-detect "^4.0.5" 481 | 482 | slash@^1.0.0: 483 | version "1.0.0" 484 | resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" 485 | 486 | source-map-support@^0.4.15: 487 | version "0.4.18" 488 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" 489 | dependencies: 490 | source-map "^0.5.6" 491 | 492 | source-map@^0.5.6, source-map@^0.5.7: 493 | version "0.5.7" 494 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" 495 | 496 | strip-ansi@^3.0.0: 497 | version "3.0.1" 498 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 499 | dependencies: 500 | ansi-regex "^2.0.0" 501 | 502 | supports-color@4.4.0: 503 | version "4.4.0" 504 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.4.0.tgz#883f7ddabc165142b2a61427f3352ded195d1a3e" 505 | dependencies: 506 | has-flag "^2.0.0" 507 | 508 | supports-color@^2.0.0: 509 | version "2.0.0" 510 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" 511 | 512 | supports-color@^5.1.0: 513 | version "5.2.0" 514 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.2.0.tgz#b0d5333b1184dd3666cbe5aa0b45c5ac7ac17a4a" 515 | dependencies: 516 | has-flag "^3.0.0" 517 | 518 | text-encoding@^0.6.4: 519 | version "0.6.4" 520 | resolved "https://registry.yarnpkg.com/text-encoding/-/text-encoding-0.6.4.tgz#e399a982257a276dae428bb92845cb71bdc26d19" 521 | 522 | to-fast-properties@^1.0.3: 523 | version "1.0.3" 524 | resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" 525 | 526 | trim-right@^1.0.1: 527 | version "1.0.1" 528 | resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" 529 | 530 | type-detect@^4.0.0, type-detect@^4.0.5: 531 | version "4.0.8" 532 | resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" 533 | 534 | wrappy@1: 535 | version "1.0.2" 536 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 537 | --------------------------------------------------------------------------------