Commit 5cc5696f3e67f2f0c38deab5a9fc739bed369015

Authored by Adhidarma Hadiwinoto
1 parent 87bdbb4d51
Exists in master

Error handling and eslint

Showing 4 changed files with 686 additions and 107 deletions Side-by-side Diff

1 1 module.exports = {
2   - "env": {
3   - "commonjs": true,
4   - "es6": true,
5   - "node": true
6   - },
7   - "extends": "eslint:recommended",
8   - "globals": {
9   - "Atomics": "readonly",
10   - "SharedArrayBuffer": "readonly"
11   - },
12   - "parserOptions": {
13   - "ecmaVersion": 2018
14   - },
15   - "rules": {
16   - }
17   -};
18 2 \ No newline at end of file
  3 + env: {
  4 + commonjs: true,
  5 + es6: true,
  6 + node: true,
  7 + },
  8 + extends: [
  9 + 'airbnb-base',
  10 + ],
  11 + globals: {
  12 + Atomics: 'readonly',
  13 + SharedArrayBuffer: 'readonly',
  14 + },
  15 + parserOptions: {
  16 + ecmaVersion: 2018,
  17 + },
  18 + rules: {
  19 + indent: ['error', 4]
  20 + },
  21 +};
1   -"use strict";
  1 +const MODULE_NAME = 'TRANSPORT';
2 2  
3 3 const MAX_LENGTH = 4096;
4 4 const DEFAULT_EXPIRED_MS = 60;
... ... @@ -9,28 +9,63 @@ const truncateLine = require('custom-truncate/lib/line');
9 9 const messagingService = require('komodo-center-messaging-client-lib');
10 10  
11 11 const config = require('komodo-sdk/config');
12   -const logger = require('komodo-sdk/logger')
  12 +const logger = require('komodo-sdk/logger');
13 13  
14 14 const addressbook = require('./addressbook');
15 15  
16 16 const bot = new Telegraf(config.telegram.token);
17 17  
  18 +async function sendMessageViaTelegram(chatId, msg) {
  19 + const [head, tail] = truncateLine(msg, MAX_LENGTH);
  20 +
  21 + try {
  22 + await bot.telegram.sendMessage(chatId, head);
  23 + } catch (e) {
  24 + logger.warn(`D16D620A ${MODULE_NAME}: Exception on sending message to telegram API server`, {
  25 + chatId,
  26 + msg,
  27 + errCode: e.code,
  28 + errMessage: e.message,
  29 + });
  30 + return;
  31 + }
  32 +
  33 + if (tail) {
  34 + sendMessageViaTelegram(chatId, tail);
  35 + }
  36 +}
  37 +
  38 +function sendToMessagingService(partner, msg) {
  39 + if (!msg || (typeof msg === 'string' && !msg.trim())) {
  40 + return;
  41 + }
  42 +
  43 + if (messagingService && messagingService.onIncomingMessage) {
  44 + messagingService.onIncomingMessage({
  45 + me: bot.context.botInfo.username,
  46 + partner,
  47 + msg: msg.trim(),
  48 + });
  49 + }
  50 +}
  51 +
  52 +
18 53 bot.start((ctx) => ctx.reply('Selamat datang. Silahkan ketik "HELP" untuk bantuan.'));
19 54  
20 55 bot.command('help', (ctx) => {
21 56 sendToMessagingService(
22   - ctx.from.username + ( config.username_suffix || '@telegram.org' ),
23   - 'help'
24   - )
25   -})
  57 + ctx.from.username + (config.username_suffix || '@telegram.org'),
  58 + 'help',
  59 + );
  60 +});
26 61  
27 62 bot.catch((err) => {
28   - logger.warn('Error catched', {err: err});
29   -})
  63 + logger.warn('Error catched', { errCode: err.code, errMessage: err.message });
  64 +});
