├── .eslintignore ├── .eslintrc.js ├── .gitattributes ├── .gitignore ├── .travis.yml ├── CHANGES.md ├── LICENSE.md ├── NOTICE.md ├── README.md ├── examples ├── javascript.js └── typescript.ts ├── package-lock.json ├── package.json ├── src ├── cloudflare.ts ├── error.ts ├── ip.ts ├── main.ts ├── options.ts ├── request.ts └── utils.ts ├── test ├── src │ └── main.ts └── tsconfig.json └── tsconfig.json /.eslintignore: -------------------------------------------------------------------------------- 1 | examples 2 | node_modules 3 | lib 4 | docs 5 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2020 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | "use strict"; 18 | 19 | module.exports = { 20 | env: { 21 | node: true 22 | }, 23 | root: true, 24 | parser: '@typescript-eslint/parser', 25 | plugins: [ 26 | '@typescript-eslint' 27 | ], 28 | extends: [ 29 | 'eslint:recommended', 30 | 'plugin:@typescript-eslint/eslint-recommended', 31 | 'plugin:@typescript-eslint/recommended' 32 | ], 33 | rules: { 34 | // Maximum line length of 80 35 | 'max-len': ['error', {'code': 80}], 36 | 37 | // Too late to change this, since interfaces are part of the public API 38 | '@typescript-eslint/interface-name-prefix': 0, 39 | 40 | // Too much noise 41 | '@typescript-eslint/explicit-function-return-type': 0, 42 | 43 | // Allow private functions at bottom of file 44 | '@typescript-eslint/no-use-before-define': 0, 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # WebStorm 2 | .idea/ 3 | 4 | # JavaScript and TypeScript 5 | lib/ 6 | test/lib/ 7 | 8 | # Documentation 9 | docs/ 10 | 11 | # Node.js 12 | node_modules/ 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - node 4 | - 8 5 | - 10 6 | install: 7 | - npm install 8 | script: npm run-script build 9 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | ## 1.0.2 ## 2 | 3 | * Update dependencies 4 | * Use ESLint instead of TSLint 5 | * Use npm instead of gulp 6 | 7 | ## 1.0.1 ## 8 | 9 | * Bug fixes 10 | 11 | ## 1.0.0 ## 12 | 13 | * Re-write in TypeScript 14 | * Add support for Cloudflare v4 API 15 | * Change options structure 16 | 17 | ## 0.1.1 ## 18 | 19 | * Fixed error in documentation 20 | 21 | ## 0.1.0 ## 22 | 23 | * Initial release 24 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | Apache License 2 | ============== 3 | 4 | _Version 2.0, January 2004_ 5 | _<>_ 6 | 7 | ### Terms and Conditions for use, reproduction, and distribution 8 | 9 | #### 1. Definitions 10 | 11 | “License” shall mean the terms and conditions for use, reproduction, and 12 | distribution as defined by Sections 1 through 9 of this document. 13 | 14 | “Licensor” shall mean the copyright owner or entity authorized by the copyright 15 | owner that is granting the License. 16 | 17 | “Legal Entity” shall mean the union of the acting entity and all other entities 18 | that control, are controlled by, or are under common control with that entity. 19 | For the purposes of this definition, “control” means **(i)** the power, direct or 20 | indirect, to cause the direction or management of such entity, whether by 21 | contract or otherwise, or **(ii)** ownership of fifty percent (50%) or more of the 22 | outstanding shares, or **(iii)** beneficial ownership of such entity. 23 | 24 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 25 | permissions granted by this License. 26 | 27 | “Source” form shall mean the preferred form for making modifications, including 28 | but not limited to software source code, documentation source, and configuration 29 | files. 30 | 31 | “Object” form shall mean any form resulting from mechanical transformation or 32 | translation of a Source form, including but not limited to compiled object code, 33 | generated documentation, and conversions to other media types. 34 | 35 | “Work” shall mean the work of authorship, whether in Source or Object form, made 36 | available under the License, as indicated by a copyright notice that is included 37 | in or attached to the work (an example is provided in the Appendix below). 38 | 39 | “Derivative Works” shall mean any work, whether in Source or Object form, that 40 | is based on (or derived from) the Work and for which the editorial revisions, 41 | annotations, elaborations, or other modifications represent, as a whole, an 42 | original work of authorship. For the purposes of this License, Derivative Works 43 | shall not include works that remain separable from, or merely link (or bind by 44 | name) to the interfaces of, the Work and Derivative Works thereof. 45 | 46 | “Contribution” shall mean any work of authorship, including the original version 47 | of the Work and any modifications or additions to that Work or Derivative Works 48 | thereof, that is intentionally submitted to Licensor for inclusion in the Work 49 | by the copyright owner or by an individual or Legal Entity authorized to submit 50 | on behalf of the copyright owner. For the purposes of this definition, 51 | “submitted” means any form of electronic, verbal, or written communication sent 52 | to the Licensor or its representatives, including but not limited to 53 | communication on electronic mailing lists, source code control systems, and 54 | issue tracking systems that are managed by, or on behalf of, the Licensor for 55 | the purpose of discussing and improving the Work, but excluding communication 56 | that is conspicuously marked or otherwise designated in writing by the copyright 57 | owner as “Not a Contribution.” 58 | 59 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 60 | of whom a Contribution has been received by Licensor and subsequently 61 | incorporated within the Work. 62 | 63 | #### 2. Grant of Copyright License 64 | 65 | Subject to the terms and conditions of this License, each Contributor hereby 66 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 67 | irrevocable copyright license to reproduce, prepare Derivative Works of, 68 | publicly display, publicly perform, sublicense, and distribute the Work and such 69 | Derivative Works in Source or Object form. 70 | 71 | #### 3. Grant of Patent License 72 | 73 | Subject to the terms and conditions of this License, each Contributor hereby 74 | grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, 75 | irrevocable (except as stated in this section) patent license to make, have 76 | made, use, offer to sell, sell, import, and otherwise transfer the Work, where 77 | such license applies only to those patent claims licensable by such Contributor 78 | that are necessarily infringed by their Contribution(s) alone or by combination 79 | of their Contribution(s) with the Work to which such Contribution(s) was 80 | submitted. If You institute patent litigation against any entity (including a 81 | cross-claim or counterclaim in a lawsuit) alleging that the Work or a 82 | Contribution incorporated within the Work constitutes direct or contributory 83 | patent infringement, then any patent licenses granted to You under this License 84 | for that Work shall terminate as of the date such litigation is filed. 85 | 86 | #### 4. Redistribution 87 | 88 | You may reproduce and distribute copies of the Work or Derivative Works thereof 89 | in any medium, with or without modifications, and in Source or Object form, 90 | provided that You meet the following conditions: 91 | 92 | * **(a)** You must give any other recipients of the Work or Derivative Works a copy of 93 | this License; and 94 | * **(b)** You must cause any modified files to carry prominent notices stating that You 95 | changed the files; and 96 | * **(c)** You must retain, in the Source form of any Derivative Works that You distribute, 97 | all copyright, patent, trademark, and attribution notices from the Source form 98 | of the Work, excluding those notices that do not pertain to any part of the 99 | Derivative Works; and 100 | * **(d)** If the Work includes a “NOTICE” text file as part of its distribution, then any 101 | Derivative Works that You distribute must include a readable copy of the 102 | attribution notices contained within such NOTICE file, excluding those notices 103 | that do not pertain to any part of the Derivative Works, in at least one of the 104 | following places: within a NOTICE text file distributed as part of the 105 | Derivative Works; within the Source form or documentation, if provided along 106 | with the Derivative Works; or, within a display generated by the Derivative 107 | Works, if and wherever such third-party notices normally appear. The contents of 108 | the NOTICE file are for informational purposes only and do not modify the 109 | License. You may add Your own attribution notices within Derivative Works that 110 | You distribute, alongside or as an addendum to the NOTICE text from the Work, 111 | provided that such additional attribution notices cannot be construed as 112 | modifying the License. 113 | 114 | You may add Your own copyright statement to Your modifications and may provide 115 | additional or different license terms and conditions for use, reproduction, or 116 | distribution of Your modifications, or for any such Derivative Works as a whole, 117 | provided Your use, reproduction, and distribution of the Work otherwise complies 118 | with the conditions stated in this License. 119 | 120 | #### 5. Submission of Contributions 121 | 122 | Unless You explicitly state otherwise, any Contribution intentionally submitted 123 | for inclusion in the Work by You to the Licensor shall be under the terms and 124 | conditions of this License, without any additional terms or conditions. 125 | Notwithstanding the above, nothing herein shall supersede or modify the terms of 126 | any separate license agreement you may have executed with Licensor regarding 127 | such Contributions. 128 | 129 | #### 6. Trademarks 130 | 131 | This License does not grant permission to use the trade names, trademarks, 132 | service marks, or product names of the Licensor, except as required for 133 | reasonable and customary use in describing the origin of the Work and 134 | reproducing the content of the NOTICE file. 135 | 136 | #### 7. Disclaimer of Warranty 137 | 138 | Unless required by applicable law or agreed to in writing, Licensor provides the 139 | Work (and each Contributor provides its Contributions) on an “AS IS” BASIS, 140 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, 141 | including, without limitation, any warranties or conditions of TITLE, 142 | NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are 143 | solely responsible for determining the appropriateness of using or 144 | redistributing the Work and assume any risks associated with Your exercise of 145 | permissions under this License. 146 | 147 | #### 8. Limitation of Liability 148 | 149 | In no event and under no legal theory, whether in tort (including negligence), 150 | contract, or otherwise, unless required by applicable law (such as deliberate 151 | and grossly negligent acts) or agreed to in writing, shall any Contributor be 152 | liable to You for damages, including any direct, indirect, special, incidental, 153 | or consequential damages of any character arising as a result of this License or 154 | out of the use or inability to use the Work (including but not limited to 155 | damages for loss of goodwill, work stoppage, computer failure or malfunction, or 156 | any and all other commercial damages or losses), even if such Contributor has 157 | been advised of the possibility of such damages. 158 | 159 | #### 9. Accepting Warranty or Additional Liability 160 | 161 | While redistributing the Work or Derivative Works thereof, You may choose to 162 | offer, and charge a fee for, acceptance of support, warranty, indemnity, or 163 | other liability obligations and/or rights consistent with this License. However, 164 | in accepting such obligations, You may act only on Your own behalf and on Your 165 | sole responsibility, not on behalf of any other Contributor, and only if You 166 | agree to indemnify, defend, and hold each Contributor harmless for any liability 167 | incurred by, or claims asserted against, such Contributor by reason of your 168 | accepting any such warranty or additional liability. 169 | 170 | _END OF TERMS AND CONDITIONS_ 171 | 172 | ### APPENDIX: How to apply the Apache License to your work 173 | 174 | To apply the Apache License to your work, attach the following boilerplate 175 | notice, with the fields enclosed by brackets `[]` replaced with your own 176 | identifying information. (Don't include the brackets!) The text should be 177 | enclosed in the appropriate comment syntax for the file format. We also 178 | recommend that a file or class name and description of purpose be included on 179 | the same “printed page” as the copyright notice for easier identification within 180 | third-party archives. 181 | 182 | Copyright [yyyy] [name of copyright owner] 183 | 184 | Licensed under the Apache License, Version 2.0 (the "License"); 185 | you may not use this file except in compliance with the License. 186 | You may obtain a copy of the License at 187 | 188 | http://www.apache.org/licenses/LICENSE-2.0 189 | 190 | Unless required by applicable law or agreed to in writing, software 191 | distributed under the License is distributed on an "AS IS" BASIS, 192 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 193 | See the License for the specific language governing permissions and 194 | limitations under the License. 195 | -------------------------------------------------------------------------------- /NOTICE.md: -------------------------------------------------------------------------------- 1 | cloudflare-dynamic-dns 2 | Copyright (C) 2014-2020 Michael Kourlas 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # cloudflare-dynamic-dns # 2 | 3 | [![Build Status](https://travis-ci.org/michaelkourlas/node-cloudflare-dynamic-dns.svg?branch=master)](https://travis-ci.org/michaelkourlas/node-cloudflare-dynamic-dns) 4 | [![npm version](https://badge.fury.io/js/cloudflare-dynamic-dns.svg)](https://badge.fury.io/js/cloudflare-dynamic-dns) 5 | 6 | ## Overview ## 7 | 8 | cloudflare-dynamic-dns is a Node.js module that updates a particular Cloudflare 9 | DNS record with an IP address, creating it if it does not exist. 10 | 11 | ## Installation ## 12 | 13 | The easiest way to install cloudflare-dynamic-dns is using npm: 14 | 15 | ``` 16 | npm install cloudflare-dynamic-dns 17 | ``` 18 | 19 | You can also build cloudflare-dynamic-dns from source using npm: 20 | 21 | ``` 22 | git clone https://github.com/michaelkourlas/node-cloudflare-dynamic-dns.git 23 | npm install 24 | npm run-script build 25 | ``` 26 | 27 | The `build` script will build the production variant of 28 | cloudflare-dynamic-dns, run all tests, and build the documentation. 29 | 30 | You can build the production variant without running tests using the script 31 | `prod`. You can also build the development version using the script `dev`. 32 | The only difference between the two is that the development version includes 33 | source maps. 34 | 35 | ## Usage ## 36 | 37 | The documentation for the current version is available [here](http://www.kourlas.com/node-cloudflare-dynamic-dns/docs/1.0.2/). 38 | 39 | You can also build the documentation using npm: 40 | 41 | ``` 42 | npm run-script docs 43 | ``` 44 | 45 | ## Examples ## 46 | 47 | The following example illustrates the basic usage of cloudflare-dynamic-dns: 48 | 49 | ```javascript 50 | var ddns = require("cloudflare-dynamic-dns"); 51 | 52 | var options = { 53 | auth: { 54 | email: "", 55 | key: "" 56 | }, 57 | recordName: "foo.bar.com", 58 | zoneName: "bar.com" 59 | }; 60 | 61 | ddns.update(options, function(err) { 62 | if (err) { 63 | console.log("An error occurred:"); 64 | console.log(err); 65 | } else { 66 | console.log("Success!"); 67 | } 68 | }); 69 | ``` 70 | 71 | Additional examples can be found in the examples directory. 72 | 73 | ## Tests ## 74 | 75 | cloudflare-dynamic-dns includes a set of tests to verify core functionality. 76 | You can run the tests using npm: 77 | 78 | ``` 79 | npm run-script test-prod 80 | ``` 81 | 82 | The only difference between the `test-prod` and `test-dev` scripts is that the 83 | development version includes source maps. 84 | 85 | ## License ## 86 | 87 | cloudflare-dynamic-dns is licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0). 88 | Please see the LICENSE.md file for more information. 89 | -------------------------------------------------------------------------------- /examples/javascript.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2014-2019 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | "use strict"; 18 | 19 | var ddns = require("../lib/main"); 20 | 21 | /** 22 | * This example demonstrates the most common use of cloudflare-dynamic-dns, 23 | * which updates a CloudFlare DNS record with the external IP address of the 24 | * machine on which the module is running, as determined by the 25 | * myexternalip.com API. 26 | */ 27 | var example1 = function() { 28 | var options = { 29 | auth: { 30 | email: "", 31 | key: "" 32 | }, 33 | recordName: "foo.bar.com", 34 | zoneName: "bar.com" 35 | }; 36 | ddns.update(options, function(err, newIp) { 37 | if (err) { 38 | console.log("An error occurred:"); 39 | console.log(err); 40 | } else { 41 | console.log("Successfully changed IP to " + newIp + "!"); 42 | } 43 | }); 44 | }; 45 | example1(); 46 | 47 | /** 48 | * This example demonstrates the use of cloudflare-dynamic-dns with a manually 49 | * specified IP address. 50 | */ 51 | var example2 = function() { 52 | var options = { 53 | auth: { 54 | email: "", 55 | key: "" 56 | }, 57 | ip: "1.1.1.1", 58 | recordName: "foo.bar.com", 59 | zoneName: "bar.com" 60 | }; 61 | ddns.update(options, function(err, newIp) { 62 | if (err) { 63 | console.log("An error occurred:"); 64 | console.log(err); 65 | } else { 66 | console.log("Successfully changed IP to " + newIp + "!"); 67 | } 68 | }); 69 | }; 70 | example2(); 71 | 72 | 73 | -------------------------------------------------------------------------------- /examples/typescript.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2019 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {update} from "../lib/main"; 18 | 19 | /** 20 | * This example demonstrates the most common use of cloudflare-dynamic-dns, 21 | * which updates a CloudFlare DNS record with the external IP address of the 22 | * machine on which the module is running, as determined by the 23 | * myexternalip.com API. 24 | */ 25 | const example1 = () => { 26 | const options = { 27 | auth: { 28 | email: "", 29 | key: "" 30 | }, 31 | recordName: "foo.bar.com", 32 | zoneName: "bar.com" 33 | }; 34 | update(options, (err, newIp) => { 35 | if (err) { 36 | console.log("An error occurred:"); 37 | console.log(err); 38 | } else { 39 | console.log("Successfully changed IP to " + newIp + "!"); 40 | } 41 | }); 42 | }; 43 | example1(); 44 | 45 | /** 46 | * This example demonstrates the use of cloudflare-dynamic-dns with a manually 47 | * specified IP address. 48 | */ 49 | const example2 = () => { 50 | const options = { 51 | auth: { 52 | email: "", 53 | key: "" 54 | }, 55 | ip: "1.1.1.1", 56 | recordName: "foo.bar.com", 57 | zoneName: "bar.com" 58 | }; 59 | update(options, (err, newIp) => { 60 | if (err) { 61 | console.log("An error occurred:"); 62 | console.log(err); 63 | } else { 64 | console.log("Successfully changed IP to " + newIp + "!"); 65 | } 66 | }); 67 | }; 68 | example2(); 69 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-dynamic-dns", 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/highlight": { 17 | "version": "7.8.3", 18 | "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", 19 | "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", 20 | "dev": true, 21 | "requires": { 22 | "chalk": "^2.0.0", 23 | "esutils": "^2.0.2", 24 | "js-tokens": "^4.0.0" 25 | }, 26 | "dependencies": { 27 | "js-tokens": { 28 | "version": "4.0.0", 29 | "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", 30 | "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", 31 | "dev": true 32 | } 33 | } 34 | }, 35 | "@types/chai": { 36 | "version": "4.2.8", 37 | "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.8.tgz", 38 | "integrity": "sha512-U1bQiWbln41Yo6EeHMr+34aUhvrMVyrhn9lYfPSpLTCrZlGxU4Rtn1bocX+0p2Fc/Jkd2FanCEXdw0WNfHHM0w==", 39 | "dev": true 40 | }, 41 | "@types/eslint-visitor-keys": { 42 | "version": "1.0.0", 43 | "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", 44 | "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", 45 | "dev": true 46 | }, 47 | "@types/json-schema": { 48 | "version": "7.0.4", 49 | "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", 50 | "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", 51 | "dev": true 52 | }, 53 | "@types/minimatch": { 54 | "version": "3.0.3", 55 | "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", 56 | "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", 57 | "dev": true 58 | }, 59 | "@types/mocha": { 60 | "version": "7.0.1", 61 | "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.1.tgz", 62 | "integrity": "sha512-L/Nw/2e5KUaprNJoRA33oly+M8X8n0K+FwLTbYqwTcR14wdPWeRkigBLfSFpN/Asf9ENZTMZwLxjtjeYucAA4Q==", 63 | "dev": true 64 | }, 65 | "@types/node": { 66 | "version": "13.7.0", 67 | "resolved": "https://registry.npmjs.org/@types/node/-/node-13.7.0.tgz", 68 | "integrity": "sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==" 69 | }, 70 | "@typescript-eslint/eslint-plugin": { 71 | "version": "2.18.0", 72 | "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.18.0.tgz", 73 | "integrity": "sha512-kuO8WQjV+RCZvAXVRJfXWiJ8iYEtfHlKgcqqqXg9uUkIolEHuUaMmm8/lcO4xwCOtaw6mY0gStn2Lg4/eUXXYQ==", 74 | "dev": true, 75 | "requires": { 76 | "@typescript-eslint/experimental-utils": "2.18.0", 77 | "eslint-utils": "^1.4.3", 78 | "functional-red-black-tree": "^1.0.1", 79 | "regexpp": "^3.0.0", 80 | "tsutils": "^3.17.1" 81 | }, 82 | "dependencies": { 83 | "tsutils": { 84 | "version": "3.17.1", 85 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 86 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 87 | "dev": true, 88 | "requires": { 89 | "tslib": "^1.8.1" 90 | } 91 | } 92 | } 93 | }, 94 | "@typescript-eslint/experimental-utils": { 95 | "version": "2.18.0", 96 | "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.18.0.tgz", 97 | "integrity": "sha512-J6MopKPHuJYmQUkANLip7g9I82ZLe1naCbxZZW3O2sIxTiq/9YYoOELEKY7oPg0hJ0V/AQ225h2z0Yp+RRMXhw==", 98 | "dev": true, 99 | "requires": { 100 | "@types/json-schema": "^7.0.3", 101 | "@typescript-eslint/typescript-estree": "2.18.0", 102 | "eslint-scope": "^5.0.0" 103 | } 104 | }, 105 | "@typescript-eslint/parser": { 106 | "version": "2.18.0", 107 | "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.18.0.tgz", 108 | "integrity": "sha512-SJJPxFMEYEWkM6pGfcnjLU+NJIPo+Ko1QrCBL+i0+zV30ggLD90huEmMMhKLHBpESWy9lVEeWlQibweNQzyc+A==", 109 | "dev": true, 110 | "requires": { 111 | "@types/eslint-visitor-keys": "^1.0.0", 112 | "@typescript-eslint/experimental-utils": "2.18.0", 113 | "@typescript-eslint/typescript-estree": "2.18.0", 114 | "eslint-visitor-keys": "^1.1.0" 115 | } 116 | }, 117 | "@typescript-eslint/typescript-estree": { 118 | "version": "2.18.0", 119 | "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.18.0.tgz", 120 | "integrity": "sha512-gVHylf7FDb8VSi2ypFuEL3hOtoC4HkZZ5dOjXvVjoyKdRrvXAOPSzpNRnKMfaUUEiSLP8UF9j9X9EDLxC0lfZg==", 121 | "dev": true, 122 | "requires": { 123 | "debug": "^4.1.1", 124 | "eslint-visitor-keys": "^1.1.0", 125 | "glob": "^7.1.6", 126 | "is-glob": "^4.0.1", 127 | "lodash": "^4.17.15", 128 | "semver": "^6.3.0", 129 | "tsutils": "^3.17.1" 130 | }, 131 | "dependencies": { 132 | "is-glob": { 133 | "version": "4.0.1", 134 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 135 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 136 | "dev": true, 137 | "requires": { 138 | "is-extglob": "^2.1.1" 139 | } 140 | }, 141 | "tsutils": { 142 | "version": "3.17.1", 143 | "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", 144 | "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", 145 | "dev": true, 146 | "requires": { 147 | "tslib": "^1.8.1" 148 | } 149 | } 150 | } 151 | }, 152 | "acorn-jsx": { 153 | "version": "5.1.0", 154 | "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", 155 | "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", 156 | "dev": true 157 | }, 158 | "ajv": { 159 | "version": "6.11.0", 160 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.11.0.tgz", 161 | "integrity": "sha512-nCprB/0syFYy9fVYU1ox1l2KN8S9I+tziH8D4zdZuLT3N6RMlGSGt5FSTpAiHB/Whv8Qs1cWHma1aMKZyaHRKA==", 162 | "dev": true, 163 | "requires": { 164 | "fast-deep-equal": "^3.1.1", 165 | "fast-json-stable-stringify": "^2.0.0", 166 | "json-schema-traverse": "^0.4.1", 167 | "uri-js": "^4.2.2" 168 | } 169 | }, 170 | "ansi-escapes": { 171 | "version": "4.3.0", 172 | "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", 173 | "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", 174 | "dev": true, 175 | "requires": { 176 | "type-fest": "^0.8.1" 177 | } 178 | }, 179 | "ansi-regex": { 180 | "version": "5.0.0", 181 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", 182 | "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", 183 | "dev": true 184 | }, 185 | "ansi-styles": { 186 | "version": "3.2.1", 187 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", 188 | "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", 189 | "dev": true, 190 | "requires": { 191 | "color-convert": "^1.9.0" 192 | } 193 | }, 194 | "argparse": { 195 | "version": "1.0.10", 196 | "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", 197 | "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", 198 | "dev": true, 199 | "requires": { 200 | "sprintf-js": "~1.0.2" 201 | } 202 | }, 203 | "assertion-error": { 204 | "version": "1.1.0", 205 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 206 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 207 | "dev": true 208 | }, 209 | "astral-regex": { 210 | "version": "1.0.0", 211 | "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", 212 | "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", 213 | "dev": true 214 | }, 215 | "backbone": { 216 | "version": "1.4.0", 217 | "resolved": "https://registry.npmjs.org/backbone/-/backbone-1.4.0.tgz", 218 | "integrity": "sha512-RLmDrRXkVdouTg38jcgHhyQ/2zjg7a8E6sz2zxfz21Hh17xDJYUHBZimVIt5fUyS8vbfpeSmTL3gUjTEvUV3qQ==", 219 | "dev": true, 220 | "requires": { 221 | "underscore": ">=1.8.3" 222 | } 223 | }, 224 | "balanced-match": { 225 | "version": "1.0.0", 226 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 227 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 228 | "dev": true 229 | }, 230 | "brace-expansion": { 231 | "version": "1.1.11", 232 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 233 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 234 | "dev": true, 235 | "requires": { 236 | "balanced-match": "^1.0.0", 237 | "concat-map": "0.0.1" 238 | } 239 | }, 240 | "braces": { 241 | "version": "3.0.2", 242 | "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", 243 | "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", 244 | "dev": true, 245 | "requires": { 246 | "fill-range": "^7.0.1" 247 | } 248 | }, 249 | "browser-stdout": { 250 | "version": "1.3.1", 251 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 252 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 253 | "dev": true 254 | }, 255 | "callsites": { 256 | "version": "3.1.0", 257 | "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", 258 | "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", 259 | "dev": true 260 | }, 261 | "chai": { 262 | "version": "4.2.0", 263 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", 264 | "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", 265 | "dev": true, 266 | "requires": { 267 | "assertion-error": "^1.1.0", 268 | "check-error": "^1.0.2", 269 | "deep-eql": "^3.0.1", 270 | "get-func-name": "^2.0.0", 271 | "pathval": "^1.1.0", 272 | "type-detect": "^4.0.5" 273 | } 274 | }, 275 | "chalk": { 276 | "version": "2.4.2", 277 | "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", 278 | "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", 279 | "dev": true, 280 | "requires": { 281 | "ansi-styles": "^3.2.1", 282 | "escape-string-regexp": "^1.0.5", 283 | "supports-color": "^5.3.0" 284 | } 285 | }, 286 | "chardet": { 287 | "version": "0.7.0", 288 | "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", 289 | "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", 290 | "dev": true 291 | }, 292 | "check-error": { 293 | "version": "1.0.2", 294 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 295 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 296 | "dev": true 297 | }, 298 | "cli-cursor": { 299 | "version": "3.1.0", 300 | "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", 301 | "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", 302 | "dev": true, 303 | "requires": { 304 | "restore-cursor": "^3.1.0" 305 | } 306 | }, 307 | "cli-width": { 308 | "version": "2.2.0", 309 | "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", 310 | "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", 311 | "dev": true 312 | }, 313 | "color-convert": { 314 | "version": "1.9.3", 315 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", 316 | "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", 317 | "dev": true, 318 | "requires": { 319 | "color-name": "1.1.3" 320 | } 321 | }, 322 | "color-name": { 323 | "version": "1.1.3", 324 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", 325 | "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", 326 | "dev": true 327 | }, 328 | "concat-map": { 329 | "version": "0.0.1", 330 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 331 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 332 | "dev": true 333 | }, 334 | "cross-spawn": { 335 | "version": "6.0.5", 336 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", 337 | "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", 338 | "dev": true, 339 | "requires": { 340 | "nice-try": "^1.0.4", 341 | "path-key": "^2.0.1", 342 | "semver": "^5.5.0", 343 | "shebang-command": "^1.2.0", 344 | "which": "^1.2.9" 345 | }, 346 | "dependencies": { 347 | "semver": { 348 | "version": "5.7.1", 349 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 350 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 351 | "dev": true 352 | } 353 | } 354 | }, 355 | "debug": { 356 | "version": "4.1.1", 357 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 358 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 359 | "dev": true, 360 | "requires": { 361 | "ms": "^2.1.1" 362 | } 363 | }, 364 | "decamelize": { 365 | "version": "1.2.0", 366 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 367 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", 368 | "dev": true 369 | }, 370 | "deep-eql": { 371 | "version": "3.0.1", 372 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 373 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 374 | "dev": true, 375 | "requires": { 376 | "type-detect": "^4.0.0" 377 | } 378 | }, 379 | "deep-is": { 380 | "version": "0.1.3", 381 | "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", 382 | "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", 383 | "dev": true 384 | }, 385 | "define-properties": { 386 | "version": "1.1.3", 387 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", 388 | "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", 389 | "dev": true, 390 | "requires": { 391 | "object-keys": "^1.0.12" 392 | } 393 | }, 394 | "diff": { 395 | "version": "3.5.0", 396 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 397 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 398 | "dev": true 399 | }, 400 | "doctrine": { 401 | "version": "3.0.0", 402 | "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", 403 | "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", 404 | "dev": true, 405 | "requires": { 406 | "esutils": "^2.0.2" 407 | } 408 | }, 409 | "emoji-regex": { 410 | "version": "8.0.0", 411 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 412 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 413 | "dev": true 414 | }, 415 | "es-abstract": { 416 | "version": "1.17.4", 417 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", 418 | "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", 419 | "dev": true, 420 | "requires": { 421 | "es-to-primitive": "^1.2.1", 422 | "function-bind": "^1.1.1", 423 | "has": "^1.0.3", 424 | "has-symbols": "^1.0.1", 425 | "is-callable": "^1.1.5", 426 | "is-regex": "^1.0.5", 427 | "object-inspect": "^1.7.0", 428 | "object-keys": "^1.1.1", 429 | "object.assign": "^4.1.0", 430 | "string.prototype.trimleft": "^2.1.1", 431 | "string.prototype.trimright": "^2.1.1" 432 | } 433 | }, 434 | "es-to-primitive": { 435 | "version": "1.2.1", 436 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", 437 | "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", 438 | "dev": true, 439 | "requires": { 440 | "is-callable": "^1.1.4", 441 | "is-date-object": "^1.0.1", 442 | "is-symbol": "^1.0.2" 443 | } 444 | }, 445 | "escape-string-regexp": { 446 | "version": "1.0.5", 447 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 448 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 449 | "dev": true 450 | }, 451 | "eslint": { 452 | "version": "6.8.0", 453 | "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", 454 | "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", 455 | "dev": true, 456 | "requires": { 457 | "@babel/code-frame": "^7.0.0", 458 | "ajv": "^6.10.0", 459 | "chalk": "^2.1.0", 460 | "cross-spawn": "^6.0.5", 461 | "debug": "^4.0.1", 462 | "doctrine": "^3.0.0", 463 | "eslint-scope": "^5.0.0", 464 | "eslint-utils": "^1.4.3", 465 | "eslint-visitor-keys": "^1.1.0", 466 | "espree": "^6.1.2", 467 | "esquery": "^1.0.1", 468 | "esutils": "^2.0.2", 469 | "file-entry-cache": "^5.0.1", 470 | "functional-red-black-tree": "^1.0.1", 471 | "glob-parent": "^5.0.0", 472 | "globals": "^12.1.0", 473 | "ignore": "^4.0.6", 474 | "import-fresh": "^3.0.0", 475 | "imurmurhash": "^0.1.4", 476 | "inquirer": "^7.0.0", 477 | "is-glob": "^4.0.0", 478 | "js-yaml": "^3.13.1", 479 | "json-stable-stringify-without-jsonify": "^1.0.1", 480 | "levn": "^0.3.0", 481 | "lodash": "^4.17.14", 482 | "minimatch": "^3.0.4", 483 | "mkdirp": "^0.5.1", 484 | "natural-compare": "^1.4.0", 485 | "optionator": "^0.8.3", 486 | "progress": "^2.0.0", 487 | "regexpp": "^2.0.1", 488 | "semver": "^6.1.2", 489 | "strip-ansi": "^5.2.0", 490 | "strip-json-comments": "^3.0.1", 491 | "table": "^5.2.3", 492 | "text-table": "^0.2.0", 493 | "v8-compile-cache": "^2.0.3" 494 | }, 495 | "dependencies": { 496 | "glob-parent": { 497 | "version": "5.1.0", 498 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 499 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 500 | "dev": true, 501 | "requires": { 502 | "is-glob": "^4.0.1" 503 | }, 504 | "dependencies": { 505 | "is-glob": { 506 | "version": "4.0.1", 507 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 508 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 509 | "dev": true, 510 | "requires": { 511 | "is-extglob": "^2.1.1" 512 | } 513 | } 514 | } 515 | }, 516 | "regexpp": { 517 | "version": "2.0.1", 518 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", 519 | "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", 520 | "dev": true 521 | } 522 | } 523 | }, 524 | "eslint-scope": { 525 | "version": "5.0.0", 526 | "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", 527 | "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", 528 | "dev": true, 529 | "requires": { 530 | "esrecurse": "^4.1.0", 531 | "estraverse": "^4.1.1" 532 | } 533 | }, 534 | "eslint-utils": { 535 | "version": "1.4.3", 536 | "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", 537 | "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", 538 | "dev": true, 539 | "requires": { 540 | "eslint-visitor-keys": "^1.1.0" 541 | } 542 | }, 543 | "eslint-visitor-keys": { 544 | "version": "1.1.0", 545 | "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", 546 | "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", 547 | "dev": true 548 | }, 549 | "espree": { 550 | "version": "6.1.2", 551 | "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", 552 | "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", 553 | "dev": true, 554 | "requires": { 555 | "acorn": "^7.1.0", 556 | "acorn-jsx": "^5.1.0", 557 | "eslint-visitor-keys": "^1.1.0" 558 | }, 559 | "dependencies": { 560 | "acorn": { 561 | "version": "7.1.0", 562 | "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", 563 | "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", 564 | "dev": true 565 | } 566 | } 567 | }, 568 | "esprima": { 569 | "version": "4.0.1", 570 | "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", 571 | "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", 572 | "dev": true 573 | }, 574 | "esquery": { 575 | "version": "1.0.1", 576 | "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", 577 | "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", 578 | "dev": true, 579 | "requires": { 580 | "estraverse": "^4.0.0" 581 | } 582 | }, 583 | "esrecurse": { 584 | "version": "4.2.1", 585 | "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", 586 | "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", 587 | "dev": true, 588 | "requires": { 589 | "estraverse": "^4.1.0" 590 | } 591 | }, 592 | "estraverse": { 593 | "version": "4.3.0", 594 | "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", 595 | "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", 596 | "dev": true 597 | }, 598 | "esutils": { 599 | "version": "2.0.2", 600 | "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", 601 | "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", 602 | "dev": true 603 | }, 604 | "external-editor": { 605 | "version": "3.1.0", 606 | "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", 607 | "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", 608 | "dev": true, 609 | "requires": { 610 | "chardet": "^0.7.0", 611 | "iconv-lite": "^0.4.24", 612 | "tmp": "^0.0.33" 613 | } 614 | }, 615 | "fast-deep-equal": { 616 | "version": "3.1.1", 617 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz", 618 | "integrity": "sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==", 619 | "dev": true 620 | }, 621 | "fast-json-stable-stringify": { 622 | "version": "2.1.0", 623 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", 624 | "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", 625 | "dev": true 626 | }, 627 | "fast-levenshtein": { 628 | "version": "2.0.6", 629 | "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", 630 | "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", 631 | "dev": true 632 | }, 633 | "figures": { 634 | "version": "3.1.0", 635 | "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", 636 | "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", 637 | "dev": true, 638 | "requires": { 639 | "escape-string-regexp": "^1.0.5" 640 | } 641 | }, 642 | "file-entry-cache": { 643 | "version": "5.0.1", 644 | "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", 645 | "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", 646 | "dev": true, 647 | "requires": { 648 | "flat-cache": "^2.0.1" 649 | } 650 | }, 651 | "fill-range": { 652 | "version": "7.0.1", 653 | "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", 654 | "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", 655 | "dev": true, 656 | "requires": { 657 | "to-regex-range": "^5.0.1" 658 | } 659 | }, 660 | "flat": { 661 | "version": "4.1.0", 662 | "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", 663 | "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", 664 | "dev": true, 665 | "requires": { 666 | "is-buffer": "~2.0.3" 667 | } 668 | }, 669 | "flat-cache": { 670 | "version": "2.0.1", 671 | "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", 672 | "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", 673 | "dev": true, 674 | "requires": { 675 | "flatted": "^2.0.0", 676 | "rimraf": "2.6.3", 677 | "write": "1.0.3" 678 | }, 679 | "dependencies": { 680 | "rimraf": { 681 | "version": "2.6.3", 682 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", 683 | "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", 684 | "dev": true, 685 | "requires": { 686 | "glob": "^7.1.3" 687 | } 688 | } 689 | } 690 | }, 691 | "flatted": { 692 | "version": "2.0.1", 693 | "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", 694 | "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", 695 | "dev": true 696 | }, 697 | "fs-extra": { 698 | "version": "8.1.0", 699 | "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", 700 | "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", 701 | "dev": true, 702 | "requires": { 703 | "graceful-fs": "^4.2.0", 704 | "jsonfile": "^4.0.0", 705 | "universalify": "^0.1.0" 706 | } 707 | }, 708 | "fs.realpath": { 709 | "version": "1.0.0", 710 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 711 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 712 | "dev": true 713 | }, 714 | "function-bind": { 715 | "version": "1.1.1", 716 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 717 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 718 | "dev": true 719 | }, 720 | "functional-red-black-tree": { 721 | "version": "1.0.1", 722 | "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", 723 | "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", 724 | "dev": true 725 | }, 726 | "get-caller-file": { 727 | "version": "2.0.5", 728 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 729 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 730 | "dev": true 731 | }, 732 | "get-func-name": { 733 | "version": "2.0.0", 734 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 735 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 736 | "dev": true 737 | }, 738 | "glob": { 739 | "version": "7.1.6", 740 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", 741 | "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", 742 | "dev": true, 743 | "requires": { 744 | "fs.realpath": "^1.0.0", 745 | "inflight": "^1.0.4", 746 | "inherits": "2", 747 | "minimatch": "^3.0.4", 748 | "once": "^1.3.0", 749 | "path-is-absolute": "^1.0.0" 750 | } 751 | }, 752 | "globals": { 753 | "version": "12.3.0", 754 | "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", 755 | "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", 756 | "dev": true, 757 | "requires": { 758 | "type-fest": "^0.8.1" 759 | } 760 | }, 761 | "graceful-fs": { 762 | "version": "4.2.3", 763 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", 764 | "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==", 765 | "dev": true 766 | }, 767 | "growl": { 768 | "version": "1.10.5", 769 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 770 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 771 | "dev": true 772 | }, 773 | "handlebars": { 774 | "version": "4.7.2", 775 | "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.2.tgz", 776 | "integrity": "sha512-4PwqDL2laXtTWZghzzCtunQUTLbo31pcCJrd/B/9JP8XbhVzpS5ZXuKqlOzsd1rtcaLo4KqAn8nl8mkknS4MHw==", 777 | "dev": true, 778 | "requires": { 779 | "neo-async": "^2.6.0", 780 | "optimist": "^0.6.1", 781 | "source-map": "^0.6.1", 782 | "uglify-js": "^3.1.4" 783 | } 784 | }, 785 | "has": { 786 | "version": "1.0.3", 787 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", 788 | "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", 789 | "dev": true, 790 | "requires": { 791 | "function-bind": "^1.1.1" 792 | } 793 | }, 794 | "has-flag": { 795 | "version": "3.0.0", 796 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 797 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 798 | "dev": true 799 | }, 800 | "has-symbols": { 801 | "version": "1.0.1", 802 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", 803 | "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", 804 | "dev": true 805 | }, 806 | "highlight.js": { 807 | "version": "9.18.1", 808 | "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.18.1.tgz", 809 | "integrity": "sha512-OrVKYz70LHsnCgmbXctv/bfuvntIKDz177h0Co37DQ5jamGZLVmoCVMtjMtNZY3X9DrCcKfklHPNeA0uPZhSJg==", 810 | "dev": true 811 | }, 812 | "iconv-lite": { 813 | "version": "0.4.24", 814 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 815 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 816 | "dev": true, 817 | "requires": { 818 | "safer-buffer": ">= 2.1.2 < 3" 819 | } 820 | }, 821 | "ignore": { 822 | "version": "4.0.6", 823 | "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", 824 | "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", 825 | "dev": true 826 | }, 827 | "import-fresh": { 828 | "version": "3.2.1", 829 | "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", 830 | "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", 831 | "dev": true, 832 | "requires": { 833 | "parent-module": "^1.0.0", 834 | "resolve-from": "^4.0.0" 835 | } 836 | }, 837 | "imurmurhash": { 838 | "version": "0.1.4", 839 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 840 | "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", 841 | "dev": true 842 | }, 843 | "inflight": { 844 | "version": "1.0.6", 845 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 846 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 847 | "dev": true, 848 | "requires": { 849 | "once": "^1.3.0", 850 | "wrappy": "1" 851 | } 852 | }, 853 | "inherits": { 854 | "version": "2.0.4", 855 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 856 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 857 | "dev": true 858 | }, 859 | "inquirer": { 860 | "version": "7.0.4", 861 | "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.4.tgz", 862 | "integrity": "sha512-Bu5Td5+j11sCkqfqmUTiwv+tWisMtP0L7Q8WrqA2C/BbBhy1YTdFrvjjlrKq8oagA/tLQBski2Gcx/Sqyi2qSQ==", 863 | "dev": true, 864 | "requires": { 865 | "ansi-escapes": "^4.2.1", 866 | "chalk": "^2.4.2", 867 | "cli-cursor": "^3.1.0", 868 | "cli-width": "^2.0.0", 869 | "external-editor": "^3.0.3", 870 | "figures": "^3.0.0", 871 | "lodash": "^4.17.15", 872 | "mute-stream": "0.0.8", 873 | "run-async": "^2.2.0", 874 | "rxjs": "^6.5.3", 875 | "string-width": "^4.1.0", 876 | "strip-ansi": "^5.1.0", 877 | "through": "^2.3.6" 878 | } 879 | }, 880 | "interpret": { 881 | "version": "1.2.0", 882 | "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", 883 | "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", 884 | "dev": true 885 | }, 886 | "is-buffer": { 887 | "version": "2.0.4", 888 | "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", 889 | "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", 890 | "dev": true 891 | }, 892 | "is-callable": { 893 | "version": "1.1.5", 894 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", 895 | "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", 896 | "dev": true 897 | }, 898 | "is-date-object": { 899 | "version": "1.0.2", 900 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", 901 | "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", 902 | "dev": true 903 | }, 904 | "is-extglob": { 905 | "version": "2.1.1", 906 | "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", 907 | "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", 908 | "dev": true 909 | }, 910 | "is-fullwidth-code-point": { 911 | "version": "3.0.0", 912 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 913 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 914 | "dev": true 915 | }, 916 | "is-glob": { 917 | "version": "4.0.0", 918 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", 919 | "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", 920 | "dev": true, 921 | "requires": { 922 | "is-extglob": "^2.1.1" 923 | } 924 | }, 925 | "is-number": { 926 | "version": "7.0.0", 927 | "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", 928 | "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", 929 | "dev": true 930 | }, 931 | "is-promise": { 932 | "version": "2.1.0", 933 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", 934 | "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", 935 | "dev": true 936 | }, 937 | "is-regex": { 938 | "version": "1.0.5", 939 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", 940 | "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", 941 | "dev": true, 942 | "requires": { 943 | "has": "^1.0.3" 944 | } 945 | }, 946 | "is-symbol": { 947 | "version": "1.0.3", 948 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", 949 | "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", 950 | "dev": true, 951 | "requires": { 952 | "has-symbols": "^1.0.1" 953 | } 954 | }, 955 | "isexe": { 956 | "version": "2.0.0", 957 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 958 | "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", 959 | "dev": true 960 | }, 961 | "jquery": { 962 | "version": "3.4.1", 963 | "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.1.tgz", 964 | "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==", 965 | "dev": true 966 | }, 967 | "js-yaml": { 968 | "version": "3.13.1", 969 | "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", 970 | "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", 971 | "dev": true, 972 | "requires": { 973 | "argparse": "^1.0.7", 974 | "esprima": "^4.0.0" 975 | } 976 | }, 977 | "json-schema-traverse": { 978 | "version": "0.4.1", 979 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", 980 | "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", 981 | "dev": true 982 | }, 983 | "json-stable-stringify-without-jsonify": { 984 | "version": "1.0.1", 985 | "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", 986 | "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", 987 | "dev": true 988 | }, 989 | "jsonfile": { 990 | "version": "4.0.0", 991 | "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", 992 | "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", 993 | "dev": true, 994 | "requires": { 995 | "graceful-fs": "^4.1.6" 996 | } 997 | }, 998 | "levn": { 999 | "version": "0.3.0", 1000 | "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", 1001 | "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", 1002 | "dev": true, 1003 | "requires": { 1004 | "prelude-ls": "~1.1.2", 1005 | "type-check": "~0.3.2" 1006 | } 1007 | }, 1008 | "locate-path": { 1009 | "version": "3.0.0", 1010 | "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", 1011 | "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", 1012 | "dev": true, 1013 | "requires": { 1014 | "p-locate": "^3.0.0", 1015 | "path-exists": "^3.0.0" 1016 | }, 1017 | "dependencies": { 1018 | "path-exists": { 1019 | "version": "3.0.0", 1020 | "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", 1021 | "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", 1022 | "dev": true 1023 | } 1024 | } 1025 | }, 1026 | "lodash": { 1027 | "version": "4.17.15", 1028 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", 1029 | "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", 1030 | "dev": true 1031 | }, 1032 | "log-symbols": { 1033 | "version": "2.2.0", 1034 | "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", 1035 | "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", 1036 | "dev": true, 1037 | "requires": { 1038 | "chalk": "^2.0.1" 1039 | } 1040 | }, 1041 | "lunr": { 1042 | "version": "2.3.8", 1043 | "resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.8.tgz", 1044 | "integrity": "sha512-oxMeX/Y35PNFuZoHp+jUj5OSEmLCaIH4KTFJh7a93cHBoFmpw2IoPs22VIz7vyO2YUnx2Tn9dzIwO2P/4quIRg==", 1045 | "dev": true 1046 | }, 1047 | "marked": { 1048 | "version": "0.8.0", 1049 | "resolved": "https://registry.npmjs.org/marked/-/marked-0.8.0.tgz", 1050 | "integrity": "sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ==", 1051 | "dev": true 1052 | }, 1053 | "mimic-fn": { 1054 | "version": "2.1.0", 1055 | "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", 1056 | "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", 1057 | "dev": true 1058 | }, 1059 | "minimatch": { 1060 | "version": "3.0.4", 1061 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 1062 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 1063 | "dev": true, 1064 | "requires": { 1065 | "brace-expansion": "^1.1.7" 1066 | } 1067 | }, 1068 | "minimist": { 1069 | "version": "0.0.8", 1070 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 1071 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 1072 | "dev": true 1073 | }, 1074 | "mkdirp": { 1075 | "version": "0.5.1", 1076 | "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 1077 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 1078 | "dev": true, 1079 | "requires": { 1080 | "minimist": "0.0.8" 1081 | } 1082 | }, 1083 | "mocha": { 1084 | "version": "7.0.1", 1085 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.0.1.tgz", 1086 | "integrity": "sha512-9eWmWTdHLXh72rGrdZjNbG3aa1/3NRPpul1z0D979QpEnFdCG0Q5tv834N+94QEN2cysfV72YocQ3fn87s70fg==", 1087 | "dev": true, 1088 | "requires": { 1089 | "ansi-colors": "3.2.3", 1090 | "browser-stdout": "1.3.1", 1091 | "chokidar": "3.3.0", 1092 | "debug": "3.2.6", 1093 | "diff": "3.5.0", 1094 | "escape-string-regexp": "1.0.5", 1095 | "find-up": "3.0.0", 1096 | "glob": "7.1.3", 1097 | "growl": "1.10.5", 1098 | "he": "1.2.0", 1099 | "js-yaml": "3.13.1", 1100 | "log-symbols": "2.2.0", 1101 | "minimatch": "3.0.4", 1102 | "mkdirp": "0.5.1", 1103 | "ms": "2.1.1", 1104 | "node-environment-flags": "1.0.6", 1105 | "object.assign": "4.1.0", 1106 | "strip-json-comments": "2.0.1", 1107 | "supports-color": "6.0.0", 1108 | "which": "1.3.1", 1109 | "wide-align": "1.1.3", 1110 | "yargs": "13.3.0", 1111 | "yargs-parser": "13.1.1", 1112 | "yargs-unparser": "1.6.0" 1113 | }, 1114 | "dependencies": { 1115 | "ansi-colors": { 1116 | "version": "3.2.3", 1117 | "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", 1118 | "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", 1119 | "dev": true 1120 | }, 1121 | "anymatch": { 1122 | "version": "3.1.1", 1123 | "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", 1124 | "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", 1125 | "dev": true, 1126 | "requires": { 1127 | "normalize-path": "^3.0.0", 1128 | "picomatch": "^2.0.4" 1129 | } 1130 | }, 1131 | "binary-extensions": { 1132 | "version": "2.0.0", 1133 | "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", 1134 | "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", 1135 | "dev": true 1136 | }, 1137 | "camelcase": { 1138 | "version": "5.3.1", 1139 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 1140 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 1141 | "dev": true 1142 | }, 1143 | "chokidar": { 1144 | "version": "3.3.0", 1145 | "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", 1146 | "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", 1147 | "dev": true, 1148 | "requires": { 1149 | "anymatch": "~3.1.1", 1150 | "braces": "~3.0.2", 1151 | "fsevents": "~2.1.1", 1152 | "glob-parent": "~5.1.0", 1153 | "is-binary-path": "~2.1.0", 1154 | "is-glob": "~4.0.1", 1155 | "normalize-path": "~3.0.0", 1156 | "readdirp": "~3.2.0" 1157 | } 1158 | }, 1159 | "cliui": { 1160 | "version": "5.0.0", 1161 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 1162 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 1163 | "dev": true, 1164 | "requires": { 1165 | "string-width": "^3.1.0", 1166 | "strip-ansi": "^5.2.0", 1167 | "wrap-ansi": "^5.1.0" 1168 | } 1169 | }, 1170 | "debug": { 1171 | "version": "3.2.6", 1172 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", 1173 | "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", 1174 | "dev": true, 1175 | "requires": { 1176 | "ms": "^2.1.1" 1177 | } 1178 | }, 1179 | "emoji-regex": { 1180 | "version": "7.0.3", 1181 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 1182 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 1183 | "dev": true 1184 | }, 1185 | "find-up": { 1186 | "version": "3.0.0", 1187 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 1188 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 1189 | "dev": true, 1190 | "requires": { 1191 | "locate-path": "^3.0.0" 1192 | } 1193 | }, 1194 | "fsevents": { 1195 | "version": "2.1.2", 1196 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", 1197 | "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", 1198 | "dev": true, 1199 | "optional": true 1200 | }, 1201 | "glob": { 1202 | "version": "7.1.3", 1203 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", 1204 | "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", 1205 | "dev": true, 1206 | "requires": { 1207 | "fs.realpath": "^1.0.0", 1208 | "inflight": "^1.0.4", 1209 | "inherits": "2", 1210 | "minimatch": "^3.0.4", 1211 | "once": "^1.3.0", 1212 | "path-is-absolute": "^1.0.0" 1213 | } 1214 | }, 1215 | "glob-parent": { 1216 | "version": "5.1.0", 1217 | "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", 1218 | "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", 1219 | "dev": true, 1220 | "requires": { 1221 | "is-glob": "^4.0.1" 1222 | } 1223 | }, 1224 | "he": { 1225 | "version": "1.2.0", 1226 | "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", 1227 | "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", 1228 | "dev": true 1229 | }, 1230 | "is-binary-path": { 1231 | "version": "2.1.0", 1232 | "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", 1233 | "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", 1234 | "dev": true, 1235 | "requires": { 1236 | "binary-extensions": "^2.0.0" 1237 | } 1238 | }, 1239 | "is-fullwidth-code-point": { 1240 | "version": "2.0.0", 1241 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1242 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1243 | "dev": true 1244 | }, 1245 | "is-glob": { 1246 | "version": "4.0.1", 1247 | "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", 1248 | "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", 1249 | "dev": true, 1250 | "requires": { 1251 | "is-extglob": "^2.1.1" 1252 | } 1253 | }, 1254 | "ms": { 1255 | "version": "2.1.1", 1256 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", 1257 | "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", 1258 | "dev": true 1259 | }, 1260 | "normalize-path": { 1261 | "version": "3.0.0", 1262 | "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", 1263 | "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", 1264 | "dev": true 1265 | }, 1266 | "readdirp": { 1267 | "version": "3.2.0", 1268 | "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", 1269 | "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", 1270 | "dev": true, 1271 | "requires": { 1272 | "picomatch": "^2.0.4" 1273 | } 1274 | }, 1275 | "string-width": { 1276 | "version": "3.1.0", 1277 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1278 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1279 | "dev": true, 1280 | "requires": { 1281 | "emoji-regex": "^7.0.1", 1282 | "is-fullwidth-code-point": "^2.0.0", 1283 | "strip-ansi": "^5.1.0" 1284 | } 1285 | }, 1286 | "strip-json-comments": { 1287 | "version": "2.0.1", 1288 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 1289 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", 1290 | "dev": true 1291 | }, 1292 | "supports-color": { 1293 | "version": "6.0.0", 1294 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", 1295 | "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", 1296 | "dev": true, 1297 | "requires": { 1298 | "has-flag": "^3.0.0" 1299 | } 1300 | }, 1301 | "which-module": { 1302 | "version": "2.0.0", 1303 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 1304 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 1305 | "dev": true 1306 | }, 1307 | "yargs": { 1308 | "version": "13.3.0", 1309 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", 1310 | "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", 1311 | "dev": true, 1312 | "requires": { 1313 | "cliui": "^5.0.0", 1314 | "find-up": "^3.0.0", 1315 | "get-caller-file": "^2.0.1", 1316 | "require-directory": "^2.1.1", 1317 | "require-main-filename": "^2.0.0", 1318 | "set-blocking": "^2.0.0", 1319 | "string-width": "^3.0.0", 1320 | "which-module": "^2.0.0", 1321 | "y18n": "^4.0.0", 1322 | "yargs-parser": "^13.1.1" 1323 | } 1324 | }, 1325 | "yargs-parser": { 1326 | "version": "13.1.1", 1327 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", 1328 | "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", 1329 | "dev": true, 1330 | "requires": { 1331 | "camelcase": "^5.0.0", 1332 | "decamelize": "^1.2.0" 1333 | } 1334 | } 1335 | } 1336 | }, 1337 | "ms": { 1338 | "version": "2.1.2", 1339 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1340 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1341 | "dev": true 1342 | }, 1343 | "mute-stream": { 1344 | "version": "0.0.8", 1345 | "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", 1346 | "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", 1347 | "dev": true 1348 | }, 1349 | "natural-compare": { 1350 | "version": "1.4.0", 1351 | "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", 1352 | "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", 1353 | "dev": true 1354 | }, 1355 | "neo-async": { 1356 | "version": "2.6.1", 1357 | "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", 1358 | "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", 1359 | "dev": true 1360 | }, 1361 | "nice-try": { 1362 | "version": "1.0.5", 1363 | "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", 1364 | "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", 1365 | "dev": true 1366 | }, 1367 | "node-environment-flags": { 1368 | "version": "1.0.6", 1369 | "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", 1370 | "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", 1371 | "dev": true, 1372 | "requires": { 1373 | "object.getownpropertydescriptors": "^2.0.3", 1374 | "semver": "^5.7.0" 1375 | }, 1376 | "dependencies": { 1377 | "semver": { 1378 | "version": "5.7.1", 1379 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", 1380 | "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", 1381 | "dev": true 1382 | } 1383 | } 1384 | }, 1385 | "object-inspect": { 1386 | "version": "1.7.0", 1387 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", 1388 | "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", 1389 | "dev": true 1390 | }, 1391 | "object-keys": { 1392 | "version": "1.1.1", 1393 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", 1394 | "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", 1395 | "dev": true 1396 | }, 1397 | "object.assign": { 1398 | "version": "4.1.0", 1399 | "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", 1400 | "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", 1401 | "dev": true, 1402 | "requires": { 1403 | "define-properties": "^1.1.2", 1404 | "function-bind": "^1.1.1", 1405 | "has-symbols": "^1.0.0", 1406 | "object-keys": "^1.0.11" 1407 | } 1408 | }, 1409 | "object.getownpropertydescriptors": { 1410 | "version": "2.1.0", 1411 | "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", 1412 | "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", 1413 | "dev": true, 1414 | "requires": { 1415 | "define-properties": "^1.1.3", 1416 | "es-abstract": "^1.17.0-next.1" 1417 | } 1418 | }, 1419 | "once": { 1420 | "version": "1.4.0", 1421 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1422 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 1423 | "dev": true, 1424 | "requires": { 1425 | "wrappy": "1" 1426 | } 1427 | }, 1428 | "onetime": { 1429 | "version": "5.1.0", 1430 | "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", 1431 | "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", 1432 | "dev": true, 1433 | "requires": { 1434 | "mimic-fn": "^2.1.0" 1435 | } 1436 | }, 1437 | "optimist": { 1438 | "version": "0.6.1", 1439 | "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", 1440 | "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", 1441 | "dev": true, 1442 | "requires": { 1443 | "minimist": "~0.0.1", 1444 | "wordwrap": "~0.0.2" 1445 | } 1446 | }, 1447 | "optionator": { 1448 | "version": "0.8.3", 1449 | "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", 1450 | "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", 1451 | "dev": true, 1452 | "requires": { 1453 | "deep-is": "~0.1.3", 1454 | "fast-levenshtein": "~2.0.6", 1455 | "levn": "~0.3.0", 1456 | "prelude-ls": "~1.1.2", 1457 | "type-check": "~0.3.2", 1458 | "word-wrap": "~1.2.3" 1459 | } 1460 | }, 1461 | "os-tmpdir": { 1462 | "version": "1.0.2", 1463 | "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", 1464 | "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", 1465 | "dev": true 1466 | }, 1467 | "p-limit": { 1468 | "version": "2.2.2", 1469 | "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", 1470 | "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", 1471 | "dev": true, 1472 | "requires": { 1473 | "p-try": "^2.0.0" 1474 | } 1475 | }, 1476 | "p-locate": { 1477 | "version": "3.0.0", 1478 | "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", 1479 | "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", 1480 | "dev": true, 1481 | "requires": { 1482 | "p-limit": "^2.0.0" 1483 | } 1484 | }, 1485 | "p-try": { 1486 | "version": "2.2.0", 1487 | "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", 1488 | "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", 1489 | "dev": true 1490 | }, 1491 | "parent-module": { 1492 | "version": "1.0.1", 1493 | "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", 1494 | "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", 1495 | "dev": true, 1496 | "requires": { 1497 | "callsites": "^3.0.0" 1498 | } 1499 | }, 1500 | "path-is-absolute": { 1501 | "version": "1.0.1", 1502 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 1503 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 1504 | "dev": true 1505 | }, 1506 | "path-key": { 1507 | "version": "2.0.1", 1508 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", 1509 | "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", 1510 | "dev": true 1511 | }, 1512 | "path-parse": { 1513 | "version": "1.0.6", 1514 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", 1515 | "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", 1516 | "dev": true 1517 | }, 1518 | "pathval": { 1519 | "version": "1.1.0", 1520 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 1521 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 1522 | "dev": true 1523 | }, 1524 | "picomatch": { 1525 | "version": "2.2.1", 1526 | "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", 1527 | "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", 1528 | "dev": true 1529 | }, 1530 | "prelude-ls": { 1531 | "version": "1.1.2", 1532 | "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", 1533 | "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", 1534 | "dev": true 1535 | }, 1536 | "progress": { 1537 | "version": "2.0.3", 1538 | "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", 1539 | "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", 1540 | "dev": true 1541 | }, 1542 | "punycode": { 1543 | "version": "2.1.1", 1544 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", 1545 | "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", 1546 | "dev": true 1547 | }, 1548 | "rechoir": { 1549 | "version": "0.6.2", 1550 | "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", 1551 | "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", 1552 | "dev": true, 1553 | "requires": { 1554 | "resolve": "^1.1.6" 1555 | } 1556 | }, 1557 | "regexpp": { 1558 | "version": "3.0.0", 1559 | "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", 1560 | "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", 1561 | "dev": true 1562 | }, 1563 | "require-directory": { 1564 | "version": "2.1.1", 1565 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1566 | "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", 1567 | "dev": true 1568 | }, 1569 | "require-main-filename": { 1570 | "version": "2.0.0", 1571 | "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", 1572 | "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", 1573 | "dev": true 1574 | }, 1575 | "resolve": { 1576 | "version": "1.15.0", 1577 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.0.tgz", 1578 | "integrity": "sha512-+hTmAldEGE80U2wJJDC1lebb5jWqvTYAfm3YZ1ckk1gBr0MnCqUKlwK1e+anaFljIl+F5tR5IoZcm4ZDA1zMQw==", 1579 | "dev": true, 1580 | "requires": { 1581 | "path-parse": "^1.0.6" 1582 | } 1583 | }, 1584 | "resolve-from": { 1585 | "version": "4.0.0", 1586 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", 1587 | "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", 1588 | "dev": true 1589 | }, 1590 | "restore-cursor": { 1591 | "version": "3.1.0", 1592 | "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", 1593 | "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", 1594 | "dev": true, 1595 | "requires": { 1596 | "onetime": "^5.1.0", 1597 | "signal-exit": "^3.0.2" 1598 | } 1599 | }, 1600 | "rimraf": { 1601 | "version": "3.0.1", 1602 | "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.1.tgz", 1603 | "integrity": "sha512-IQ4ikL8SjBiEDZfk+DFVwqRK8md24RWMEJkdSlgNLkyyAImcjf8SWvU1qFMDOb4igBClbTQ/ugPqXcRwdFTxZw==", 1604 | "dev": true, 1605 | "requires": { 1606 | "glob": "^7.1.3" 1607 | } 1608 | }, 1609 | "run-async": { 1610 | "version": "2.3.0", 1611 | "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", 1612 | "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", 1613 | "dev": true, 1614 | "requires": { 1615 | "is-promise": "^2.1.0" 1616 | } 1617 | }, 1618 | "rxjs": { 1619 | "version": "6.5.4", 1620 | "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", 1621 | "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", 1622 | "dev": true, 1623 | "requires": { 1624 | "tslib": "^1.9.0" 1625 | } 1626 | }, 1627 | "safer-buffer": { 1628 | "version": "2.1.2", 1629 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1630 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1631 | "dev": true 1632 | }, 1633 | "semver": { 1634 | "version": "6.3.0", 1635 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", 1636 | "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", 1637 | "dev": true 1638 | }, 1639 | "set-blocking": { 1640 | "version": "2.0.0", 1641 | "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", 1642 | "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", 1643 | "dev": true 1644 | }, 1645 | "shebang-command": { 1646 | "version": "1.2.0", 1647 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", 1648 | "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", 1649 | "dev": true, 1650 | "requires": { 1651 | "shebang-regex": "^1.0.0" 1652 | } 1653 | }, 1654 | "shebang-regex": { 1655 | "version": "1.0.0", 1656 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", 1657 | "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", 1658 | "dev": true 1659 | }, 1660 | "shelljs": { 1661 | "version": "0.8.3", 1662 | "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.8.3.tgz", 1663 | "integrity": "sha512-fc0BKlAWiLpwZljmOvAOTE/gXawtCoNrP5oaY7KIaQbbyHeQVg01pSEuEGvGh3HEdBU4baCD7wQBwADmM/7f7A==", 1664 | "dev": true, 1665 | "requires": { 1666 | "glob": "^7.0.0", 1667 | "interpret": "^1.0.0", 1668 | "rechoir": "^0.6.2" 1669 | } 1670 | }, 1671 | "signal-exit": { 1672 | "version": "3.0.2", 1673 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", 1674 | "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", 1675 | "dev": true 1676 | }, 1677 | "slice-ansi": { 1678 | "version": "2.1.0", 1679 | "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", 1680 | "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", 1681 | "dev": true, 1682 | "requires": { 1683 | "ansi-styles": "^3.2.0", 1684 | "astral-regex": "^1.0.0", 1685 | "is-fullwidth-code-point": "^2.0.0" 1686 | }, 1687 | "dependencies": { 1688 | "is-fullwidth-code-point": { 1689 | "version": "2.0.0", 1690 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1691 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1692 | "dev": true 1693 | } 1694 | } 1695 | }, 1696 | "source-map": { 1697 | "version": "0.6.1", 1698 | "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", 1699 | "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", 1700 | "dev": true 1701 | }, 1702 | "sprintf-js": { 1703 | "version": "1.0.3", 1704 | "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", 1705 | "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", 1706 | "dev": true 1707 | }, 1708 | "string-width": { 1709 | "version": "4.2.0", 1710 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", 1711 | "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", 1712 | "dev": true, 1713 | "requires": { 1714 | "emoji-regex": "^8.0.0", 1715 | "is-fullwidth-code-point": "^3.0.0", 1716 | "strip-ansi": "^6.0.0" 1717 | }, 1718 | "dependencies": { 1719 | "strip-ansi": { 1720 | "version": "6.0.0", 1721 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", 1722 | "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", 1723 | "dev": true, 1724 | "requires": { 1725 | "ansi-regex": "^5.0.0" 1726 | } 1727 | } 1728 | } 1729 | }, 1730 | "string.prototype.trimleft": { 1731 | "version": "2.1.1", 1732 | "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", 1733 | "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", 1734 | "dev": true, 1735 | "requires": { 1736 | "define-properties": "^1.1.3", 1737 | "function-bind": "^1.1.1" 1738 | } 1739 | }, 1740 | "string.prototype.trimright": { 1741 | "version": "2.1.1", 1742 | "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", 1743 | "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", 1744 | "dev": true, 1745 | "requires": { 1746 | "define-properties": "^1.1.3", 1747 | "function-bind": "^1.1.1" 1748 | } 1749 | }, 1750 | "strip-ansi": { 1751 | "version": "5.2.0", 1752 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", 1753 | "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", 1754 | "dev": true, 1755 | "requires": { 1756 | "ansi-regex": "^4.1.0" 1757 | }, 1758 | "dependencies": { 1759 | "ansi-regex": { 1760 | "version": "4.1.0", 1761 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", 1762 | "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", 1763 | "dev": true 1764 | } 1765 | } 1766 | }, 1767 | "strip-json-comments": { 1768 | "version": "3.0.1", 1769 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", 1770 | "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", 1771 | "dev": true 1772 | }, 1773 | "supports-color": { 1774 | "version": "5.5.0", 1775 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", 1776 | "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", 1777 | "dev": true, 1778 | "requires": { 1779 | "has-flag": "^3.0.0" 1780 | } 1781 | }, 1782 | "table": { 1783 | "version": "5.4.6", 1784 | "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", 1785 | "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", 1786 | "dev": true, 1787 | "requires": { 1788 | "ajv": "^6.10.2", 1789 | "lodash": "^4.17.14", 1790 | "slice-ansi": "^2.1.0", 1791 | "string-width": "^3.0.0" 1792 | }, 1793 | "dependencies": { 1794 | "emoji-regex": { 1795 | "version": "7.0.3", 1796 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 1797 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 1798 | "dev": true 1799 | }, 1800 | "is-fullwidth-code-point": { 1801 | "version": "2.0.0", 1802 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1803 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1804 | "dev": true 1805 | }, 1806 | "string-width": { 1807 | "version": "3.1.0", 1808 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 1809 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 1810 | "dev": true, 1811 | "requires": { 1812 | "emoji-regex": "^7.0.1", 1813 | "is-fullwidth-code-point": "^2.0.0", 1814 | "strip-ansi": "^5.1.0" 1815 | } 1816 | } 1817 | } 1818 | }, 1819 | "text-table": { 1820 | "version": "0.2.0", 1821 | "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", 1822 | "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", 1823 | "dev": true 1824 | }, 1825 | "through": { 1826 | "version": "2.3.8", 1827 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 1828 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", 1829 | "dev": true 1830 | }, 1831 | "tmp": { 1832 | "version": "0.0.33", 1833 | "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", 1834 | "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", 1835 | "dev": true, 1836 | "requires": { 1837 | "os-tmpdir": "~1.0.2" 1838 | } 1839 | }, 1840 | "to-regex-range": { 1841 | "version": "5.0.1", 1842 | "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", 1843 | "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", 1844 | "dev": true, 1845 | "requires": { 1846 | "is-number": "^7.0.0" 1847 | } 1848 | }, 1849 | "tslib": { 1850 | "version": "1.9.3", 1851 | "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", 1852 | "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", 1853 | "dev": true 1854 | }, 1855 | "type-check": { 1856 | "version": "0.3.2", 1857 | "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", 1858 | "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", 1859 | "dev": true, 1860 | "requires": { 1861 | "prelude-ls": "~1.1.2" 1862 | } 1863 | }, 1864 | "type-detect": { 1865 | "version": "4.0.8", 1866 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 1867 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 1868 | "dev": true 1869 | }, 1870 | "type-fest": { 1871 | "version": "0.8.1", 1872 | "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", 1873 | "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", 1874 | "dev": true 1875 | }, 1876 | "typedoc": { 1877 | "version": "0.16.9", 1878 | "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.16.9.tgz", 1879 | "integrity": "sha512-UvOGoy76yqwCXwxPgatwgXWfsQ3FczyZ6ZNLjhCPK+TsDir6LiU3YB6N9XZmPv36E+7LA860mnc8a0v6YADKFw==", 1880 | "dev": true, 1881 | "requires": { 1882 | "@types/minimatch": "3.0.3", 1883 | "fs-extra": "^8.1.0", 1884 | "handlebars": "^4.7.2", 1885 | "highlight.js": "^9.17.1", 1886 | "lodash": "^4.17.15", 1887 | "marked": "^0.8.0", 1888 | "minimatch": "^3.0.0", 1889 | "progress": "^2.0.3", 1890 | "shelljs": "^0.8.3", 1891 | "typedoc-default-themes": "^0.7.2", 1892 | "typescript": "3.7.x" 1893 | } 1894 | }, 1895 | "typedoc-default-themes": { 1896 | "version": "0.7.2", 1897 | "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.7.2.tgz", 1898 | "integrity": "sha512-fiFKlFO6VTqjcno8w6WpTsbCgXmfPHVjnLfYkmByZE7moaz+E2DSpAT+oHtDHv7E0BM5kAhPrHJELP2J2Y2T9A==", 1899 | "dev": true, 1900 | "requires": { 1901 | "backbone": "^1.4.0", 1902 | "jquery": "^3.4.1", 1903 | "lunr": "^2.3.8", 1904 | "underscore": "^1.9.1" 1905 | } 1906 | }, 1907 | "typescript": { 1908 | "version": "3.7.5", 1909 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", 1910 | "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", 1911 | "dev": true 1912 | }, 1913 | "uglify-js": { 1914 | "version": "3.7.6", 1915 | "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.6.tgz", 1916 | "integrity": "sha512-yYqjArOYSxvqeeiYH2VGjZOqq6SVmhxzaPjJC1W2F9e+bqvFL9QXQ2osQuKUFjM2hGjKG2YclQnRKWQSt/nOTQ==", 1917 | "dev": true, 1918 | "optional": true, 1919 | "requires": { 1920 | "commander": "~2.20.3", 1921 | "source-map": "~0.6.1" 1922 | }, 1923 | "dependencies": { 1924 | "commander": { 1925 | "version": "2.20.3", 1926 | "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", 1927 | "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", 1928 | "dev": true, 1929 | "optional": true 1930 | } 1931 | } 1932 | }, 1933 | "underscore": { 1934 | "version": "1.9.2", 1935 | "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.2.tgz", 1936 | "integrity": "sha512-D39qtimx0c1fI3ya1Lnhk3E9nONswSKhnffBI0gME9C99fYOkNi04xs8K6pePLhvl1frbDemkaBQ5ikWllR2HQ==", 1937 | "dev": true 1938 | }, 1939 | "universalify": { 1940 | "version": "0.1.2", 1941 | "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", 1942 | "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", 1943 | "dev": true 1944 | }, 1945 | "uri-js": { 1946 | "version": "4.2.2", 1947 | "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", 1948 | "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", 1949 | "dev": true, 1950 | "requires": { 1951 | "punycode": "^2.1.0" 1952 | } 1953 | }, 1954 | "v8-compile-cache": { 1955 | "version": "2.1.0", 1956 | "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", 1957 | "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", 1958 | "dev": true 1959 | }, 1960 | "which": { 1961 | "version": "1.3.1", 1962 | "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", 1963 | "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", 1964 | "dev": true, 1965 | "requires": { 1966 | "isexe": "^2.0.0" 1967 | } 1968 | }, 1969 | "wide-align": { 1970 | "version": "1.1.3", 1971 | "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", 1972 | "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", 1973 | "dev": true, 1974 | "requires": { 1975 | "string-width": "^1.0.2 || 2" 1976 | }, 1977 | "dependencies": { 1978 | "ansi-regex": { 1979 | "version": "3.0.0", 1980 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", 1981 | "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", 1982 | "dev": true 1983 | }, 1984 | "is-fullwidth-code-point": { 1985 | "version": "2.0.0", 1986 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 1987 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 1988 | "dev": true 1989 | }, 1990 | "string-width": { 1991 | "version": "2.1.1", 1992 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", 1993 | "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", 1994 | "dev": true, 1995 | "requires": { 1996 | "is-fullwidth-code-point": "^2.0.0", 1997 | "strip-ansi": "^4.0.0" 1998 | } 1999 | }, 2000 | "strip-ansi": { 2001 | "version": "4.0.0", 2002 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", 2003 | "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", 2004 | "dev": true, 2005 | "requires": { 2006 | "ansi-regex": "^3.0.0" 2007 | } 2008 | } 2009 | } 2010 | }, 2011 | "word-wrap": { 2012 | "version": "1.2.3", 2013 | "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", 2014 | "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", 2015 | "dev": true 2016 | }, 2017 | "wordwrap": { 2018 | "version": "0.0.3", 2019 | "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", 2020 | "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", 2021 | "dev": true 2022 | }, 2023 | "wrap-ansi": { 2024 | "version": "5.1.0", 2025 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", 2026 | "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", 2027 | "dev": true, 2028 | "requires": { 2029 | "ansi-styles": "^3.2.0", 2030 | "string-width": "^3.0.0", 2031 | "strip-ansi": "^5.0.0" 2032 | }, 2033 | "dependencies": { 2034 | "emoji-regex": { 2035 | "version": "7.0.3", 2036 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2037 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2038 | "dev": true 2039 | }, 2040 | "is-fullwidth-code-point": { 2041 | "version": "2.0.0", 2042 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2043 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2044 | "dev": true 2045 | }, 2046 | "string-width": { 2047 | "version": "3.1.0", 2048 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2049 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2050 | "dev": true, 2051 | "requires": { 2052 | "emoji-regex": "^7.0.1", 2053 | "is-fullwidth-code-point": "^2.0.0", 2054 | "strip-ansi": "^5.1.0" 2055 | } 2056 | } 2057 | } 2058 | }, 2059 | "wrappy": { 2060 | "version": "1.0.2", 2061 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2062 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 2063 | "dev": true 2064 | }, 2065 | "write": { 2066 | "version": "1.0.3", 2067 | "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", 2068 | "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", 2069 | "dev": true, 2070 | "requires": { 2071 | "mkdirp": "^0.5.1" 2072 | } 2073 | }, 2074 | "y18n": { 2075 | "version": "4.0.0", 2076 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", 2077 | "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", 2078 | "dev": true 2079 | }, 2080 | "yargs-unparser": { 2081 | "version": "1.6.0", 2082 | "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", 2083 | "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", 2084 | "dev": true, 2085 | "requires": { 2086 | "flat": "^4.1.0", 2087 | "lodash": "^4.17.15", 2088 | "yargs": "^13.3.0" 2089 | }, 2090 | "dependencies": { 2091 | "camelcase": { 2092 | "version": "5.3.1", 2093 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", 2094 | "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", 2095 | "dev": true 2096 | }, 2097 | "cliui": { 2098 | "version": "5.0.0", 2099 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", 2100 | "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", 2101 | "dev": true, 2102 | "requires": { 2103 | "string-width": "^3.1.0", 2104 | "strip-ansi": "^5.2.0", 2105 | "wrap-ansi": "^5.1.0" 2106 | } 2107 | }, 2108 | "emoji-regex": { 2109 | "version": "7.0.3", 2110 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", 2111 | "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", 2112 | "dev": true 2113 | }, 2114 | "find-up": { 2115 | "version": "3.0.0", 2116 | "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", 2117 | "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", 2118 | "dev": true, 2119 | "requires": { 2120 | "locate-path": "^3.0.0" 2121 | } 2122 | }, 2123 | "is-fullwidth-code-point": { 2124 | "version": "2.0.0", 2125 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", 2126 | "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", 2127 | "dev": true 2128 | }, 2129 | "string-width": { 2130 | "version": "3.1.0", 2131 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", 2132 | "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", 2133 | "dev": true, 2134 | "requires": { 2135 | "emoji-regex": "^7.0.1", 2136 | "is-fullwidth-code-point": "^2.0.0", 2137 | "strip-ansi": "^5.1.0" 2138 | } 2139 | }, 2140 | "which-module": { 2141 | "version": "2.0.0", 2142 | "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", 2143 | "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", 2144 | "dev": true 2145 | }, 2146 | "yargs": { 2147 | "version": "13.3.0", 2148 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", 2149 | "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", 2150 | "dev": true, 2151 | "requires": { 2152 | "cliui": "^5.0.0", 2153 | "find-up": "^3.0.0", 2154 | "get-caller-file": "^2.0.1", 2155 | "require-directory": "^2.1.1", 2156 | "require-main-filename": "^2.0.0", 2157 | "set-blocking": "^2.0.0", 2158 | "string-width": "^3.0.0", 2159 | "which-module": "^2.0.0", 2160 | "y18n": "^4.0.0", 2161 | "yargs-parser": "^13.1.1" 2162 | } 2163 | }, 2164 | "yargs-parser": { 2165 | "version": "13.1.1", 2166 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", 2167 | "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", 2168 | "dev": true, 2169 | "requires": { 2170 | "camelcase": "^5.0.0", 2171 | "decamelize": "^1.2.0" 2172 | } 2173 | } 2174 | } 2175 | } 2176 | } 2177 | } 2178 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudflare-dynamic-dns", 3 | "version": "1.0.2", 4 | "description": "Updates a Cloudflare DNS address record with an IP address or hostname", 5 | "keywords": [ 6 | "cloudflare", 7 | "dynamic", 8 | "dns" 9 | ], 10 | "license": "Apache-2.0", 11 | "author": { 12 | "name": "Michael Kourlas", 13 | "email": "michael@kourlas.com" 14 | }, 15 | "files": [ 16 | "lib", 17 | "CHANGES.md", 18 | "LICENSE.md", 19 | "NOTICE.md", 20 | "package.json", 21 | "README.md" 22 | ], 23 | "main": "./lib/main.js", 24 | "typings": "./lib/main", 25 | "repository": { 26 | "type": "git", 27 | "url": "git://github.com/michaelkourlas/node-cloudflare-dynamic-dns.git" 28 | }, 29 | "scripts": { 30 | "build": "npm run-script prod && npm run-script test-prod && npm run-script docs", 31 | "clean": "rimraf lib", 32 | "clean-docs": "rimraf docs", 33 | "clean-test": "rimraf test/lib", 34 | "dev": "npm run-script clean && npm run-script lint && tsc -p tsconfig.json --sourceMap", 35 | "docs": "npm run-script clean-docs && typedoc --mode file --module commonjs --out docs --target es5 --tsconfig tsconfig.json", 36 | "lint": "eslint . --ext .ts", 37 | "prod": "npm run-script clean && npm run-script lint && tsc -p tsconfig.json", 38 | "test-dev": "npm run-script clean-test && tsc -p test/tsconfig.json --sourceMap && mocha test/lib", 39 | "test-prod": "npm run-script clean-test && tsc -p test/tsconfig.json && mocha test/lib" 40 | }, 41 | "dependencies": { 42 | "@types/node": "^13.7.0" 43 | }, 44 | "devDependencies": { 45 | "@types/chai": "^4.2.8", 46 | "@types/mocha": "^7.0.1", 47 | "@typescript-eslint/eslint-plugin": "^2.18.0", 48 | "@typescript-eslint/parser": "^2.18.0", 49 | "chai": "^4.2.0", 50 | "eslint": "^6.8.0", 51 | "mocha": "^7.0.1", 52 | "rimraf": "^3.0.1", 53 | "typedoc": "^0.16.9", 54 | "typescript": "^3.7.5" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/cloudflare.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016-2019 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {ApiError} from "./error"; 18 | import {Auth} from "./options"; 19 | import {httpsRequest} from "./request"; 20 | import { 21 | isArray, 22 | isCloudFlareResponse, 23 | isDnsRecordArray, 24 | isString, 25 | isZoneArray 26 | } from "./utils"; 27 | 28 | /** 29 | * @private 30 | */ 31 | const BASE_URL = "https://api.cloudflare.com/client/v4"; 32 | 33 | /** 34 | * Represents a CloudFlare API response. 35 | * 36 | * @private 37 | */ 38 | export interface ICloudFlareResponse { 39 | success: boolean; 40 | result?: unknown; 41 | result_info?: { 42 | page: number; 43 | total_pages: number; 44 | }; 45 | } 46 | 47 | /** 48 | * Represents a CloudFlare DNS record. 49 | * 50 | * @private 51 | */ 52 | export interface IDnsRecord { 53 | name: string; 54 | id: string; 55 | } 56 | 57 | /** 58 | * Represents a CloudFlare zone record. 59 | * 60 | * @private 61 | */ 62 | export interface IZone { 63 | name: string; 64 | id: string; 65 | } 66 | 67 | /** 68 | * Creates or updates a CloudFlare DNS record, depending on whether it already 69 | * exists. An error is returned if there are multiple DNS records for the 70 | * specified record name. 71 | * 72 | * @param auth CloudFlare API authentication information. 73 | * @param ip The IP to update the record with. 74 | * @param recordName The name of the record. 75 | * @param zoneName The name of the zone. 76 | * @param callback Callback function called with any error that occurred. 77 | * 78 | * @private 79 | */ 80 | export function createOrUpdateDnsRecord(auth: Auth, ip: string, 81 | recordName: string, 82 | zoneName: string, 83 | callback: (error?: Error) => void): void 84 | { 85 | getZoneId(zoneName, auth, (error, zoneId) => { 86 | if (error || !zoneId) { 87 | callback(error || new Error("Unknown error")); 88 | return; 89 | } 90 | getDnsRecordId(zoneId, recordName, auth, (error2, dnsRecordId) => { 91 | if (error2) { 92 | callback(error2); 93 | return; 94 | } 95 | 96 | if (dnsRecordId) { 97 | updateDnsRecord(zoneId, dnsRecordId, ip, auth, 98 | (error3?: Error) => { 99 | callback(error3); 100 | }); 101 | } else { 102 | createDnsRecord(zoneId, recordName, ip, auth, 103 | (error3?: Error) => { 104 | callback(error3); 105 | }); 106 | } 107 | }); 108 | }); 109 | } 110 | 111 | /** 112 | * Gets the specified DNS record from CloudFlare. This function is only used 113 | * for testing this module. 114 | * 115 | * @param auth CloudFlare API authentication information. 116 | * @param recordName The name of the record. 117 | * @param zoneName The name of the zone. 118 | * @param callback Callback function called with any error that occurred as 119 | * well as the ID of the record retrieved. 120 | * 121 | * @private 122 | */ 123 | export function getDnsRecord(auth: Auth, recordName: string, zoneName: string, 124 | callback: (err?: Error, 125 | dnsRecordId?: string) => void): void 126 | { 127 | getZoneId(zoneName, auth, (error, zoneId) => { 128 | if (error || !zoneId) { 129 | callback(error || new Error("Unknown error")); 130 | return; 131 | } 132 | getDnsRecordId(zoneId, recordName, auth, (error2, dnsRecordId) => { 133 | if (error2) { 134 | callback(error2); 135 | return; 136 | } 137 | callback(undefined, dnsRecordId); 138 | }); 139 | }); 140 | } 141 | 142 | /** 143 | * Deletes the specified DNS record from CloudFlare. This function is only used 144 | * for testing this module. 145 | * 146 | * @param auth CloudFlare API authentication information. 147 | * @param recordName The name of the record. 148 | * @param zoneName The name of the zone. 149 | * @param callback Callback function called with any error that occurred. 150 | * 151 | * @private 152 | */ 153 | export function deleteDnsRecord(auth: Auth, recordName: string, 154 | zoneName: string, 155 | callback: (err?: Error) => void): void 156 | { 157 | getZoneId(zoneName, auth, (error, zoneId) => { 158 | if (error || !zoneId) { 159 | callback(error || new Error("Unknown error")); 160 | return; 161 | } 162 | getDnsRecordId(zoneId, recordName, auth, (error2, dnsRecordId) => { 163 | if (error2) { 164 | callback(error2); 165 | return; 166 | } 167 | 168 | if (dnsRecordId) { 169 | getResults(`zones/${zoneId}/dns_records/${dnsRecordId}`, 170 | auth, 171 | (error3, results) => { 172 | if (error3 || !results) { 173 | callback( 174 | error3 || new Error("Unknown error")); 175 | return; 176 | } 177 | callback(); 178 | }, 179 | "DELETE"); 180 | } else { 181 | callback(); 182 | } 183 | }); 184 | }); 185 | } 186 | 187 | /** 188 | * Creates a DNS record with the specified information. 189 | * 190 | * @param zoneId The zone ID. 191 | * @param dnsRecordName The DNS record name. 192 | * @param ip The IP to update the record with. 193 | * @param auth CloudFlare API authentication information. 194 | * @param callback Callback function called with any error that occurred. 195 | * 196 | * @private 197 | */ 198 | function createDnsRecord(zoneId: string, dnsRecordName: string, 199 | ip: string, auth: Auth, 200 | callback: (error?: Error) => void) 201 | { 202 | getResults(`zones/${zoneId}/dns_records`, 203 | auth, 204 | (error, results) => { 205 | if (error || !results) { 206 | callback(error || new Error("Unknown error")); 207 | return; 208 | } 209 | callback(); 210 | }, 211 | "POST", 212 | JSON.stringify({ 213 | content: ip, 214 | name: dnsRecordName, 215 | type: "A" 216 | })); 217 | } 218 | 219 | /** 220 | * Updates a DNS record with the specified information. 221 | * 222 | * @param zoneId The zone ID. 223 | * @param recordId The DNS record ID. 224 | * @param ip The IP to update the record with. 225 | * @param auth CloudFlare API authentication information. 226 | * @param callback Callback function called with any error that occurred. 227 | * 228 | * @private 229 | */ 230 | function updateDnsRecord(zoneId: string, recordId: string, ip: string, 231 | auth: Auth, callback: (error?: Error) => void) 232 | { 233 | getResults(`zones/${zoneId}/dns_records/${recordId}`, 234 | auth, 235 | (error, results) => { 236 | if (error || !results) { 237 | callback(error || new Error("Unknown error")); 238 | return; 239 | } 240 | callback(); 241 | }, 242 | "PATCH", 243 | JSON.stringify({ 244 | content: ip, 245 | type: "A" 246 | })); 247 | } 248 | 249 | /** 250 | * Gets the DNS record ID associated with the specified record name. 251 | * 252 | * @param zoneId The zone ID. 253 | * @param dnsRecordName The DNS record name. 254 | * @param auth CloudFlare API authentication information. 255 | * @param callback Callback function called with any error that occurred, as 256 | * well as the DNS record ID. 257 | * 258 | * @private 259 | */ 260 | export function getDnsRecordId(zoneId: string, dnsRecordName: string, 261 | auth: Auth, 262 | callback: (error?: Error, 263 | dnsRecordId?: string) => void): void 264 | { 265 | getResults(`zones/${zoneId}/dns_records`, auth, (error, results) => { 266 | if (error || !results) { 267 | callback(error || new Error("Unknown error")); 268 | return; 269 | } 270 | 271 | if (!isDnsRecordArray(results)) { 272 | callback(new ApiError( 273 | { 274 | message: "Malformed CloudFlare API response", 275 | result: results 276 | })); 277 | return; 278 | } 279 | const matchingResults = results.filter( 280 | (r) => r.name === dnsRecordName); 281 | if (matchingResults.length === 0) { 282 | callback(); 283 | return; 284 | } 285 | if (matchingResults.length > 1) { 286 | callback(new ApiError( 287 | { 288 | message: `Multiple DNS record entries found with name` 289 | + ` ${dnsRecordName}`, 290 | result: results 291 | })); 292 | return; 293 | } 294 | 295 | const result = matchingResults[0]; 296 | if (!isString(result.id)) { 297 | callback(new ApiError( 298 | { 299 | message: "ID for DNS record entry malformed or missing", 300 | result: results 301 | })); 302 | return; 303 | } 304 | 305 | callback(undefined, result.id); 306 | }); 307 | } 308 | 309 | /** 310 | * Gets the zone ID associated with the specified zone name. 311 | * 312 | * @param zoneName The zone name. 313 | * @param auth CloudFlare API authentication information. 314 | * @param callback Callback function called with any error that occurred, as 315 | * well as the zone ID. 316 | * 317 | * @private 318 | */ 319 | export function getZoneId(zoneName: string, auth: Auth, 320 | callback: (error?: Error, 321 | id?: string) => void): void 322 | { 323 | getResults("zones", auth, (error, results) => { 324 | if (error || !results) { 325 | callback(error || new Error("Unknown error")); 326 | return; 327 | } 328 | 329 | if (!isZoneArray(results)) { 330 | callback(new ApiError( 331 | { 332 | message: "Malformed CloudFlare API response", 333 | result: results 334 | })); 335 | return; 336 | } 337 | const matchingResults = results.filter( 338 | (r) => r.name === zoneName); 339 | if (matchingResults.length === 0) { 340 | callback(new ApiError( 341 | { 342 | message: `No zone entries found with name ${zoneName}`, 343 | result: results 344 | })); 345 | return; 346 | } 347 | if (matchingResults.length > 1) { 348 | callback(new ApiError( 349 | { 350 | message: `No zone entries found with name ${zoneName}`, 351 | result: results 352 | })); 353 | return; 354 | } 355 | 356 | const result = matchingResults[0]; 357 | if (!isString(result.id)) { 358 | callback(new ApiError( 359 | { 360 | message: "ID for zone entry malformed or missing", 361 | result: results 362 | })); 363 | return; 364 | } 365 | 366 | callback(undefined, result.id); 367 | }); 368 | } 369 | 370 | /** 371 | * Gets results from the CloudFlare API. 372 | * 373 | * @param path The URI. 374 | * @param auth CloudFlare API authentication information. 375 | * @param callback Callback function called with any error that occurred, as 376 | * well as the API results. 377 | * @param method The HTTP method. 378 | * @param body The request body. 379 | * @param startPage The start page associated with the request. 380 | * 381 | * @private 382 | */ 383 | export function getResults( 384 | path: string, 385 | auth: Auth, 386 | callback: (error?: Error, results?: unknown[]) => void, 387 | method = "GET", 388 | body?: string, 389 | startPage = 1): void 390 | { 391 | let uri = `${BASE_URL}/${path}`; 392 | if (method === "GET") { 393 | uri += `?page=${startPage}`; 394 | } 395 | const headers = { 396 | "X-Auth-Email": auth.email, 397 | "X-Auth-Key": auth.key 398 | }; 399 | httpsRequest(uri, (error, response, responseBody) => { 400 | if (error) { 401 | callback(new ApiError( 402 | { 403 | body: responseBody, 404 | innerError: error, 405 | message: "Error accessing CloudFlare API", 406 | response 407 | })); 408 | return; 409 | } 410 | 411 | if (!responseBody) { 412 | callback(new ApiError( 413 | { 414 | innerError: error, 415 | message: "Missing response body", 416 | response 417 | })); 418 | return; 419 | } 420 | 421 | let validatedJson: ICloudFlareResponse; 422 | try { 423 | const json = JSON.parse(responseBody); 424 | if (!isCloudFlareResponse(json)) { 425 | callback(new ApiError( 426 | { 427 | message: "Malformed CloudFlare API response", 428 | result: json 429 | })); 430 | return; 431 | } 432 | validatedJson = json; 433 | } catch (ex) { 434 | callback(new ApiError( 435 | { 436 | message: "Malformed CloudFlare API response", 437 | result: responseBody 438 | })); 439 | return; 440 | } 441 | 442 | if (!validatedJson.success) { 443 | callback(new ApiError( 444 | { 445 | body: responseBody, 446 | message: "CloudFlare API returned success false", 447 | response 448 | })); 449 | return; 450 | } 451 | 452 | let results: unknown[] = []; 453 | if (isArray(validatedJson.result)) { 454 | results = results.concat(validatedJson.result); 455 | } else { 456 | results.push(validatedJson.result); 457 | } 458 | 459 | if (validatedJson.result_info 460 | && validatedJson.result_info.page 461 | < validatedJson.result_info.total_pages) 462 | { 463 | getResults(path, auth, (extraError, extraResults) => { 464 | if (error) { 465 | callback(extraError); 466 | return; 467 | } 468 | 469 | results = results.concat(extraResults); 470 | callback(undefined, results); 471 | }, method, body, startPage + 1); 472 | } else { 473 | callback(undefined, results); 474 | } 475 | }, method, headers, body); 476 | } 477 | -------------------------------------------------------------------------------- /src/error.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import * as http from "http"; 18 | 19 | /** 20 | * @private 21 | */ 22 | export interface IApiErrorOptions { 23 | message: string; 24 | innerError?: unknown; 25 | response?: http.IncomingMessage; 26 | body?: unknown; 27 | result?: unknown; 28 | } 29 | 30 | /** 31 | * Represents an error in contacting or parsing a response from the CloudFlare 32 | * API or the myexternalip.com API. 33 | */ 34 | export class ApiError extends Error { 35 | /** 36 | * The message associated with the error. 37 | */ 38 | public message: string; 39 | 40 | /** 41 | * The error that caused this error, if applicable. 42 | */ 43 | public innerError?: unknown; 44 | 45 | /** 46 | * The response returned from the API, if applicable. 47 | */ 48 | public response?: http.IncomingMessage; 49 | 50 | /** 51 | * The body of the response returned from the API, if applicable. 52 | */ 53 | public body?: unknown; 54 | 55 | /** 56 | * The API result, if applicable. 57 | */ 58 | public result?: unknown; 59 | 60 | /** 61 | * @private 62 | */ 63 | constructor(options: IApiErrorOptions) { 64 | super(options.message); 65 | this.message = options.message; 66 | this.innerError = options.innerError; 67 | this.response = options.response; 68 | this.body = options.body; 69 | this.result = options.result; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/ip.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {ApiError} from "./error"; 18 | import {httpsRequest} from "./request"; 19 | 20 | /** 21 | * @private 22 | */ 23 | const URL = "https://myexternalip.com/raw"; 24 | 25 | /** 26 | * Gets the current external IP from the myexternalip.com API. 27 | * 28 | * @param callback Callback function called with any error that occurred as 29 | * well as the IP address returned from the API. 30 | * 31 | * @private 32 | */ 33 | export function getExternalIp(callback: (error?: Error, 34 | ip?: string) => void): void { 35 | httpsRequest(URL, (error, response, responseBody) => { 36 | if (error) { 37 | callback(new ApiError({ 38 | body: responseBody, 39 | message: `Error accessing ${URL}`, 40 | response 41 | })); 42 | return; 43 | } 44 | if (!responseBody) { 45 | callback(new ApiError({ 46 | message: "Missing response body", 47 | response 48 | })); 49 | return; 50 | } 51 | callback(undefined, responseBody.trim()); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2014-2016 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {createOrUpdateDnsRecord} from "./cloudflare"; 18 | import {getExternalIp} from "./ip"; 19 | import {IOptions, Options} from "./options"; 20 | 21 | /** 22 | * Updates the specified CloudFlare DNS record with an IP address, creating it 23 | * if it does not exist. 24 | * 25 | * @param options The options associated with the update request. 26 | * @param callback Callback function called with any error that occurred as 27 | * well as the new IP address if the request succeeded. 28 | */ 29 | export function update(options: IOptions, 30 | callback: (err?: Error, newIp?: string) => void): void { 31 | const {auth, ip, recordName, zoneName} = new Options(options); 32 | 33 | if (ip) { 34 | createOrUpdateDnsRecord(auth, ip, recordName, zoneName, (error) => { 35 | if (error) { 36 | callback(error); 37 | return; 38 | } 39 | callback(undefined, ip); 40 | }); 41 | } else { 42 | getExternalIp((error, externalIp) => { 43 | if (error || !externalIp) { 44 | callback(error || new Error("Unknown error")); 45 | return; 46 | } 47 | createOrUpdateDnsRecord(auth, externalIp, recordName, zoneName, 48 | (error2) => { 49 | if (error2) { 50 | callback(error2); 51 | return; 52 | } 53 | callback(undefined, externalIp); 54 | }); 55 | }); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/options.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {isObject, isString, isUndefined} from "./utils"; 18 | 19 | /** 20 | * Represents CloudFlare API settings for key and email authentication. 21 | */ 22 | export interface IAuth { 23 | /** 24 | * The API key associated with your CloudFlare account. 25 | */ 26 | key: string; 27 | 28 | /** 29 | * The email associated with your CloudFlare account. 30 | */ 31 | email: string; 32 | } 33 | 34 | /** 35 | * Implementation of the IAuth interface used to provide default values 36 | * to fields. 37 | * 38 | * @private 39 | */ 40 | export class Auth implements IAuth { 41 | public key: string; 42 | public email: string; 43 | 44 | constructor(options: IAuth) { 45 | if (!isObject(options)) { 46 | throw new TypeError("options.auth should be an Object"); 47 | } 48 | 49 | if (!isString(options.key)) { 50 | throw new TypeError("options.auth.key should be a string"); 51 | } else { 52 | this.key = options.key; 53 | } 54 | 55 | if (!isString(options.email)) { 56 | throw new TypeError("options.auth.email should be a string"); 57 | } else { 58 | this.email = options.email; 59 | } 60 | } 61 | } 62 | 63 | /** 64 | * The options associated with updating a CloudFlare DNS record with an IP 65 | * address. 66 | */ 67 | export interface IOptions { 68 | /** 69 | * CloudFlare API settings for key and email authentication. 70 | */ 71 | auth: IAuth; 72 | 73 | /** 74 | * The new IP address for the record. If left undefined, the external IP as 75 | * defined by myexternalip.com API is used. 76 | */ 77 | ip?: string; 78 | 79 | /** 80 | * The name of the DNS record (e.g. `subdomain.example.com`). 81 | */ 82 | recordName: string; 83 | 84 | /** 85 | * The name of the CloudFlare zone (e.g. `example.com`). 86 | */ 87 | zoneName: string; 88 | } 89 | 90 | /** 91 | * Implementation of the IOptions interface used to provide default values 92 | * to fields. 93 | * 94 | * @private 95 | */ 96 | export class Options implements IOptions { 97 | public auth: Auth; 98 | public ip?: string; 99 | public recordName: string; 100 | public zoneName: string; 101 | 102 | constructor(options: IOptions) { 103 | this.auth = new Auth(options.auth); 104 | 105 | this.ip = options.ip; 106 | 107 | if (!isString(options.ip)) { 108 | if (!isUndefined(options.ip)) { 109 | throw new TypeError("options.ip should be a string or" 110 | + " undefined"); 111 | } 112 | } else { 113 | this.ip = options.ip; 114 | } 115 | 116 | if (!isString(options.recordName)) { 117 | throw new TypeError("options.recordName should be a string"); 118 | } else { 119 | this.recordName = options.recordName; 120 | } 121 | 122 | if (!isString(options.zoneName)) { 123 | throw new TypeError("options.zoneName should be a string"); 124 | } else { 125 | this.zoneName = options.zoneName; 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /src/request.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import * as http from "http"; 18 | import * as https from "https"; 19 | import {parse} from "url"; 20 | 21 | /** 22 | * Creates an HTTPS request to the specified URL. 23 | * 24 | * @param url The URL of the HTTP request. 25 | * @param callback Called when a response is received with any error that 26 | * occurred as well as the response and response body if one is 27 | * received. 28 | * @param method The HTTP method associated with the request. 29 | * @param headers An object containing the headers of the request. 30 | * @param body The body of the request. 31 | * 32 | * @private 33 | */ 34 | export function httpsRequest(url: string, 35 | callback: (error?: Error, 36 | response?: http.IncomingMessage, 37 | body?: string) => void, 38 | method = "GET", 39 | headers: { [name: string]: string } = {}, 40 | body?: string): void 41 | { 42 | const uri = parse(url); 43 | 44 | const options: https.RequestOptions = {}; 45 | options.protocol = uri.protocol; 46 | options.host = uri.host; 47 | options.auth = uri.auth; 48 | options.path = uri.path; 49 | if (uri.hash) { 50 | options.path += uri.hash; 51 | } 52 | options.method = method; 53 | options.headers = headers; 54 | 55 | if (method !== "GET") { 56 | options.headers["Content-Type"] = "application/json"; 57 | } 58 | 59 | const request = https.request(options, 60 | (response: http.IncomingMessage) => { 61 | let responseBody = ""; 62 | 63 | response.setEncoding("utf8"); 64 | response.on("data", (chunk: string) => { 65 | responseBody += chunk; 66 | }); 67 | response.on("end", () => { 68 | callback(undefined, response, 69 | responseBody); 70 | }); 71 | response.on("error", (error?: Error) => { 72 | callback(error, response); 73 | }); 74 | }); 75 | request.on("error", (error?: Error) => { 76 | callback(error); 77 | }); 78 | if (body) { 79 | request.end(body); 80 | } else { 81 | request.end(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016-2019 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {ICloudFlareResponse, IDnsRecord, IZone} from "./cloudflare"; 18 | 19 | /** 20 | * Returns whether or not the value is a string. 21 | * 22 | * @private 23 | */ 24 | export function isString(val: unknown): val is string { 25 | return Object.prototype.toString.call(val) === "[object String]"; 26 | } 27 | 28 | /** 29 | * Returns whether or not the value is undefined. 30 | * 31 | * @private 32 | */ 33 | export function isUndefined(val: unknown): val is undefined { 34 | return Object.prototype.toString.call(val) === "[object Undefined]"; 35 | } 36 | 37 | /** 38 | * Returns whether or not the value is an object. 39 | * 40 | * @private 41 | */ 42 | export function isObject(val: unknown): val is Record { 43 | return Object.prototype.toString.call(val) === "[object Object]"; 44 | } 45 | 46 | /** 47 | * Returns whether or not the value is an array. 48 | * 49 | * @private 50 | */ 51 | export function isArray(val: unknown): val is unknown[] { 52 | return Object.prototype.toString.call(val) === "[object Array]"; 53 | } 54 | 55 | /** 56 | * Returns whether or not the value is a number. 57 | * 58 | * @private 59 | */ 60 | export function isNumber(val: unknown): val is number { 61 | return Object.prototype.toString.call(val) === "[object Number]"; 62 | } 63 | 64 | /** 65 | * Returns whether or not the value is a boolean. 66 | * 67 | * @private 68 | */ 69 | export function isBoolean(val: unknown): val is boolean { 70 | return Object.prototype.toString.call(val) === "[object Boolean]"; 71 | } 72 | 73 | /** 74 | * Returns whether or not the value is an ICloudFlareResponse. 75 | * 76 | * @private 77 | */ 78 | export function isCloudFlareResponse(val: unknown): val is ICloudFlareResponse { 79 | return isObject(val) && "success" in val && isBoolean(val.success) 80 | && (!("result_info" in val) 81 | || (isObject(val.result_info) 82 | && "page" in val.result_info 83 | && isNumber(val.result_info.page) 84 | && "total_pages" in val.result_info 85 | && isNumber(val.result_info.total_pages))); 86 | } 87 | 88 | /** 89 | * Returns whether or not the value is an IDnsRecord array. 90 | * 91 | * @private 92 | */ 93 | export function isDnsRecordArray(val: unknown[]): val is IDnsRecord[] { 94 | return val.every((e) => isObject(e) && "name" in e && isString(e.name) 95 | && "id" in e && isString(e.name)); 96 | } 97 | 98 | /** 99 | * Returns whether or not the value is an IZone array. 100 | * 101 | * @private 102 | */ 103 | export function isZoneArray(val: unknown[]): val is IZone[] { 104 | return val.every((e) => isObject(e) && "name" in e && isString(e.name) 105 | && "id" in e && isString(e.name)); 106 | } 107 | -------------------------------------------------------------------------------- /test/src/main.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (C) 2016-2019 Michael Kourlas 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import {assert} from "chai"; 18 | import {deleteDnsRecord, getDnsRecord} from "../../lib/cloudflare"; 19 | import {update} from "../../lib/main"; 20 | import {Auth} from "../../lib/options"; 21 | 22 | const auth = { 23 | email: process.env.CLOUDFLARE_API_EMAIL as string, 24 | key: process.env.CLOUDFLARE_API_KEY as string 25 | }; 26 | const authObj = new Auth(auth); 27 | 28 | const recordName = "cloudflare-dynamic-dns-test.kourlas.com"; 29 | const zoneName = "kourlas.com"; 30 | 31 | describe("main", () => { 32 | describe("#update", () => { 33 | it("should correctly create a DNS record with a specified" 34 | + " IP", (callback) => { 35 | deleteDnsRecord(authObj, recordName, zoneName, (err) => { 36 | assert.isUndefined(err); 37 | const options = { 38 | auth, 39 | ip: "1.1.1.1", 40 | recordName, 41 | zoneName 42 | }; 43 | update(options, (err2) => { 44 | assert.isUndefined(err2); 45 | getDnsRecord( 46 | authObj, 47 | recordName, 48 | zoneName, 49 | (err3, dnsRecordId) => { 50 | assert.isUndefined(err3); 51 | assert.isString(dnsRecordId); 52 | 53 | deleteDnsRecord( 54 | authObj, 55 | recordName, 56 | zoneName, 57 | (err4) => { 58 | assert.isUndefined( 59 | err4); 60 | callback(); 61 | }); 62 | }); 63 | }); 64 | }); 65 | }).timeout(5000); 66 | 67 | it("should correctly update a DNS record with a specified" 68 | + " IP", (callback) => { 69 | deleteDnsRecord(authObj, recordName, zoneName, (err) => { 70 | assert.isUndefined(err); 71 | const options = { 72 | auth, 73 | ip: "1.1.1.1", 74 | recordName, 75 | zoneName 76 | }; 77 | update(options, (err2) => { 78 | assert.isUndefined(err2); 79 | const options2 = { 80 | auth, 81 | ip: "1.1.1.1", 82 | recordName, 83 | zoneName 84 | }; 85 | update(options2, (err3) => { 86 | assert.isUndefined(err3); 87 | getDnsRecord( 88 | authObj, 89 | recordName, 90 | zoneName, 91 | (err4, dnsRecordId) => { 92 | assert.isUndefined(err4); 93 | assert.isString(dnsRecordId); 94 | 95 | deleteDnsRecord( 96 | authObj, 97 | recordName, 98 | zoneName, 99 | (err5) => { 100 | assert.isUndefined(err5); 101 | callback(); 102 | }); 103 | }); 104 | }); 105 | }); 106 | }); 107 | }).timeout(5000); 108 | 109 | it("should correctly create a DNS record with the external" 110 | + " IP", (callback) => { 111 | deleteDnsRecord(authObj, recordName, zoneName, (err) => { 112 | assert.isUndefined(err); 113 | const options = { 114 | auth, 115 | recordName, 116 | zoneName 117 | }; 118 | update(options, (err2) => { 119 | assert.isUndefined(err2); 120 | getDnsRecord( 121 | authObj, 122 | recordName, 123 | zoneName, 124 | (err3, dnsRecordId) => { 125 | assert.isUndefined(err3); 126 | assert.isString(dnsRecordId); 127 | 128 | deleteDnsRecord( 129 | authObj, 130 | recordName, 131 | zoneName, 132 | (err4) => { 133 | assert.isUndefined( 134 | err4); 135 | callback(); 136 | }); 137 | }); 138 | }); 139 | }); 140 | }).timeout(5000); 141 | 142 | it("should correctly update a DNS record with the external" 143 | + " IP", (callback) => { 144 | deleteDnsRecord(authObj, recordName, zoneName, (err) => { 145 | assert.isUndefined(err); 146 | const options = { 147 | auth, 148 | ip: "1.1.1.1", 149 | recordName, 150 | zoneName 151 | }; 152 | update(options, (err2) => { 153 | assert.isUndefined(err2); 154 | const options2 = { 155 | auth, 156 | recordName, 157 | zoneName 158 | }; 159 | update(options2, (err3) => { 160 | assert.isUndefined(err3); 161 | getDnsRecord( 162 | authObj, 163 | recordName, 164 | zoneName, 165 | (err4, dnsRecordId) => { 166 | assert.isUndefined(err4); 167 | assert.isString(dnsRecordId); 168 | 169 | deleteDnsRecord( 170 | authObj, 171 | recordName, 172 | zoneName, 173 | (err5) => { 174 | assert.isUndefined(err5); 175 | callback(); 176 | }); 177 | }); 178 | }); 179 | }); 180 | }); 181 | }).timeout(5000); 182 | }); 183 | }); 184 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "esModuleInterop": true, 4 | "forceConsistentCasingInFileNames": true, 5 | "module": "commonjs", 6 | "noFallthroughCasesInSwitch": true, 7 | "noImplicitReturns": true, 8 | "noUnusedLocals": true, 9 | "noUnusedParameters": true, 10 | "outDir": "lib", 11 | "strict": true, 12 | "target": "es5", 13 | "types": [ 14 | "node", 15 | "chai", 16 | "mocha" 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": true, 4 | "esModuleInterop": true, 5 | "forceConsistentCasingInFileNames": true, 6 | "module": "commonjs", 7 | "noFallthroughCasesInSwitch": true, 8 | "noImplicitReturns": true, 9 | "noUnusedLocals": true, 10 | "noUnusedParameters": true, 11 | "outDir": "lib", 12 | "strict": true, 13 | "target": "es5", 14 | "types": [ 15 | "node" 16 | ] 17 | }, 18 | "exclude": [ 19 | "docs", 20 | "examples", 21 | "lib", 22 | "node_modules", 23 | "test" 24 | ] 25 | } 26 | --------------------------------------------------------------------------------