├── .env_sample
├── .eslintrc.json
├── .gitignore
├── .travis.yml
├── README.md
├── SETUP.md
├── index.js
├── lib
├── debug.js
├── http_request.js
├── parse.js
├── s3.js
└── send.js
├── package-lock.json
├── package.json
├── templates
├── hello.html
├── hello.txt
├── simulator.html
├── simulator.txt
├── verify.html
├── verify.txt
├── welcome.html
└── welcome.txt
└── test
├── debug.test.js
├── fixtures
├── sample_sns_bounce.json
└── ses_sent.js
├── http_request.test.js
├── index.test.js
├── parse.test.js
├── s3.test.js
└── send.test.js
/.env_sample:
--------------------------------------------------------------------------------
1 | export AWS_ACCESS_KEY_ID=YOURACCESSKEYID
2 | export AWS_IAM_ROLE=arn:aws:iam::123456789:role/LambdaExecRole
3 | export AWS_REGION=eu-west-1
4 | export AWS_S3_BUCKET=yourbucket
5 | export AWS_SECRET_ACCESS_KEY=SUPERSECRETACCESSKEY
6 | export EMAIL_APP_URL=dwylmail.herokuapp.com
7 | export JWT_SECRET=mustmatchphoenixemailappsecret
8 | export SENDER_EMAIL_ADDRESS=your.ses.verified@email.com
9 | export TEMPLATE_DIRECTORY=./templates
10 | export TMPDIR=/Users/n/code/aws-lambda-depl/tmp/
11 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "node": true,
5 | "es6": true
6 | },
7 | "extends": "eslint:recommended",
8 | "globals": {
9 | "Atomics": "readonly",
10 | "SharedArrayBuffer": "readonly"
11 | },
12 | "parserOptions": {
13 | "ecmaVersion": 2018,
14 | "sourceType": "module"
15 | },
16 | "rules": {
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 | *.pid.lock
11 |
12 | # Directory for instrumented libs generated by jscoverage/JSCover
13 | lib-cov
14 |
15 | # Coverage directory used by tools like istanbul
16 | coverage
17 |
18 | # nyc test coverage
19 | .nyc_output
20 |
21 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
22 | .grunt
23 |
24 | # Bower dependency directory (https://bower.io/)
25 | bower_components
26 |
27 | # node-waf configuration
28 | .lock-wscript
29 |
30 | # Compiled binary addons (http://nodejs.org/api/addons.html)
31 | build/Release
32 |
33 | # Dependency directories
34 | node_modules/
35 | jspm_packages/
36 |
37 | # Typescript v1 declaration files
38 | typings/
39 |
40 | # Optional npm cache directory
41 | .npm
42 |
43 | # Optional eslint cache
44 | .eslintcache
45 |
46 | # Optional REPL history
47 | .node_repl_history
48 |
49 | # Output of 'npm pack'
50 | *.tgz
51 |
52 | # Yarn Integrity file
53 | .yarn-integrity
54 |
55 | # .env environment variables file
56 | .env
57 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - '12'
4 | cache:
5 | directories:
6 | - node_modules
7 | before_install:
8 | - echo "export HELLO=world" >> .env
9 | before_script:
10 | - npm run eslint
11 | after_success:
12 | - bash <(curl -s https://codecov.io/bash)
13 | env:
14 | global:
15 | - AWS_REGION=eu-west-1
16 | - TEMPLATE_DIRECTORY=$TRAVIS_BUILD_DIR/templates
17 | - AWS_S3_BUCKET=ademoapp
18 | - EMAIL_APP_URL=dwylmail.herokuapp.com
19 | - secure: O5U1QiCgj1+HTYPh9qUHQC24r0ou8Pf7MnpQDLFdpzNvZnIjTX7LIb5xlfzerLH/kmijcw6oXHA1LlaG2FLKcnAzJ26Tn9sooCDbKN8MpLG4DXE7sWN6cWTgP/Mn2Viw3EYY+yweNhCx3KPR0pZ560r1fOXVpLBR7KszGKuHYrZQKMc/KR45ycvPdRzEr1NNV7rUuZVj1MxGdOGVDT067A0F5+cqPy0p7meDykAbd3kGt5tIMXcsIYVJKPrMrQP3may44w8q2/r2YmxJszahUnERLUtY/1Bl3S9+RB/WVSI7FaKOxAx78NF9IwjTh8Y//9QyZS4qR5MZexh0OL/jqNEeEw35oqeYAZktMeL8MHspt0mpMdHBJMgXeW0CIjj6Y2AWu1nP1NY6QaI429xOtK34DP/Gw8dpmVCbPMXEF7JZbR5qMx+hn0nBKBnTBc+M3jezqceAkAjXT2tlsSFSKnAKjXmasX9zt3tk11ny0YgVDL/kEtZn9NRD0K1zOHXwBYhr+YrUsDXSA1vzpw//QRG+ar05oRWDOxgGlMlu2Ebjw8wrqm49+IQItU6x8lVg4YqlcOLKUPHWG8TKh53j1RyejlDl6ZRdHIYKzIfY8xjr8k4epnXXRK/YjFFcc3MVnCpS14QO9Pr6cQpBlE6W50/H5e28Kw36EDL7b+fFdoU=
20 | - secure: pcZzSoPYs5wYKgbBkJYkyjOkrIWEn3xWr86Oe21DByTVrfe6UOgQRl+zNNHo2q/omssyHiB8J4THKqBY9GDXLVY18JZY8ujNXzfTxRcu+OcLpt3JeT5vt9hmxHuqteYbmBgMGMgz76O8zBAqJLD8+p0wdnJ7mkCM5vedIb86ifaJQHgDcajGxl04GeVMnASzM2bVkwaInI2LaVClFQhi61QahZVThH7HI9uq6x1zKU4d6saHM/mwVZOtbEyxJHpCuH0uuyt55IVX5XbabmTi7toR+y8f+5Ot/dtMGrNqNntUSdrYt338Yf/k1a0vhQBZuraN6VJaZniGi9OAtHWe86fJiuqiWZ2dNeyDx14WVOfMI04kHPSlUUm9X9qt7fLsLTcaHgsQM2UTeQIggXNjFtm4h9yGFDvoespRtG0kk8AnwYR+wRJSRaOFI6SO3lECH3PGEtZkoPVCXXXSIpFP/ZZEq7G5SeDnFmkQksubMsHvb8T70YJFoMu0d8CNFuk0cVtifC7Hh7Z3Y0F4SeOqOPckbKOpX/BruOCVOY+W2wh9Tmt+E+t+Tw0/KLAnmUYes9eAHX/S/UlOWSkXW8dACNE82VzDwBWE5m+F1gI812ORy+FTCtW48WJAi1kZcnACh/QQhZ/qthaWAHKGG0+T6WGi7OjmpKJA/5J6PkBFQcA=
21 | - secure: YhXKuNQ/pmLgxbkCx6E56ccLjXNTQCx3v5ja+Chh+6O0Uyz9THqw2viXrE3e//NX9XiTsELKOZJhTnCwakqNtjozZVWzs/fSOdy1Reh8SBEe0JkKWVEhFv5aheMgdhlYw2mWCGNhHI+Pc0qbLDBPM+vYRiVdMoT4vRzQ06Ii71tgv55K9nR8Ct5GHpvkAuAYlGqHA1Yi1KPcYVUOLFPZ+ToG/r6lzu0SvlVu+9tELU14oMkFZunG0Tv/PBVG9nEvGNbyVCW4Rb6UsUW4MwX7flOF7opu9oycJ4AMnoqakgeWkU7qWEbtZiaSfA3r+3NA2gUB6NAHUjQ0bq/f5vJRz2LkBxr3k3GTEv1u+mpeQNW2W2/AmfKBmlPiH+DLP601jPrfFAJEaVUBAxL9iU+p9AO9Jfe9hokjCat/xN1w48ABPjnK4PlkJr79Q5c5Bt7Fga4ZTTCVXzCUQQ0OvcRZQZ+raT2o0ctJ8ae+nVgXNZiyqsqj8m+TCJ/BcStyaS0Sv9zYsdcbi1I2VOf2vOHJQtcRyJ1zC3ecQCJn94kQOg9xkUuzzQsStnSw2BHyN0xoS9VL36ptegiUpCe2ckUS1O9Lzn3HUn2/rzjgLbflSey3fjBIjxt6g/uBOxPcCGP78GYLVHu8M+1rUwO/M58Q7qvshCwLii0mQ6ApIvgD37I=
22 | - secure: nWx0T+v1eB0XznB/0HlrGKHT0OWE+rXSEfehkz4foEXt7cPGtzy5F168Y0RjwtTXCrKCFAc1kUKKR3dbj1wKa73ygGXluY/xdelSTSmIamNdVqN6OzUlcWvMWNUiDyOZN8PoT3aTnXyDFlPJAd8K5PWtUL15IRvuQBmQ1/WfGYFpEZzw5F7crh2lTT7qnvl0GGJ8Es6IWvF1Au/nGAb7XC3Q+iWAfngGsrJpnGOGwCB6rMXPifm1CjiZYlop1NXjYt+q3LoS4dhf6s7TmsscFVpj0XAp1MkLsSdfi4HpnHm0DJidKnNXvd0isAlnmAfQsOr6A9pWdLcP8oQU5fMOwTaqy+Ro4W95kL+CU/JTK8QzPZGRp+wqRUPWcxE8iDU2rBEIw1lt51sOj03TfWcEQdq9DoycECnWg82t9C8NwEJ8SECTj7sK8vJe6x9WEgLf3oGtS0XY1ONh4b7tpAEzLLcdJRg67U6Fqooa/lt5Eh69B4s8VTY22LVVG6+9W6HK6c/Id7vDH12322bAnL5pejeQ489YP9Nt/i6Tcl+ghF1qJ7WCyouv19hi/PSOoeKdVc2Isq45b89hL+ArxsOzyr5yMAMS2ElaewYqt7UnMjj2sopmytd1H86SoFysNR17m5cL5BtW++ZGg0+cuRoJVhQCsU8wB46yDDB6qpWflxQ=
23 | - secure: YBQ2q1twsNHcXfuiLnQPR2Z9jO1sq+Ya4eY73JnAI8k2dY0GNE6ohKrkwToEt6rIs4D4T1cML++fo8BSJb2CCjYfZaafuG9UqqgRW9KCEgnQJmNjsIWIkGUWMScgcGdbIoNJU5FgI6cAhXmMF3F6YMNJw7fo35INEzk7ulup+zIWUH5VX2PGJyQutqczK1PGV/tz9NQCRlOYGcxf233lwTcNaDLMMbxLGstmMVvvXCk/6oUy+ZD3g57lyC6TBMSIMZhLB8xtCkGnAUZVR5KS0MBTZ9JYmiUrsogm3gRCcE3xdHYbmpWhITBQhIjMM/yZoz1VrdHG9wp9flKnHVmwEywwuNV6uancqOBK950kyk4oiTQwaCHnGdBLvUd1Eh3BaK/A8xNvMlYjcK9onX2oQ+XMZwLtnHVZHb/klMXHNLCu0q90/Y18ytQBYU7QE31SgaA6vx2U6A6wtvUpQwaTN4E5VntmwjJg981AazhZ0ofh+9a1Q1dMs7FiDLmXhFXSaUxjlrLfZtJFf9rb2OrfH8mElI+1yFjGEn4fZtOat/KpbgimSN1/2oQBOu1VmMXIBcFQomxN+bfJoXc9HupwCVc4kPsEqo0o15ZRezS1AJ0ah+RgQOlEZL/82Rpw48BhII0QJkA1XTLiHIQUatvBml097YXYDMLyScxpVO1aq3M=
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | # AWS SES Lambda 📬
4 |
5 | An AWS Lambda Function that Sends Email
6 | via Simple Email Service (SES)
7 | and handles notifications for bounces, etc. 📈
8 |
9 |
10 | [](https://travis-ci.org/dwyl/aws-ses-lambda)
11 | [](http://codecov.io/github/dwyl/aws-ses-lambda?branch=master)
12 | [](https://codeclimate.com/github/dwyl/aws-ses-lambda)
13 | [](https://david-dm.org/dwyl/aws-ses-lambda)
14 | [](http://hits.dwyl.com/dwyl/aws-ses-lambda)
15 | [](https://www.npmjs.com/package/aws-ses-lambda)
16 | [](http://nodejs.org/download/)
17 |
18 |
19 |
20 |
21 |
22 | ## _Why_? 🤷
23 |
24 | We send (_and receive_) a lot of email
25 | both for the @dwyl App
26 | and our newsletter.
27 | We need a simple, scalable & maintainable way of sending email,
28 | and _most importantly_ we needed to _**know** with **certainty**_:
29 |
30 | + Are our emails being ***delivered***?
31 | + How many emails are ***bouncing***?
32 | + Are we attempting to **re-send email**
33 | to addresses that have "***bounced***"?
34 | (_i.e. wasting money?!_)
35 | + Are people ***opening*** / ***reading*** the email?
36 | + Do people ***engage*** with the **content** of the email? (_click through_)
37 | + If someone no longer wants to receive emails (_too many or not relevant_),
38 | do we have a reliable way for them to ***unsubscribe***?
39 |
40 | This project is our quest to answer these questions.
41 |
42 |
43 | ## _What_? 💡
44 |
45 | The `aws-ses-lambda` function does three _related_ things1:
46 |
47 | 1. **Send** emails.
48 | 2. **Parse** AWS SNS notifications related to the emails that were sent.
49 | 3. **Save** the parsed SNS notification data for aggregation and visualisation.
50 |
51 | The _How?_ section below explains
52 | how each of these functions works.
53 |
54 | This diagram explains the context where `aws-ses-lambda` is used:
55 |
56 | 
57 |
58 | [Edit this diagram](https://docs.google.com/presentation/d/1PUKzbRQOEgHaOmaEheU7T3AHQhRT8mhGuqVKotEJkM0/edit?usp=sharing)
59 |
60 | The Email App receives requests from the Auth App
61 | and and triggers the `aws-ses-lambda` function.
62 |
63 | The `aws-ses-lambda` function Sends email
64 | and handles SNS notifications for bounce events.
65 |
66 |
67 | ## _How_?
68 |
69 | As the name of this project suggests, we are using AWS Lambda,
70 | to handle all email-related tasks via AWS SES.
71 |
72 | > If you (_or anyone `else` on your team_) are new to AWS Lambda,
73 | see:
74 | [github.com/dwyl/learn-aws-lambda](https://github.com/dwyl/learn-aws-lambda)
75 |
76 | In this section we will break down _how_ the lambda works.
77 |
78 |
79 | ### 1. _Send_ Email
80 |
81 | Thanks to the work we did earlier on
82 | [`sendemail`](https://github.com/dwyl/sendemail),
83 | sending emails using AWS Simple Email Service (SES)
84 | from our Lambda function is _very_ simple.
85 |
86 | We just need to follow the setup instructions in
87 | [github.com/dwyl/sendemail#how](https://github.com/dwyl/sendemail#how-)
88 | including creating a `/templates` directory,
89 | then create a handler function:
90 |
91 |
92 | ```js
93 | const sendemail = require('sendemail').email;
94 |
95 | module.exports = function send (event, callback) {
96 | return sendemail(event.template, event, callback);
97 | };
98 | ```
99 |
100 | Don't you just _love_ it when things are _that_ simple?!
101 | All the data required for sending an email
102 | is received in the Lambda **`event`** object.
103 |
104 | The required keys in the `event` object are:
105 | + `email` - the email address we want to send an email to.
106 | + `name` - the name of the person we are sending the email to.
107 | (_if your email messages aren't personal, don't send them!_)
108 | + `subject` - the subject of the email you are sending.
109 | + `template` - the template you want to send.
110 |
111 | It works flawlessly.
112 |
113 |
114 |
115 |
116 | The full code is:
117 | [`lib/send.js`](https://github.com/dwyl/aws-ses-lambda/blob/master/lib/send.js#L21)
118 |
119 |
120 |
121 | ### 2. _Parse_ AWS SNS Notifications
122 |
123 | After an email is sent using AWS SES,
124 | AWS keeps track of the status of the emails
125 | e.g `delivered`, `bounce` or `complaint`.
126 | By _subscribing_ to AWS Simple Notification System (SNS)
127 | notifications, we can keep track of the status.
128 |
129 | There are a few steps
130 | for setting up SNS notifications for SES events,
131 | so we created detailed setup instructions:
132 | [`SETUP.md`](https://github.com/dwyl/aws-ses-lambda/blob/master/SETUP.md)
133 |
134 | Once you have configured the SNS Topic,
135 | used the topic for SES notifications
136 | and set the topic as the trigger for the lambda function,
137 | it's time to _parse_ the notifications.
138 |
139 | Thankfully this is _also_ really simple code!
140 |
141 | ```js
142 | let json = {};
143 | if(event && event.Records && event.Records.length > 0) {
144 | const msg = JSON.parse(event.Records[0].Sns.Message);
145 | json.messageId = msg.mail.messageId;
146 | json.notificationType = msg.notificationType + ' ' + msg.bounce.bounceType;
147 | }
148 | ```
149 |
150 | We are only interested in the `messageId` and `notificationType`.
151 | This code is included in
152 | [`lib/parse.js`](https://github.com/dwyl/aws-ses-lambda/blob/master/lib/parse.js#L16)
153 |
154 |
155 | During MVP we are only interested in the emails that _bounce_.
156 | So we are only parsing the bounce event.
157 | Gmail does not send _delivery_ notifications,
158 | so we will need to _implement_ a workaround.
159 | See: https://github.com/dwyl/email/issues/1
160 |
161 | More detail on the various SES SNS notifications:
162 | https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-examples.html
163 |
164 |
165 |
166 | ### 3. _Save_ SNS Notification Data
167 |
168 | Once we have _parsed_ the SNS notifications for SES events,
169 | we need to _save_ the data back to our PostgreSQL database
170 | so that we can build our analytics dashboard!
171 |
172 | This again is pretty simple code;
173 | we just invoke `http_request`
174 | with the `json` data we want to send to the Phoenix App:
175 |
176 | ```js
177 | const json = parse(event); // parse SNS event see: step 2.
178 | http_request(json, callback); // json data & lambda callback argument
179 | ```
180 |
181 | View the complete code in [`index.js`]()
182 | and the supporting `http_request` function in
183 | [`lib/http_request.js`]()
184 |
185 | The **`http_request`** function wraps the Node.js core
186 | [`http.request`](https://nodejs.org/api/http.html#http_http_request_options_callback)
187 | method with a few basic options
188 | and allows us to pass in a `json` Object
189 | to send to the Phoenix App.
190 |
191 | ### Required Environment Variables
192 |
193 | In order for all parts of the Lambda function to work,
194 | we need to ensure that all environment variables are defined.
195 |
196 | For the complete list of required environment variables,
197 | please see the [`.env_sample`](https://github.com/dwyl/aws-ses-lambda/blob/master/.env_sample) file.
198 |
199 | Copy the [`.env_sample`](https://github.com/dwyl/aws-ses-lambda/blob/master/.env_sample) file and create a `.env` file:
200 |
201 | ```
202 | cp .env_sample .env
203 | ```
204 |
205 | Then update all the values in the file
206 | so that they are the _real_ values.
207 |
208 |
209 | Once you have a `.env` file with all the correct environment variables,
210 | it's time to _deploy_ the Lambda function to AWS!
211 |
212 | ### _Deploy_ the Lambda to AWS!
213 |
214 | Run the following command in your terminal:
215 |
216 | ```
217 | npm run deploy
218 | ```
219 |
220 | You should see output similar to the following:
221 |
222 | ```sh
223 | - - - - - - - - > Lambda Function Deployed:
224 | {
225 | FunctionName: 'aws-ses-lambda-v1',
226 | FunctionArn: 'arn:aws:lambda:eu-west-1:123456789247:function:aws-ses-lambda-v1',
227 | Runtime: 'nodejs12.x',
228 | Role: 'arn:aws:iam::123456789247:role/service-role/LambdaExecRole',
229 | Handler: 'index.handler',
230 | CodeSize: 8091768,
231 | Description: 'A complete solution for sending email via AWS SES using Lambda',
232 | Timeout: 42,
233 | MemorySize: 128,
234 | LastModified: '2020-03-05T23:42:56.809+0000',
235 | CodeSha256: 'jvOg/+8y9UwBcLeTprMRIEvT0ryun1bdjzrAJXAk5m8=',
236 | Version: '$LATEST',
237 | Environment: { Variables: { EMAIL_APP_URL: 'phemail.herokuapp.com' } },
238 | TracingConfig: { Mode: 'PassThrough' },
239 | RevisionId: '42442cee-d506-4aa5-aec5-d7fb73145a58',
240 | State: 'Active',
241 | LastUpdateStatus: 'Successful'
242 | }
243 | - - - - - - - - > took 8.767 seconds
244 | ```
245 |
246 | Ensure you follow all the instructions in
247 | [`SETUP.md`](https://github.com/dwyl/aws-ses-lambda/blob/master/SETUP.md)
248 | to get the SNS Topic to trigger the Lambda function for SES notifications.
249 |
250 |
251 | ### Debugging
252 |
253 |
254 | Enable debugging by setting the `NODE_ENV=test` environment variable.
255 |
256 |
257 |
258 | Now the _latest_ `event` will be saved to:
259 | https://ademoapp.s3.eu-west-1.amazonaws.com/event.json
260 |
261 | 
262 |
263 | And SNS messages are saved to:
264 | https://ademoapp.s3.eu-west-1.amazonaws.com/sns.json
265 |
266 | 
267 |
268 |
269 |
270 |
271 |
272 | # tl;dr
273 |
274 | ## _Extended_ Why?
275 |
276 | There are _way_ more reasons
277 | _why_ we are handcrafting this app
278 | than the ones stated above.
279 | We see email as our primary feedback mechanism
280 | and thus "_operationally strategic_",
281 | not merely "_transactional_".
282 | i.e. not something to be "_outsourced_"
283 | to a "black box" provider that "_takes care of everything_" for us.
284 | We want to have full control and deep insights into our email system.
285 | By using a _decoupled_ lambda function to send email
286 | and subscribe to SNS events
287 | we keep all the AWS specific
288 | functionality in a single place.
289 | This is easy to reason about, maintain and _extend_ when required.
290 | In the future, if we decide to switch email sending provider,
291 | (_or run our own email service_),
292 | we can simply re-write the `sendemail`
293 | and `parse_notification` functions
294 | and not need to touch our **`email`** analytics dashboard at all!
295 |
296 | For now SES is _by far_ the cheapest
297 | and superbly reliable way to send email.
298 | We are very happy to let AWS take care of _this_ part of our stack.
299 |
300 |
301 | ### Why Only _One_ Lambda Function?
302 |
303 | 1 The `aws-ses-lambda` function **does 3 things**
304 | because they relate to the unifying theme of
305 | sending email via SES and tracking the status of the sent emails via SNS.
306 | We _could_ have split these 3 bits of functionality into separate repositories
307 | and deploy them separately as distinct lambda functions,
308 | however in our experience having _too many_ lambda functions
309 | can quickly become a maintenance headache.
310 | We _chose_ to _group_ them together
311 | because they are small, easy to reason about
312 | and work well as a team!
313 | If you feel strongly about the
314 | [UNIX Philosophy](https://en.wikipedia.org/wiki/Unix_philosophy#Do_One_Thing_and_Do_It_Well)
315 | definitely split out the functions in your _own_ fork/implementation.
316 | The code for this Lambda function is less than
317 | [**100 lines**](https://codecov.io/gh/dwyl/aws-ses-lambda/tree/master/lib)
318 | and can be read in **10 minutes**.
319 | The [**`sendemail`**](https://github.com/dwyl/sendemail) module
320 | which the Lambda uses to send emails via AWS SES is **38 lines** of code. See:
321 | [lib/index.js](https://codecov.io/gh/dwyl/sendemail/src/master/lib/index.js)
322 | it's mostly comments which make it very beginner friendly.
323 |
--------------------------------------------------------------------------------
/SETUP.md:
--------------------------------------------------------------------------------
1 | ## AWS SNS Setup Instructions
2 |
3 |
4 | ### Create an SNS Topic
5 |
6 | Visit the AWS Simple Notifications Service (SNS) home page and create a new topic: https://eu-west-1.console.aws.amazon.com/sns/v3/home
7 |
8 |
9 |
10 | We called ours `SESNotifications` and then clicked **`Next step`**.
11 | You will see a page where you can configure your SNS topic:
12 |
13 |
14 |
15 | Ignore all the _optional_ configurations and
16 | just scroll to the bottom of the page
17 | and click **`Create topic`**:
18 |
19 |
20 |
21 | You will then see a confirmation page saying your topic was created successfully:
22 |
23 |
24 |
25 | ### Create SNS Subscription to the Topic
26 |
27 |
28 | On this page, scroll till you find the **`Create subscription`** button:
29 | (Click it)
30 |
31 |
32 |
33 | Once you have selected/input the relevant data,
34 | click the **`Create subscription`** button:
35 |
36 |
37 |
38 | You should see a confirmation that your subscription was created successfully:
39 |
40 |
41 |
42 |
43 | ### Configuring Notifications on Amazon SES Console
44 |
45 | > This section follows and expands on the _official_
46 | instructions:
47 | https://docs.aws.amazon.com/ses/latest/DeveloperGuide/configure-sns-notifications.html
48 |
49 | Once you have created the SNS Topic,
50 | visit the SES home page
51 | and click on **`Email Addresses`**:
52 | https://eu-west-1.console.aws.amazon.com/ses
53 |
54 |
55 |
56 | Click on the _verified_ email address
57 | you want to configure SNS notifications for:
58 |
59 |
60 |
61 | In the **`Notifications`** section,
62 | click on **`Edit configuration`**:
63 |
64 |
65 |
66 | Select the SNS topic we created above
67 | for _all_ the types of notification
68 | then click **`Save Config`**:
69 |
70 |
71 |
72 | Your configuration should now look something like this:
73 |
74 |
75 |
76 |
77 | ### Test it!!
78 |
79 | In the Lambda configuration page
80 | https://eu-west-1.console.aws.amazon.com/lambda/home?region=eu-west-1#/functions/aws-ses-lambda-v1
81 | configure a bounce event to an email address you _know_ does not exist:
82 |
83 |
84 |
85 | _Run_ the bounce event in the Lambda console:
86 |
87 |
88 |
89 | You will see a "success" message confirming that the `aws-ses-lambda` ***attempted*** to send the email to the **`bounce@dwyl.com`** address (_which we know will fail_). Our lambda function and AWS SES does not _know_ that the **`bounce@dwyl.com`** address will bounce. That's the _reason_ we need to have the SNS topic so we can _monitor_ bounce events!
90 |
91 | The SNS bounce notification **`event`** is saved to S3
92 | thanks to [#12](https://github.com/dwyl/aws-ses-lambda/issues/12)
93 | https://ademoapp.s3-eu-west-1.amazonaws.com/event.json
94 |
95 |
96 | For the purposes of _testing_ our parser,
97 | we save this `event` JSON in:
98 | [`test/fixtures/sample_sns_bounce.json`](https://github.com/dwyl/aws-ses-lambda/blob/9ad2381bda7a2f35049732569af055ff80e167d2/test/fixtures/sample_sns_bounce.json)
99 |
100 | Now we can _parse_ the notification!
101 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | require("env2")(".env");
2 | const debug = require("./lib/debug.js");
3 | const send = require("./lib/send.js");
4 | const parse = require('./lib/parse.js');
5 | const http_request = require('./lib/http_request');
6 | const bounce_list = ["nelson@gmail.com", "test@gmail.com"];
7 |
8 | exports.handler = function handler (event, context, callback) {
9 | debug(event);
10 |
11 | if (event.ping || (event.email && bounce_list.indexOf(event.email) > -1)) {
12 | return callback(null, event);
13 | }
14 | else if (event.email) {
15 | send(event, function send_cb (error, data) { // send the email
16 | const json = {...event, ...parse(data)};
17 | http_request(json, function http_cb (_status, response) { // save to API
18 | const merged = {...json, ...response};
19 | return callback(error, merged);
20 | });
21 | });
22 | }
23 | else {
24 | const json = {...event, ...parse(event)}; // parse sns event
25 | return http_request(json, callback); // POST parsed data to Email App
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/lib/debug.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('env2')('.env');
3 | const save = require('../lib/s3.js').save;
4 |
5 | /**
6 | * `debug` is used to debug SNS notification events.
7 | * it only gets executed if the NODE_ENV is set to "test".
8 | * To save event data to S3 you will need to add AWS_S3_BUCKET to .env
9 | * see: github.com/dwyl/aws-ses-lambda/issues/12
10 | * @param {Object} event - the object we want to store on S3
11 | */
12 | module.exports = function debug (event) {
13 | // console.log("process.env.NODE_ENV:", process.env.NODE_ENV);
14 | if (process.env.NODE_ENV === "test") {
15 | if(event.Records && !event.key) {
16 | event.key = "sns";
17 | }
18 | save(event, function callback (error, data) {
19 | console.log("DEBUG - - - error:", error, " - - - data:");
20 | console.log(data);
21 | console.log(" - - - - - - - - - - - - - - - - - - - - ");
22 | });
23 | }
24 | };
25 |
--------------------------------------------------------------------------------
/lib/http_request.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | require("env2")(".env"); // ensure JWT_SECRET environment variable is defined.
4 | const http = require('https'); // ALWAYS use TLS over the internets!
5 | const jwt = require('jsonwebtoken');
6 | /**
7 | * simple_http_request is a bare-bones http request using node.js core http
8 | * see: https://nodejs.org/api/http.html#http_http_request_options_callback
9 | * @param {Object} json - the JSON data we want to send to the Phoenix App.
10 | * @param {Function} callback - a standard callback with error & response args
11 | * response is a JSON Object unless there is an error. No error handling yet ...
12 | */
13 |
14 | module.exports = function simple_http_request (json, callback) {
15 | const options = { // the json data is included in the token! 😮
16 | headers: {
17 | 'Authorization': jwt.sign(json, process.env.JWT_SECRET),
18 | 'Accept': 'application/json'
19 | },
20 | hostname: process.env.EMAIL_APP_URL, // e.g: phemail.herokuapp.com
21 | method: 'POST', // HTTP post sans body: stackoverflow.com/questions/4191593
22 | port: '443',
23 | path: '/api/sns' // the API endpoint that processes and stores SNS data
24 | }
25 |
26 | http.request(options, function (res) {
27 | let resStr = '';
28 | res.setEncoding('utf8');
29 | res.on('data', function (chunk) {
30 | resStr += chunk;
31 | }).on('end', function () {
32 | return callback(res.statusCode, JSON.parse(resStr));
33 | });
34 | })
35 | // .on('error', (e) => {
36 | // console.error(`problem with request: ${e.message}`);
37 | // })
38 | .end();
39 | };
40 |
--------------------------------------------------------------------------------
/lib/parse.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | /**
3 | * `parse` extracts the relevant data from SNS notification events.
4 | * @param {Object} event - the object we want to store on S3
5 | * @returns {Object} json - parsed json data returned
6 | */
7 | module.exports = function parse (event) {
8 | let json = {};
9 | // sent event:
10 | if (event && event.MessageId) {
11 | json.message_id = event.MessageId;
12 | json.request_id = event.ResponseMetadata.RequestId;
13 | json.status = "Sent"; // email was successfully sent by SES
14 | }
15 | // bounce event:
16 | if (event && event.Records && event.Records.length > 0) {
17 | const msg = JSON.parse(event.Records[0].Sns.Message);
18 | // console.log('msg', msg);
19 | json.message_id = msg.mail.messageId; // NOT the same as Sns.MessageId 🤷
20 | json.status = msg.notificationType + ' ' + msg.bounce.bounceType;
21 | json.email = msg.mail.destination[0];
22 | }
23 | return json;
24 | };
25 |
--------------------------------------------------------------------------------
/lib/s3.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | require('env2')('.env');
3 | const AWS = require('aws-sdk');
4 | AWS.config.region = 'eu-west-1';
5 | var s3 = new AWS.S3({params: {Bucket: process.env.AWS_S3_BUCKET}});
6 |
7 | /**
8 | * `save` saves a JSON object to S3.
9 | * if you need to specify the file name, use `json.key`
10 | * @param {Object} json - the object we want to store on S3
11 | * @param {Function} callback - called once the file has been uploaded
12 | */
13 | module.exports.save = function save (json, callback) {
14 | if (json) {
15 | const filename = json.key || 'event'
16 | const params = {
17 | Key: filename + '.json',
18 | Body: JSON.stringify(json),
19 | ContentType: 'application/json',
20 | ACL: 'public-read'
21 | };
22 |
23 | s3.upload(params, function (err, data) {
24 | if (callback && typeof callback === "function") {
25 | return callback(err, data);
26 | }
27 | else {
28 | return data;
29 | }
30 | });
31 |
32 | } else {
33 | return callback('ERROR: please provide json data');
34 | }
35 | }
36 |
37 | /**
38 | * `get` retrieves and parses a JSON file from S3
39 | * this function is only used to test that the `save` method.
40 | * @param {String} key - the filename of the object to get from S3
41 | * @param {Function} callback - called once the file has been uploaded
42 | */
43 | module.exports.get = function get (key, callback) {
44 | s3.getObject({Key: key}, function (error, data) {
45 | if (error) {
46 | return callback(error);
47 | }
48 | else {
49 | return callback(error, JSON.parse(data.Body.toString()));
50 | }
51 | });
52 | };
53 |
--------------------------------------------------------------------------------
/lib/send.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | const sendemail = require('sendemail').email;
3 | const jwt = require('jsonwebtoken');
4 |
5 | /**
6 | * `send` sends an email using sendmail.
7 | * the data for to be replaced in the email template are included in event.
8 | * @param {Object} event - the Lambda invocation event
9 | * required keys in the `event` object are: email, name, subject and template.
10 | * @param {Function} callback - called once the file has been uploaded
11 | */
12 | module.exports = function send (event, callback) {
13 | const template = event.template || 'welcome';
14 | const token = jwt.sign({id: event.id}, process.env.JWT_SECRET);
15 | const options = {
16 | subject: event.subject || 'Welcome to dwyl ' + event.name,
17 | email: event.email,
18 | name: event.name || "", // allow email to be sent without name
19 | pixel_url: "https://" + process.env.EMAIL_APP_URL + "/read/" + token
20 | };
21 | const merged = {...event, ...options}; // expose all of event to template
22 | return sendemail(template, merged, callback);
23 | };
24 |
--------------------------------------------------------------------------------
/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-ses-lambda",
3 | "version": "1.0.2",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "@babel/code-frame": {
8 | "version": "7.8.3",
9 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
10 | "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
11 | "dev": true,
12 | "requires": {
13 | "@babel/highlight": "^7.8.3"
14 | }
15 | },
16 | "@babel/core": {
17 | "version": "7.8.4",
18 | "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.4.tgz",
19 | "integrity": "sha512-0LiLrB2PwrVI+a2/IEskBopDYSd8BCb3rOvH7D5tzoWd696TBEduBvuLVm4Nx6rltrLZqvI3MCalB2K2aVzQjA==",
20 | "dev": true,
21 | "requires": {
22 | "@babel/code-frame": "^7.8.3",
23 | "@babel/generator": "^7.8.4",
24 | "@babel/helpers": "^7.8.4",
25 | "@babel/parser": "^7.8.4",
26 | "@babel/template": "^7.8.3",
27 | "@babel/traverse": "^7.8.4",
28 | "@babel/types": "^7.8.3",
29 | "convert-source-map": "^1.7.0",
30 | "debug": "^4.1.0",
31 | "gensync": "^1.0.0-beta.1",
32 | "json5": "^2.1.0",
33 | "lodash": "^4.17.13",
34 | "resolve": "^1.3.2",
35 | "semver": "^5.4.1",
36 | "source-map": "^0.5.0"
37 | },
38 | "dependencies": {
39 | "debug": {
40 | "version": "4.1.1",
41 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
42 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
43 | "dev": true,
44 | "requires": {
45 | "ms": "^2.1.1"
46 | }
47 | },
48 | "ms": {
49 | "version": "2.1.2",
50 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
51 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
52 | "dev": true
53 | },
54 | "semver": {
55 | "version": "5.7.2",
56 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
57 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
58 | "dev": true
59 | },
60 | "source-map": {
61 | "version": "0.5.7",
62 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
63 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
64 | "dev": true
65 | }
66 | }
67 | },
68 | "@babel/generator": {
69 | "version": "7.8.4",
70 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.4.tgz",
71 | "integrity": "sha512-PwhclGdRpNAf3IxZb0YVuITPZmmrXz9zf6fH8lT4XbrmfQKr6ryBzhv593P5C6poJRciFCL/eHGW2NuGrgEyxA==",
72 | "dev": true,
73 | "requires": {
74 | "@babel/types": "^7.8.3",
75 | "jsesc": "^2.5.1",
76 | "lodash": "^4.17.13",
77 | "source-map": "^0.5.0"
78 | },
79 | "dependencies": {
80 | "source-map": {
81 | "version": "0.5.7",
82 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
83 | "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
84 | "dev": true
85 | }
86 | }
87 | },
88 | "@babel/helper-environment-visitor": {
89 | "version": "7.22.20",
90 | "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
91 | "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
92 | "dev": true
93 | },
94 | "@babel/helper-hoist-variables": {
95 | "version": "7.22.5",
96 | "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
97 | "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
98 | "dev": true,
99 | "requires": {
100 | "@babel/types": "^7.22.5"
101 | },
102 | "dependencies": {
103 | "@babel/types": {
104 | "version": "7.23.0",
105 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
106 | "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
107 | "dev": true,
108 | "requires": {
109 | "@babel/helper-string-parser": "^7.22.5",
110 | "@babel/helper-validator-identifier": "^7.22.20",
111 | "to-fast-properties": "^2.0.0"
112 | }
113 | }
114 | }
115 | },
116 | "@babel/helper-string-parser": {
117 | "version": "7.22.5",
118 | "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz",
119 | "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==",
120 | "dev": true
121 | },
122 | "@babel/helper-validator-identifier": {
123 | "version": "7.22.20",
124 | "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz",
125 | "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==",
126 | "dev": true
127 | },
128 | "@babel/helpers": {
129 | "version": "7.8.4",
130 | "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz",
131 | "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==",
132 | "dev": true,
133 | "requires": {
134 | "@babel/template": "^7.8.3",
135 | "@babel/traverse": "^7.8.4",
136 | "@babel/types": "^7.8.3"
137 | }
138 | },
139 | "@babel/highlight": {
140 | "version": "7.8.3",
141 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
142 | "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
143 | "dev": true,
144 | "requires": {
145 | "chalk": "^2.0.0",
146 | "esutils": "^2.0.2",
147 | "js-tokens": "^4.0.0"
148 | },
149 | "dependencies": {
150 | "ansi-styles": {
151 | "version": "3.2.1",
152 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
153 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
154 | "dev": true,
155 | "requires": {
156 | "color-convert": "^1.9.0"
157 | }
158 | },
159 | "chalk": {
160 | "version": "2.4.2",
161 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
162 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
163 | "dev": true,
164 | "requires": {
165 | "ansi-styles": "^3.2.1",
166 | "escape-string-regexp": "^1.0.5",
167 | "supports-color": "^5.3.0"
168 | }
169 | },
170 | "has-flag": {
171 | "version": "3.0.0",
172 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
173 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
174 | "dev": true
175 | },
176 | "js-tokens": {
177 | "version": "4.0.0",
178 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
179 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
180 | "dev": true
181 | },
182 | "supports-color": {
183 | "version": "5.5.0",
184 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
185 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
186 | "dev": true,
187 | "requires": {
188 | "has-flag": "^3.0.0"
189 | }
190 | }
191 | }
192 | },
193 | "@babel/parser": {
194 | "version": "7.8.4",
195 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.4.tgz",
196 | "integrity": "sha512-0fKu/QqildpXmPVaRBoXOlyBb3MC+J0A66x97qEfLOMkn3u6nfY5esWogQwi/K0BjASYy4DbnsEWnpNL6qT5Mw==",
197 | "dev": true
198 | },
199 | "@babel/template": {
200 | "version": "7.8.3",
201 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz",
202 | "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==",
203 | "dev": true,
204 | "requires": {
205 | "@babel/code-frame": "^7.8.3",
206 | "@babel/parser": "^7.8.3",
207 | "@babel/types": "^7.8.3"
208 | }
209 | },
210 | "@babel/traverse": {
211 | "version": "7.23.2",
212 | "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz",
213 | "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==",
214 | "dev": true,
215 | "requires": {
216 | "@babel/code-frame": "^7.22.13",
217 | "@babel/generator": "^7.23.0",
218 | "@babel/helper-environment-visitor": "^7.22.20",
219 | "@babel/helper-function-name": "^7.23.0",
220 | "@babel/helper-hoist-variables": "^7.22.5",
221 | "@babel/helper-split-export-declaration": "^7.22.6",
222 | "@babel/parser": "^7.23.0",
223 | "@babel/types": "^7.23.0",
224 | "debug": "^4.1.0",
225 | "globals": "^11.1.0"
226 | },
227 | "dependencies": {
228 | "@babel/code-frame": {
229 | "version": "7.22.13",
230 | "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz",
231 | "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==",
232 | "dev": true,
233 | "requires": {
234 | "@babel/highlight": "^7.22.13",
235 | "chalk": "^2.4.2"
236 | }
237 | },
238 | "@babel/generator": {
239 | "version": "7.23.0",
240 | "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz",
241 | "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==",
242 | "dev": true,
243 | "requires": {
244 | "@babel/types": "^7.23.0",
245 | "@jridgewell/gen-mapping": "^0.3.2",
246 | "@jridgewell/trace-mapping": "^0.3.17",
247 | "jsesc": "^2.5.1"
248 | }
249 | },
250 | "@babel/helper-function-name": {
251 | "version": "7.23.0",
252 | "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
253 | "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
254 | "dev": true,
255 | "requires": {
256 | "@babel/template": "^7.22.15",
257 | "@babel/types": "^7.23.0"
258 | }
259 | },
260 | "@babel/helper-split-export-declaration": {
261 | "version": "7.22.6",
262 | "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
263 | "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
264 | "dev": true,
265 | "requires": {
266 | "@babel/types": "^7.22.5"
267 | }
268 | },
269 | "@babel/highlight": {
270 | "version": "7.22.20",
271 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz",
272 | "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==",
273 | "dev": true,
274 | "requires": {
275 | "@babel/helper-validator-identifier": "^7.22.20",
276 | "chalk": "^2.4.2",
277 | "js-tokens": "^4.0.0"
278 | }
279 | },
280 | "@babel/parser": {
281 | "version": "7.23.0",
282 | "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz",
283 | "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==",
284 | "dev": true
285 | },
286 | "@babel/template": {
287 | "version": "7.22.15",
288 | "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
289 | "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
290 | "dev": true,
291 | "requires": {
292 | "@babel/code-frame": "^7.22.13",
293 | "@babel/parser": "^7.22.15",
294 | "@babel/types": "^7.22.15"
295 | }
296 | },
297 | "@babel/types": {
298 | "version": "7.23.0",
299 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz",
300 | "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==",
301 | "dev": true,
302 | "requires": {
303 | "@babel/helper-string-parser": "^7.22.5",
304 | "@babel/helper-validator-identifier": "^7.22.20",
305 | "to-fast-properties": "^2.0.0"
306 | }
307 | },
308 | "ansi-styles": {
309 | "version": "3.2.1",
310 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
311 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
312 | "dev": true,
313 | "requires": {
314 | "color-convert": "^1.9.0"
315 | }
316 | },
317 | "chalk": {
318 | "version": "2.4.2",
319 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
320 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
321 | "dev": true,
322 | "requires": {
323 | "ansi-styles": "^3.2.1",
324 | "escape-string-regexp": "^1.0.5",
325 | "supports-color": "^5.3.0"
326 | }
327 | },
328 | "globals": {
329 | "version": "11.12.0",
330 | "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
331 | "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
332 | "dev": true
333 | },
334 | "supports-color": {
335 | "version": "5.5.0",
336 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
337 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
338 | "dev": true,
339 | "requires": {
340 | "has-flag": "^3.0.0"
341 | }
342 | }
343 | }
344 | },
345 | "@babel/types": {
346 | "version": "7.8.3",
347 | "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz",
348 | "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==",
349 | "dev": true,
350 | "requires": {
351 | "esutils": "^2.0.2",
352 | "lodash": "^4.17.13",
353 | "to-fast-properties": "^2.0.0"
354 | }
355 | },
356 | "@istanbuljs/load-nyc-config": {
357 | "version": "1.0.0",
358 | "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz",
359 | "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==",
360 | "dev": true,
361 | "requires": {
362 | "camelcase": "^5.3.1",
363 | "find-up": "^4.1.0",
364 | "js-yaml": "^3.13.1",
365 | "resolve-from": "^5.0.0"
366 | },
367 | "dependencies": {
368 | "resolve-from": {
369 | "version": "5.0.0",
370 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
371 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
372 | "dev": true
373 | }
374 | }
375 | },
376 | "@istanbuljs/schema": {
377 | "version": "0.1.2",
378 | "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz",
379 | "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==",
380 | "dev": true
381 | },
382 | "@jridgewell/gen-mapping": {
383 | "version": "0.3.3",
384 | "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
385 | "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
386 | "dev": true,
387 | "requires": {
388 | "@jridgewell/set-array": "^1.0.1",
389 | "@jridgewell/sourcemap-codec": "^1.4.10",
390 | "@jridgewell/trace-mapping": "^0.3.9"
391 | }
392 | },
393 | "@jridgewell/resolve-uri": {
394 | "version": "3.1.1",
395 | "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
396 | "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
397 | "dev": true
398 | },
399 | "@jridgewell/set-array": {
400 | "version": "1.1.2",
401 | "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
402 | "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
403 | "dev": true
404 | },
405 | "@jridgewell/sourcemap-codec": {
406 | "version": "1.4.15",
407 | "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
408 | "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
409 | "dev": true
410 | },
411 | "@jridgewell/trace-mapping": {
412 | "version": "0.3.20",
413 | "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz",
414 | "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==",
415 | "dev": true,
416 | "requires": {
417 | "@jridgewell/resolve-uri": "^3.1.0",
418 | "@jridgewell/sourcemap-codec": "^1.4.14"
419 | }
420 | },
421 | "@types/color-name": {
422 | "version": "1.1.1",
423 | "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
424 | "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
425 | "dev": true
426 | },
427 | "acorn": {
428 | "version": "7.1.1",
429 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz",
430 | "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==",
431 | "dev": true
432 | },
433 | "acorn-jsx": {
434 | "version": "5.1.0",
435 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz",
436 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==",
437 | "dev": true
438 | },
439 | "aggregate-error": {
440 | "version": "3.0.1",
441 | "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
442 | "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
443 | "dev": true,
444 | "requires": {
445 | "clean-stack": "^2.0.0",
446 | "indent-string": "^4.0.0"
447 | }
448 | },
449 | "aguid": {
450 | "version": "2.0.0",
451 | "resolved": "https://registry.npmjs.org/aguid/-/aguid-2.0.0.tgz",
452 | "integrity": "sha1-ZLwmSHDe3w65xyvdtT5bMNMrwik=",
453 | "dev": true,
454 | "requires": {
455 | "uuid": "^3.0.1"
456 | }
457 | },
458 | "ajv": {
459 | "version": "6.12.6",
460 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
461 | "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
462 | "dev": true,
463 | "requires": {
464 | "fast-deep-equal": "^3.1.1",
465 | "fast-json-stable-stringify": "^2.0.0",
466 | "json-schema-traverse": "^0.4.1",
467 | "uri-js": "^4.2.2"
468 | }
469 | },
470 | "ansi-escapes": {
471 | "version": "4.3.0",
472 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz",
473 | "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==",
474 | "dev": true,
475 | "requires": {
476 | "type-fest": "^0.8.1"
477 | }
478 | },
479 | "ansi-regex": {
480 | "version": "2.1.1",
481 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
482 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
483 | "dev": true
484 | },
485 | "ansi-styles": {
486 | "version": "2.2.1",
487 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
488 | "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
489 | "dev": true
490 | },
491 | "append-transform": {
492 | "version": "2.0.0",
493 | "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz",
494 | "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==",
495 | "dev": true,
496 | "requires": {
497 | "default-require-extensions": "^3.0.0"
498 | }
499 | },
500 | "archy": {
501 | "version": "1.0.0",
502 | "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
503 | "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
504 | "dev": true
505 | },
506 | "argparse": {
507 | "version": "1.0.10",
508 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
509 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
510 | "dev": true,
511 | "requires": {
512 | "sprintf-js": "~1.0.2"
513 | }
514 | },
515 | "astral-regex": {
516 | "version": "1.0.0",
517 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
518 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
519 | "dev": true
520 | },
521 | "available-typed-arrays": {
522 | "version": "1.0.5",
523 | "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
524 | "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
525 | },
526 | "aws-lambda-test-utils": {
527 | "version": "1.3.0",
528 | "resolved": "https://registry.npmjs.org/aws-lambda-test-utils/-/aws-lambda-test-utils-1.3.0.tgz",
529 | "integrity": "sha1-urtyBxeXfhG/H5Hr5Hc4zha+iyU=",
530 | "dev": true
531 | },
532 | "aws-sdk": {
533 | "version": "2.1354.0",
534 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1354.0.tgz",
535 | "integrity": "sha512-3aDxvyuOqMB9DqJguCq6p8momdsz0JR1axwkWOOCzHA7a35+Bw+WLmqt3pWwRjR1tGIwkkZ2CvGJObYHsOuw3w==",
536 | "requires": {
537 | "buffer": "4.9.2",
538 | "events": "1.1.1",
539 | "ieee754": "1.1.13",
540 | "jmespath": "0.16.0",
541 | "querystring": "0.2.0",
542 | "sax": "1.2.1",
543 | "url": "0.10.3",
544 | "util": "^0.12.4",
545 | "uuid": "8.0.0",
546 | "xml2js": "0.5.0"
547 | },
548 | "dependencies": {
549 | "buffer": {
550 | "version": "4.9.2",
551 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz",
552 | "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==",
553 | "requires": {
554 | "base64-js": "^1.0.2",
555 | "ieee754": "^1.1.4",
556 | "isarray": "^1.0.0"
557 | }
558 | },
559 | "jmespath": {
560 | "version": "0.16.0",
561 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz",
562 | "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw=="
563 | },
564 | "uuid": {
565 | "version": "8.0.0",
566 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz",
567 | "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw=="
568 | },
569 | "xml2js": {
570 | "version": "0.5.0",
571 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz",
572 | "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==",
573 | "requires": {
574 | "sax": ">=0.6.0",
575 | "xmlbuilder": "~11.0.0"
576 | }
577 | },
578 | "xmlbuilder": {
579 | "version": "11.0.1",
580 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
581 | "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="
582 | }
583 | }
584 | },
585 | "balanced-match": {
586 | "version": "1.0.0",
587 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
588 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
589 | "dev": true
590 | },
591 | "base64-js": {
592 | "version": "1.3.1",
593 | "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
594 | "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
595 | },
596 | "brace-expansion": {
597 | "version": "1.1.11",
598 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
599 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
600 | "dev": true,
601 | "requires": {
602 | "balanced-match": "^1.0.0",
603 | "concat-map": "0.0.1"
604 | }
605 | },
606 | "buffer": {
607 | "version": "4.9.1",
608 | "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
609 | "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
610 | "dev": true,
611 | "requires": {
612 | "base64-js": "^1.0.2",
613 | "ieee754": "^1.1.4",
614 | "isarray": "^1.0.0"
615 | }
616 | },
617 | "buffer-equal-constant-time": {
618 | "version": "1.0.1",
619 | "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
620 | "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA=="
621 | },
622 | "caching-transform": {
623 | "version": "4.0.0",
624 | "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz",
625 | "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==",
626 | "dev": true,
627 | "requires": {
628 | "hasha": "^5.0.0",
629 | "make-dir": "^3.0.0",
630 | "package-hash": "^4.0.0",
631 | "write-file-atomic": "^3.0.0"
632 | }
633 | },
634 | "call-bind": {
635 | "version": "1.0.2",
636 | "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz",
637 | "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
638 | "requires": {
639 | "function-bind": "^1.1.1",
640 | "get-intrinsic": "^1.0.2"
641 | }
642 | },
643 | "callsite": {
644 | "version": "1.0.0",
645 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
646 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=",
647 | "dev": true
648 | },
649 | "callsites": {
650 | "version": "3.1.0",
651 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
652 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
653 | "dev": true
654 | },
655 | "camelcase": {
656 | "version": "5.3.1",
657 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
658 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
659 | "dev": true
660 | },
661 | "chalk": {
662 | "version": "1.1.3",
663 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
664 | "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
665 | "dev": true,
666 | "requires": {
667 | "ansi-styles": "^2.2.1",
668 | "escape-string-regexp": "^1.0.2",
669 | "has-ansi": "^2.0.0",
670 | "strip-ansi": "^3.0.0",
671 | "supports-color": "^2.0.0"
672 | }
673 | },
674 | "chardet": {
675 | "version": "0.7.0",
676 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
677 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
678 | "dev": true
679 | },
680 | "clean-stack": {
681 | "version": "2.2.0",
682 | "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
683 | "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
684 | "dev": true
685 | },
686 | "cli-cursor": {
687 | "version": "3.1.0",
688 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
689 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
690 | "dev": true,
691 | "requires": {
692 | "restore-cursor": "^3.1.0"
693 | }
694 | },
695 | "cli-width": {
696 | "version": "2.2.0",
697 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
698 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
699 | "dev": true
700 | },
701 | "cliui": {
702 | "version": "6.0.0",
703 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
704 | "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
705 | "dev": true,
706 | "requires": {
707 | "string-width": "^4.2.0",
708 | "strip-ansi": "^6.0.0",
709 | "wrap-ansi": "^6.2.0"
710 | },
711 | "dependencies": {
712 | "ansi-regex": {
713 | "version": "5.0.0",
714 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
715 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
716 | "dev": true
717 | },
718 | "is-fullwidth-code-point": {
719 | "version": "3.0.0",
720 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
721 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
722 | "dev": true
723 | },
724 | "string-width": {
725 | "version": "4.2.0",
726 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
727 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
728 | "dev": true,
729 | "requires": {
730 | "emoji-regex": "^8.0.0",
731 | "is-fullwidth-code-point": "^3.0.0",
732 | "strip-ansi": "^6.0.0"
733 | }
734 | },
735 | "strip-ansi": {
736 | "version": "6.0.0",
737 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
738 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
739 | "dev": true,
740 | "requires": {
741 | "ansi-regex": "^5.0.0"
742 | }
743 | }
744 | }
745 | },
746 | "color-convert": {
747 | "version": "1.9.3",
748 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
749 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
750 | "dev": true,
751 | "requires": {
752 | "color-name": "1.1.3"
753 | }
754 | },
755 | "color-name": {
756 | "version": "1.1.3",
757 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
758 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
759 | "dev": true
760 | },
761 | "commander": {
762 | "version": "2.20.3",
763 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
764 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
765 | "optional": true
766 | },
767 | "commondir": {
768 | "version": "1.0.1",
769 | "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
770 | "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
771 | "dev": true
772 | },
773 | "concat-map": {
774 | "version": "0.0.1",
775 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
776 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
777 | "dev": true
778 | },
779 | "convert-source-map": {
780 | "version": "1.7.0",
781 | "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz",
782 | "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==",
783 | "dev": true,
784 | "requires": {
785 | "safe-buffer": "~5.1.1"
786 | }
787 | },
788 | "core-util-is": {
789 | "version": "1.0.2",
790 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
791 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
792 | "dev": true
793 | },
794 | "cross-spawn": {
795 | "version": "7.0.1",
796 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.1.tgz",
797 | "integrity": "sha512-u7v4o84SwFpD32Z8IIcPZ6z1/ie24O6RU3RbtL5Y316l3KuHVPx9ItBgWQ6VlfAFnRnTtMUrsQ9MUUTuEZjogg==",
798 | "dev": true,
799 | "requires": {
800 | "path-key": "^3.1.0",
801 | "shebang-command": "^2.0.0",
802 | "which": "^2.0.1"
803 | },
804 | "dependencies": {
805 | "which": {
806 | "version": "2.0.2",
807 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
808 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
809 | "dev": true,
810 | "requires": {
811 | "isexe": "^2.0.0"
812 | }
813 | }
814 | }
815 | },
816 | "debug": {
817 | "version": "4.1.1",
818 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
819 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
820 | "dev": true,
821 | "requires": {
822 | "ms": "^2.1.1"
823 | }
824 | },
825 | "decache": {
826 | "version": "4.5.1",
827 | "resolved": "https://registry.npmjs.org/decache/-/decache-4.5.1.tgz",
828 | "integrity": "sha512-5J37nATc6FmOTLbcsr9qx7Nm28qQyg1SK4xyEHqM0IBkNhWFp0Sm+vKoWYHD8wq+OUEb9jLyaKFfzzd1A9hcoA==",
829 | "dev": true,
830 | "requires": {
831 | "callsite": "^1.0.0"
832 | }
833 | },
834 | "decamelize": {
835 | "version": "1.2.0",
836 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
837 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
838 | "dev": true
839 | },
840 | "deep-equal": {
841 | "version": "1.1.1",
842 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz",
843 | "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==",
844 | "dev": true,
845 | "requires": {
846 | "is-arguments": "^1.0.4",
847 | "is-date-object": "^1.0.1",
848 | "is-regex": "^1.0.4",
849 | "object-is": "^1.0.1",
850 | "object-keys": "^1.1.1",
851 | "regexp.prototype.flags": "^1.2.0"
852 | }
853 | },
854 | "deep-is": {
855 | "version": "0.1.3",
856 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
857 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
858 | "dev": true
859 | },
860 | "default-require-extensions": {
861 | "version": "3.0.0",
862 | "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz",
863 | "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==",
864 | "dev": true,
865 | "requires": {
866 | "strip-bom": "^4.0.0"
867 | },
868 | "dependencies": {
869 | "strip-bom": {
870 | "version": "4.0.0",
871 | "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz",
872 | "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==",
873 | "dev": true
874 | }
875 | }
876 | },
877 | "define-properties": {
878 | "version": "1.1.3",
879 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
880 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
881 | "dev": true,
882 | "requires": {
883 | "object-keys": "^1.0.12"
884 | }
885 | },
886 | "defined": {
887 | "version": "1.0.0",
888 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
889 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=",
890 | "dev": true
891 | },
892 | "doctrine": {
893 | "version": "3.0.0",
894 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
895 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
896 | "dev": true,
897 | "requires": {
898 | "esutils": "^2.0.2"
899 | }
900 | },
901 | "dotignore": {
902 | "version": "0.1.2",
903 | "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz",
904 | "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==",
905 | "dev": true,
906 | "requires": {
907 | "minimatch": "^3.0.4"
908 | }
909 | },
910 | "dpl": {
911 | "version": "4.0.0",
912 | "resolved": "https://registry.npmjs.org/dpl/-/dpl-4.0.0.tgz",
913 | "integrity": "sha512-/s9zeZULR1hSyzR15PHGY7PmrtPN+lYWiMIksNtAlamvutq7Cyb3Iwq+ji9BQwB0Wx5dfHWawNPoni+HbGW9gA==",
914 | "dev": true,
915 | "requires": {
916 | "aws-sdk": "^2.614.0",
917 | "env2": "^2.1.1"
918 | },
919 | "dependencies": {
920 | "aws-sdk": {
921 | "version": "2.615.0",
922 | "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.615.0.tgz",
923 | "integrity": "sha512-ktkOQgJLTcsfLzy/GPfUiEJd09SeJPnUj7ZeXa0Wb2/JVIRDbSmyG/IYQqAvXWUcD4thuv2h9wbLgXyzvX8dtw==",
924 | "dev": true,
925 | "requires": {
926 | "buffer": "4.9.1",
927 | "events": "1.1.1",
928 | "ieee754": "1.1.13",
929 | "jmespath": "0.15.0",
930 | "querystring": "0.2.0",
931 | "sax": "1.2.1",
932 | "url": "0.10.3",
933 | "uuid": "3.3.2",
934 | "xml2js": "0.4.19"
935 | }
936 | },
937 | "env2": {
938 | "version": "2.2.2",
939 | "resolved": "https://registry.npmjs.org/env2/-/env2-2.2.2.tgz",
940 | "integrity": "sha512-KHS47Smwr5AtT9RCxjsoCc+83sUI2uJIeK+VTI5MS8F0k312xzqFvbC4AyRNefPCNou7bvL7QSxmkT/h8x9rTg==",
941 | "dev": true
942 | }
943 | }
944 | },
945 | "duplexer": {
946 | "version": "0.1.1",
947 | "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
948 | "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
949 | "dev": true
950 | },
951 | "ecdsa-sig-formatter": {
952 | "version": "1.0.11",
953 | "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
954 | "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
955 | "requires": {
956 | "safe-buffer": "^5.0.1"
957 | }
958 | },
959 | "emoji-regex": {
960 | "version": "8.0.0",
961 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
962 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
963 | "dev": true
964 | },
965 | "env2": {
966 | "version": "2.2.2",
967 | "resolved": "https://registry.npmjs.org/env2/-/env2-2.2.2.tgz",
968 | "integrity": "sha512-KHS47Smwr5AtT9RCxjsoCc+83sUI2uJIeK+VTI5MS8F0k312xzqFvbC4AyRNefPCNou7bvL7QSxmkT/h8x9rTg=="
969 | },
970 | "es-abstract": {
971 | "version": "1.17.5",
972 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
973 | "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
974 | "dev": true,
975 | "requires": {
976 | "es-to-primitive": "^1.2.1",
977 | "function-bind": "^1.1.1",
978 | "has": "^1.0.3",
979 | "has-symbols": "^1.0.1",
980 | "is-callable": "^1.1.5",
981 | "is-regex": "^1.0.5",
982 | "object-inspect": "^1.7.0",
983 | "object-keys": "^1.1.1",
984 | "object.assign": "^4.1.0",
985 | "string.prototype.trimleft": "^2.1.1",
986 | "string.prototype.trimright": "^2.1.1"
987 | }
988 | },
989 | "es-to-primitive": {
990 | "version": "1.2.1",
991 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
992 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
993 | "dev": true,
994 | "requires": {
995 | "is-callable": "^1.1.4",
996 | "is-date-object": "^1.0.1",
997 | "is-symbol": "^1.0.2"
998 | }
999 | },
1000 | "es6-error": {
1001 | "version": "4.1.1",
1002 | "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz",
1003 | "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==",
1004 | "dev": true
1005 | },
1006 | "escape-string-regexp": {
1007 | "version": "1.0.5",
1008 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
1009 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
1010 | "dev": true
1011 | },
1012 | "eslint": {
1013 | "version": "6.8.0",
1014 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz",
1015 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==",
1016 | "dev": true,
1017 | "requires": {
1018 | "@babel/code-frame": "^7.0.0",
1019 | "ajv": "^6.10.0",
1020 | "chalk": "^2.1.0",
1021 | "cross-spawn": "^6.0.5",
1022 | "debug": "^4.0.1",
1023 | "doctrine": "^3.0.0",
1024 | "eslint-scope": "^5.0.0",
1025 | "eslint-utils": "^1.4.3",
1026 | "eslint-visitor-keys": "^1.1.0",
1027 | "espree": "^6.1.2",
1028 | "esquery": "^1.0.1",
1029 | "esutils": "^2.0.2",
1030 | "file-entry-cache": "^5.0.1",
1031 | "functional-red-black-tree": "^1.0.1",
1032 | "glob-parent": "^5.0.0",
1033 | "globals": "^12.1.0",
1034 | "ignore": "^4.0.6",
1035 | "import-fresh": "^3.0.0",
1036 | "imurmurhash": "^0.1.4",
1037 | "inquirer": "^7.0.0",
1038 | "is-glob": "^4.0.0",
1039 | "js-yaml": "^3.13.1",
1040 | "json-stable-stringify-without-jsonify": "^1.0.1",
1041 | "levn": "^0.3.0",
1042 | "lodash": "^4.17.14",
1043 | "minimatch": "^3.0.4",
1044 | "mkdirp": "^0.5.1",
1045 | "natural-compare": "^1.4.0",
1046 | "optionator": "^0.8.3",
1047 | "progress": "^2.0.0",
1048 | "regexpp": "^2.0.1",
1049 | "semver": "^6.1.2",
1050 | "strip-ansi": "^5.2.0",
1051 | "strip-json-comments": "^3.0.1",
1052 | "table": "^5.2.3",
1053 | "text-table": "^0.2.0",
1054 | "v8-compile-cache": "^2.0.3"
1055 | },
1056 | "dependencies": {
1057 | "ansi-regex": {
1058 | "version": "4.1.0",
1059 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1060 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1061 | "dev": true
1062 | },
1063 | "ansi-styles": {
1064 | "version": "3.2.1",
1065 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1066 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1067 | "dev": true,
1068 | "requires": {
1069 | "color-convert": "^1.9.0"
1070 | }
1071 | },
1072 | "chalk": {
1073 | "version": "2.4.2",
1074 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
1075 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
1076 | "dev": true,
1077 | "requires": {
1078 | "ansi-styles": "^3.2.1",
1079 | "escape-string-regexp": "^1.0.5",
1080 | "supports-color": "^5.3.0"
1081 | }
1082 | },
1083 | "cross-spawn": {
1084 | "version": "6.0.5",
1085 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
1086 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
1087 | "dev": true,
1088 | "requires": {
1089 | "nice-try": "^1.0.4",
1090 | "path-key": "^2.0.1",
1091 | "semver": "^5.5.0",
1092 | "shebang-command": "^1.2.0",
1093 | "which": "^1.2.9"
1094 | },
1095 | "dependencies": {
1096 | "semver": {
1097 | "version": "5.7.2",
1098 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
1099 | "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
1100 | "dev": true
1101 | }
1102 | }
1103 | },
1104 | "path-key": {
1105 | "version": "2.0.1",
1106 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
1107 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1108 | "dev": true
1109 | },
1110 | "semver": {
1111 | "version": "6.3.1",
1112 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1113 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1114 | "dev": true
1115 | },
1116 | "shebang-command": {
1117 | "version": "1.2.0",
1118 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
1119 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
1120 | "dev": true,
1121 | "requires": {
1122 | "shebang-regex": "^1.0.0"
1123 | }
1124 | },
1125 | "shebang-regex": {
1126 | "version": "1.0.0",
1127 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
1128 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
1129 | "dev": true
1130 | },
1131 | "strip-ansi": {
1132 | "version": "5.2.0",
1133 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
1134 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
1135 | "dev": true,
1136 | "requires": {
1137 | "ansi-regex": "^4.1.0"
1138 | }
1139 | },
1140 | "supports-color": {
1141 | "version": "5.5.0",
1142 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1143 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1144 | "dev": true,
1145 | "requires": {
1146 | "has-flag": "^3.0.0"
1147 | }
1148 | }
1149 | }
1150 | },
1151 | "eslint-scope": {
1152 | "version": "5.0.0",
1153 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
1154 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==",
1155 | "dev": true,
1156 | "requires": {
1157 | "esrecurse": "^4.1.0",
1158 | "estraverse": "^4.1.1"
1159 | }
1160 | },
1161 | "eslint-utils": {
1162 | "version": "1.4.3",
1163 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz",
1164 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==",
1165 | "dev": true,
1166 | "requires": {
1167 | "eslint-visitor-keys": "^1.1.0"
1168 | }
1169 | },
1170 | "eslint-visitor-keys": {
1171 | "version": "1.1.0",
1172 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz",
1173 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==",
1174 | "dev": true
1175 | },
1176 | "espree": {
1177 | "version": "6.1.2",
1178 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz",
1179 | "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==",
1180 | "dev": true,
1181 | "requires": {
1182 | "acorn": "^7.1.0",
1183 | "acorn-jsx": "^5.1.0",
1184 | "eslint-visitor-keys": "^1.1.0"
1185 | }
1186 | },
1187 | "esprima": {
1188 | "version": "4.0.1",
1189 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
1190 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
1191 | "dev": true
1192 | },
1193 | "esquery": {
1194 | "version": "1.1.0",
1195 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz",
1196 | "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==",
1197 | "dev": true,
1198 | "requires": {
1199 | "estraverse": "^4.0.0"
1200 | }
1201 | },
1202 | "esrecurse": {
1203 | "version": "4.2.1",
1204 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
1205 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
1206 | "dev": true,
1207 | "requires": {
1208 | "estraverse": "^4.1.0"
1209 | }
1210 | },
1211 | "estraverse": {
1212 | "version": "4.3.0",
1213 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
1214 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
1215 | "dev": true
1216 | },
1217 | "esutils": {
1218 | "version": "2.0.3",
1219 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
1220 | "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
1221 | "dev": true
1222 | },
1223 | "events": {
1224 | "version": "1.1.1",
1225 | "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
1226 | "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
1227 | },
1228 | "external-editor": {
1229 | "version": "3.1.0",
1230 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
1231 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
1232 | "dev": true,
1233 | "requires": {
1234 | "chardet": "^0.7.0",
1235 | "iconv-lite": "^0.4.24",
1236 | "tmp": "^0.0.33"
1237 | }
1238 | },
1239 | "fast-deep-equal": {
1240 | "version": "3.1.1",
1241 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz",
1242 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==",
1243 | "dev": true
1244 | },
1245 | "fast-json-stable-stringify": {
1246 | "version": "2.1.0",
1247 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
1248 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
1249 | "dev": true
1250 | },
1251 | "fast-levenshtein": {
1252 | "version": "2.0.6",
1253 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
1254 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
1255 | "dev": true
1256 | },
1257 | "figures": {
1258 | "version": "1.7.0",
1259 | "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
1260 | "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
1261 | "dev": true,
1262 | "requires": {
1263 | "escape-string-regexp": "^1.0.5",
1264 | "object-assign": "^4.1.0"
1265 | }
1266 | },
1267 | "file-entry-cache": {
1268 | "version": "5.0.1",
1269 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
1270 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
1271 | "dev": true,
1272 | "requires": {
1273 | "flat-cache": "^2.0.1"
1274 | }
1275 | },
1276 | "find-cache-dir": {
1277 | "version": "3.2.0",
1278 | "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz",
1279 | "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==",
1280 | "dev": true,
1281 | "requires": {
1282 | "commondir": "^1.0.1",
1283 | "make-dir": "^3.0.0",
1284 | "pkg-dir": "^4.1.0"
1285 | }
1286 | },
1287 | "find-up": {
1288 | "version": "4.1.0",
1289 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
1290 | "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
1291 | "dev": true,
1292 | "requires": {
1293 | "locate-path": "^5.0.0",
1294 | "path-exists": "^4.0.0"
1295 | }
1296 | },
1297 | "flat-cache": {
1298 | "version": "2.0.1",
1299 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
1300 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
1301 | "dev": true,
1302 | "requires": {
1303 | "flatted": "^2.0.0",
1304 | "rimraf": "2.6.3",
1305 | "write": "1.0.3"
1306 | }
1307 | },
1308 | "flatted": {
1309 | "version": "2.0.1",
1310 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
1311 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
1312 | "dev": true
1313 | },
1314 | "for-each": {
1315 | "version": "0.3.3",
1316 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
1317 | "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
1318 | "requires": {
1319 | "is-callable": "^1.1.3"
1320 | }
1321 | },
1322 | "foreground-child": {
1323 | "version": "2.0.0",
1324 | "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz",
1325 | "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==",
1326 | "dev": true,
1327 | "requires": {
1328 | "cross-spawn": "^7.0.0",
1329 | "signal-exit": "^3.0.2"
1330 | }
1331 | },
1332 | "fromentries": {
1333 | "version": "1.2.0",
1334 | "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.2.0.tgz",
1335 | "integrity": "sha512-33X7H/wdfO99GdRLLgkjUrD4geAFdq/Uv0kl3HD4da6HDixd2GUg8Mw7dahLCV9r/EARkmtYBB6Tch4EEokFTQ==",
1336 | "dev": true
1337 | },
1338 | "fs.realpath": {
1339 | "version": "1.0.0",
1340 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
1341 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
1342 | "dev": true
1343 | },
1344 | "function-bind": {
1345 | "version": "1.1.1",
1346 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
1347 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
1348 | },
1349 | "functional-red-black-tree": {
1350 | "version": "1.0.1",
1351 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
1352 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
1353 | "dev": true
1354 | },
1355 | "gensync": {
1356 | "version": "1.0.0-beta.1",
1357 | "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
1358 | "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
1359 | "dev": true
1360 | },
1361 | "get-caller-file": {
1362 | "version": "2.0.5",
1363 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
1364 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
1365 | "dev": true
1366 | },
1367 | "get-intrinsic": {
1368 | "version": "1.2.0",
1369 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.0.tgz",
1370 | "integrity": "sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==",
1371 | "requires": {
1372 | "function-bind": "^1.1.1",
1373 | "has": "^1.0.3",
1374 | "has-symbols": "^1.0.3"
1375 | },
1376 | "dependencies": {
1377 | "has-symbols": {
1378 | "version": "1.0.3",
1379 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1380 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
1381 | }
1382 | }
1383 | },
1384 | "glob": {
1385 | "version": "7.1.6",
1386 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
1387 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
1388 | "dev": true,
1389 | "requires": {
1390 | "fs.realpath": "^1.0.0",
1391 | "inflight": "^1.0.4",
1392 | "inherits": "2",
1393 | "minimatch": "^3.0.4",
1394 | "once": "^1.3.0",
1395 | "path-is-absolute": "^1.0.0"
1396 | }
1397 | },
1398 | "glob-parent": {
1399 | "version": "5.1.0",
1400 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
1401 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
1402 | "dev": true,
1403 | "requires": {
1404 | "is-glob": "^4.0.1"
1405 | }
1406 | },
1407 | "globals": {
1408 | "version": "12.3.0",
1409 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz",
1410 | "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==",
1411 | "dev": true,
1412 | "requires": {
1413 | "type-fest": "^0.8.1"
1414 | }
1415 | },
1416 | "gopd": {
1417 | "version": "1.0.1",
1418 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
1419 | "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
1420 | "requires": {
1421 | "get-intrinsic": "^1.1.3"
1422 | }
1423 | },
1424 | "graceful-fs": {
1425 | "version": "4.2.3",
1426 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
1427 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
1428 | "dev": true
1429 | },
1430 | "handlebars": {
1431 | "version": "4.7.7",
1432 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz",
1433 | "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==",
1434 | "requires": {
1435 | "minimist": "^1.2.5",
1436 | "neo-async": "^2.6.0",
1437 | "source-map": "^0.6.1",
1438 | "uglify-js": "^3.1.4",
1439 | "wordwrap": "^1.0.0"
1440 | },
1441 | "dependencies": {
1442 | "wordwrap": {
1443 | "version": "1.0.0",
1444 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
1445 | "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
1446 | }
1447 | }
1448 | },
1449 | "has": {
1450 | "version": "1.0.3",
1451 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
1452 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
1453 | "requires": {
1454 | "function-bind": "^1.1.1"
1455 | }
1456 | },
1457 | "has-ansi": {
1458 | "version": "2.0.0",
1459 | "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
1460 | "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
1461 | "dev": true,
1462 | "requires": {
1463 | "ansi-regex": "^2.0.0"
1464 | }
1465 | },
1466 | "has-flag": {
1467 | "version": "3.0.0",
1468 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1469 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
1470 | "dev": true
1471 | },
1472 | "has-symbols": {
1473 | "version": "1.0.1",
1474 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
1475 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
1476 | "dev": true
1477 | },
1478 | "has-tostringtag": {
1479 | "version": "1.0.0",
1480 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz",
1481 | "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==",
1482 | "requires": {
1483 | "has-symbols": "^1.0.2"
1484 | },
1485 | "dependencies": {
1486 | "has-symbols": {
1487 | "version": "1.0.3",
1488 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
1489 | "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
1490 | }
1491 | }
1492 | },
1493 | "hasha": {
1494 | "version": "5.1.0",
1495 | "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.1.0.tgz",
1496 | "integrity": "sha512-OFPDWmzPN1l7atOV1TgBVmNtBxaIysToK6Ve9DK+vT6pYuklw/nPNT+HJbZi0KDcI6vWB+9tgvZ5YD7fA3CXcA==",
1497 | "dev": true,
1498 | "requires": {
1499 | "is-stream": "^2.0.0",
1500 | "type-fest": "^0.8.0"
1501 | }
1502 | },
1503 | "html-escaper": {
1504 | "version": "2.0.0",
1505 | "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.0.tgz",
1506 | "integrity": "sha512-a4u9BeERWGu/S8JiWEAQcdrg9v4QArtP9keViQjGMdff20fBdd8waotXaNmODqBe6uZ3Nafi7K/ho4gCQHV3Ig==",
1507 | "dev": true
1508 | },
1509 | "iconv-lite": {
1510 | "version": "0.4.24",
1511 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
1512 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
1513 | "dev": true,
1514 | "requires": {
1515 | "safer-buffer": ">= 2.1.2 < 3"
1516 | }
1517 | },
1518 | "ieee754": {
1519 | "version": "1.1.13",
1520 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
1521 | "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
1522 | },
1523 | "ignore": {
1524 | "version": "4.0.6",
1525 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
1526 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
1527 | "dev": true
1528 | },
1529 | "import-fresh": {
1530 | "version": "3.2.1",
1531 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz",
1532 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==",
1533 | "dev": true,
1534 | "requires": {
1535 | "parent-module": "^1.0.0",
1536 | "resolve-from": "^4.0.0"
1537 | }
1538 | },
1539 | "imurmurhash": {
1540 | "version": "0.1.4",
1541 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
1542 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
1543 | "dev": true
1544 | },
1545 | "indent-string": {
1546 | "version": "4.0.0",
1547 | "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
1548 | "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
1549 | "dev": true
1550 | },
1551 | "inflight": {
1552 | "version": "1.0.6",
1553 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
1554 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
1555 | "dev": true,
1556 | "requires": {
1557 | "once": "^1.3.0",
1558 | "wrappy": "1"
1559 | }
1560 | },
1561 | "inherits": {
1562 | "version": "2.0.4",
1563 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1564 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
1565 | },
1566 | "inquirer": {
1567 | "version": "7.0.4",
1568 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz",
1569 | "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==",
1570 | "dev": true,
1571 | "requires": {
1572 | "ansi-escapes": "^4.2.1",
1573 | "chalk": "^2.4.2",
1574 | "cli-cursor": "^3.1.0",
1575 | "cli-width": "^2.0.0",
1576 | "external-editor": "^3.0.3",
1577 | "figures": "^3.0.0",
1578 | "lodash": "^4.17.15",
1579 | "mute-stream": "0.0.8",
1580 | "run-async": "^2.2.0",
1581 | "rxjs": "^6.5.3",
1582 | "string-width": "^4.1.0",
1583 | "strip-ansi": "^5.1.0",
1584 | "through": "^2.3.6"
1585 | },
1586 | "dependencies": {
1587 | "ansi-regex": {
1588 | "version": "4.1.0",
1589 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
1590 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
1591 | "dev": true
1592 | },
1593 | "ansi-styles": {
1594 | "version": "3.2.1",
1595 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
1596 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
1597 | "dev": true,
1598 | "requires": {
1599 | "color-convert": "^1.9.0"
1600 | }
1601 | },
1602 | "chalk": {
1603 | "version": "2.4.2",
1604 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
1605 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
1606 | "dev": true,
1607 | "requires": {
1608 | "ansi-styles": "^3.2.1",
1609 | "escape-string-regexp": "^1.0.5",
1610 | "supports-color": "^5.3.0"
1611 | }
1612 | },
1613 | "figures": {
1614 | "version": "3.1.0",
1615 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz",
1616 | "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==",
1617 | "dev": true,
1618 | "requires": {
1619 | "escape-string-regexp": "^1.0.5"
1620 | }
1621 | },
1622 | "strip-ansi": {
1623 | "version": "5.2.0",
1624 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
1625 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
1626 | "dev": true,
1627 | "requires": {
1628 | "ansi-regex": "^4.1.0"
1629 | }
1630 | },
1631 | "supports-color": {
1632 | "version": "5.5.0",
1633 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
1634 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
1635 | "dev": true,
1636 | "requires": {
1637 | "has-flag": "^3.0.0"
1638 | }
1639 | }
1640 | }
1641 | },
1642 | "is-arguments": {
1643 | "version": "1.0.4",
1644 | "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz",
1645 | "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA=="
1646 | },
1647 | "is-callable": {
1648 | "version": "1.1.5",
1649 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
1650 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q=="
1651 | },
1652 | "is-date-object": {
1653 | "version": "1.0.2",
1654 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
1655 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
1656 | "dev": true
1657 | },
1658 | "is-extglob": {
1659 | "version": "2.1.1",
1660 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
1661 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
1662 | "dev": true
1663 | },
1664 | "is-finite": {
1665 | "version": "1.1.0",
1666 | "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.1.0.tgz",
1667 | "integrity": "sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==",
1668 | "dev": true
1669 | },
1670 | "is-fullwidth-code-point": {
1671 | "version": "3.0.0",
1672 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
1673 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
1674 | "dev": true
1675 | },
1676 | "is-generator-function": {
1677 | "version": "1.0.10",
1678 | "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz",
1679 | "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==",
1680 | "requires": {
1681 | "has-tostringtag": "^1.0.0"
1682 | }
1683 | },
1684 | "is-glob": {
1685 | "version": "4.0.1",
1686 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
1687 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
1688 | "dev": true,
1689 | "requires": {
1690 | "is-extglob": "^2.1.1"
1691 | }
1692 | },
1693 | "is-promise": {
1694 | "version": "2.1.0",
1695 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
1696 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
1697 | "dev": true
1698 | },
1699 | "is-regex": {
1700 | "version": "1.0.5",
1701 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
1702 | "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
1703 | "dev": true,
1704 | "requires": {
1705 | "has": "^1.0.3"
1706 | }
1707 | },
1708 | "is-stream": {
1709 | "version": "2.0.0",
1710 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz",
1711 | "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==",
1712 | "dev": true
1713 | },
1714 | "is-symbol": {
1715 | "version": "1.0.3",
1716 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
1717 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
1718 | "dev": true,
1719 | "requires": {
1720 | "has-symbols": "^1.0.1"
1721 | }
1722 | },
1723 | "is-typed-array": {
1724 | "version": "1.1.10",
1725 | "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
1726 | "integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
1727 | "requires": {
1728 | "available-typed-arrays": "^1.0.5",
1729 | "call-bind": "^1.0.2",
1730 | "for-each": "^0.3.3",
1731 | "gopd": "^1.0.1",
1732 | "has-tostringtag": "^1.0.0"
1733 | }
1734 | },
1735 | "is-typedarray": {
1736 | "version": "1.0.0",
1737 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
1738 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
1739 | "dev": true
1740 | },
1741 | "is-windows": {
1742 | "version": "1.0.2",
1743 | "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
1744 | "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
1745 | "dev": true
1746 | },
1747 | "isarray": {
1748 | "version": "1.0.0",
1749 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
1750 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
1751 | },
1752 | "isexe": {
1753 | "version": "2.0.0",
1754 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1755 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
1756 | "dev": true
1757 | },
1758 | "istanbul-lib-coverage": {
1759 | "version": "3.0.0",
1760 | "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
1761 | "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
1762 | "dev": true
1763 | },
1764 | "istanbul-lib-hook": {
1765 | "version": "3.0.0",
1766 | "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz",
1767 | "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==",
1768 | "dev": true,
1769 | "requires": {
1770 | "append-transform": "^2.0.0"
1771 | }
1772 | },
1773 | "istanbul-lib-instrument": {
1774 | "version": "4.0.1",
1775 | "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz",
1776 | "integrity": "sha512-imIchxnodll7pvQBYOqUu88EufLCU56LMeFPZZM/fJZ1irYcYdqroaV+ACK1Ila8ls09iEYArp+nqyC6lW1Vfg==",
1777 | "dev": true,
1778 | "requires": {
1779 | "@babel/core": "^7.7.5",
1780 | "@babel/parser": "^7.7.5",
1781 | "@babel/template": "^7.7.4",
1782 | "@babel/traverse": "^7.7.4",
1783 | "@istanbuljs/schema": "^0.1.2",
1784 | "istanbul-lib-coverage": "^3.0.0",
1785 | "semver": "^6.3.0"
1786 | },
1787 | "dependencies": {
1788 | "semver": {
1789 | "version": "6.3.1",
1790 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
1791 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
1792 | "dev": true
1793 | }
1794 | }
1795 | },
1796 | "istanbul-lib-processinfo": {
1797 | "version": "2.0.2",
1798 | "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz",
1799 | "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==",
1800 | "dev": true,
1801 | "requires": {
1802 | "archy": "^1.0.0",
1803 | "cross-spawn": "^7.0.0",
1804 | "istanbul-lib-coverage": "^3.0.0-alpha.1",
1805 | "make-dir": "^3.0.0",
1806 | "p-map": "^3.0.0",
1807 | "rimraf": "^3.0.0",
1808 | "uuid": "^3.3.3"
1809 | },
1810 | "dependencies": {
1811 | "rimraf": {
1812 | "version": "3.0.2",
1813 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
1814 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
1815 | "dev": true,
1816 | "requires": {
1817 | "glob": "^7.1.3"
1818 | }
1819 | },
1820 | "uuid": {
1821 | "version": "3.4.0",
1822 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
1823 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
1824 | "dev": true
1825 | }
1826 | }
1827 | },
1828 | "istanbul-lib-report": {
1829 | "version": "3.0.0",
1830 | "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz",
1831 | "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==",
1832 | "dev": true,
1833 | "requires": {
1834 | "istanbul-lib-coverage": "^3.0.0",
1835 | "make-dir": "^3.0.0",
1836 | "supports-color": "^7.1.0"
1837 | },
1838 | "dependencies": {
1839 | "has-flag": {
1840 | "version": "4.0.0",
1841 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
1842 | "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
1843 | "dev": true
1844 | },
1845 | "supports-color": {
1846 | "version": "7.1.0",
1847 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz",
1848 | "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==",
1849 | "dev": true,
1850 | "requires": {
1851 | "has-flag": "^4.0.0"
1852 | }
1853 | }
1854 | }
1855 | },
1856 | "istanbul-lib-source-maps": {
1857 | "version": "4.0.0",
1858 | "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz",
1859 | "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==",
1860 | "dev": true,
1861 | "requires": {
1862 | "debug": "^4.1.1",
1863 | "istanbul-lib-coverage": "^3.0.0",
1864 | "source-map": "^0.6.1"
1865 | },
1866 | "dependencies": {
1867 | "debug": {
1868 | "version": "4.1.1",
1869 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
1870 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
1871 | "dev": true,
1872 | "requires": {
1873 | "ms": "^2.1.1"
1874 | }
1875 | },
1876 | "ms": {
1877 | "version": "2.1.2",
1878 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
1879 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
1880 | "dev": true
1881 | }
1882 | }
1883 | },
1884 | "istanbul-reports": {
1885 | "version": "3.0.0",
1886 | "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.0.tgz",
1887 | "integrity": "sha512-2osTcC8zcOSUkImzN2EWQta3Vdi4WjjKw99P2yWx5mLnigAM0Rd5uYFn1cf2i/Ois45GkNjaoTqc5CxgMSX80A==",
1888 | "dev": true,
1889 | "requires": {
1890 | "html-escaper": "^2.0.0",
1891 | "istanbul-lib-report": "^3.0.0"
1892 | }
1893 | },
1894 | "jmespath": {
1895 | "version": "0.15.0",
1896 | "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.15.0.tgz",
1897 | "integrity": "sha1-o/Iiqarp+Wb10nx5ZRDigJF2Qhc=",
1898 | "dev": true
1899 | },
1900 | "js-tokens": {
1901 | "version": "4.0.0",
1902 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
1903 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
1904 | "dev": true
1905 | },
1906 | "js-yaml": {
1907 | "version": "3.13.1",
1908 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
1909 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
1910 | "dev": true,
1911 | "requires": {
1912 | "argparse": "^1.0.7",
1913 | "esprima": "^4.0.0"
1914 | }
1915 | },
1916 | "jsesc": {
1917 | "version": "2.5.2",
1918 | "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
1919 | "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
1920 | "dev": true
1921 | },
1922 | "json-schema-traverse": {
1923 | "version": "0.4.1",
1924 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
1925 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
1926 | "dev": true
1927 | },
1928 | "json-stable-stringify-without-jsonify": {
1929 | "version": "1.0.1",
1930 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
1931 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
1932 | "dev": true
1933 | },
1934 | "json5": {
1935 | "version": "2.2.3",
1936 | "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
1937 | "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
1938 | "dev": true
1939 | },
1940 | "jsonwebtoken": {
1941 | "version": "9.0.0",
1942 | "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz",
1943 | "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==",
1944 | "requires": {
1945 | "jws": "^3.2.2",
1946 | "lodash": "^4.17.21",
1947 | "ms": "^2.1.1",
1948 | "semver": "^7.3.8"
1949 | }
1950 | },
1951 | "jwa": {
1952 | "version": "1.4.1",
1953 | "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
1954 | "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
1955 | "requires": {
1956 | "buffer-equal-constant-time": "1.0.1",
1957 | "ecdsa-sig-formatter": "1.0.11",
1958 | "safe-buffer": "^5.0.1"
1959 | }
1960 | },
1961 | "jws": {
1962 | "version": "3.2.2",
1963 | "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
1964 | "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
1965 | "requires": {
1966 | "jwa": "^1.4.1",
1967 | "safe-buffer": "^5.0.1"
1968 | }
1969 | },
1970 | "levn": {
1971 | "version": "0.3.0",
1972 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
1973 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
1974 | "dev": true,
1975 | "requires": {
1976 | "prelude-ls": "~1.1.2",
1977 | "type-check": "~0.3.2"
1978 | }
1979 | },
1980 | "locate-path": {
1981 | "version": "5.0.0",
1982 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
1983 | "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
1984 | "dev": true,
1985 | "requires": {
1986 | "p-locate": "^4.1.0"
1987 | }
1988 | },
1989 | "lodash": {
1990 | "version": "4.17.21",
1991 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
1992 | "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
1993 | },
1994 | "lodash.flattendeep": {
1995 | "version": "4.4.0",
1996 | "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz",
1997 | "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=",
1998 | "dev": true
1999 | },
2000 | "lru-cache": {
2001 | "version": "6.0.0",
2002 | "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
2003 | "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
2004 | "requires": {
2005 | "yallist": "^4.0.0"
2006 | }
2007 | },
2008 | "make-dir": {
2009 | "version": "3.0.2",
2010 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz",
2011 | "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==",
2012 | "dev": true,
2013 | "requires": {
2014 | "semver": "^6.0.0"
2015 | },
2016 | "dependencies": {
2017 | "semver": {
2018 | "version": "6.3.1",
2019 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
2020 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
2021 | "dev": true
2022 | }
2023 | }
2024 | },
2025 | "mimic-fn": {
2026 | "version": "2.1.0",
2027 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
2028 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
2029 | "dev": true
2030 | },
2031 | "minimatch": {
2032 | "version": "3.1.2",
2033 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
2034 | "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
2035 | "dev": true,
2036 | "requires": {
2037 | "brace-expansion": "^1.1.7"
2038 | }
2039 | },
2040 | "minimist": {
2041 | "version": "1.2.6",
2042 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
2043 | "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
2044 | },
2045 | "mkdirp": {
2046 | "version": "0.5.3",
2047 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz",
2048 | "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==",
2049 | "dev": true,
2050 | "requires": {
2051 | "minimist": "^1.2.5"
2052 | }
2053 | },
2054 | "ms": {
2055 | "version": "2.1.2",
2056 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
2057 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
2058 | },
2059 | "mute-stream": {
2060 | "version": "0.0.8",
2061 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
2062 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
2063 | "dev": true
2064 | },
2065 | "natural-compare": {
2066 | "version": "1.4.0",
2067 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
2068 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
2069 | "dev": true
2070 | },
2071 | "neo-async": {
2072 | "version": "2.6.1",
2073 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz",
2074 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw=="
2075 | },
2076 | "nice-try": {
2077 | "version": "1.0.5",
2078 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
2079 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
2080 | "dev": true
2081 | },
2082 | "node-preload": {
2083 | "version": "0.2.1",
2084 | "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz",
2085 | "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==",
2086 | "dev": true,
2087 | "requires": {
2088 | "process-on-spawn": "^1.0.0"
2089 | }
2090 | },
2091 | "nyc": {
2092 | "version": "15.0.0",
2093 | "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.0.0.tgz",
2094 | "integrity": "sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg==",
2095 | "dev": true,
2096 | "requires": {
2097 | "@istanbuljs/load-nyc-config": "^1.0.0",
2098 | "@istanbuljs/schema": "^0.1.2",
2099 | "caching-transform": "^4.0.0",
2100 | "convert-source-map": "^1.7.0",
2101 | "decamelize": "^1.2.0",
2102 | "find-cache-dir": "^3.2.0",
2103 | "find-up": "^4.1.0",
2104 | "foreground-child": "^2.0.0",
2105 | "glob": "^7.1.6",
2106 | "istanbul-lib-coverage": "^3.0.0",
2107 | "istanbul-lib-hook": "^3.0.0",
2108 | "istanbul-lib-instrument": "^4.0.0",
2109 | "istanbul-lib-processinfo": "^2.0.2",
2110 | "istanbul-lib-report": "^3.0.0",
2111 | "istanbul-lib-source-maps": "^4.0.0",
2112 | "istanbul-reports": "^3.0.0",
2113 | "js-yaml": "^3.13.1",
2114 | "make-dir": "^3.0.0",
2115 | "node-preload": "^0.2.0",
2116 | "p-map": "^3.0.0",
2117 | "process-on-spawn": "^1.0.0",
2118 | "resolve-from": "^5.0.0",
2119 | "rimraf": "^3.0.0",
2120 | "signal-exit": "^3.0.2",
2121 | "spawn-wrap": "^2.0.0",
2122 | "test-exclude": "^6.0.0",
2123 | "uuid": "^3.3.3",
2124 | "yargs": "^15.0.2"
2125 | },
2126 | "dependencies": {
2127 | "resolve-from": {
2128 | "version": "5.0.0",
2129 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
2130 | "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
2131 | "dev": true
2132 | },
2133 | "rimraf": {
2134 | "version": "3.0.2",
2135 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
2136 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
2137 | "dev": true,
2138 | "requires": {
2139 | "glob": "^7.1.3"
2140 | }
2141 | },
2142 | "uuid": {
2143 | "version": "3.4.0",
2144 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz",
2145 | "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==",
2146 | "dev": true
2147 | }
2148 | }
2149 | },
2150 | "object-assign": {
2151 | "version": "4.1.1",
2152 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
2153 | "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
2154 | "dev": true
2155 | },
2156 | "object-inspect": {
2157 | "version": "1.7.0",
2158 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
2159 | "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
2160 | "dev": true
2161 | },
2162 | "object-is": {
2163 | "version": "1.0.2",
2164 | "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.2.tgz",
2165 | "integrity": "sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==",
2166 | "dev": true
2167 | },
2168 | "object-keys": {
2169 | "version": "1.1.1",
2170 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
2171 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
2172 | "dev": true
2173 | },
2174 | "object.assign": {
2175 | "version": "4.1.0",
2176 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
2177 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
2178 | "dev": true,
2179 | "requires": {
2180 | "define-properties": "^1.1.2",
2181 | "function-bind": "^1.1.1",
2182 | "has-symbols": "^1.0.0",
2183 | "object-keys": "^1.0.11"
2184 | }
2185 | },
2186 | "once": {
2187 | "version": "1.4.0",
2188 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
2189 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
2190 | "dev": true,
2191 | "requires": {
2192 | "wrappy": "1"
2193 | }
2194 | },
2195 | "onetime": {
2196 | "version": "5.1.0",
2197 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz",
2198 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==",
2199 | "dev": true,
2200 | "requires": {
2201 | "mimic-fn": "^2.1.0"
2202 | }
2203 | },
2204 | "optionator": {
2205 | "version": "0.8.3",
2206 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
2207 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
2208 | "dev": true,
2209 | "requires": {
2210 | "deep-is": "~0.1.3",
2211 | "fast-levenshtein": "~2.0.6",
2212 | "levn": "~0.3.0",
2213 | "prelude-ls": "~1.1.2",
2214 | "type-check": "~0.3.2",
2215 | "word-wrap": "~1.2.3"
2216 | }
2217 | },
2218 | "os-tmpdir": {
2219 | "version": "1.0.2",
2220 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
2221 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
2222 | "dev": true
2223 | },
2224 | "p-limit": {
2225 | "version": "2.2.2",
2226 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz",
2227 | "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==",
2228 | "dev": true,
2229 | "requires": {
2230 | "p-try": "^2.0.0"
2231 | }
2232 | },
2233 | "p-locate": {
2234 | "version": "4.1.0",
2235 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
2236 | "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
2237 | "dev": true,
2238 | "requires": {
2239 | "p-limit": "^2.2.0"
2240 | }
2241 | },
2242 | "p-map": {
2243 | "version": "3.0.0",
2244 | "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
2245 | "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
2246 | "dev": true,
2247 | "requires": {
2248 | "aggregate-error": "^3.0.0"
2249 | }
2250 | },
2251 | "p-try": {
2252 | "version": "2.2.0",
2253 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
2254 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
2255 | "dev": true
2256 | },
2257 | "package-hash": {
2258 | "version": "4.0.0",
2259 | "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz",
2260 | "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==",
2261 | "dev": true,
2262 | "requires": {
2263 | "graceful-fs": "^4.1.15",
2264 | "hasha": "^5.0.0",
2265 | "lodash.flattendeep": "^4.4.0",
2266 | "release-zalgo": "^1.0.0"
2267 | }
2268 | },
2269 | "parent-module": {
2270 | "version": "1.0.1",
2271 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
2272 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
2273 | "dev": true,
2274 | "requires": {
2275 | "callsites": "^3.0.0"
2276 | }
2277 | },
2278 | "parse-ms": {
2279 | "version": "1.0.1",
2280 | "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
2281 | "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
2282 | "dev": true
2283 | },
2284 | "path-exists": {
2285 | "version": "4.0.0",
2286 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
2287 | "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
2288 | "dev": true
2289 | },
2290 | "path-is-absolute": {
2291 | "version": "1.0.1",
2292 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
2293 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
2294 | "dev": true
2295 | },
2296 | "path-key": {
2297 | "version": "3.1.1",
2298 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
2299 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
2300 | "dev": true
2301 | },
2302 | "path-parse": {
2303 | "version": "1.0.7",
2304 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
2305 | "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
2306 | "dev": true
2307 | },
2308 | "pkg-dir": {
2309 | "version": "4.2.0",
2310 | "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
2311 | "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
2312 | "dev": true,
2313 | "requires": {
2314 | "find-up": "^4.0.0"
2315 | }
2316 | },
2317 | "plur": {
2318 | "version": "1.0.0",
2319 | "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
2320 | "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
2321 | "dev": true
2322 | },
2323 | "prelude-ls": {
2324 | "version": "1.1.2",
2325 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
2326 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
2327 | "dev": true
2328 | },
2329 | "pretty-ms": {
2330 | "version": "2.1.0",
2331 | "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
2332 | "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
2333 | "dev": true,
2334 | "requires": {
2335 | "is-finite": "^1.0.1",
2336 | "parse-ms": "^1.0.0",
2337 | "plur": "^1.0.0"
2338 | }
2339 | },
2340 | "process-nextick-args": {
2341 | "version": "2.0.1",
2342 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
2343 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
2344 | "dev": true
2345 | },
2346 | "process-on-spawn": {
2347 | "version": "1.0.0",
2348 | "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz",
2349 | "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==",
2350 | "dev": true,
2351 | "requires": {
2352 | "fromentries": "^1.2.0"
2353 | }
2354 | },
2355 | "progress": {
2356 | "version": "2.0.3",
2357 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
2358 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
2359 | "dev": true
2360 | },
2361 | "punycode": {
2362 | "version": "1.3.2",
2363 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
2364 | "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
2365 | },
2366 | "querystring": {
2367 | "version": "0.2.0",
2368 | "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
2369 | "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
2370 | },
2371 | "re-emitter": {
2372 | "version": "1.1.4",
2373 | "resolved": "https://registry.npmjs.org/re-emitter/-/re-emitter-1.1.4.tgz",
2374 | "integrity": "sha512-C0SIXdXDSus2yqqvV7qifnb4NoWP7mEBXJq3axci301mXHCZb8Djwm4hrEZo4UeXRaEnfjH98uQ8EBppk2oNWA==",
2375 | "dev": true
2376 | },
2377 | "readable-stream": {
2378 | "version": "2.3.7",
2379 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz",
2380 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==",
2381 | "dev": true,
2382 | "requires": {
2383 | "core-util-is": "~1.0.0",
2384 | "inherits": "~2.0.3",
2385 | "isarray": "~1.0.0",
2386 | "process-nextick-args": "~2.0.0",
2387 | "safe-buffer": "~5.1.1",
2388 | "string_decoder": "~1.1.1",
2389 | "util-deprecate": "~1.0.1"
2390 | }
2391 | },
2392 | "regexp.prototype.flags": {
2393 | "version": "1.3.0",
2394 | "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz",
2395 | "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==",
2396 | "dev": true,
2397 | "requires": {
2398 | "define-properties": "^1.1.3",
2399 | "es-abstract": "^1.17.0-next.1"
2400 | }
2401 | },
2402 | "regexpp": {
2403 | "version": "2.0.1",
2404 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
2405 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
2406 | "dev": true
2407 | },
2408 | "release-zalgo": {
2409 | "version": "1.0.0",
2410 | "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
2411 | "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=",
2412 | "dev": true,
2413 | "requires": {
2414 | "es6-error": "^4.0.1"
2415 | }
2416 | },
2417 | "repeat-string": {
2418 | "version": "1.6.1",
2419 | "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
2420 | "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
2421 | "dev": true
2422 | },
2423 | "require-directory": {
2424 | "version": "2.1.1",
2425 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
2426 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
2427 | "dev": true
2428 | },
2429 | "require-main-filename": {
2430 | "version": "2.0.0",
2431 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
2432 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
2433 | "dev": true
2434 | },
2435 | "resolve": {
2436 | "version": "1.15.1",
2437 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz",
2438 | "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==",
2439 | "dev": true,
2440 | "requires": {
2441 | "path-parse": "^1.0.6"
2442 | }
2443 | },
2444 | "resolve-from": {
2445 | "version": "4.0.0",
2446 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
2447 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
2448 | "dev": true
2449 | },
2450 | "restore-cursor": {
2451 | "version": "3.1.0",
2452 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
2453 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
2454 | "dev": true,
2455 | "requires": {
2456 | "onetime": "^5.1.0",
2457 | "signal-exit": "^3.0.2"
2458 | }
2459 | },
2460 | "resumer": {
2461 | "version": "0.0.0",
2462 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz",
2463 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=",
2464 | "dev": true,
2465 | "requires": {
2466 | "through": "~2.3.4"
2467 | }
2468 | },
2469 | "rimraf": {
2470 | "version": "2.6.3",
2471 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
2472 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
2473 | "dev": true,
2474 | "requires": {
2475 | "glob": "^7.1.3"
2476 | }
2477 | },
2478 | "run-async": {
2479 | "version": "2.3.0",
2480 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
2481 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
2482 | "dev": true,
2483 | "requires": {
2484 | "is-promise": "^2.1.0"
2485 | }
2486 | },
2487 | "rxjs": {
2488 | "version": "6.5.4",
2489 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
2490 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
2491 | "dev": true,
2492 | "requires": {
2493 | "tslib": "^1.9.0"
2494 | }
2495 | },
2496 | "safe-buffer": {
2497 | "version": "5.1.2",
2498 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
2499 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
2500 | },
2501 | "safer-buffer": {
2502 | "version": "2.1.2",
2503 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
2504 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2505 | "dev": true
2506 | },
2507 | "sax": {
2508 | "version": "1.2.1",
2509 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz",
2510 | "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o="
2511 | },
2512 | "semver": {
2513 | "version": "7.5.4",
2514 | "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
2515 | "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
2516 | "requires": {
2517 | "lru-cache": "^6.0.0"
2518 | }
2519 | },
2520 | "sendemail": {
2521 | "version": "4.0.0",
2522 | "resolved": "https://registry.npmjs.org/sendemail/-/sendemail-4.0.0.tgz",
2523 | "integrity": "sha512-rF/mBzuDHC6Ufx2ewO8MIvZZxAQNeaNyHbivNZurcaOGZkiYfqyiqgZIyEIGG9aMi+vAMdclMBKHcv0rSDEyfQ==",
2524 | "requires": {
2525 | "aws-sdk": "^2.614.0",
2526 | "handlebars": "^4.7.3"
2527 | }
2528 | },
2529 | "set-blocking": {
2530 | "version": "2.0.0",
2531 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
2532 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
2533 | "dev": true
2534 | },
2535 | "shebang-command": {
2536 | "version": "2.0.0",
2537 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2538 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2539 | "dev": true,
2540 | "requires": {
2541 | "shebang-regex": "^3.0.0"
2542 | }
2543 | },
2544 | "shebang-regex": {
2545 | "version": "3.0.0",
2546 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2547 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2548 | "dev": true
2549 | },
2550 | "signal-exit": {
2551 | "version": "3.0.2",
2552 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
2553 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
2554 | "dev": true
2555 | },
2556 | "slice-ansi": {
2557 | "version": "2.1.0",
2558 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
2559 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
2560 | "dev": true,
2561 | "requires": {
2562 | "ansi-styles": "^3.2.0",
2563 | "astral-regex": "^1.0.0",
2564 | "is-fullwidth-code-point": "^2.0.0"
2565 | },
2566 | "dependencies": {
2567 | "ansi-styles": {
2568 | "version": "3.2.1",
2569 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
2570 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
2571 | "dev": true,
2572 | "requires": {
2573 | "color-convert": "^1.9.0"
2574 | }
2575 | },
2576 | "is-fullwidth-code-point": {
2577 | "version": "2.0.0",
2578 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2579 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2580 | "dev": true
2581 | }
2582 | }
2583 | },
2584 | "source-map": {
2585 | "version": "0.6.1",
2586 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
2587 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
2588 | },
2589 | "spawn-wrap": {
2590 | "version": "2.0.0",
2591 | "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz",
2592 | "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==",
2593 | "dev": true,
2594 | "requires": {
2595 | "foreground-child": "^2.0.0",
2596 | "is-windows": "^1.0.2",
2597 | "make-dir": "^3.0.0",
2598 | "rimraf": "^3.0.0",
2599 | "signal-exit": "^3.0.2",
2600 | "which": "^2.0.1"
2601 | },
2602 | "dependencies": {
2603 | "rimraf": {
2604 | "version": "3.0.2",
2605 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
2606 | "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
2607 | "dev": true,
2608 | "requires": {
2609 | "glob": "^7.1.3"
2610 | }
2611 | },
2612 | "which": {
2613 | "version": "2.0.2",
2614 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2615 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2616 | "dev": true,
2617 | "requires": {
2618 | "isexe": "^2.0.0"
2619 | }
2620 | }
2621 | }
2622 | },
2623 | "split": {
2624 | "version": "1.0.1",
2625 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
2626 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
2627 | "dev": true,
2628 | "requires": {
2629 | "through": "2"
2630 | }
2631 | },
2632 | "sprintf-js": {
2633 | "version": "1.0.3",
2634 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
2635 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
2636 | "dev": true
2637 | },
2638 | "string-width": {
2639 | "version": "4.2.0",
2640 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
2641 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
2642 | "dev": true,
2643 | "requires": {
2644 | "emoji-regex": "^8.0.0",
2645 | "is-fullwidth-code-point": "^3.0.0",
2646 | "strip-ansi": "^6.0.0"
2647 | },
2648 | "dependencies": {
2649 | "ansi-regex": {
2650 | "version": "5.0.0",
2651 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
2652 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
2653 | "dev": true
2654 | },
2655 | "strip-ansi": {
2656 | "version": "6.0.0",
2657 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
2658 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
2659 | "dev": true,
2660 | "requires": {
2661 | "ansi-regex": "^5.0.0"
2662 | }
2663 | }
2664 | }
2665 | },
2666 | "string.prototype.trim": {
2667 | "version": "1.2.1",
2668 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.1.tgz",
2669 | "integrity": "sha512-MjGFEeqixw47dAMFMtgUro/I0+wNqZB5GKXGt1fFr24u3TzDXCPu7J9Buppzoe3r/LqkSDLDDJzE15RGWDGAVw==",
2670 | "dev": true,
2671 | "requires": {
2672 | "define-properties": "^1.1.3",
2673 | "es-abstract": "^1.17.0-next.1",
2674 | "function-bind": "^1.1.1"
2675 | }
2676 | },
2677 | "string.prototype.trimleft": {
2678 | "version": "2.1.1",
2679 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz",
2680 | "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==",
2681 | "dev": true,
2682 | "requires": {
2683 | "define-properties": "^1.1.3",
2684 | "function-bind": "^1.1.1"
2685 | }
2686 | },
2687 | "string.prototype.trimright": {
2688 | "version": "2.1.1",
2689 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz",
2690 | "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==",
2691 | "dev": true,
2692 | "requires": {
2693 | "define-properties": "^1.1.3",
2694 | "function-bind": "^1.1.1"
2695 | }
2696 | },
2697 | "string_decoder": {
2698 | "version": "1.1.1",
2699 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
2700 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
2701 | "dev": true,
2702 | "requires": {
2703 | "safe-buffer": "~5.1.0"
2704 | }
2705 | },
2706 | "strip-ansi": {
2707 | "version": "3.0.1",
2708 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
2709 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
2710 | "dev": true,
2711 | "requires": {
2712 | "ansi-regex": "^2.0.0"
2713 | }
2714 | },
2715 | "strip-json-comments": {
2716 | "version": "3.0.1",
2717 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
2718 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
2719 | "dev": true
2720 | },
2721 | "supports-color": {
2722 | "version": "2.0.0",
2723 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
2724 | "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
2725 | "dev": true
2726 | },
2727 | "table": {
2728 | "version": "5.4.6",
2729 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
2730 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
2731 | "dev": true,
2732 | "requires": {
2733 | "ajv": "^6.10.2",
2734 | "lodash": "^4.17.14",
2735 | "slice-ansi": "^2.1.0",
2736 | "string-width": "^3.0.0"
2737 | },
2738 | "dependencies": {
2739 | "ansi-regex": {
2740 | "version": "4.1.0",
2741 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
2742 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
2743 | "dev": true
2744 | },
2745 | "emoji-regex": {
2746 | "version": "7.0.3",
2747 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
2748 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
2749 | "dev": true
2750 | },
2751 | "is-fullwidth-code-point": {
2752 | "version": "2.0.0",
2753 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
2754 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
2755 | "dev": true
2756 | },
2757 | "string-width": {
2758 | "version": "3.1.0",
2759 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
2760 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
2761 | "dev": true,
2762 | "requires": {
2763 | "emoji-regex": "^7.0.1",
2764 | "is-fullwidth-code-point": "^2.0.0",
2765 | "strip-ansi": "^5.1.0"
2766 | }
2767 | },
2768 | "strip-ansi": {
2769 | "version": "5.2.0",
2770 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
2771 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
2772 | "dev": true,
2773 | "requires": {
2774 | "ansi-regex": "^4.1.0"
2775 | }
2776 | }
2777 | }
2778 | },
2779 | "tap-nyc": {
2780 | "version": "1.0.3",
2781 | "resolved": "https://registry.npmjs.org/tap-nyc/-/tap-nyc-1.0.3.tgz",
2782 | "integrity": "sha1-W2CAUuwPxZTejgxbdl+k6i/3VPg=",
2783 | "dev": true,
2784 | "requires": {
2785 | "chalk": "^1.0.0",
2786 | "duplexer": "^0.1.1",
2787 | "figures": "^1.4.0",
2788 | "pretty-ms": "^2.1.0",
2789 | "repeat-string": "^1.5.2",
2790 | "tap-out": "^1.4.1",
2791 | "through2": "^2.0.0"
2792 | }
2793 | },
2794 | "tap-out": {
2795 | "version": "1.4.2",
2796 | "resolved": "https://registry.npmjs.org/tap-out/-/tap-out-1.4.2.tgz",
2797 | "integrity": "sha1-yQfsG/lAURHQiCY+kvVgi4jLs3o=",
2798 | "dev": true,
2799 | "requires": {
2800 | "re-emitter": "^1.0.0",
2801 | "readable-stream": "^2.0.0",
2802 | "split": "^1.0.0",
2803 | "trim": "0.0.1"
2804 | }
2805 | },
2806 | "tape": {
2807 | "version": "4.13.2",
2808 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.13.2.tgz",
2809 | "integrity": "sha512-waWwC/OqYVE9TS6r1IynlP2sEdk4Lfo6jazlgkuNkPTHIbuG2BTABIaKdlQWwPeB6Oo4ksZ1j33Yt0NTOAlYMQ==",
2810 | "dev": true,
2811 | "requires": {
2812 | "deep-equal": "~1.1.1",
2813 | "defined": "~1.0.0",
2814 | "dotignore": "~0.1.2",
2815 | "for-each": "~0.3.3",
2816 | "function-bind": "~1.1.1",
2817 | "glob": "~7.1.6",
2818 | "has": "~1.0.3",
2819 | "inherits": "~2.0.4",
2820 | "is-regex": "~1.0.5",
2821 | "minimist": "~1.2.0",
2822 | "object-inspect": "~1.7.0",
2823 | "resolve": "~1.15.1",
2824 | "resumer": "~0.0.0",
2825 | "string.prototype.trim": "~1.2.1",
2826 | "through": "~2.3.8"
2827 | }
2828 | },
2829 | "test-exclude": {
2830 | "version": "6.0.0",
2831 | "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
2832 | "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
2833 | "dev": true,
2834 | "requires": {
2835 | "@istanbuljs/schema": "^0.1.2",
2836 | "glob": "^7.1.4",
2837 | "minimatch": "^3.0.4"
2838 | }
2839 | },
2840 | "text-table": {
2841 | "version": "0.2.0",
2842 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
2843 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
2844 | "dev": true
2845 | },
2846 | "through": {
2847 | "version": "2.3.8",
2848 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
2849 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
2850 | "dev": true
2851 | },
2852 | "through2": {
2853 | "version": "2.0.5",
2854 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
2855 | "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
2856 | "dev": true,
2857 | "requires": {
2858 | "readable-stream": "~2.3.6",
2859 | "xtend": "~4.0.1"
2860 | }
2861 | },
2862 | "tmp": {
2863 | "version": "0.0.33",
2864 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
2865 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
2866 | "dev": true,
2867 | "requires": {
2868 | "os-tmpdir": "~1.0.2"
2869 | }
2870 | },
2871 | "to-fast-properties": {
2872 | "version": "2.0.0",
2873 | "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
2874 | "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
2875 | "dev": true
2876 | },
2877 | "trim": {
2878 | "version": "0.0.1",
2879 | "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
2880 | "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
2881 | "dev": true
2882 | },
2883 | "tslib": {
2884 | "version": "1.10.0",
2885 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
2886 | "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
2887 | "dev": true
2888 | },
2889 | "type-check": {
2890 | "version": "0.3.2",
2891 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
2892 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
2893 | "dev": true,
2894 | "requires": {
2895 | "prelude-ls": "~1.1.2"
2896 | }
2897 | },
2898 | "type-fest": {
2899 | "version": "0.8.1",
2900 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
2901 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==",
2902 | "dev": true
2903 | },
2904 | "typedarray-to-buffer": {
2905 | "version": "3.1.5",
2906 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz",
2907 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==",
2908 | "dev": true,
2909 | "requires": {
2910 | "is-typedarray": "^1.0.0"
2911 | }
2912 | },
2913 | "uglify-js": {
2914 | "version": "3.7.7",
2915 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.7.tgz",
2916 | "integrity": "sha512-FeSU+hi7ULYy6mn8PKio/tXsdSXN35lm4KgV2asx00kzrLU9Pi3oAslcJT70Jdj7PHX29gGUPOT6+lXGBbemhA==",
2917 | "optional": true,
2918 | "requires": {
2919 | "commander": "~2.20.3",
2920 | "source-map": "~0.6.1"
2921 | }
2922 | },
2923 | "uri-js": {
2924 | "version": "4.2.2",
2925 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
2926 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
2927 | "dev": true,
2928 | "requires": {
2929 | "punycode": "^2.1.0"
2930 | },
2931 | "dependencies": {
2932 | "punycode": {
2933 | "version": "2.1.1",
2934 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
2935 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
2936 | "dev": true
2937 | }
2938 | }
2939 | },
2940 | "url": {
2941 | "version": "0.10.3",
2942 | "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz",
2943 | "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=",
2944 | "requires": {
2945 | "punycode": "1.3.2",
2946 | "querystring": "0.2.0"
2947 | }
2948 | },
2949 | "util": {
2950 | "version": "0.12.5",
2951 | "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
2952 | "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==",
2953 | "requires": {
2954 | "inherits": "^2.0.3",
2955 | "is-arguments": "^1.0.4",
2956 | "is-generator-function": "^1.0.7",
2957 | "is-typed-array": "^1.1.3",
2958 | "which-typed-array": "^1.1.2"
2959 | }
2960 | },
2961 | "util-deprecate": {
2962 | "version": "1.0.2",
2963 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
2964 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
2965 | "dev": true
2966 | },
2967 | "uuid": {
2968 | "version": "3.3.2",
2969 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
2970 | "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
2971 | "dev": true
2972 | },
2973 | "v8-compile-cache": {
2974 | "version": "2.1.0",
2975 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz",
2976 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
2977 | "dev": true
2978 | },
2979 | "which": {
2980 | "version": "1.3.1",
2981 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
2982 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
2983 | "dev": true,
2984 | "requires": {
2985 | "isexe": "^2.0.0"
2986 | }
2987 | },
2988 | "which-module": {
2989 | "version": "2.0.0",
2990 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
2991 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
2992 | "dev": true
2993 | },
2994 | "which-typed-array": {
2995 | "version": "1.1.9",
2996 | "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.9.tgz",
2997 | "integrity": "sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==",
2998 | "requires": {
2999 | "available-typed-arrays": "^1.0.5",
3000 | "call-bind": "^1.0.2",
3001 | "for-each": "^0.3.3",
3002 | "gopd": "^1.0.1",
3003 | "has-tostringtag": "^1.0.0",
3004 | "is-typed-array": "^1.1.10"
3005 | }
3006 | },
3007 | "word-wrap": {
3008 | "version": "1.2.4",
3009 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz",
3010 | "integrity": "sha512-2V81OA4ugVo5pRo46hAoD2ivUJx8jXmWXfUkY4KFNw0hEptvN0QfH3K4nHiwzGeKl5rFKedV48QVoqYavy4YpA==",
3011 | "dev": true
3012 | },
3013 | "wrap-ansi": {
3014 | "version": "6.2.0",
3015 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
3016 | "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
3017 | "dev": true,
3018 | "requires": {
3019 | "ansi-styles": "^4.0.0",
3020 | "string-width": "^4.1.0",
3021 | "strip-ansi": "^6.0.0"
3022 | },
3023 | "dependencies": {
3024 | "ansi-regex": {
3025 | "version": "5.0.0",
3026 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
3027 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
3028 | "dev": true
3029 | },
3030 | "ansi-styles": {
3031 | "version": "4.2.1",
3032 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
3033 | "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
3034 | "dev": true,
3035 | "requires": {
3036 | "@types/color-name": "^1.1.1",
3037 | "color-convert": "^2.0.1"
3038 | }
3039 | },
3040 | "color-convert": {
3041 | "version": "2.0.1",
3042 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
3043 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
3044 | "dev": true,
3045 | "requires": {
3046 | "color-name": "~1.1.4"
3047 | }
3048 | },
3049 | "color-name": {
3050 | "version": "1.1.4",
3051 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
3052 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
3053 | "dev": true
3054 | },
3055 | "is-fullwidth-code-point": {
3056 | "version": "3.0.0",
3057 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
3058 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
3059 | "dev": true
3060 | },
3061 | "string-width": {
3062 | "version": "4.2.0",
3063 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
3064 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
3065 | "dev": true,
3066 | "requires": {
3067 | "emoji-regex": "^8.0.0",
3068 | "is-fullwidth-code-point": "^3.0.0",
3069 | "strip-ansi": "^6.0.0"
3070 | }
3071 | },
3072 | "strip-ansi": {
3073 | "version": "6.0.0",
3074 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
3075 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
3076 | "dev": true,
3077 | "requires": {
3078 | "ansi-regex": "^5.0.0"
3079 | }
3080 | }
3081 | }
3082 | },
3083 | "wrappy": {
3084 | "version": "1.0.2",
3085 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
3086 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
3087 | "dev": true
3088 | },
3089 | "write": {
3090 | "version": "1.0.3",
3091 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
3092 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
3093 | "dev": true,
3094 | "requires": {
3095 | "mkdirp": "^0.5.1"
3096 | }
3097 | },
3098 | "write-file-atomic": {
3099 | "version": "3.0.1",
3100 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz",
3101 | "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==",
3102 | "dev": true,
3103 | "requires": {
3104 | "imurmurhash": "^0.1.4",
3105 | "is-typedarray": "^1.0.0",
3106 | "signal-exit": "^3.0.2",
3107 | "typedarray-to-buffer": "^3.1.5"
3108 | }
3109 | },
3110 | "xml2js": {
3111 | "version": "0.4.19",
3112 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
3113 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
3114 | "dev": true,
3115 | "requires": {
3116 | "sax": ">=0.6.0",
3117 | "xmlbuilder": "~9.0.1"
3118 | }
3119 | },
3120 | "xmlbuilder": {
3121 | "version": "9.0.7",
3122 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
3123 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=",
3124 | "dev": true
3125 | },
3126 | "xtend": {
3127 | "version": "4.0.2",
3128 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
3129 | "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
3130 | "dev": true
3131 | },
3132 | "y18n": {
3133 | "version": "4.0.0",
3134 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
3135 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
3136 | "dev": true
3137 | },
3138 | "yallist": {
3139 | "version": "4.0.0",
3140 | "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
3141 | "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
3142 | },
3143 | "yargs": {
3144 | "version": "15.4.1",
3145 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
3146 | "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
3147 | "dev": true,
3148 | "requires": {
3149 | "cliui": "^6.0.0",
3150 | "decamelize": "^1.2.0",
3151 | "find-up": "^4.1.0",
3152 | "get-caller-file": "^2.0.1",
3153 | "require-directory": "^2.1.1",
3154 | "require-main-filename": "^2.0.0",
3155 | "set-blocking": "^2.0.0",
3156 | "string-width": "^4.2.0",
3157 | "which-module": "^2.0.0",
3158 | "y18n": "^4.0.0",
3159 | "yargs-parser": "^18.1.2"
3160 | },
3161 | "dependencies": {
3162 | "yargs-parser": {
3163 | "version": "18.1.3",
3164 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
3165 | "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
3166 | "dev": true,
3167 | "requires": {
3168 | "camelcase": "^5.0.0",
3169 | "decamelize": "^1.2.0"
3170 | }
3171 | }
3172 | }
3173 | }
3174 | }
3175 | }
3176 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "aws-ses-lambda",
3 | "version": "1.0.2",
4 | "description": "A complete solution for sending email via AWS SES using Lambda",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "nocov": "./node_modules/tape/bin/tape ./test/*.test.js",
8 | "test": "NODE_ENV=test nyc tape ./test/*.test.js | tap-nyc",
9 | "deploy": "dpl",
10 | "check-coverage": "npm test && nyc check-coverage --statements 100 --functions 100 --lines 100 --branches 100",
11 | "eslint": "eslint lib"
12 | },
13 | "files_to_deploy": [
14 | "index.js",
15 | "package.json",
16 | "lib/",
17 | ".env",
18 | "templates/"
19 | ],
20 | "lambda_memory": 128,
21 | "lambda_timeout": 42,
22 | "repository": {
23 | "type": "git",
24 | "url": "git+https://github.com/dwyl/aws-ses-lambda.git"
25 | },
26 | "keywords": [
27 | "AWS",
28 | "Amazon Web Services",
29 | "SES",
30 | "Simple Email Service",
31 | "Lambda",
32 | "bounce checker",
33 | "stat counter",
34 | "Dynamo DB",
35 | "Serverless"
36 | ],
37 | "author": "dwyl & pals :-)",
38 | "license": "ISC",
39 | "bugs": {
40 | "url": "https://github.com/dwyl/aws-ses-lambda/issues"
41 | },
42 | "homepage": "https://github.com/dwyl/aws-ses-lambda#readme",
43 | "devDependencies": {
44 | "aguid": "^2.0.0",
45 | "aws-lambda-test-utils": "^1.3.0",
46 | "decache": "^4.5.1",
47 | "dpl": "^4.0.0",
48 | "eslint": "^6.8.0",
49 | "nyc": "^15.0.0",
50 | "tap-nyc": "^1.0.3",
51 | "tape": "^4.13.2"
52 | },
53 | "dependencies": {
54 | "aws-sdk": "^2.649.0",
55 | "env2": "^2.2.2",
56 | "sendemail": "^4.0.0",
57 | "jsonwebtoken": "^9.0.0"
58 | },
59 | "engines": {
60 | "node": ">=12.5.0"
61 | },
62 | "pre-commit": [
63 | "eslint",
64 | "check-coverage"
65 | ],
66 | "nyc": {
67 | "check-coverage": true,
68 | "lines": 100,
69 | "statements": 100,
70 | "functions": 100,
71 | "branches": 100,
72 | "include": [
73 | "lib/"
74 | ],
75 | "exclude": [
76 | "test/"
77 | ],
78 | "reporter": [
79 | "lcov",
80 | "text-summary"
81 | ],
82 | "cache": false,
83 | "all": true,
84 | "report-dir": "./coverage"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/templates/hello.html:
--------------------------------------------------------------------------------
1 | Hello {{name}}!
2 |
--------------------------------------------------------------------------------
/templates/hello.txt:
--------------------------------------------------------------------------------
1 | Hello {{name}}!
2 |
--------------------------------------------------------------------------------
/templates/simulator.html:
--------------------------------------------------------------------------------
1 | Hello {{name}}!
2 |
--------------------------------------------------------------------------------
/templates/simulator.txt:
--------------------------------------------------------------------------------
1 | Hello {{name}}!
2 |
--------------------------------------------------------------------------------
/templates/verify.html:
--------------------------------------------------------------------------------
1 | Hi!
2 |
3 | Thank you for signing up with your
4 | email address: {{email}}
5 |
6 | Please click the link to verify your address:
7 | {{link}}
8 |
9 | Or if you prefer, copy-paste it into your web browser.
10 |
11 |
12 |
13 | If you have any questions or find any issues, big or small,
14 | please drop us a note (by email or twitter) or
15 |
16 | add an issue to github,
17 | we really appreciate your feedback!
18 |
19 | Happy dwyling!
20 | Inês & Nelson
21 |
Co-Founders
22 | http://www.dwyl.com
23 |
24 |
--------------------------------------------------------------------------------
/templates/verify.txt:
--------------------------------------------------------------------------------
1 | Hi!
2 |
3 | Thank you for signing up to alpha test dwyl with your
4 | email address: {{email}}!
5 |
6 | Please follow this link to verify your address:
7 | {{link}}.
8 |
9 | If you have any questions or find any issues, big or small,
10 | please drop us a note or add an issue to GitHub:
11 | https://github.com/dwyl/app/labels/MVP
12 | We really appreciate your feedback!
13 |
14 | Inês & Nelson
15 | Co-Founders
16 | http://www.dwyl.com
17 |
--------------------------------------------------------------------------------
/templates/welcome.html:
--------------------------------------------------------------------------------
1 |
Hi {{name}}!
2 |
3 | Thanks so much for joining us to alpha test dwyl
4 | (Do What You Love),
5 | we’re excited to have you on board!
6 |
7 | For now, dwyl will help you track your time and soon it will help you
8 | do much more, including
9 |
10 | making time for what you love.
11 |
12 |
13 | If you have any questions or find any issues, big or small,
14 | please drop us a note (by email or twitter) or
15 | add an issue to github,
16 | we really appreciate your feedback!
17 |
18 | Happy dwyling!
19 | Inês & Nelson
20 |
Co-Founders
21 | http://www.dwyl.com
22 |
23 |
--------------------------------------------------------------------------------
/templates/welcome.txt:
--------------------------------------------------------------------------------
1 | Hi {{name}}!
2 |
3 | Thanks so much for joining us to alpha test dwyl (Do What You Love),
4 | we’re excited to have you on board!
5 |
6 | For now, dwyl will help you track your time
7 | and soon it will help you do much more,
8 | including making time for what you love.
9 | https://github.com/dwyl/start-here/blob/master/manifesto.md
10 |
11 | If you have any questions or find any issues, big or small,
12 | please drop us a note or add an issue to GitHub:
13 | https://github.com/dwyl/app/labels/MVP
14 | We really appreciate your feedback!
15 |
16 | Happy dwyling
17 | Inês & Nelson
18 | Co-Founders
19 | http://www.dwyl.com
20 |
--------------------------------------------------------------------------------
/test/debug.test.js:
--------------------------------------------------------------------------------
1 | const test = require('tape');
2 | const debug = require('../lib/debug.js');
3 | const get = require('../lib/s3.js').get;
4 |
5 | test('save event data to S3 without callback', function (t) {
6 | const time = Date.now().toString();
7 | let event = {"Bonjour":"le monde!", time: time, key: "event_test"};
8 | process.env.NODE_ENV="test";
9 | debug(event);
10 | setTimeout(function delay (){
11 | get('event_test.json', function(error2, data2) {
12 | // console.log(' - - - - get:');
13 | // console.log(error2, data2);
14 | t.deepEqual(event, data2, "event saved and retrieved! " + data2.time);
15 | process.env.NODE_ENV=null;
16 | t.end();
17 | });
18 | }, 3000);
19 | });
20 |
21 | test('debug sns event', function (t) {
22 | let event = require('./fixtures/sample_sns_bounce.json');
23 | event.time = Date.now().toString();
24 | process.env.NODE_ENV="test";
25 | debug(event);
26 | setTimeout(function delay (){
27 | get('sns.json', function(error2, data2) {
28 | // console.log(' - - - - get:');
29 | // console.log(error2, data2);
30 | t.deepEqual(event, data2, "sns event saved and retrieved! " + data2.time);
31 | process.env.NODE_ENV=null;
32 | t.end();
33 | });
34 | }, 3000);
35 | });
36 |
--------------------------------------------------------------------------------
/test/fixtures/sample_sns_bounce.json:
--------------------------------------------------------------------------------
1 | {
2 | "Records": [
3 | {
4 | "EventSource": "aws:sns",
5 | "EventVersion": "1.0",
6 | "EventSubscriptionArn": "arn:aws:sns:eu-west-1:123456789247:SESNotifications:efb916bb-1431-4fa3-9070-26b4cc115420",
7 | "Sns": {
8 | "Type": "Notification",
9 | "MessageId": "731cb327-2d34-528d-833e-e5f38f2d698d",
10 | "TopicArn": "arn:aws:sns:eu-west-1:123456789247:SESNotifications",
11 | "Subject": null,
12 | "Message": "{\"notificationType\":\"Bounce\",\"bounce\":{\"bounceType\":\"Permanent\",\"bounceSubType\":\"OnAccountSuppressionList\",\"bouncedRecipients\":[{\"emailAddress\":\"bounce@dwyl.com\",\"action\":\"failed\",\"status\":\"5.1.1\",\"diagnosticCode\":\"Amazon SES did not send the message to this address because it is on the suppression list for your account. For more information about removing addresses from the suppression list, see the Amazon SES Developer Guide at https://docs.aws.amazon.com/ses/latest/DeveloperGuide/sending-email-suppression-list.html\"}],\"timestamp\":\"2020-02-29T17:31:05.179Z\",\"feedbackId\":\"010201709200682d-59f64ce3-6e6a-4e3f-a48d-c9f9f2b924e0-000000\",\"reportingMTA\":\"dns; amazonses.com\"},\"mail\":{\"timestamp\":\"2020-02-29T17:31:05.179Z\",\"source\":\"hello@ademo.app\",\"sourceArn\":\"arn:aws:ses:eu-west-1:123456789247:identity/hello@ademo.app\",\"sourceIp\":\"34.247.165.191\",\"sendingAccountId\":\"123456789247\",\"messageId\":\"0102017092006798-f0456694-ac24-487b-9467-b79b8ce798f2-000000\",\"destination\":[\"bounce@dwyl.com\"],\"headersTruncated\":false,\"headers\":[{\"name\":\"From\",\"value\":\"hello@ademo.app\"},{\"name\":\"Reply-To\",\"value\":\"hello@ademo.app\"},{\"name\":\"To\",\"value\":\"bounce@dwyl.com\"},{\"name\":\"Subject\",\"value\":\"Welcome to dwyl Bouncerino\"},{\"name\":\"MIME-Version\",\"value\":\"1.0\"},{\"name\":\"Content-Type\",\"value\":\"multipart/alternative; boundary=\\\"----=_Part_7127832_1654059516.1582997464986\\\"\"}],\"commonHeaders\":{\"from\":[\"hello@ademo.app\"],\"replyTo\":[\"hello@ademo.app\"],\"to\":[\"bounce@dwyl.com\"],\"subject\":\"Welcome to dwyl Bouncerino\"}}}",
13 | "Timestamp": "2020-02-29T17:31:05.199Z",
14 | "SignatureVersion": "1",
15 | "Signature": "cOnptKPHCIW4x2iPsjGr7Oay74Br52VkrraMfsi+iqqKnKmqmYkNm04j7UoNaymn0cUUGURqByHdiyvVG+J9ADfQHdYtmOgStsi2I50cCNw68bATz0mDzQ9fIzOskV5uePW26z5yXlreuB+V4kA6NKygmlHPIbZ9UFWzTKjStAlxXqooh7c/KdlgZGtrYtgu74pRIdQIaagNJAMlDvhDnrf72fupvACHPgDKIOM9E70vMMziUNdC78bZ2lvl8j2JCKdAenO+uTBzxKj6DuUXCD95jJj4gGiYARGLK+nf3uE17RE7o4xDyjgiMYhob/gdRD1k2C5SiGBwm2RIDO7pwA==",
16 | "SigningCertUrl": "https://sns.eu-west-1.amazonaws.com/SimpleNotificationService-a86cb10b4e1f29c941702d737128f7b6.pem",
17 | "UnsubscribeUrl": "https://sns.eu-west-1.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:eu-west-1:123456789247:SESNotifications:efb916bb-1431-4fa3-9070-26b4cc115420",
18 | "MessageAttributes": {}
19 | }
20 | }
21 | ]
22 | }
23 |
--------------------------------------------------------------------------------
/test/fixtures/ses_sent.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | ResponseMetadata: { RequestId: '950d09c6-eefd-4877-a2e1-2ded26d9ba05' },
3 | MessageId: '01020170b0c80030-02edabfa-bf8d-4985-8c29-3c77e1b89aa5-000000'
4 | }
5 |
--------------------------------------------------------------------------------
/test/http_request.test.js:
--------------------------------------------------------------------------------
1 | require("env2")(".env");
2 | const test = require('tape');
3 | const http_request = require('../lib/http_request');
4 | const jwt = require('jsonwebtoken');
5 |
6 | test('test extracting data from JWT', function (t) {
7 | const json = {
8 | message_id: '0102017092006798-f0456694-ac24-487b-9467-b79b8ce798f2-000000',
9 | status: 'Bounce Permanent'
10 | }
11 | const token = jwt.sign(json, process.env.JWT_SECRET);
12 | // console.log("token:", token);
13 | const decoded = jwt.verify(token, process.env.JWT_SECRET);
14 |
15 | t.equal(decoded.message_id, json.message_id, "JWT verification works");
16 | // console.log('decoded:', decoded);
17 | // t.end();
18 | http_request(json, function (status, response) {
19 | // console.log('status:', status, 'response:', response);
20 | t.equal(status, 200, "data successfully sent to Phoenix!");
21 | t.end();
22 | });
23 | });
24 |
25 |
26 | test('send data to Phoenix', function (t) {
27 | const json = {
28 | message_id: '01020170fa0c2a82-67271308-6fcd-466d-b9a8-185d735efb5b-000000',
29 | status: 'Sent'
30 | }
31 | http_request(json, function (status, response) {
32 | // console.log('status:', status, 'response:', response);
33 | t.equal(status, 200, "data successfully sent to Phoenix!");
34 | t.end();
35 | });
36 | });
37 |
38 |
39 | test('make jwt', function (t) {
40 | const json = {
41 | id: 142
42 | }
43 | const token = jwt.sign(json, process.env.JWT_SECRET)
44 | console.log('token:', token);
45 | const decoded = jwt.decode(token);
46 | t.equal(decoded.id, json.id, "id matches")
47 | t.end();
48 | });
49 |
--------------------------------------------------------------------------------
/test/index.test.js:
--------------------------------------------------------------------------------
1 | const test = require('tape');
2 | const handler = require('../index.js').handler;
3 | const context = require('aws-lambda-test-utils').mockContextCreator({}, test);
4 |
5 | test('ping to warm up lambda function', function (t) {
6 | const event = {ping: Date.now(), key: "ping"};
7 | handler(event, context, function (error, data) {
8 | t.equal(data, event, "event returned without modification");
9 | t.end();
10 | })
11 | });
12 |
13 |
14 | test('send email to success simulator and save to API', function (t) {
15 | const event = {
16 | "email": "success@simulator.amazonses.com",
17 | "name": "Alex!",
18 | "subject": "my amazing subject!",
19 | "key": "test",
20 | "template": "welcome",
21 | "time": Date.now().toString()
22 | };
23 | handler(event, context, function cb (err, data) {
24 | console.log('event:', event);
25 | console.log('err:', err);
26 | console.log('data:', data);
27 | t.equal(data.message_id.length, 60, "message_id: " + data.message_id);
28 | t.equal(data.status, "Sent", "Status: " + data.status);
29 | t.end();
30 | })
31 | });
32 |
33 |
34 | test('POST sns event to Phoenix App via index.handler', function (t) {
35 | const event = require('./fixtures/sample_sns_bounce.json');
36 | handler(event, context, function (status, data) {
37 | // console.log('event:', event);
38 | // console.log('status:', status);
39 | // console.log('data:', data);
40 | t.equal(status, 200, "data successfully sent to Phoenix!");
41 | t.end();
42 | })
43 | });
44 |
45 | test('avoid sending email to addresses on the bounce list', function (t) {
46 | const event = {
47 | "email": "test@gmail.com",
48 | "name": "Alex McTesting!",
49 | "subject": "my amazing subject!",
50 | "key": "test",
51 | "time": Date.now().toString()
52 | };
53 | handler(event, context, function (error, data) {
54 | t.equal(data, event, "event returned without modification");
55 | t.end();
56 | })
57 | });
58 |
--------------------------------------------------------------------------------
/test/parse.test.js:
--------------------------------------------------------------------------------
1 | const test = require('tape');
2 | const parse = require('../lib/parse.js');
3 |
4 | test('parse the bounce sns notification event', function (t) {
5 | const event = require('./fixtures/sample_sns_bounce.json');
6 | // console.log('event:', event);
7 | // console.log('event.Records[0].Sns', event.Records[0].Sns);
8 | const json = parse(event)
9 | // console.log('json', json);
10 | // console.log(' - - - - - - - - ');
11 | const mid = '0102017092006798-f0456694-ac24-487b-9467-b79b8ce798f2-000000';
12 | t.equal(json.message_id, mid, "json.message_id: " + json.message_id);
13 | t.equal(json.status, "Bounce Permanent", "json.status: " + json.status);
14 | t.equal(json.email, "bounce@dwyl.com", 'json.email: ' + json.email);
15 | t.end();
16 | });
17 |
18 | test('attempt to parse an SNS event without event.Records', function (t) {
19 | const event = require('./fixtures/sample_sns_bounce.json');
20 | delete event.Records;
21 | const json = parse(event);
22 | t.deepEqual(json, {}, "Does not choke when SNS event is invalid");
23 | t.end();
24 | });
25 |
26 | test('parse response from sendemail to save to Phoenix', function (t) {
27 | const event = require('./fixtures/ses_sent.js')
28 | // console.log('event:', event);
29 | const json = parse(event);
30 | // console.log('json:', json);
31 | const expected = {
32 | message_id: '01020170b0c80030-02edabfa-bf8d-4985-8c29-3c77e1b89aa5-000000',
33 | request_id: '950d09c6-eefd-4877-a2e1-2ded26d9ba05',
34 | status: "Sent"
35 | };
36 | t.deepEqual(json, expected, "json.message_id:" + json.message_id)
37 | t.end()
38 | });
39 |
--------------------------------------------------------------------------------
/test/s3.test.js:
--------------------------------------------------------------------------------
1 | const test = require('tape');
2 | const save = require('../lib/s3.js').save;
3 | const get = require('../lib/s3.js').get;
4 | const context = require('aws-lambda-test-utils').mockContextCreator({}, test);
5 |
6 | test('save event data to S3 with callback', function (t) {
7 | const time = Date.now().toString();
8 | const event = {"hello":"world!", time: time};
9 | save(event, function(error, data) {
10 | // console.log('error:', error);
11 | // console.log('data (event):', data);
12 | // retrieve the data from S3 to confirm it was saved correctly!
13 | get(data.key, function(error2, data2) {
14 | // console.log(' - - - - get:');
15 | // console.log(error2, data2);
16 | t.deepEqual(event, data2, "event save/get success! " + data2.time);
17 | t.end();
18 | });
19 | })
20 | });
21 |
22 | test('save event data to S3 without callback', function (t) {
23 | let event = require('./fixtures/sample_sns_bounce.json');
24 | event.key = "without_callabck"
25 | save(event);
26 | setTimeout(function delay () {
27 | get('without_callabck.json', function(error2, data2) {
28 | // console.log(' - - - - get:');
29 | // console.log(error2, data2);
30 | t.deepEqual(event, data2, "event saved and retrieved! " + data2.time);
31 | t.end();
32 | });
33 | }, 2000);
34 | });
35 |
36 | test('attempt s3.save without an event (should error)', function (t) {
37 | save(null, function callback (error, data) {
38 | // console.log('error:', error);
39 | t.equal(error, "ERROR: please provide json data", error + " (as expected)");
40 | t.end();
41 | })
42 | });
43 |
44 | test('attempt s3.get invalid key (should error)', function (t) {
45 | const key = Date.now().toString();
46 | get(key, function callback (error, data) {
47 | // console.log('error:', error, "data:", data);
48 | t.equal(error.message, "The specified key does not exist.",
49 | error + " (as expected)");
50 | t.end();
51 | })
52 | });
53 |
--------------------------------------------------------------------------------
/test/send.test.js:
--------------------------------------------------------------------------------
1 | const test = require('tape');
2 | const handler = require('../index.js').handler;
3 | const send = require("../lib/send.js");
4 | const context = require('aws-lambda-test-utils').mockContextCreator({}, test);
5 |
6 | test('send a welcome email to the simulator', function (t) {
7 | const event = {
8 | "template": "welcome",
9 | "email": "success@simulator.amazonses.com",
10 | "name": "Great Success!",
11 | "subject": "my amazing subject!",
12 | "id": 1,
13 | "key": "welcome_test"
14 | };
15 | handler(event, context, function(err, data){
16 | // console.log(err, data);
17 | // console.log(' - - - - - - - - ');
18 | t.equal(data.message_id.length, 60,
19 | "Email sent! MessageId: " + data.message_id)
20 | t.end();
21 | })
22 | });
23 |
24 | test('send email without template or name', function (t) {
25 | const event = {
26 | "email": "success@simulator.amazonses.com",
27 | "id": 1,
28 | "key": "no_template"
29 | }; // no template
30 | handler(event, context, function(err, data) {
31 | // console.log(data);
32 | t.equal(data.message_id.length, 60, "Sent! message_id: " + data.message_id);
33 | t.end();
34 | })
35 | });
36 |
37 | test('simulate bounce and complaint', function (t) {
38 | const event = {
39 | "email": [
40 | "success@simulator.amazonses.com",
41 | "complaint@simulator.amazonses.com"
42 | ],
43 | "template": "simulator",
44 | "name": "Testy McTestface",
45 | "id": 1,
46 | "key": "simulate_bounce"
47 | }; // no template
48 | send(event, function(err, data) {
49 | // console.log(data);
50 | t.equal(data.MessageId.length, 60, "Sent! message_id: " + data.message_id);
51 | t.end();
52 | })
53 | });
54 |
55 | test('simulate verification email', function (t) {
56 | const event = {
57 | "email": [
58 | "success@simulator.amazonses.com",
59 | // "nelson@dwyl.com"
60 | ],
61 | "template": "verify",
62 | "name": "Testy McTestface",
63 | "id": 1,
64 | "key": "simulate_verify",
65 | "link": "https://dwyl.com/person/verify/StTqXEQ2l-Y"
66 | }; // no template
67 | send(event, function(err, data) {
68 | console.log(data);
69 | t.equal(data.MessageId.length, 60, "Sent! message_id: " + data.MessageId);
70 | t.end();
71 | })
72 | });
73 |
--------------------------------------------------------------------------------