30 65  
31 66 bot.on('text', async (ctx) => {
32 67 const me = ctx.botInfo.username;
33   - const from = ctx.from.username + ( config.username_suffix || '@telegram.org' );
  68 + const from = ctx.from.username + (config.username_suffix || '@telegram.org');
34 69 const msg = ctx.message.text;
35 70 const delaySecs = Math.floor(new Date() / 1000 - ctx.message.date);
36 71  
... ... @@ -41,41 +76,27 @@ bot.on('text', async (ctx) => {
41 76  
42 77 const isExpired = delaySecs > (config.expired_secs || DEFAULT_EXPIRED_MS);
43 78 if (isExpired) {
44   - logger.verbose(
45   - 'Ignoring expired messages',
46   - { transport: 'telegram', ts: moment(ctx.date).format('YYYY-MM-DD HH:mm:ss'), delay_secs: delaySecs, is_expired: isExpired, chat_id: ctx.chat.id, me: me, from: from, msg: msg }
47   - );
  79 + logger.verbose('Ignoring expired messages', {
  80 + transport: 'telegram', ts: moment(ctx.date).format('YYYY-MM-DD HH:mm:ss'), delay_secs: delaySecs, is_expired: isExpired, chat_id: ctx.chat.id, me, from, msg,
  81 + });
48 82 return;
49   -
50 83 }
51 84  
52 85 logger.info(
53   - 'Incoming message from Telegram transport',
54   - { transport: 'telegram', ts: moment(ctx.date).format('YYYY-MM-DD HH:mm:ss'), delay_secs: delaySecs, is_expired: isExpired, chat_id: ctx.chat.id, me: me, from: from, msg: msg }
  86 + 'Incoming message from Telegram transport', {
  87 + transport: 'telegram', ts: moment(ctx.date).format('YYYY-MM-DD HH:mm:ss'), delay_secs: delaySecs, is_expired: isExpired, chat_id: ctx.chat.id, me, from, msg,
  88 + },
55 89 );
56 90  
57 91 addressbook.put(from, ctx.chat.id);
58   -
59   - if (messagingService && messagingService.onIncomingMessage) {
60   - messagingService.onIncomingMessage({
61   - me: me,
62   - partner: from,
63   - msg: msg.trim()
64   - })
65   - }
66   -})
67 92  
68   -async function sendMessageViaTelegram(chatId, msg) {
69   - const [head, tail] = truncateLine(msg, MAX_LENGTH);
70   - await bot.telegram.sendMessage(chatId, head);
71   -
72   - if (tail) {
73   - sendMessageViaTelegram(chatId, tail);
  93 + if (messagingService && messagingService.onIncomingMessage) {
  94 + messagingService.onIncomingMessage({ me, partner: from, msg: msg.trim() });
74 95 }
75   -}
  96 +});
76 97  
77 98 async function send(partner, msg) {
78   - const me = bot.context.botInfo.username;
  99 + const me = bot.context.botInfo.username;
79 100  
80 101 if (!partner || !msg) {
81 102 return;
... ... @@ -83,33 +104,23 @@ async function send(partner, msg) {
83 104  
84 105 const chatId = await addressbook.get(partner);
85 106 if (!chatId) {
86   - logger.info('Not sending message because partner does not exist on address book', {transport: 'telegram', me: me, partner: partner, msg: msg });
  107 + logger.info('Not sending message because partner does not exist on address book', {
  108 + transport: 'telegram', me, partner, msg,
  109 + });
87 110 return;
88 111 }
89 112  
90   - logger.info('Sending message via Telegram transport', { transport: 'telegram', me: me, partner: partner, msg: msg });
  113 + logger.info('Sending message via Telegram transport', {
  114 + transport: 'telegram', me, partner, msg,
  115 + });
91 116 // bot.telegram.sendMessage(chatId, msg);
92 117 sendMessageViaTelegram(chatId, msg);
93 118 }
94 119  
95   -function sendToMessagingService(partner, msg) {
96   - if (!msg || (typeof msg === 'string' && !msg.trim())) {
97   - return;
98   - }
99   -
100   - if (messagingService && messagingService.onIncomingMessage) {
101   - messagingService.onIncomingMessage({
102   - me: bot.context.botInfo.username,
103   - partner: partner,
104   - msg: msg.trim()
105   - })
106   - }
107   -}
108   -
109 120 bot.launch().then(() => {
110   - logger.info(`Connected to Telegram Bot API as "@${ bot.context.botInfo.username }"`);
  121 + logger.info(`Connected to Telegram Bot API as "@${bot.context.botInfo.username}"`);
111 122 });
112 123  
113 124 messagingService.setTransport(exports);
114 125  
115   -exports.send = send;
116 126 \ No newline at end of file
  127 +exports.send = send;
... ... @@ -13,14 +13,20 @@
13 13 "@babel/highlight": "^7.8.3"
14 14 }
15 15 },
  16 + "@babel/helper-validator-identifier": {
  17 + "version": "7.9.5",
  18 + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.5.tgz",
  19 + "integrity": "sha512-/8arLKUFq882w4tWGj9JYzRpAlZgiWUJ+dtteNTDqrRBz9Iguck9Rn3ykuBDoUwh2TO4tSAJlrxDUOXWklJe4g==",
  20 + "dev": true
  21 + },
16 22 "@babel/highlight": {
17   - "version": "7.8.3",
18   - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz",
19   - "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==",
  23 + "version": "7.9.0",
  24 + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
  25 + "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
20 26 "dev": true,
21 27 "requires": {
  28 + "@babel/helper-validator-identifier": "^7.9.0",
22 29 "chalk": "^2.0.0",
23   - "esutils": "^2.0.2",
24 30 "js-tokens": "^4.0.0"
25 31 }
26 32 },
... ... @@ -139,11 +145,32 @@
139 145 "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
140 146 "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
141 147 },
  148 + "array-includes": {
  149 + "version": "3.1.1",
  150 + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz",
  151 + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==",
  152 + "dev": true,
  153 + "requires": {
  154 + "define-properties": "^1.1.3",
  155 + "es-abstract": "^1.17.0",
  156 + "is-string": "^1.0.5"
  157 + }
  158 + },
142 159 "array-unique": {
143 160 "version": "0.3.2",
144 161 "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
145 162 "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg="
146 163 },
  164 + "array.prototype.flat": {
  165 + "version": "1.2.3",
  166 + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz",
  167 + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==",
  168 + "dev": true,
  169 + "requires": {
  170 + "define-properties": "^1.1.3",
  171 + "es-abstract": "^1.17.0-next.1"
  172 + }
  173 + },
147 174 "asap": {
148 175 "version": "2.0.6",
149 176 "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
... ... @@ -337,9 +364,9 @@
337 364 }
338 365 },
339 366 "cli-width": {
340   - "version": "2.2.0",
341   - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
342   - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
  367 + "version": "2.2.1",
  368 + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz",
  369 + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==",
343 370 "dev": true
344 371 },
345 372 "color": {
... ... @@ -410,6 +437,18 @@
410 437 "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
411 438 "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
412 439 },
  440 + "confusing-browser-globals": {
  441 + "version": "1.0.9",
  442 + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz",
  443 + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==",
  444 + "dev": true
  445 + },
  446 + "contains-path": {
  447 + "version": "0.1.0",
  448 + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
  449 + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
  450 + "dev": true
  451 + },
413 452 "content-disposition": {
414 453 "version": "0.5.3",
415 454 "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
... ... @@ -501,6 +540,15 @@
501 540 "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
502 541 "dev": true
503 542 },
  543 + "define-properties": {
  544 + "version": "1.1.3",
  545 + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
  546 + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
  547 + "dev": true,
  548 + "requires": {
  549 + "object-keys": "^1.0.12"
  550 + }
  551 + },
504 552 "delayed-stream": {
505 553 "version": "1.0.0",
506 554 "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
... ... @@ -587,6 +635,53 @@
587 635 "resolved": "https://registry.npmjs.org/env-variable/-/env-variable-0.0.6.tgz",
588 636 "integrity": "sha512-bHz59NlBbtS0NhftmR8+ExBEekE7br0e01jw+kk0NDro7TtZzBYZ5ScGPs3OmwnpyfHTHOtr1Y6uedCdrIldtg=="
589 637 },
  638 + "error-ex": {
  639 + "version": "1.3.2",
  640 + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
  641 + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
  642 + "dev": true,
  643 + "requires": {
  644 + "is-arrayish": "^0.2.1"
  645 + },
  646 + "dependencies": {
  647 + "is-arrayish": {
  648 + "version": "0.2.1",
  649 + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
  650 + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
  651 + "dev": true
  652 + }
  653 + }
  654 + },
  655 + "es-abstract": {
  656 + "version": "1.17.5",
  657 + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz",
  658 + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==",
  659 + "dev": true,
  660 + "requires": {
  661 + "es-to-primitive": "^1.2.1",
  662 + "function-bind": "^1.1.1",
  663 + "has": "^1.0.3",
  664 + "has-symbols": "^1.0.1",
  665 + "is-callable": "^1.1.5",
  666 + "is-regex": "^1.0.5",
  667 + "object-inspect": "^1.7.0",
  668 + "object-keys": "^1.1.1",
  669 + "object.assign": "^4.1.0",
  670 + "string.prototype.trimleft": "^2.1.1",
  671 + "string.prototype.trimright": "^2.1.1"
  672 + }
  673 + },
  674 + "es-to-primitive": {
  675 + "version": "1.2.1",
  676 + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz",
  677 + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==",
  678 + "dev": true,
  679 + "requires": {
  680 + "is-callable": "^1.1.4",
  681 + "is-date-object": "^1.0.1",
  682 + "is-symbol": "^1.0.2"
  683 + }
  684 + },
590 685 "es6-promisify": {
591 686 "version": "6.1.0",
592 687 "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-6.1.0.tgz",
... ... @@ -648,6 +743,118 @@
648 743 "v8-compile-cache": "^2.0.3"
649 744 }
650 745 },
  746 + "eslint-config-airbnb-base": {
  747 + "version": "14.1.0",
  748 + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.1.0.tgz",
  749 + "integrity": "sha512-+XCcfGyCnbzOnktDVhwsCAx+9DmrzEmuwxyHUJpw+kqBVT744OUBrB09khgFKlK1lshVww6qXGsYPZpavoNjJw==",
  750 + "dev": true,
  751 + "requires": {
  752 + "confusing-browser-globals": "^1.0.9",
  753 + "object.assign": "^4.1.0",
  754 + "object.entries": "^1.1.1"
  755 + }
  756 + },
  757 + "eslint-import-resolver-node": {
  758 + "version": "0.3.3",
  759 + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz",
  760 + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==",
  761 + "dev": true,
  762 + "requires": {
  763 + "debug": "^2.6.9",
  764 + "resolve": "^1.13.1"
  765 + },
  766 + "dependencies": {
  767 + "debug": {
  768 + "version": "2.6.9",
  769 + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
  770 + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
  771 + "dev": true,
  772 + "requires": {
  773 + "ms": "2.0.0"
  774 + }
  775 + },
  776 + "ms": {
  777 + "version": "2.0.0",
  778 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
  779 + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
  780 + "dev": true
  781 + }
  782 + }
  783 + },
  784 + "eslint-module-utils": {
  785 + "version": "2.6.0",
  786 + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz",
  787 + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==",
  788 + "dev": true,
  789 + "requires": {
  790 + "debug": "^2.6.9",
  791 + "pkg-dir": "^2.0.0"
  792 + },
  793 + "dependencies": {
  794 + "debug": {
  795 + "version": "2.6.9",
  796 + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
  797 + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
  798 + "dev": true,
  799 + "requires": {
  800 + "ms": "2.0.0"
  801 + }
  802 + },
  803 + "ms": {
  804 + "version": "2.0.0",
  805 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
  806 + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
  807 + "dev": true
  808 + }
  809 + }
  810 + },
  811 + "eslint-plugin-import": {
  812 + "version": "2.20.2",
  813 + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.2.tgz",
  814 + "integrity": "sha512-FObidqpXrR8OnCh4iNsxy+WACztJLXAHBO5hK79T1Hc77PgQZkyDGA5Ag9xAvRpglvLNxhH/zSmZ70/pZ31dHg==",
  815 + "dev": true,
  816 + "requires": {
  817 + "array-includes": "^3.0.3",
  818 + "array.prototype.flat": "^1.2.1",
  819 + "contains-path": "^0.1.0",
  820 + "debug": "^2.6.9",
  821 + "doctrine": "1.5.0",
  822 + "eslint-import-resolver-node": "^0.3.2",
  823 + "eslint-module-utils": "^2.4.1",
  824 + "has": "^1.0.3",
  825 + "minimatch": "^3.0.4",
  826 + "object.values": "^1.1.0",
  827 + "read-pkg-up": "^2.0.0",
  828 + "resolve": "^1.12.0"
  829 + },
  830 + "dependencies": {
  831 + "debug": {
  832 + "version": "2.6.9",
  833 + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
  834 + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
  835 + "dev": true,
  836 + "requires": {
  837 + "ms": "2.0.0"
  838 + }
  839 + },
  840 + "doctrine": {
  841 + "version": "1.5.0",
  842 + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
  843 + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
  844 + "dev": true,
  845 + "requires": {
  846 + "esutils": "^2.0.2",
  847 + "isarray": "^1.0.0"
  848 + }
  849 + },
  850 + "ms": {
  851 + "version": "2.0.0",
  852 + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
  853 + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
  854 + "dev": true
  855 + }
  856 + }
  857 + },
651 858 "eslint-scope": {
652 859 "version": "5.0.0",
653 860 "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz",
... ... @@ -691,12 +898,20 @@
691 898 "dev": true
692 899 },
693 900 "esquery": {
694   - "version": "1.1.0",
695   - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz",
696   - "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==",
  901 + "version": "1.3.1",
  902 + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz",
  903 + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==",
697 904 "dev": true,
698 905 "requires": {
699   - "estraverse": "^4.0.0"
  906 + "estraverse": "^5.1.0"
  907 + },
  908 + "dependencies": {
  909 + "estraverse": {
  910 + "version": "5.1.0",
  911 + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz",
  912 + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==",
  913 + "dev": true
  914 + }
700 915 }
701 916 },
702 917 "esrecurse": {
... ... @@ -928,6 +1143,15 @@
928 1143 }
929 1144 }
930 1145 },
  1146 + "find-up": {
  1147 + "version": "2.1.0",
  1148 + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
  1149 + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
  1150 + "dev": true,
  1151 + "requires": {
  1152 + "locate-path": "^2.0.0"
  1153 + }
  1154 + },
931 1155 "flat-cache": {
932 1156 "version": "2.0.1",
933 1157 "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
... ... @@ -940,9 +1164,9 @@
940 1164 }
941 1165 },
942 1166 "flatted": {
943   - "version": "2.0.1",
944   - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz",
945   - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==",
  1167 + "version": "2.0.2",
  1168 + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
  1169 + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
946 1170 "dev": true
947 1171 },
948 1172 "forever-agent": {
... ... @@ -989,6 +1213,12 @@
989 1213 "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==",
990 1214 "optional": true
991 1215 },
  1216 + "function-bind": {
  1217 + "version": "1.1.1",
  1218 + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
  1219 + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
  1220 + "dev": true
  1221 + },
992 1222 "functional-red-black-tree": {
993 1223 "version": "1.0.1",
994 1224 "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
... ... @@ -1033,6 +1263,12 @@
1033 1263 "type-fest": "^0.8.1"
1034 1264 }
1035 1265 },
  1266 + "graceful-fs": {
  1267 + "version": "4.2.4",
  1268 + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz",
  1269 + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==",
  1270 + "dev": true
  1271 + },
1036 1272 "har-schema": {
1037 1273 "version": "2.0.0",
1038 1274 "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
... ... @@ -1047,12 +1283,33 @@
1047 1283 "har-schema": "^2.0.0"
1048 1284 }
1049 1285 },
  1286 + "has": {
  1287 + "version": "1.0.3",
  1288 + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
  1289 + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
  1290 + "dev": true,
  1291 + "requires": {
  1292 + "function-bind": "^1.1.1"
  1293 + }
  1294 + },
1050 1295 "has-flag": {
1051 1296 "version": "3.0.0",
1052 1297 "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
1053 1298 "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
1054 1299 "dev": true
1055 1300 },
  1301 + "has-symbols": {
  1302 + "version": "1.0.1",
  1303 + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
  1304 + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==",
  1305 + "dev": true
  1306 + },
  1307 + "hosted-git-info": {
  1308 + "version": "2.8.8",
  1309 + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
  1310 + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
  1311 + "dev": true
  1312 + },
1056 1313 "http-errors": {
1057 1314 "version": "1.7.2",
1058 1315 "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
... ... @@ -1227,6 +1484,18 @@
1227 1484 "binary-extensions": "^2.0.0"
1228 1485 }
1229 1486 },
  1487 + "is-callable": {
  1488 + "version": "1.1.5",
  1489 + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz",
  1490 + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==",
  1491 + "dev": true
  1492 + },
  1493 + "is-date-object": {
  1494 + "version": "1.0.2",
  1495 + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz",
  1496 + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==",
  1497 + "dev": true
  1498 + },
1230 1499 "is-extglob": {
1231 1500 "version": "2.1.1",
1232 1501 "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
... ... @@ -1252,17 +1521,35 @@
1252 1521 "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
1253 1522 "optional": true
1254 1523 },
1255   - "is-promise": {
1256   - "version": "2.1.0",
1257   - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
1258   - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
1259   - "dev": true
  1524 + "is-regex": {
  1525 + "version": "1.0.5",
  1526 + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz",
  1527 + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==",
  1528 + "dev": true,
  1529 + "requires": {
  1530 + "has": "^1.0.3"
  1531 + }
1260 1532 },
1261 1533 "is-stream": {
1262 1534 "version": "1.1.0",
1263 1535 "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
1264 1536 "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
1265 1537 },
  1538 + "is-string": {
  1539 + "version": "1.0.5",
  1540 + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz",
  1541 + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==",
  1542 + "dev": true
  1543 + },
  1544 + "is-symbol": {
  1545 + "version": "1.0.3",
  1546 + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz",
  1547 + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==",
  1548 + "dev": true,
  1549 + "requires": {
  1550 + "has-symbols": "^1.0.1"
  1551 + }
  1552 + },
1266 1553 "is-typedarray": {
1267 1554 "version": "1.0.0",
1268 1555 "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
... ... @@ -1371,7 +1658,7 @@
1371 1658 "node-machine-id": "^1.1.10",
1372 1659 "node-natural-sort": "^0.8.6",
1373 1660 "numeral": "^2.0.6",
1374   - "nunjucks": "^3.2.0",
  1661 + "nunjucks": "^3.2.1",
1375 1662 "pkginfo": "^0.4.1",
1376 1663 "redis": "^2.8.0",
1377 1664 "request": "^2.88.0",
... ... @@ -1404,6 +1691,28 @@
1404 1691 "type-check": "~0.3.2"
1405 1692 }
1406 1693 },
  1694 + "load-json-file": {
  1695 + "version": "2.0.0",
  1696 + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
  1697 + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
  1698 + "dev": true,
  1699 + "requires": {
  1700 + "graceful-fs": "^4.1.2",
  1701 + "parse-json": "^2.2.0",
  1702 + "pify": "^2.0.0",
  1703 + "strip-bom": "^3.0.0"
  1704 + }
  1705 + },
  1706 + "locate-path": {
  1707 + "version": "2.0.0",
  1708 + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
  1709 + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
  1710 + "dev": true,
  1711 + "requires": {
  1712 + "p-locate": "^2.0.0",
  1713 + "path-exists": "^3.0.0"
  1714 + }
  1715 + },
1407 1716 "lodash": {
1408 1717 "version": "4.17.15",
1409 1718 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
... ... @@ -1489,9 +1798,9 @@
1489 1798 "dev": true
1490 1799 },
1491 1800 "mkdirp": {
1492   - "version": "0.5.3",
1493   - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.3.tgz",
1494   - "integrity": "sha512-P+2gwrFqx8lhew375MQHHeTlY8AuOJSrGf0R5ddkEndUkmwpgUob/vQuBD1V22/Cw1/lJr4x+EjllSezBThzBg==",
  1801 + "version": "0.5.5",
  1802 + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz",
  1803 + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==",
1495 1804 "dev": true,
1496 1805 "requires": {
1497 1806 "minimist": "^1.2.5"
... ... @@ -1550,6 +1859,26 @@
1550 1859 "resolved": "https://registry.npmjs.org/node-natural-sort/-/node-natural-sort-0.8.7.tgz",
1551 1860 "integrity": "sha512-rMaLlHV5BlnRhIl6jUfgqdLY5U0NJkIxUdOsmpz3Txwh7js4+GwTiomhO8W4rp3SvX1zZ56mx13zfEWESr+qqA=="
1552 1861 },
  1862 + "normalize-package-data": {
  1863 + "version": "2.5.0",
  1864 + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
  1865 + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
  1866 + "dev": true,
  1867 + "requires": {
  1868 + "hosted-git-info": "^2.1.4",
  1869 + "resolve": "^1.10.0",
  1870 + "semver": "2 || 3 || 4 || 5",
  1871 + "validate-npm-package-license": "^3.0.1"
  1872 + },
  1873 + "dependencies": {
  1874 + "semver": {
  1875 + "version": "5.7.1",
  1876 + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
  1877 + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
  1878 + "dev": true
  1879 + }
  1880 + }
  1881 + },
1553 1882 "normalize-path": {
1554 1883 "version": "3.0.0",
1555 1884 "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
... ... @@ -1589,6 +1918,54 @@
1589 1918 "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-1.3.1.tgz",
1590 1919 "integrity": "sha512-OSuu/pU4ENM9kmREg0BdNrUDIl1heYa4mBZacJc+vVWz4GtAwu7jO8s4AIt2aGRUTqxykpWzI3Oqnsm13tTMDA=="
1591 1920 },
  1921 + "object-inspect": {
  1922 + "version": "1.7.0",
  1923 + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz",
  1924 + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==",
  1925 + "dev": true
  1926 + },
  1927 + "object-keys": {
  1928 + "version": "1.1.1",
  1929 + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz",
  1930 + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==",
  1931 + "dev": true
  1932 + },
  1933 + "object.assign": {
  1934 + "version": "4.1.0",
  1935 + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
  1936 + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
  1937 + "dev": true,
  1938 + "requires": {
  1939 + "define-properties": "^1.1.2",
  1940 + "function-bind": "^1.1.1",
  1941 + "has-symbols": "^1.0.0",
  1942 + "object-keys": "^1.0.11"
  1943 + }
  1944 + },
  1945 + "object.entries": {
  1946 + "version": "1.1.1",
  1947 + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz",
  1948 + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==",
  1949 + "dev": true,
  1950 + "requires": {
  1951 + "define-properties": "^1.1.3",
  1952 + "es-abstract": "^1.17.0-next.1",
  1953 + "function-bind": "^1.1.1",
  1954 + "has": "^1.0.3"
  1955 + }
  1956 + },
  1957 + "object.values": {
  1958 + "version": "1.1.1",
  1959 + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz",
  1960 + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==",
  1961 + "dev": true,
  1962 + "requires": {
  1963 + "define-properties": "^1.1.3",
  1964 + "es-abstract": "^1.17.0-next.1",
  1965 + "function-bind": "^1.1.1",
  1966 + "has": "^1.0.3"
  1967 + }
  1968 + },
1592 1969 "on-finished": {
1593 1970 "version": "2.3.0",
1594 1971 "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
... ... @@ -1644,6 +2021,30 @@
1644 2021 "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
1645 2022 "dev": true
1646 2023 },
  2024 + "p-limit": {
  2025 + "version": "1.3.0",
  2026 + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
  2027 + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
  2028 + "dev": true,
  2029 + "requires": {
  2030 + "p-try": "^1.0.0"
  2031 + }
  2032 + },
  2033 + "p-locate": {
  2034 + "version": "2.0.0",
  2035 + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
  2036 + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
  2037 + "dev": true,
  2038 + "requires": {
  2039 + "p-limit": "^1.1.0"
  2040 + }
  2041 + },
  2042 + "p-try": {
  2043 + "version": "1.0.0",
  2044 + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
  2045 + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
  2046 + "dev": true
  2047 + },
1647 2048 "parent-module": {
1648 2049 "version": "1.0.1",
1649 2050 "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
... ... @@ -1653,11 +2054,26 @@
1653 2054 "callsites": "^3.0.0"
1654 2055 }
1655 2056 },
  2057 + "parse-json": {
  2058 + "version": "2.2.0",
  2059 + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
  2060 + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
  2061 + "dev": true,
  2062 + "requires": {
  2063 + "error-ex": "^1.2.0"
  2064 + }
  2065 + },
1656 2066 "parseurl": {
1657 2067 "version": "1.3.3",
1658 2068 "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
1659 2069 "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
1660 2070 },
  2071 + "path-exists": {
  2072 + "version": "3.0.0",
  2073 + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
  2074 + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
  2075 + "dev": true
  2076 + },
1661 2077 "path-is-absolute": {
1662 2078 "version": "1.0.1",
1663 2079 "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
... ... @@ -1669,11 +2085,26 @@
1669 2085 "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
1670 2086 "dev": true
1671 2087 },
  2088 + "path-parse": {
  2089 + "version": "1.0.6",
  2090 + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
  2091 + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
  2092 + "dev": true
  2093 + },
1672 2094 "path-to-regexp": {
1673 2095 "version": "0.1.7",
1674 2096 "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
1675 2097 "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
1676 2098 },
  2099 + "path-type": {
  2100 + "version": "2.0.0",
  2101 + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
  2102 + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
  2103 + "dev": true,
  2104 + "requires": {
  2105 + "pify": "^2.0.0"
  2106 + }
  2107 + },
1677 2108 "performance-now": {
1678 2109 "version": "2.1.0",
1679 2110 "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
... ... @@ -1685,11 +2116,26 @@
1685 2116 "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
1686 2117 "optional": true
1687 2118 },
  2119 + "pify": {
  2120 + "version": "2.3.0",
  2121 + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
  2122 + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
  2123 + "dev": true
  2124 + },
1688 2125 "pipe-io": {
1689 2126 "version": "3.0.12",
1690 2127 "resolved": "https://registry.npmjs.org/pipe-io/-/pipe-io-3.0.12.tgz",
1691 2128 "integrity": "sha512-reR49NtpkVgedzCQ9DPV727VAZKw8Ax3N/3iQwD1vHxTmswsuhurFh0Z5woVNM1OhHDigKzDN7u4kNipAA9yyA=="
1692 2129 },
  2130 + "pkg-dir": {
  2131 + "version": "2.0.0",
  2132 + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
  2133 + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
  2134 + "dev": true,
  2135 + "requires": {
  2136 + "find-up": "^2.1.0"
  2137 + }
  2138 + },
1693 2139 "pkginfo": {
1694 2140 "version": "0.4.1",
1695 2141 "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz",
... ... @@ -1762,6 +2208,27 @@
1762 2208 "unpipe": "1.0.0"
1763 2209 }
1764 2210 },
  2211 + "read-pkg": {
  2212 + "version": "2.0.0",
  2213 + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
  2214 + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
  2215 + "dev": true,
  2216 + "requires": {
  2217 + "load-json-file": "^2.0.0",
  2218 + "normalize-package-data": "^2.3.2",
  2219 + "path-type": "^2.0.0"
  2220 + }
  2221 + },
  2222 + "read-pkg-up": {
  2223 + "version": "2.0.0",
  2224 + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
  2225 + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
  2226 + "dev": true,
  2227 + "requires": {
  2228 + "find-up": "^2.0.0",
  2229 + "read-pkg": "^2.0.0"
  2230 + }
  2231 + },
1765 2232 "readable-stream": {
1766 2233 "version": "3.6.0",
1767 2234 "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
... ... @@ -1841,6 +2308,15 @@
1841 2308 }
1842 2309 }
1843 2310 },
  2311 + "resolve": {
  2312 + "version": "1.17.0",
  2313 + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
  2314 + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
  2315 + "dev": true,
  2316 + "requires": {
  2317 + "path-parse": "^1.0.6"
  2318 + }
  2319 + },
1844 2320 "resolve-from": {
1845 2321 "version": "4.0.0",
1846 2322 "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
... ... @@ -1867,18 +2343,15 @@
1867 2343 }
1868 2344 },
1869 2345 "run-async": {
1870   - "version": "2.4.0",
1871   - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz",
1872   - "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==",
1873   - "dev": true,
1874   - "requires": {
1875   - "is-promise": "^2.1.0"
1876   - }
  2346 + "version": "2.4.1",
  2347 + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
  2348 + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
  2349 + "dev": true
1877 2350 },
1878 2351 "rxjs": {
1879   - "version": "6.5.4",
1880   - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz",
1881   - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==",
  2352 + "version": "6.5.5",
  2353 + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz",
  2354 + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==",
1882 2355 "dev": true,
1883 2356 "requires": {
1884 2357 "tslib": "^1.9.0"
... ... @@ -1987,9 +2460,9 @@
1987 2460 "dev": true
1988 2461 },
1989 2462 "signal-exit": {
1990   - "version": "3.0.2",
1991   - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
1992   - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
  2463 + "version": "3.0.3",
  2464 + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz",
  2465 + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==",
1993 2466 "dev": true
1994 2467 },
1995 2468 "simple-git": {
... ... @@ -2027,6 +2500,38 @@
2027 2500 }
2028 2501 }
2029 2502 },
  2503 + "spdx-correct": {
  2504 + "version": "3.1.0",
  2505 + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
  2506 + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
  2507 + "dev": true,
  2508 + "requires": {
  2509 + "spdx-expression-parse": "^3.0.0",
  2510 + "spdx-license-ids": "^3.0.0"
  2511 + }
  2512 + },
  2513 + "spdx-exceptions": {
  2514 + "version": "2.3.0",
  2515 + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
  2516 + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==",
  2517 + "dev": true
  2518 + },
  2519 + "spdx-expression-parse": {
  2520 + "version": "3.0.0",
  2521 + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
  2522 + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
  2523 + "dev": true,
  2524 + "requires": {
  2525 + "spdx-exceptions": "^2.1.0",
  2526 + "spdx-license-ids": "^3.0.0"
  2527 + }
  2528 + },
  2529 + "spdx-license-ids": {
  2530 + "version": "3.0.5",
  2531 + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz",
  2532 + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==",
  2533 + "dev": true
  2534 + },
2030 2535 "sprintf-js": {
2031 2536 "version": "1.0.3",
2032 2537 "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
... ... @@ -2091,6 +2596,48 @@
2091 2596 }
2092 2597 }
2093 2598 },
  2599 + "string.prototype.trimend": {
  2600 + "version": "1.0.1",
  2601 + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz",
  2602 + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==",
  2603 + "dev": true,
  2604 + "requires": {
  2605 + "define-properties": "^1.1.3",
  2606 + "es-abstract": "^1.17.5"
  2607 + }
  2608 + },
  2609 + "string.prototype.trimleft": {
  2610 + "version": "2.1.2",
  2611 + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz",
  2612 + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==",
  2613 + "dev": true,
  2614 + "requires": {
  2615 + "define-properties": "^1.1.3",
  2616 + "es-abstract": "^1.17.5",
  2617 + "string.prototype.trimstart": "^1.0.0"
  2618 + }
  2619 + },
  2620 + "string.prototype.trimright": {
  2621 + "version": "2.1.2",
  2622 + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz",
  2623 + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==",
  2624 + "dev": true,
  2625 + "requires": {
  2626 + "define-properties": "^1.1.3",
  2627 + "es-abstract": "^1.17.5",
  2628 + "string.prototype.trimend": "^1.0.0"
  2629 + }
  2630 + },
  2631 + "string.prototype.trimstart": {
  2632 + "version": "1.0.1",
  2633 + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz",
  2634 + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==",
  2635 + "dev": true,
  2636 + "requires": {
  2637 + "define-properties": "^1.1.3",
  2638 + "es-abstract": "^1.17.5"
  2639 + }
  2640 + },
2094 2641 "string_decoder": {
2095 2642 "version": "1.3.0",
2096 2643 "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
... ... @@ -2123,10 +2670,16 @@
2123 2670 }
2124 2671 }
2125 2672 },
  2673 + "strip-bom": {
  2674 + "version": "3.0.0",
  2675 + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
  2676 + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
  2677 + "dev": true
  2678 + },
2126 2679 "strip-json-comments": {
2127   - "version": "3.0.1",
2128   - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
2129   - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
  2680 + "version": "3.1.0",
  2681 + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz",
  2682 + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==",
2130 2683 "dev": true
2131 2684 },
2132 2685 "supports-color": {
... ... @@ -2355,6 +2908,16 @@
2355 2908 "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==",
2356 2909 "dev": true
2357 2910 },
  2911 + "validate-npm-package-license": {
  2912 + "version": "3.0.4",
  2913 + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
  2914 + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
  2915 + "dev": true,
  2916 + "requires": {
  2917 + "spdx-correct": "^3.0.0",
  2918 + "spdx-expression-parse": "^3.0.0"
  2919 + }
  2920 + },
2358 2921 "vary": {
2359 2922 "version": "1.1.2",
2360 2923 "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
... ... @@ -20,7 +20,9 @@
20 20 "author": "Adhidarma Hadiwinoto <me@adhisimon.org>",
21 21 "license": "ISC",
22 22 "devDependencies": {
23   - "eslint": "^6.8.0"
  23 + "eslint": "^6.8.0",
  24 + "eslint-config-airbnb-base": "^14.1.0",
  25 + "eslint-plugin-import": "^2.20.2"
24 26 },
25 27 "dependencies": {
26 28 "custom-truncate": "^0.9.1",