diff --git a/docs/conf.py b/docs/conf.py index 06a986f5..68d78c94 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -82,4 +82,74 @@ def setup(app): # the docs. This file should be a Windows icon file (.ico) being 16x16 or # 32x32 pixels large. # -html_favicon = "static/favicon.ico" \ No newline at end of file +html_favicon = "static/favicon.ico" + +# -- Options for LaTeX output ------------------------------------------------------------------------------------------- +latex_engine = 'lualatex' +latex_use_xindy = False + +# latex config taken from connextdds repo +latex_elements = { + # The paper size ('letterpaper' or 'a4paper'). + 'papersize': 'letterpaper', + + # The font size ('10pt', '11pt' or '12pt') + 'pointsize': '11pt', + 'preamble': '''\ +\\sphinxsetup{TitleColor={named}{black},InnerLinkColor={named}{black},OuterLinkColor={named}{blue}} +\\usepackage[utf8]{inputenc} +\\usepackage[titles]{tocloft} +\\usepackage{multirow} +\\usepackage{newunicodechar} +\\usepackage{hyperref} +\\usepackage{fontspec} +\\usepackage{graphicx} +\\setkeys{Gin}{width=.85\\textwidth} +\\hypersetup{bookmarksnumbered} +\\setcounter{tocdepth}{3} +\\usepackage{fancyhdr} +\\setlength{\headheight}{14pt} +\\usepackage[draft]{minted}\\fvset{breaklines=true, breakanywhere=true}''', + 'printindex': '\\footnotesize\\raggedright\\printindex', + 'inputenc': '', + 'utf8extra': '', + 'classoptions': ',openany,oneside', + 'releasename': 'Version', + 'fncychap': '', + 'maketitle': '''\ + \\pagenumbering{Roman} %%% to avoid page 1 conflict with actual page 1 + \\begin{titlepage} + \\centering + + \\vspace{40mm} %%% * is used to give space from top + + \\textbf{\\Huge{''' + project + '''}} + \\vspace{17mm} + + \\textbf{\\Large{Version ''' + version + '''}} + + \\vspace{100mm} + \\vspace{0mm} + \\end{titlepage} + ''' +} + +latex_use_modindex = True + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ( + master_doc, + 'rticonnectorforjavascript.tex', + 'RTI Connector for Javascript', + '2021, Real-Time Innovations, Inc.', + 'manual' + ), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# +html_logo = "static/rti-logo-FINALv2-White-OrangeDot.png" \ No newline at end of file diff --git a/docs/copyright_license.rst b/docs/copyright_license.rst index 545d0de1..f07a825e 100644 --- a/docs/copyright_license.rst +++ b/docs/copyright_license.rst @@ -104,7 +104,7 @@ Website: https://support.rti.com/ |br| notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE diff --git a/docs/index.rst b/docs/index.rst index 750e9a00..902e67e3 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,8 +1,10 @@ .. highlight:: javascript -.. image:: static/RTI_Launcher_Icon_Connector_JavaScript_100x100_0919_forDocumentation.png - :align: left +.. only:: html + + .. image:: static/RTI_Launcher_Icon_Connector_JavaScript_100x100_0919_forDocumentation.png + :align: left Welcome to RTI Connector for JavaScript! ======================================== @@ -19,9 +21,6 @@ You can learn how to use *RTI Connector* by reading the following sections, whic include examples and detailed API reference. You can also find a specific type or function in the :ref:`genindex`. -Table of Contents -================= - .. toctree:: :maxdepth: 2 :numbered: diff --git a/package-lock.json b/package-lock.json index 68f5e7d1..46617990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,77 +4,2337 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.13.tgz", + "integrity": "sha512-HV1Cm0Q3ZrpCR93tkWOYiuYIgLxZXZFVG2VgK+MBWjUqZTundupbfx2aXarXuw5Ko5aMcjtJgbSs4vUGBS5v6g==", + "dev": true, + "requires": { + "@babel/highlight": "^7.12.13" + } + }, + "@babel/compat-data": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.14.0.tgz", + "integrity": "sha512-vu9V3uMM/1o5Hl5OekMUowo3FqXLJSw+s+66nt0fSWVWTtmosdzn45JHOB3cPtZoe6CTBDzvSw0RdOY85Q37+Q==", + "dev": true + }, + "@babel/core": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.14.0.tgz", + "integrity": "sha512-8YqpRig5NmIHlMLw09zMlPTvUVMILjqCOtVgu+TVNWEBvy9b5I3RRyhqnrV4hjgEK7n8P9OqvkWJAFmEL6Wwfw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-compilation-targets": "^7.13.16", + "@babel/helper-module-transforms": "^7.14.0", + "@babel/helpers": "^7.14.0", + "@babel/parser": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.1.2", + "semver": "^6.3.0", + "source-map": "^0.5.0" + } + }, + "@babel/generator": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.14.1.tgz", + "integrity": "sha512-TMGhsXMXCP/O1WtQmZjpEYDhCYC9vFhayWZPJSZCGkPJgUqX0rF0wwtrYvnzVxIjcF80tkUertXVk5cwqi5cAQ==", + "dev": true, + "requires": { + "@babel/types": "^7.14.1", + "jsesc": "^2.5.1", + "source-map": "^0.5.0" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.13.16", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.13.16.tgz", + "integrity": "sha512-3gmkYIrpqsLlieFwjkGgLaSHmhnvlAYzZLlYVjlW+QwI+1zE17kGxuJGmIqDQdYp56XdmGeD+Bswx0UTyG18xA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.13.15", + "@babel/helper-validator-option": "^7.12.17", + "browserslist": "^4.14.5", + "semver": "^6.3.0" + } + }, + "@babel/helper-function-name": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.12.13.tgz", + "integrity": "sha512-TZvmPn0UOqmvi5G4vvw0qZTpVptGkB1GL61R6lKvrSdIxGm5Pky7Q3fpKiIkQCAtRCBUwB0PaThlx9vebCDSwA==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.12.13", + "@babel/template": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz", + "integrity": "sha512-DjEVzQNz5LICkzN0REdpD5prGoidvbdYk1BVgRUOINaWJP2t6avB27X1guXK1kXNrX0WMfsrm1A/ZBthYuIMQg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.12.tgz", + "integrity": "sha512-48ql1CLL59aKbU94Y88Xgb2VFy7a95ykGRbJJaaVv+LX5U8wFpLfiGXJJGUozsmA1oEh/o5Bp60Voq7ACyA/Sw==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-imports": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz", + "integrity": "sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-module-transforms": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.14.0.tgz", + "integrity": "sha512-L40t9bxIuGOfpIGA3HNkJhU9qYrf4y5A5LUSw7rGMSn+pcG8dfJ0g6Zval6YJGd2nEjI7oP00fRdnhLKndx6bw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.13.12", + "@babel/helper-replace-supers": "^7.13.12", + "@babel/helper-simple-access": "^7.13.12", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/helper-validator-identifier": "^7.14.0", + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.12.13.tgz", + "integrity": "sha512-BdWQhoVJkp6nVjB7nkFWcn43dkprYauqtk++Py2eaf/GRDFm5BxRqEIZCiHlZUGAVmtwKcsVL1dC68WmzeFmiA==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-replace-supers": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.13.12.tgz", + "integrity": "sha512-Gz1eiX+4yDO8mT+heB94aLVNCL+rbuT2xy4YfyNqu8F+OI6vMvJK891qGBTqL9Uc8wxEvRW92Id6G7sDen3fFw==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.13.12", + "@babel/helper-optimise-call-expression": "^7.12.13", + "@babel/traverse": "^7.13.0", + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-simple-access": { + "version": "7.13.12", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz", + "integrity": "sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==", + "dev": true, + "requires": { + "@babel/types": "^7.13.12" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.12.13.tgz", + "integrity": "sha512-tCJDltF83htUtXx5NLcaDqRmknv652ZWCHyoTETf1CXYJdPC7nohZohjUgieXhv0hTJdRf2FjDueFehdNucpzg==", + "dev": true, + "requires": { + "@babel/types": "^7.12.13" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz", + "integrity": "sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.12.17", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz", + "integrity": "sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw==", + "dev": true + }, + "@babel/helpers": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.14.0.tgz", + "integrity": "sha512-+ufuXprtQ1D1iZTO/K9+EBRn+qPWMJjZSw/S0KlFrxCw4tkrzv9grgpDHkY9MeQTjTY8i2sp7Jep8DfU6tN9Mg==", + "dev": true, + "requires": { + "@babel/template": "^7.12.13", + "@babel/traverse": "^7.14.0", + "@babel/types": "^7.14.0" + } + }, + "@babel/highlight": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.14.0.tgz", + "integrity": "sha512-YSCOwxvTYEIMSGaBQb5kDDsCopDdiUGsqpatp3fOlI4+2HQSkTmEVWnVuySdAC5EWCqSWWTv0ib63RjR7dTBdg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.1.tgz", + "integrity": "sha512-muUGEKu8E/ftMTPlNp+mc6zL3E9zKWmF5sDHZ5MSsoTP9Wyz64AhEf9kD08xYJ7w6Hdcu8H550ircnPyWSIF0Q==", + "dev": true + }, + "@babel/template": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.12.13.tgz", + "integrity": "sha512-/7xxiGA57xMo/P2GVvdEumr8ONhFOhfgq2ihK3h1e6THqzTAkHbkXgB0xI9yeTfIUoH3+oAeHhqm/I43OTbbjA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/parser": "^7.12.13", + "@babel/types": "^7.12.13" + } + }, + "@babel/traverse": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.14.0.tgz", + "integrity": "sha512-dZ/a371EE5XNhTHomvtuLTUyx6UEoJmYX+DT5zBCQN3McHemsuIaKKYqsc/fs26BEkHs/lBZy0J571LP5z9kQA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@babel/generator": "^7.14.0", + "@babel/helper-function-name": "^7.12.13", + "@babel/helper-split-export-declaration": "^7.12.13", + "@babel/parser": "^7.14.0", + "@babel/types": "^7.14.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.14.1", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.1.tgz", + "integrity": "sha512-S13Qe85fzLs3gYRUnrpyeIrBJIMYv33qSTg1qoBwiG6nPKwUWAD9odSzWhEedpwOIzSEI6gbdQIWEMiCI42iBA==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.14.0", + "to-fast-properties": "^2.0.0" + } + }, + "@eslint/eslintrc": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.1.tgz", + "integrity": "sha512-5v7TDE9plVhvxQeWLXDTvFvJBdH6pEsdnl2g/dAptmuFEPedQ4Erq5rsDsX+mvAM610IhNaO2W5V1dOOnDKxkQ==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.1.1", + "espree": "^7.3.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.2.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + } + } + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "acorn-jsx": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.1.tgz", + "integrity": "sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==", + "dev": true + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-includes": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.3.tgz", + "integrity": "sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "get-intrinsic": "^1.1.1", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz", + "integrity": "sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.1" + } + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "babel-eslint": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", + "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.7.0", + "@babel/traverse": "^7.7.0", + "@babel/types": "^7.7.0", + "eslint-visitor-keys": "^1.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browserslist": { + "version": "4.16.6", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.16.6.tgz", + "integrity": "sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001219", + "colorette": "^1.2.2", + "electron-to-chromium": "^1.3.723", + "escalade": "^3.1.1", + "node-releases": "^1.1.71" + } + }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30001228", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001228.tgz", + "integrity": "sha512-QQmLOGJ3DEgokHbMSA8cj2a+geXqmnpyOFT0lhQV6P3/YOJvGDEwoedcwxEQ30gJIwIIunHIicunJ2rzK5gB2A==", + "dev": true + }, + "chai": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.4.tgz", + "integrity": "sha512-yS5H68VYOCtN1cjfwumDSuzn/9c+yza4f3reKXlE5rUg7SFcCEy90gJvydNgOYtblyf4Zi6jIWRnXOgErta0KA==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colorette": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz", + "integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, "debug": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "requires": { - "ms": "2.1.2" + "ms": "2.1.2" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.3.727", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.727.tgz", + "integrity": "sha512-Mfz4FIB4FSvEwBpDfdipRIrwd6uo8gUDoRDF4QEYb4h4tSuI3ov594OrjU6on042UlFHouIJpClDODGkPcBSbg==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "dev": true, + "requires": { + "ansi-colors": "^4.1.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.18.0.tgz", + "integrity": "sha512-LJzK7MrQa8TS0ja2w3YNLzUgJCGPdPOV1yVvezjNnS89D+VR08+Szt2mz3YB2Dck/+w5tfIq/RoUAFqJJGM2yw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "get-intrinsic": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.2", + "is-callable": "^1.2.3", + "is-negative-zero": "^2.0.1", + "is-regex": "^1.1.2", + "is-string": "^1.0.5", + "object-inspect": "^1.9.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "string.prototype.trimend": "^1.0.4", + "string.prototype.trimstart": "^1.0.4", + "unbox-primitive": "^1.0.0" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.26.0.tgz", + "integrity": "sha512-4R1ieRf52/izcZE7AlLy56uIHHDLT74Yzz2Iv2l6kDaYvEu9x+wMB5dZArVL8SYGXSYV2YAg70FcW5Y5nGGNIg==", + "dev": true, + "requires": { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.1", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + "espree": "^7.3.1", + "esquery": "^1.4.0", + "esutils": "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^13.6.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.4.1", + "lodash": "^4.17.21", + "minimatch": "^3.0.4", + "natural-compare": "^1.4.0", + "optionator": "^0.9.1", + "progress": "^2.0.0", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + "table": "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.12.11", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.12.11.tgz", + "integrity": "sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.4" + } + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "globals": { + "version": "13.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.8.0.tgz", + "integrity": "sha512-rHtdA6+PDBIjeEvA91rpqzEvk/k3/i7EeNQiryiWuJH0Hw9cpyJMAt2jtbAwUaRdhD+573X4vWw6IcjKPasi9Q==", + "dev": true, + "requires": { + "type-fest": "^0.20.2" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + } + } + }, + "eslint-config-standard": { + "version": "16.0.2", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-16.0.2.tgz", + "integrity": "sha512-fx3f1rJDsl9bY7qzyX8SAtP8GBSk6MfXFaTfaGgk12aAYW4gJSyRm7dM790L6cbXv63fvjY4XeSzXnb4WM+SKw==", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz", + "integrity": "sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.6.0.tgz", + "integrity": "sha512-6j9xxegbqe8/kZY8cYpcp0xhbK0EgJlg3g9mib3/miLaExuuwc3n5UEfSnU6hWMbT0FAYVvDbL9RrRgpUeQIvA==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-es": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz", + "integrity": "sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==", + "dev": true, + "requires": { + "eslint-utils": "^2.0.0", + "regexpp": "^3.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.22.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.22.1.tgz", + "integrity": "sha512-8K7JjINHOpH64ozkAhpT3sd+FswIZTfMZTjdx052pnWrgRCVfp8op9tbjpAk3DdUeI/Ba4C8OjdC0r90erHEOw==", + "dev": true, + "requires": { + "array-includes": "^3.1.1", + "array.prototype.flat": "^1.2.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.4", + "eslint-module-utils": "^2.6.0", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.1", + "read-pkg-up": "^2.0.0", + "resolve": "^1.17.0", + "tsconfig-paths": "^3.9.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-node": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz", + "integrity": "sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==", + "dev": true, + "requires": { + "eslint-plugin-es": "^3.0.0", + "eslint-utils": "^2.0.0", + "ignore": "^5.1.1", + "minimatch": "^3.0.4", + "resolve": "^1.10.1", + "semver": "^6.1.0" + }, + "dependencies": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true + } + } + }, + "eslint-plugin-promise": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.3.1.tgz", + "integrity": "sha512-bY2sGqyptzFBDLh/GMbAxfdJC+b0f23ME63FOE4+Jao0oZ3E1LEwFtWJX/1pGMJLiTtrSSern2CRM/g+dfc0eQ==", + "dev": true + }, + "eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "espree": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz", + "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==", + "dev": true, + "requires": { + "acorn": "^7.4.0", + "acorn-jsx": "^5.3.1", + "eslint-visitor-keys": "^1.3.0" + }, + "dependencies": { + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + } + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "requires": { + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "requires": { + "estraverse": "^5.2.0" + }, + "dependencies": { + "estraverse": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz", + "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==", + "dev": true + } + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "ffi-napi": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-3.1.0.tgz", + "integrity": "sha512-EsHO+sP2p/nUC/3l/l8m9niee1BLm4asUFDzkkBGR4kYVgp2KqdAYUomZhkKtzim4Fq7mcYHjpUaIHsMqs+E1g==", + "requires": { + "debug": "^4.1.1", + "get-uv-event-loop-napi-h": "^1.0.5", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.1", + "ref-napi": "^2.0.1", + "ref-struct-di": "^1.1.0" + }, + "dependencies": { + "ref-napi": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.1.2.tgz", + "integrity": "sha512-aFl+vrIuLWUXMUTQGAwGAuSNLX3Ub5W3iVP8b7KyFFZUdn4+i4U1TXXTop0kCTUfGNu8glBGVz4lowkwMcPVVA==", + "requires": { + "debug": "^4.1.1", + "get-symbol-from-current-process-h": "^1.0.2", + "node-addon-api": "^2.0.0", + "node-gyp-build": "^4.2.1" + } + } + } + }, + "file-entry-cache": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } + }, + "flatted": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.1.tgz", + "integrity": "sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==", + "dev": true + }, + "foreground-child": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", + "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^3.0.2" + } + }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-intrinsic": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", + "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1" + } + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-symbol-from-current-process-h": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", + "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" + }, + "get-uv-event-loop-napi-h": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", + "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", + "requires": { + "get-symbol-from-current-process-h": "^1.0.1" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.6.tgz", + "integrity": "sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-bigints": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.1.tgz", + "integrity": "sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", + "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "dev": true + }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + } + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-bigint": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.2.tgz", + "integrity": "sha512-0JV5+SOCQkIdzjBK9buARcV804Ddu7A0Qet6sHi3FimE9ne6m4BGQZfRn+NZiXbBk4F4XmHfDZIipLj9pX8dSA==", + "dev": true + }, + "is-boolean-object": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.1.tgz", + "integrity": "sha512-bXdQWkECBUIAcCkeH1unwJLIpZYaa5VvuygSyS/c2lf719mTKZDU5UdDRlpd01UjADgmW8RfqaP+mRaVPdr/Ng==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-callable": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.3.tgz", + "integrity": "sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==", + "dev": true + }, + "is-core-module": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz", + "integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.4.tgz", + "integrity": "sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-negative-zero": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", + "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==", + "dev": true + }, + "is-number-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.5.tgz", + "integrity": "sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==", + "dev": true + }, + "is-regex": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.3.tgz", + "integrity": "sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-symbols": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "is-string": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.6.tgz", + "integrity": "sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz", + "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, + "istanbul-lib-instrument": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", + "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", + "dev": true, + "requires": { + "@babel/core": "^7.7.5", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.0.0", + "semver": "^6.3.0" + } + }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz", + "integrity": "sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "istanbul-reports": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz", + "integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.0.tgz", + "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", + "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha1-WjUNoLERO4N+z//VgSy+WNbq4ZM=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "nan": { + "version": "2.14.2", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", + "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node-addon-api": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", + "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + }, + "node-gyp-build": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", + "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, + "node-releases": { + "version": "1.1.71", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", + "integrity": "sha512-zR6HoT6LrLCRBwukmrVbHv0EpEQjksO6GmFcZQQuCAy139BEsoVKPYnf3jongYW83fAa1torLGYwxxky/p28sg==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + } + }, + "object-inspect": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.10.3.tgz", + "integrity": "sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.2.tgz", + "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "define-properties": "^1.1.3", + "has-symbols": "^1.0.1", + "object-keys": "^1.1.1" + } + }, + "object.values": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.3.tgz", + "integrity": "sha512-nkF6PfDB9alkOUxpf1HNm/QlkeW3SReqL5WXeBLpEJJnlPSvRaDQpW3gQTksTN3fgJX4hL42RzKyOin6ff3tyw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.18.0-next.2", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" } }, - "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==" + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } }, - "ffi-napi": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/ffi-napi/-/ffi-napi-3.1.0.tgz", - "integrity": "sha512-EsHO+sP2p/nUC/3l/l8m9niee1BLm4asUFDzkkBGR4kYVgp2KqdAYUomZhkKtzim4Fq7mcYHjpUaIHsMqs+E1g==", + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, "requires": { - "debug": "^4.1.1", - "get-uv-event-loop-napi-h": "^1.0.5", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1", - "ref-napi": "^2.0.1", - "ref-struct-di": "^1.1.0" - }, - "dependencies": { - "ref-napi": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ref-napi/-/ref-napi-2.1.2.tgz", - "integrity": "sha512-aFl+vrIuLWUXMUTQGAwGAuSNLX3Ub5W3iVP8b7KyFFZUdn4+i4U1TXXTop0kCTUfGNu8glBGVz4lowkwMcPVVA==", - "requires": { - "debug": "^4.1.1", - "get-symbol-from-current-process-h": "^1.0.2", - "node-addon-api": "^2.0.0", - "node-gyp-build": "^4.2.1" - } - } + "error-ex": "^1.2.0" } }, - "get-symbol-from-current-process-h": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-symbol-from-current-process-h/-/get-symbol-from-current-process-h-1.0.2.tgz", - "integrity": "sha512-syloC6fsCt62ELLrr1VKBM1ggOpMdetX9hTrdW77UQdcApPHLmf7CI7OKcN1c9kYuNxKcDe4iJ4FY9sX3aw2xw==" + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true }, - "get-uv-event-loop-napi-h": { + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { "version": "1.0.6", - "resolved": "https://registry.npmjs.org/get-uv-event-loop-napi-h/-/get-uv-event-loop-napi-h-1.0.6.tgz", - "integrity": "sha512-t5c9VNR84nRoF+eLiz6wFrEp1SE2Acg0wS+Ysa2zF0eROes+LzOfuTaVHxGy8AbS8rq7FHEJzjnCZo1BupwdJg==", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, "requires": { - "get-symbol-from-current-process-h": "^1.0.1" + "isarray": "0.0.1" } }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==" + "pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true }, - "node-addon-api": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-2.0.2.tgz", - "integrity": "sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==" + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true }, - "node-gyp-build": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.2.3.tgz", - "integrity": "sha512-MN6ZpzmfNCRM+3t57PTJHgHyw/h4OWnZ6mR8P5j/uZtqQr46RRuDE/P+g3n0YR/AiYXeWixZZzaip77gdICfRg==" + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } }, "ref-napi": { "version": "3.0.1", @@ -154,6 +2414,134 @@ } } }, + "regexpp": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==", + "dev": true + }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "resolve": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz", + "integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sinon": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-10.0.0.tgz", + "integrity": "sha512-XAn5DxtGVJBlBWYrcYKEhWCz7FLwZGdyvANRyK06419hyEpdT0dMc5A8Vcxg5SCGHc40CsqoKsc1bt1CbJPfNw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "sleep": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/sleep/-/sleep-6.3.0.tgz", @@ -161,6 +2549,483 @@ "requires": { "nan": "^2.14.1" } + }, + "slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + } + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz", + "integrity": "sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.4.tgz", + "integrity": "sha512-y9xCjw1P23Awk8EvTpcyL2NIr1j7wJ39f+k6lvRnSMz+mz9CGz9NYPelDk42kOz6+ql8xjfK8oYzy3jAP5QU5A==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "string.prototype.trimstart": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz", + "integrity": "sha512-jh6e984OBfvxS50tdY2nRZnoC5/mLFKOREQfw8t5yytkoUsJRNxvI/E39qu1sD0OtWI3OC0XgKSmcWwziwYuZw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.7.0.tgz", + "integrity": "sha512-SAM+5p6V99gYiiy2gT5ArdzgM1dLDed0nkrWmG6Fry/bUS/m9x83BwpJUOf1Qj/x2qJd+thL6IkIx7qPGRxqBw==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.clonedeep": "^4.5.0", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.3.0.tgz", + "integrity": "sha512-RYE7B5An83d7eWnDR8kbdaIFqmKCNsP16ay1hDbJEU+sa0e3H9SebskCt0Uufem6cfAVu7Col6ubcn/W+Sm8/Q==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + } + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "tsconfig-paths": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz", + "integrity": "sha512-dRcuzokWhajtZWkQsDVKbWyY+jgcLC5sqJhg2PSgf4ZkH2aHPvaOY8YWGhmjb68b5qqTfasSsDO9k7RUiEmZAw==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "unbox-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.1.tgz", + "integrity": "sha512-tZU/3NqK3dA5gpE1KtyiJUrEB0lxnGkMFHptJ7q6ewdZ8s12QrODwNbhIJStmJkd1QDXa1NRA8aF2A1zk/Ypyw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has-bigints": "^1.0.1", + "has-symbols": "^1.0.2", + "which-boxed-primitive": "^1.0.2" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", + "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } } } } diff --git a/package.json b/package.json index fdb31cc3..c1055c99 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,14 @@ "ffi-napi": "^3.1.0", "sleep": "^6.3.0" }, + "scripts": { + "test": "mocha ./test/nodejs/", + "test-ci": "mocha ./test/nodejs/ --reporter mocha-junit-reporter", + "coverage": "nyc --reporter=clover --reporter=lcov --reporter=text-summary --check-coverage npm run test", + "coverage-ci": "nyc --reporter=clover --reporter=lcov --reporter=text-summary --check-coverage npm run test-ci", + "lint": "eslint rticonnextdds-connector.js test/nodejs/ --ext .js", + "lint-fix": "eslint --fix rticonnextdds-connector.js test/nodejs/ --ext .js" + }, "keywords": [ "rti", "dds", @@ -33,5 +41,17 @@ "bugs": { "url": "https://github.com/rticommunity/rticonnextdds-connector-js/issues" }, - "homepage": "https://github.com/rticommunity/rticonnextdds-connector-js" + "homepage": "https://github.com/rticommunity/rticonnextdds-connector-js", + "devDependencies": { + "babel-eslint": "^10.1.0", + "chai": "^4.3.4", + "chai-as-promised": "^7.1.1", + "eslint": "^7.26.0", + "eslint-config-standard": "^16.0.2", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.3.1", + "nyc": "^15.1.0", + "sinon": "^10.0.0" + } } diff --git a/rticonnextdds-connector.js b/rticonnextdds-connector.js index 5f1ac428..26eb8a29 100644 --- a/rticonnextdds-connector.js +++ b/rticonnextdds-connector.js @@ -17,16 +17,19 @@ const EventEmitter = require('events').EventEmitter * The Node.js representation of the RTI_Connector_Options structure within * the core. * - * We define it here using the module ref-struct (require above). This allows + * We define it here using the module ref-struct (require above). This allows * us to pass it by value into the Core when creating a :class:`Connector` object. * * @private */ -var _ConnectorOptions = StructType({ +const _ConnectorOptions = StructType({ enable_on_data_event: ref.types.int, one_based_sequence_indexing: ref.types.int }) +// We ignore the loading of the libraries in code coverage since it is +// not easily testable +/* istanbul ignore next */ class _ConnectorBinding { constructor () { let libDir = '' @@ -36,50 +39,50 @@ class _ConnectorBinding { // Obtain the name of the library that contains the Connector native libraries if (os.arch() === 'arm64') { - if (os.platform() === 'linux') { - libDir = 'linux-arm64' - libName = 'librtiddsconnector.so' - } else { - throw new Error('This platform (' + os.platform() + ' ' + os.arch() + ') is not supported') - } - } else if (os.arch() === 'arm') { - if (os.platform() === 'linux') { - libDir = 'linux-arm' - libName = 'librtiddsconnector.so' - } else { - throw new Error('This platform (' + os.platform() + ' ' + os.arch() + ') is not supported') - } + if (os.platform() === 'linux') { + libDir = 'linux-arm64' + libName = 'librtiddsconnector.so' + } else { + throw new Error('This platform (' + os.platform() + ' ' + os.arch() + ') is not supported') + } + } else if (os.arch() === 'arm') { + if (os.platform() === 'linux') { + libDir = 'linux-arm' + libName = 'librtiddsconnector.so' + } else { + throw new Error('This platform (' + os.platform() + ' ' + os.arch() + ') is not supported') + } } else { - // Note that we are intentionally not checking if os.arch() is x64. - // This allows somebody with access to 32-bit libraries to replace them - // in the corresponding x64 directory and we will try to load them. - // This behaviour is not officially supported. - switch (os.platform()) { + // Note that we are intentionally not checking if os.arch() is x64. + // This allows somebody with access to 32-bit libraries to replace them + // in the corresponding x64 directory and we will try to load them. + // This behaviour is not officially supported. + switch (os.platform()) { case 'darwin': - libDir = 'osx-x64' - libName = 'librtiddsconnector.dylib' - break + libDir = 'osx-x64' + libName = 'librtiddsconnector.dylib' + break case 'linux': - libDir = 'linux-x64' - libName = 'librtiddsconnector.so' - break + libDir = 'linux-x64' + libName = 'librtiddsconnector.so' + break // Windows returns win32 even on 64-bit platforms case 'win32': - libDir = 'win-x64' - libName = 'rtiddsconnector.dll' - additionalLib = 'msvcr120.dll' - isWindows = true - break + libDir = 'win-x64' + libName = 'rtiddsconnector.dll' + additionalLib = 'msvcr120.dll' + isWindows = true + break default: - throw new Error(os.platform() + ' not yet supported') - } + throw new Error(os.platform() + ' not yet supported') + } } // Connector is not supported on a (non ARM) 32-bit platform // We continue, incase the user has manually replaced the libraries within // the directory which we are going to load. if (os.arch() === 'ia32') { - console.log('Warning: 32-bit ' + os.platform() + ' is not supported') + console.log('Warning: 32-bit ' + os.platform() + ' is not supported') } if (additionalLib !== null) { @@ -92,8 +95,8 @@ class _ConnectorBinding { // On Windows we need to explicitly load the dependent libraries if (isWindows) { - ffi.Library(path.join(__dirname, '/rticonnextdds-connector/lib/', libDir, '/', 'nddscore.dll')) - ffi.Library(path.join(__dirname, '/rticonnextdds-connector/lib/', libDir, '/', 'nddsc.dll')) + ffi.Library(path.join(__dirname, '/rticonnextdds-connector/lib/', libDir, '/', 'nddscore.dll')) + ffi.Library(path.join(__dirname, '/rticonnextdds-connector/lib/', libDir, '/', 'nddsc.dll')) } this.library = path.join(__dirname, '/rticonnextdds-connector/lib/', libDir, '/', libName) @@ -143,7 +146,7 @@ class _ConnectorBinding { } // Create an instance of the connectorBinding class, allowing us to call the FFI'd methods -var connectorBinding = new _ConnectorBinding() +const connectorBinding = new _ConnectorBinding() /** * Copies a natively allocated string into a Node.js string and frees the @@ -221,7 +224,7 @@ class TimeoutError extends Error { */ class DDSError extends Error { /** - * This error is thrown when an error is encountered from within one of the + * This error is thrown when an error is encountered from within one of the * APIs within the *RTI Connext DDS* Core. * @private */ @@ -235,7 +238,7 @@ class DDSError extends Error { } /** - * Checks the value returned by the functions in the core for success and + * Checks the value returned by the functions in the core for success and * throws the appropriate error on failure. * * We do not handle DDS_RETCODE_NO_DATA here, since in some operations (those @@ -335,7 +338,7 @@ function _getAnyValue (getter, connector, inputName, index, fieldName) { /** * Provides access to the meta-data contained in samples read by an input. * - * Note: The Infos class is deprecated and should not be used directly. + * Note: The Infos class is deprecated and should not be used directly. * Instead, use :meth:`SampleIterator.info`. * * @private @@ -362,7 +365,7 @@ class Infos { /** * Checks if the sample at the given index contains valid data. * - * @param {number} index - The index of the sample in the :class:`Input`'s + * @param {number} index - The index of the sample in the :class:`Input`'s * queue to check for valid data * @returns{boolean} True if the sample contains valid data * @private @@ -398,14 +401,14 @@ class SampleIterator { /** * A SampleIterator provides access to the data receieved by an :class:`Input`. * - * The :attr:`Input.samples` attribute implements a :class:`SampleIterator`, - * meaning it can be iterated over. An individual sample can be accessed + * The :attr:`Input.samples` attribute implements a :class:`SampleIterator`, + * meaning it can be iterated over. An individual sample can be accessed * using :meth:`Input.samples.get`. * * See :class:`ValidSampleIterator`. * * This class provides both an iterator and iterable, and is used internally - * by the :class:`Samples` class. The following options to iterate over the + * by the :class:`Samples` class. The following options to iterate over the * samples exist:: * * // option 1 - The iterable can be used in for...of loops @@ -415,11 +418,11 @@ class SampleIterator { * // option 3 - Returns a generator which must be incremented by the application * const iterator = input.samples.iterator() * - * @property {boolean} validData - Whether or not the current sample + * @property {boolean} validData - Whether or not the current sample * contains valid data. - * @property {SampleInfo} infos - The meta-data associated with the + * @property {SampleInfo} infos - The meta-data associated with the * current sample. - * @property {pointer} native - A native handle that allows accessing + * @property {pointer} native - A native handle that allows accessing * additional *Connext DDS* APIs in C. */ constructor (input, index) { @@ -434,10 +437,10 @@ class SampleIterator { /** * Whether or not this sample contains valid data. * - * If ``false``, the methods to obtain values of the samples - * (e.g., :meth:`SampleIterator.getNumber`, - * :meth:`SampleIterator.getBoolean`, :meth:`SampleIterator.getJson`, - * :meth:`SampleIterator.getString`) should not be called. To avoid + * If ``false``, the methods to obtain values of the samples + * (e.g., :meth:`SampleIterator.getNumber`, + * :meth:`SampleIterator.getBoolean`, :meth:`SampleIterator.getJson`, + * :meth:`SampleIterator.getString`) should not be called. To avoid * this restraint, use a :class:`ValidSampleIterator`. * @type {boolean} */ @@ -456,17 +459,17 @@ class SampleIterator { * * * ``'source_timestamp'`` returns an integer representing nanoseconds * * ``'reception_timestamp'`` returns an integer representing nanoseconds - * * ``'sample_identity'`` or ``'identity'`` returns a JSON object + * * ``'sample_identity'`` or ``'identity'`` returns a JSON object * (see :meth:`Output.write`) - * * ``'related_sample_identity'`` returns a JSON object + * * ``'related_sample_identity'`` returns a JSON object * (see :meth:`Output.write`) - * * ``'valid_data'`` returns a boolean (equivalent to + * * ``'valid_data'`` returns a boolean (equivalent to * :attr:`SampleIterator.validData`) * * ``'view_state'``, returns a string (either "NEW" or "NOT_NEW") * * ``'instance_state'``, returns a string (one of "ALIVE", "NOT_ALIVE_DISPOSED" or "NOT_ALIVE_NO_WRITERS") * * ``'sample_state'``, returns a string (either "READ" or "NOT_READ") * - * These fields are documented in `The SampleInfo Structure + * These fields are documented in `The SampleInfo Structure * `__ * section in the *RTI Connext DDS Core Libraries User's Manual*. * @@ -481,7 +484,7 @@ class SampleIterator { * * See :ref:`Accessing the data samples`. * - * @param {string} [memberName] - The name of the complex member or field + * @param {string} [memberName] - The name of the complex member or field * to obtain. * @returns {JSON} The obtained JSON object. */ @@ -578,7 +581,7 @@ class SampleIterator { /** * Iterates and provides access to data samples with valid data. * - * This iterator provides the same methods as :class:`SampleIterator`. + * This iterator provides the same methods as :class:`SampleIterator`. * It can be obtained using :attr:`Input.samples.validDataIter`. * @extends SampleIterator * @@ -618,12 +621,12 @@ class ValidSampleIterator extends SampleIterator { */ class Samples { /** - * This class provides access to data samples read by an - * :class:`Input` (using either the :meth:`Input.read` + * This class provides access to data samples read by an + * :class:`Input` (using either the :meth:`Input.read` * or :meth:`Input.take` methods). * - * This class implements a ``[Symbol.iterator]()`` method, making it an - * iterable. This allows it to be used in ``for... of`` loops, to iterate + * This class implements a ``[Symbol.iterator]()`` method, making it an + * iterable. This allows it to be used in ``for... of`` loops, to iterate * through available samples:: * * for (const sample of input.samples) { @@ -638,12 +641,12 @@ class Samples { * * The samples returned by these methods may only contain meta-data * (see :attr:`SampleIterator.info`). The :attr:`Samples.validDataIter` - * iterable only iterates over samples that contain valid data + * iterable only iterates over samples that contain valid data * (a :class:`ValidSampleIterator`). * - * :class:`Samples` and :class:`ValidSampleIterator` both also provide - * generators to the samples, allowing applications to define their own - * iterables (see :meth:`Samples.iterator()` and + * :class:`Samples` and :class:`ValidSampleIterator` both also provide + * generators to the samples, allowing applications to define their own + * iterables (see :meth:`Samples.iterator()` and * :meth:`ValidSampleIterator.iterator()`). * * ``Samples`` is the type of the property :meth:`Input.samples`. @@ -651,9 +654,9 @@ class Samples { * For more information and examples, see :ref:`Accessing the data samples`. * * Attributes: - * * length (number) - The number of samples available since the last time + * * length (number) - The number of samples available since the last time * :meth:`Input.read` or :meth:`Input.take` was called. - * * validDataIter (:class:`ValidSampleIterator`) - The class used to + * * validDataIter (:class:`ValidSampleIterator`) - The class used to * iterate through the available samples that have valid data. */ constructor (input) { @@ -663,18 +666,18 @@ class Samples { /** * Returns an iterator to the data samples, starting at the index specified. * - * The iterator provides access to all the data samples retrieved by the + * The iterator provides access to all the data samples retrieved by the * most recent call to :meth:`Input.read` or :meth:`Input.take`. * - * This iterator may return samples with invalid data (samples that only + * This iterator may return samples with invalid data (samples that only * contain meta-data). - * Use :attr:`Samples.validDataIter` to avoid having to check + * Use :attr:`Samples.validDataIter` to avoid having to check * :attr:`SampleIterator.validData`. * - * @param {number} [index] The index of the sample from which the iteration + * @param {number} [index] The index of the sample from which the iteration * should begin. By default, the iterator begins with the first sample. * - * @returns :class:`SampleIterator` - An iterator to the samples (which + * @returns :class:`SampleIterator` - An iterator to the samples (which * implements both iterable and iterator logic). */ get (index) { @@ -689,7 +692,7 @@ class Samples { * * This iterable may return samples with invalid data (samples that only contain * meta-data). - * Use :attr:`Samples.validDataIter` to avoid having to check + * Use :attr:`Samples.validDataIter` to avoid having to check * :attr:`SampleIterator.validData`. * * Allows for the following syntax:: @@ -734,13 +737,13 @@ class Samples { * Returns an iterator to the data samples that contain valid data. * * The iterator provides access to all the data samples retrieved by the most - * recent call to :meth:`Input.read` or :meth:`Input.take`, and skips samples + * recent call to :meth:`Input.read` or :meth:`Input.take`, and skips samples * with invalid data (meta-data only). * * By using this iterator, it is not necessary to check if each sample contains * valid data. * - * @returns {ValidSampleIterator} An iterator to the samples containing valid + * @returns {ValidSampleIterator} An iterator to the samples containing valid * data (which implements both iterable and iterator logic). */ get validDataIter () { @@ -904,8 +907,8 @@ class Samples { * Gets a JSON object with the values of all the fields of this sample. * * @param {number} index The index of the sample. - * @param {string} [memberName] The name of the complex member. The type - * of the member with name memberName must be an array, sequence, struct, + * @param {string} [memberName] The name of the complex member. The type + * of the member with name memberName must be an array, sequence, struct, * value or union. * @returns {JSON} The obtained JSON object. * @@ -948,10 +951,10 @@ class Samples { } /** - * Obtains a native handle to the sample, which can be used to access + * Obtains a native handle to the sample, which can be used to access * additional *Connext DDS* APIs in C. * - * @param {number} index The index of the sample for which to obtain + * @param {number} index The index of the sample for which to obtain * the native pointer. * @returns {pointer} A native pointer to the sample. */ @@ -971,9 +974,9 @@ class Samples { /** * This method is deprecated, use :meth:`Samples.getJson`. * - * @param {number} index - The index of the sample for which to obtain + * @param {number} index - The index of the sample for which to obtain * the JSON object. - * @param {string} [memberName] - The name of the complex member for + * @param {string} [memberName] - The name of the complex member for * which to obtain the JSON object. * @returns {JSON} A JSON object representing the current sample. * @private @@ -1002,14 +1005,14 @@ class SampleInfo { * * * ``'source_timestamp'`` returns an integer representing nanoseconds * * ``'reception_timestamp'`` returns an integer representing nanoseconds - * * ``'sample_identity'`` or ``'identity'`` returns a JSON object + * * ``'sample_identity'`` or ``'identity'`` returns a JSON object * (see :meth:`Output.write`) - * * ``'related_sample_identity'`` returns a JSON object + * * ``'related_sample_identity'`` returns a JSON object * (see :meth:`Output.write`) - * * ``'valid_data'`` returns a boolean (equivalent to + * * ``'valid_data'`` returns a boolean (equivalent to * :attr:`SampleIterator.validData`) * - * These fields are documented in `The SampleInfo Structure + * These fields are documented in `The SampleInfo Structure * `__ * section in the *RTI Connext DDS Core Libraries User's Manual*. * @@ -1042,11 +1045,11 @@ class Input { * * Attributes: * * connector (:class:`Connector`) - The Connector creates this Input. - * * name (string) - The name of the Input (the name used in + * * name (string) - The name of the Input (the name used in * :meth:`Connector.getInput`). - * * native (pointer) - A native handle that allows accessing additional + * * native (pointer) - A native handle that allows accessing additional * *Connext DDS* APIs in C. - * * matchedPublications (JSON) - A JSON object containing information + * * matchedPublications (JSON) - A JSON object containing information * about all the publications currently matched with this Input. */ constructor (connector, name) { @@ -1074,8 +1077,8 @@ class Input { /** * Accesses the samples received by this Input. * - * This operation performs the same operation as :meth:`Input.take` but - * the samples remain accessible (in the internal queue) after the + * This operation performs the same operation as :meth:`Input.take` but + * the samples remain accessible (in the internal queue) after the * operation has been called. */ read () { @@ -1087,7 +1090,7 @@ class Input { /** * Accesses the samples receieved by this Input. * - * After calling this method, the samples are accessible using + * After calling this method, the samples are accessible using * :meth:`Input.samples`. */ take () { @@ -1114,18 +1117,18 @@ class Input { * .. note:: * This operation is asynchronous. * - * This method waits for the specified timeout (or if no timeout is + * This method waits for the specified timeout (or if no timeout is * specified, it waits forever), for a match (or unmatch) to occur. - * @param {number} [timeout] The maximum time to wait, in milliseconds. + * @param {number} [timeout] The maximum time to wait, in milliseconds. * By default, infinite. - * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the + * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the * timeout expires before any publications are matched. - * @returns {Promise} Promise object resolving with the change in the - * current number of matched outputs. If this is a positive number, - * the input has matched with new publishers. If it is negative, the - * input has unmatched from an output. It is possible for multiple - * matches and/or unmatches to be returned (e.g., 0 could be returned, - * indicating that the input matched the same number of outputs as it + * @returns {Promise} Promise object resolving with the change in the + * current number of matched outputs. If this is a positive number, + * the input has matched with new publishers. If it is negative, the + * input has unmatched from an output. It is possible for multiple + * matches and/or unmatches to be returned (e.g., 0 could be returned, + * indicating that the input matched the same number of outputs as it * unmatched). */ waitForPublications (timeout) { @@ -1164,15 +1167,15 @@ class Input { /** * Returns information about matched publications. * - * This property returns a JSON array, with each element of the + * This property returns a JSON array, with each element of the * array containing information about a matched publication. * - * Currently the only information contained in this JSON object is - * the publication name of the matched publication. If the matched - * publication doesn't have a name, the name for that specific + * Currently the only information contained in this JSON object is + * the publication name of the matched publication. If the matched + * publication doesn't have a name, the name for that specific * publication will be null. * - * Note that :class:`Connector` Outputs are automatically assigned + * Note that :class:`Connector` Outputs are automatically assigned * a name from the ``data_writer name`` element in the XML configuration. * * @type {JSON} @@ -1192,11 +1195,11 @@ class Input { * .. note:: * This operation is asynchronous. * - * @param {number} [timeout] The maximum time to wait, in milliseconds. + * @param {number} [timeout] The maximum time to wait, in milliseconds. * By default, infinite. - * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the + * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the * timeout expires before data is received. - * @returns {Promise} A ``Promise`` which will be resolved once data is + * @returns {Promise} A ``Promise`` which will be resolved once data is * available, or rejected if the timeout expires. */ wait (timeout) { @@ -1235,17 +1238,17 @@ class Instance { /** * A data sample. * - * :class:`Instance` is the type obtained through ``Output.instance`` + * :class:`Instance` is the type obtained through ``Output.instance`` * and is the object that is published by :meth:`Output.write`. * - * An Instance has an associated DDS Type, specified in the XML - * configuration, and it allows setting the values for the fields of + * An Instance has an associated DDS Type, specified in the XML + * configuration, and it allows setting the values for the fields of * the DDS Type. * * Attributes: - * * ``output`` (:class:`Output`) - The :class:`Output` that owns + * * ``output`` (:class:`Output`) - The :class:`Output` that owns * this Instance. - * * ``native`` (pointer) - Native handle to this Instance that allows + * * ``native`` (pointer) - Native handle to this Instance that allows * for additional *Connext DDS Pro* C APIs to be called. */ constructor (output) { @@ -1255,9 +1258,9 @@ class Instance { /** * Resets a member to its default value. * - * The effect is the same as that of :meth:`Output.clearMembers`, except + * The effect is the same as that of :meth:`Output.clearMembers`, except * that only one member is cleared. - * @param {string} fieldName The name of the field. It can be a complex + * @param {string} fieldName The name of the field. It can be a complex * member or a primitive member. */ clearMember (fieldName) { @@ -1276,7 +1279,7 @@ class Instance { * Sets a numeric field. * * @param {string} fieldName - The name of the field. - * @param {number} value - A numeric value, or null, to unset an + * @param {number} value - A numeric value, or null, to unset an * optional member. */ setNumber (fieldName, value) { @@ -1301,7 +1304,7 @@ class Instance { * Sets a boolean field. * * @param {string} fieldName - The name of the field. - * @param {boolean} value - A boolean value, or null, to unset an + * @param {boolean} value - A boolean value, or null, to unset an * optional member. */ setBoolean (fieldName, value) { @@ -1327,7 +1330,7 @@ class Instance { * Sets a string field. * * @param {string} fieldName - The name of the field. - * @param {number} value - A string value, or null, to unset an + * @param {number} value - A string value, or null, to unset an * optional member. */ setString (fieldName, value) { @@ -1352,20 +1355,20 @@ class Instance { /** * Sets the member values specified in a JSON object. * - * The keys in the JSON object are the member names of the DDS Type - * associated with the Output, and the values are the values to set + * The keys in the JSON object are the member names of the DDS Type + * associated with the Output, and the values are the values to set * for those members. * - * This method sets the values of those members that are explicitly - * specified in the JSON object. Any member that is not specified in + * This method sets the values of those members that are explicitly + * specified in the JSON object. Any member that is not specified in * the JSON object will retain its previous value. * - * To clear members that are not in the JSON object, call - * :meth:`Output.clearMembers` before this method. You can also - * explicitly set any value in the JSON object to *null* to reset that + * To clear members that are not in the JSON object, call + * :meth:`Output.clearMembers` before this method. You can also + * explicitly set any value in the JSON object to *null* to reset that * field to its default value. * - * @param {JSON} jsonObj - The JSON object containing the keys + * @param {JSON} jsonObj - The JSON object containing the keys * (field names) and values (values for the fields). */ setFromJson (jsonObj) { @@ -1378,16 +1381,16 @@ class Instance { /** * Sets the value of fieldName. * - * The type of the argument ``value`` must correspond with the type of the + * The type of the argument ``value`` must correspond with the type of the * field with name ``fieldName`` (as defined in the configuration XML file). * - * This method is an alternative to - * :meth:`Instance.setNumber`, :meth:`Instance.setString` and - * :meth:`Instance.setBoolean`. The main difference is that it is + * This method is an alternative to + * :meth:`Instance.setNumber`, :meth:`Instance.setString` and + * :meth:`Instance.setBoolean`. The main difference is that it is * type-independent (in that the same method can be used for all fields). * * @param {string} fieldName The name of the field. - * @param {number|boolean|string|null} value The value to set. Note that + * @param {number|boolean|string|null} value The value to set. Note that * ``null`` is used to unset an optional member. */ set (fieldName, value) { @@ -1420,13 +1423,13 @@ class Instance { */ getJson () { const nativeStr = connectorBinding.api.RTIDDSConnector_getJSONInstance( - this.output.connector.native, - this.output.name) + this.output.connector.native, + this.output.name) // Now move the native string if (nativeStr === null) { - throw new Error('Failed to create JSON object of instance') + throw new Error('Failed to create JSON object of instance') } else { - return JSON.parse(_moveCString(nativeStr)) + return JSON.parse(_moveCString(nativeStr)) } } @@ -1466,15 +1469,15 @@ class Output { * To get an Output object, use :meth:`Connector.getOutput`. * * Attributes: - * * ``instance`` (:class:`Instance`) - The data that is written when + * * ``instance`` (:class:`Instance`) - The data that is written when * :meth:`Output.write` is called. - * * ``connector`` (:class:`Connector`) - The :class:`Connector` object + * * ``connector`` (:class:`Connector`) - The :class:`Connector` object * that created this object. - * * ``name`` (str) - The name of this Output (the name used in + * * ``name`` (str) - The name of this Output (the name used in * :meth:`Connector.getOutput`). - * * ``native`` (pointer) - The native handle that allows accessing + * * ``native`` (pointer) - The native handle that allows accessing * additional *Connext DDS* APIs in C. - * * ``matchedSubscriptions`` (JSON) - Information about matched + * * ``matchedSubscriptions`` (JSON) - Information about matched * subscriptions (see below). * */ @@ -1494,40 +1497,40 @@ class Output { /** * Publishes the values of the current Instance. * - * Note that after writing it, the Instance's values remain unchanged. - * If, for the next write, you need to start from scratch, you must + * Note that after writing it, the Instance's values remain unchanged. + * If, for the next write, you need to start from scratch, you must * first call :meth:`Output.clearMembers`. * - * This method accepts an optional JSON object as a parameter, which may + * This method accepts an optional JSON object as a parameter, which may * specify the parameters to use in the `write` call. - * The supported parameters are a subset of those documented in the + * The supported parameters are a subset of those documented in the * `Writing Data section `__ * of the *RTI Connext DDS Core Libraries User's Manual*. These are: * * * ``action`` – One of ``write`` (default), ``dispose`` or ``unregister`` - * * ``source_timestamp`` – An integer representing the total number of + * * ``source_timestamp`` – An integer representing the total number of * nanoseconds - * * ``identity`` – A JSON object containing the fields ``writer_guid`` and + * * ``identity`` – A JSON object containing the fields ``writer_guid`` and * ``sequence_number`` - * * ``related_sample_identity`` – Used for request-reply communications. + * * ``related_sample_identity`` – Used for request-reply communications. * It has the same format as identity * * @example output.write() - * @example output.write({ - * action: 'dispose', - * identity: { writer_guid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], sequence_number: 1 } + * @example output.write({ + * action: 'dispose', + * identity: { writer_guid: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], sequence_number: 1 } * }) * * @param {JSON} [params] [Optional] The optional parameters described above - * @throws {TimeoutError} The write method can block under multiple - * circumstances (see 'Blocking During a write()' in the `Writing Data section + * @throws {TimeoutError} The write method can block under multiple + * circumstances (see 'Blocking During a write()' in the `Writing Data section * `__ * of the *RTI Connext DDS Core Libraries User's Manual*.) - * If the blocking time exceeds the ``max_blocking_time``, this method + * If the blocking time exceeds the ``max_blocking_time``, this method * throws :class:`TimeoutError`. */ write (params) { - var cStr + let cStr if (params === undefined) { cStr = null } else { @@ -1542,10 +1545,10 @@ class Output { /** * Resets the values of the members of this :class:`Instance`. * - * If the member is defined with a *default* attribute in the configuration - * file, it gets that value. Otherwise, numbers are set to 0 and strings are + * If the member is defined with a *default* attribute in the configuration + * file, it gets that value. Otherwise, numbers are set to 0 and strings are * set to empty. Sequences are cleared and optional members are set to 'null'. - * For example, if this Output's type is *ShapeType*, then ``clearMembers()`` + * For example, if this Output's type is *ShapeType*, then ``clearMembers()`` * sets:: * color = 'RED' * shapesize = 30 @@ -1559,7 +1562,7 @@ class Output { } /** - * Waits until all matching reliable subscriptions have acknowledged all the + * Waits until all matching reliable subscriptions have acknowledged all the * samples that have currently been written. * * This method only waits if this Output is configured with a reliable QoS. @@ -1567,13 +1570,13 @@ class Output { * .. note:: * This operation is asynchronous * - * @param {timeout} [timeout] The maximum time to wait, in milliseconds. + * @param {timeout} [timeout] The maximum time to wait, in milliseconds. * By default, infinite. * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the timeout - * expires before all matching reliable subscriptions acknowledge all the + * expires before all matching reliable subscriptions acknowledge all the * samples. - * @returns {Promise} Promise object which will be rejected if not all matching - * reliable subscriptions acknowledge all of the samples within the specified + * @returns {Promise} Promise object which will be rejected if not all matching + * reliable subscriptions acknowledge all of the samples within the specified * timeout. */ wait (timeout) { @@ -1588,10 +1591,14 @@ class Output { timeout, (err, res) => { if (err) { - reject(err) + return reject(err) + } else if (res === _ReturnCodes.ok) { + return resolve() + } else if (res === _ReturnCodes.timeout) { + return reject(new TimeoutError('Timeout error')) + } else { + return reject(new DDSError('res: ' + res)) } - _checkRetcode(res) - resolve() } ) }) @@ -1600,21 +1607,21 @@ class Output { /** * Waits for this Output to match or unmatch a compatible DDS Publication. * - * This method waits for the specified timeout (or if no timeout is + * This method waits for the specified timeout (or if no timeout is * specified, it waits forever), for a match (or unmatch) to occur. * * .. note:: * This operation is asynchronous * - * @param {number} [timeout] - The maximum time to wait, in milliseconds. + * @param {number} [timeout] - The maximum time to wait, in milliseconds. * By default, infinite. - * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the + * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the * timeout expires before a subscription is matched. - * @returns {Promise} Promise object resolving with the change in the - * current number of matched inputs. If this is a positive number, the - * output has matched with new subscribers. If it is negative, the output - * has unmatched from a subscription. It is possible for multiple matches - * and/or unmatches to be returned (e.g., 0 could be returned, indicating + * @returns {Promise} Promise object resolving with the change in the + * current number of matched inputs. If this is a positive number, the + * output has matched with new subscribers. If it is negative, the output + * has unmatched from a subscription. It is possible for multiple matches + * and/or unmatches to be returned (e.g., 0 could be returned, indicating * that the output matched the same number of inputs as it unmatched). */ waitForSubscriptions (timeout) { @@ -1642,7 +1649,7 @@ class Output { } else if (res === _ReturnCodes.timeout) { return reject(new TimeoutError('Timeout error')) } else { - return reject(new DDSError('DDS error')) + return reject(new DDSError('res: ' + res)) } } ) @@ -1653,14 +1660,14 @@ class Output { /** * Provides information about matched subscriptions. * - * This property returns a JSON array, with each element of the array + * This property returns a JSON array, with each element of the array * containing information about a matched subscription. * - * Currently the only information contained in this JSON object is the + * Currently the only information contained in this JSON object is the * subscription name of the matched subscription. If the matched subscription * doesn't have a name, the name for that specific subscription will be null. * - * Note that :class:`Connector` Inputs are automatically assigned a name from + * Note that :class:`Connector` Inputs are automatically assigned a name from * the ``data_reader name`` element in the XML configuration. * * @type {JSON} @@ -1674,6 +1681,7 @@ class Output { return JSON.parse(_moveCString(cStr.deref())) } + /* istanbul ignore next */ // Deprecated, use clearMembers clear_members () { // eslint-disable-line camelcase return this.clearMembers() @@ -1684,9 +1692,9 @@ class Output { * Loads a configuration and creates its Inputs and Outputs. * * .. note:: - * The :class:`Connector` class inherits from + * The :class:`Connector` class inherits from * `EventEmitter `__. - * This allows us to support event-based notification for data, using the + * This allows us to support event-based notification for data, using the * following syntax: * * .. code-block:: javascript @@ -1695,32 +1703,32 @@ class Output { * * Please refer to :ref:`Reading data (Input)` for more information. * - * A :class:`Connector` instance loads a configuration file from an XML + * A :class:`Connector` instance loads a configuration file from an XML * document. For example:: * const connector = new rti.Connector('MyParticipantLibrary::MyParticipant', 'MyExample.xml') * - * After creating it, the :class:`Connector` object's Inputs can be used to - * read data, and the Outputs to write data. The methods - * :meth:`Connector.getOutput` and :meth:`Connector.getInput` return an + * After creating it, the :class:`Connector` object's Inputs can be used to + * read data, and the Outputs to write data. The methods + * :meth:`Connector.getOutput` and :meth:`Connector.getInput` return an * :class:`Input` and :class:`Output`, respectively. * - * An application can create multiple :class:`Connector` instances for the + * An application can create multiple :class:`Connector` instances for the * same or different configurations. */ class Connector extends EventEmitter { /** - * @arg {string} configName The configuration to load. The configName format - * is `LibraryName::ParticipantName`, where LibraryName is the name - * attribute of a ```` tag, and - * ParticipantName is the name attribute of a ```` tag + * @arg {string} configName The configuration to load. The configName format + * is `LibraryName::ParticipantName`, where LibraryName is the name + * attribute of a ```` tag, and + * ParticipantName is the name attribute of a ```` tag * within that library. - * @arg {string} url A URL locating the XML document. It can be a file path - * (e.g., ``/tmp/my_dds_config.xml``), a string containing the full XML + * @arg {string} url A URL locating the XML document. It can be a file path + * (e.g., ``/tmp/my_dds_config.xml``), a string containing the full XML * document with the following format: ``str://"..."``, or a - * combination of multiple files or strings, as explained in the + * combination of multiple files or strings, as explained in the * `URL Groups `__ * section of the *Connext DDS Core Libraries User's Manual*. - * + * */ constructor (configName, url) { super() @@ -1741,18 +1749,18 @@ class Connector extends EventEmitter { } /** - * This method is used internally by the public APIs - * :meth:`Connector.close` and + * This method is used internally by the public APIs + * :meth:`Connector.close` and * :meth:`Connector.waitForCallbackFinalization`. It should not be used * directly by applications. * - * @param {function} resolve The resolve() callback to call once waitSetBusy + * @param {function} resolve The resolve() callback to call once waitSetBusy * is false. - * @param {function} reject The reject() callback to call if we timeout, + * @param {function} reject The reject() callback to call if we timeout, * or if another error occurs. - * @param {number} iterations Maximum number of iterations to perform + * @param {number} iterations Maximum number of iterations to perform * before timing out. - * @param {boolean} cleanup Whether or not the :class:`Connector` object + * @param {boolean} cleanup Whether or not the :class:`Connector` object * should be deleted once the waitset is no longer busy. * @private */ @@ -1782,27 +1790,27 @@ class Connector extends EventEmitter { * by the :class:`Connector` are no longer in use. * * .. note:: - * This returned promise will be rejected if there are any listeners - * registered for the ``on_data_available`` event. Ensure that they have - * all been removed before calling this method using + * This returned promise will be rejected if there are any listeners + * registered for the ``on_data_available`` event. Ensure that they have + * all been removed before calling this method using * ``connector.removeAllListeners(on_data_available)``. * - * It is currently only necessary to call this method if you remove all of + * It is currently only necessary to call this method if you remove all of * the listeners for the ``on_data_available`` event and at some point in the - * future wish to use the same :class:`Connector` object to get notifications - * of new data (via the :meth:`Connector.wait` method, or by re-adding a + * future wish to use the same :class:`Connector` object to get notifications + * of new data (via the :meth:`Connector.wait` method, or by re-adding a * listener for the ``on_data_available`` event). * - * This operation does **not** free any resources. It is still necessary to - * call :meth:`Connector.close` when the :class:`Connector` is no longer + * This operation does **not** free any resources. It is still necessary to + * call :meth:`Connector.close` when the :class:`Connector` is no longer * required. * - * @argument {number} [timeout] Optional parameter to indicate the timeout - * of the operation, in seconds. By default, 10s. If this operation does - * not complete within the specified timeout, the returned Promise will + * @argument {number} [timeout] Optional parameter to indicate the timeout + * of the operation, in seconds. By default, 10s. If this operation does + * not complete within the specified timeout, the returned Promise will * be rejected. - * @returns {Promise} A Promise that will be resolved once the resources - * being used internally by the :class:`Connector` object are no longer + * @returns {Promise} A Promise that will be resolved once the resources + * being used internally by the :class:`Connector` object are no longer * in use. */ waitForCallbackFinalization (timeout) { @@ -1818,12 +1826,12 @@ class Connector extends EventEmitter { /** * Frees all the resources created by this :class:`Connector` instance. * - * @argument {number} [timeout] Optional parameter to indicate the timeout - * of the operation, in seconds. By default, 10s. If this operation does - * not complete within the specified timeout, the returned Promise will + * @argument {number} [timeout] Optional parameter to indicate the timeout + * of the operation, in seconds. By default, 10s. If this operation does + * not complete within the specified timeout, the returned Promise will * be rejected. - * @returns {Promise} Which resolves once the :class:`Connector` object has - * been freed. It is only necessary to wait for this promise to resolve + * @returns {Promise} Which resolves once the :class:`Connector` object has + * been freed. It is only necessary to wait for this promise to resolve * if you have attached a listener for the ``on_data_available`` event. */ close (timeout) { @@ -1850,7 +1858,7 @@ class Connector extends EventEmitter { /** * Returns the :class:`Input` named inputName. * - * ``inputName`` identifies a ```` tag in the configuration + * ``inputName`` identifies a ```` tag in the configuration * loaded by the :class:`Connector`. For example:: * * const connector = new rti.Connector('MyParticipantLibrary::MyParticipant', 'MyExample.xml') @@ -1871,7 +1879,7 @@ class Connector extends EventEmitter { * ... * * - * @param {string} inputName The name of the ``data_reader`` to load, with the + * @param {string} inputName The name of the ``data_reader`` to load, with the * format `SubscriberName::DataReaderName`. * @returns {Input} The Input, if it exists. */ @@ -1882,7 +1890,7 @@ class Connector extends EventEmitter { /** * Returns the :class:`Output` named outputName. * - * ``outputName`` identifies a ```` tag in the configuration + * ``outputName`` identifies a ```` tag in the configuration * loaded by the :class:`Connector`. For example:: * * const connector = new rti.Connector('MyParticipantLibrary::MyParticipant', 'MyExample.xml') @@ -1903,7 +1911,7 @@ class Connector extends EventEmitter { * ... * * - * @param {string} outputName The name of the ``data_writer`` to load, with + * @param {string} outputName The name of the ``data_writer`` to load, with * the format ``PublisherName::DataWriterName``. * @returns {Output} The Output, if it exists. */ @@ -1917,11 +1925,11 @@ class Connector extends EventEmitter { * .. note:: * This operation is asynchronous. * - * @param {number} timeout The maximum time to wait, in milliseconds. + * @param {number} timeout The maximum time to wait, in milliseconds. * By default, infinite. - * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the + * @throws {TimeoutError} :class:`TimeoutError` will be thrown if the * timeout expires before data is received. - * @returns {Promise} A ``Promise`` which will be resolved once data + * @returns {Promise} A ``Promise`` which will be resolved once data * is available, or rejected once the timeout expires. */ wait (timeout) { @@ -1956,17 +1964,17 @@ class Connector extends EventEmitter { } /** - * Emits the ``on_data_available`` event when any Inputs within this + * Emits the ``on_data_available`` event when any Inputs within this * :class:`Connector` object receive data. * * .. note:: * This operation is asynchronous * - * This API is used internally to emit the ``on_data_available`` event when - * data is received on any of the Inputs contained within this + * This API is used internally to emit the ``on_data_available`` event when + * data is received on any of the Inputs contained within this * :class:`Connector` object. * - * The :class:`Connector` class extends EventEmitter, meaning that callbacks + * The :class:`Connector` class extends EventEmitter, meaning that callbacks * can be registered for specific events using the following syntax: * * .. code-block:: javascript @@ -1978,9 +1986,9 @@ class Connector extends EventEmitter { * // ... * connector.off('on_data_available', myCallback) * - * Once the ``on_data_available`` event has fired, either :meth:`Input.read` - * or :meth:`Input.take` should be called on the :class:`Input` that has - * new data. This will prevent ``on_data_available`` from being fired more + * Once the ``on_data_available`` event has fired, either :meth:`Input.read` + * or :meth:`Input.take` should be called on the :class:`Input` that has + * new data. This will prevent ``on_data_available`` from being fired more * than once for the same data. * * @private diff --git a/test/nodejs/test_rticonnextdds_connector.js b/test/nodejs/test_rticonnextdds_connector.js index e3a2803a..5f91f20e 100644 --- a/test/nodejs/test_rticonnextdds_connector.js +++ b/test/nodejs/test_rticonnextdds_connector.js @@ -55,7 +55,7 @@ describe('Connector Tests', function () { const participantProfile = 'MyParticipantLibrary::Zero' const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') const connectors = [] - for (var i = 0; i < 3; i++) { + for (let i = 0; i < 3; i++) { connectors.push(new rti.Connector(participantProfile, xmlProfile)) } connectors.forEach((connector) => { @@ -70,10 +70,10 @@ describe('Connector Tests', function () { const participantProfile = 'MyParticipantLibrary::MyParticipant' const xmlProfile = path.join(__dirname, '/../xml/TestConnector3.xml') const connectors = [] - for (var i = 0; i < 2; i++) { - connectors.push(new rti.Connector(participantProfile, xmlProfile)) + for (let i = 0; i < 2; i++) { + connectors.push(new rti.Connector(participantProfile, xmlProfile)) } - connectors.forEach((connector) => { + connectors.forEach((connector) => { expect(connector).to.exist expect(connector).to.be.instanceOf(rti.Connector) connector.close() @@ -81,24 +81,24 @@ describe('Connector Tests', function () { }) it('Load two XML files using the url group syntax', function () { - const xmlProfile1 = path.join(__dirname, '/../xml/TestConnector.xml') - const xmlProfile2 = path.join(__dirname, '/../xml/TestConnector2.xml') - const fullXmlPath = xmlProfile1 + ';' + xmlProfile2 - const connector = new rti.Connector('MyParticipantLibrary2::MyParticipant2', fullXmlPath) - expect(connector).to.exist - expect(connector).to.be.instanceOf(rti.Connector) - const output = connector.getOutput('MyPublisher2::MySquareWriter2') - expect(output).to.exist - connector.close() + const xmlProfile1 = path.join(__dirname, '/../xml/TestConnector.xml') + const xmlProfile2 = path.join(__dirname, '/../xml/TestConnector2.xml') + const fullXmlPath = xmlProfile1 + ';' + xmlProfile2 + const connector = new rti.Connector('MyParticipantLibrary2::MyParticipant2', fullXmlPath) + expect(connector).to.exist + expect(connector).to.be.instanceOf(rti.Connector) + const output = connector.getOutput('MyPublisher2::MySquareWriter2') + expect(output).to.exist + connector.close() }) it('Should be possible to create a Connector with participant qos', function () { - const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') - const connector = new rti.Connector( - 'MyParticipantLibrary::ConnectorWithParticipantQos', - xmlProfile) - expect(connector).to.exist - expect(connector).to.be.instanceOf(rti.Connector) + const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') + const connector = new rti.Connector( + 'MyParticipantLibrary::ConnectorWithParticipantQos', + xmlProfile) + expect(connector).to.exist + expect(connector).to.be.instanceOf(rti.Connector) }) // Test for CON-200 @@ -116,30 +116,68 @@ describe('Connector Tests', function () { describe('Connector callback test', function () { let connector - // Initialization before all tests are executed - before(() => { - const participantProfile = 'MyParticipantLibrary::Zero' - const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') - connector = new rti.Connector(participantProfile, xmlProfile) - }) +describe('Connector callback test', function () { + let connector - // Cleanup after all tests have executed - after(async () => { - await connector.delete() - }) + // Initialization before all tests are executed + before(() => { + const participantProfile = 'MyParticipantLibrary::Zero' + const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') + connector = new rti.Connector(participantProfile, xmlProfile) + }) - it('on_data_available callback gets called when data is available', function (done) { - // spies are used for testing callbacks - const spy = sinon.spy() - setTimeout(() => { - expect(spy.calledOnce).to.be.true - done() // Pattern for async testing: next test won't execute until done gets called. - }, 1000) // Expectation Test will execute after 1000 milisec - connector.once('on_data_available', spy) - output = connector.getOutput('MyPublisher::MySquareWriter') - testMsg = '{"x":1,"y":1,"z":true,"color":"BLUE","shapesize":5}' - output.instance.setFromJson(JSON.parse(testMsg)) + // Cleanup after all tests have executed + after(async () => { + await connector.delete() + }) + + it('on_data_available callback gets called when data is available', function (done) { + // spies are used for testing callbacks + const spy = sinon.spy() + setTimeout(() => { + expect(spy.calledOnce).to.be.true + done() // Pattern for async testing: next test won't execute until done gets called. + }, 1000) // Expectation Test will execute after 1000 milisec + connector.once('on_data_available', spy) + output = connector.getOutput('MyPublisher::MySquareWriter') + testMsg = '{"x":1,"y":1,"z":true,"color":"BLUE","shapesize":5}' + output.instance.setFromJson(JSON.parse(testMsg)) + output.write() + }) + + it('on_data_available emits the error event on error', function (done) { + const errorSpy = sinon.spy() + // We expect the "error" event to be emitted within the next second + setTimeout(() => { + expect(errorSpy.calledOnce).to.be.true + connector.removeAllListeners('on_data_available') + done() + }, 1000) + connector.once('error', errorSpy) + // Need to cause the onDataAvailable callback to throw an error, we do + // this by concurrently waiting on the same connector object + connector.wait(500) + connector.once('on_data_available', () => {}) + }) + + it('internal waitset is waited on repeatedly within on_data_available', function (done) { + const spy = sinon.spy() + // We expect the data to be received within the next second + setTimeout(() => { + expect(spy.calledOnce).to.be.true + done() + }, 1500) + // Set the listener + connector.once('on_data_available', spy) + // Internally, on_data_available calls connector.wait every 500ms. + // Test that if no data is received within the first 500ms, we call wait + // multiple times + output = connector.getOutput('MyPublisher::MySquareWriter') + testMsg = '{"x":1,"y":1,"z":true,"color":"BLUE","shapesize":5}' + output.instance.setFromJson(JSON.parse(testMsg)) + // In 500ms, write the data + setTimeout(() => { output.write() - }) + }, 1000) }) }) diff --git a/test/nodejs/test_rticonnextdds_data_access.js b/test/nodejs/test_rticonnextdds_data_access.js index 563b4cf9..f9b8f17e 100644 --- a/test/nodejs/test_rticonnextdds_data_access.js +++ b/test/nodejs/test_rticonnextdds_data_access.js @@ -70,7 +70,7 @@ describe('Data access tests with a pre-populated input', function () { } catch (err) { console.log('Caught err: ' + err) // Fail the test - throw(err) + throw (err) } // Write data on the the output output.instance.setFromJson(testJsonObject) @@ -81,7 +81,7 @@ describe('Data access tests with a pre-populated input', function () { } catch (err) { console.log('Caught err: ' + err) // Fail the test - throw(err) + throw (err) } // Take the data on the input so that we can access it from the test prepopulatedInput.take() @@ -101,16 +101,64 @@ describe('Data access tests with a pre-populated input', function () { expect(sample.get('my_long')).to.deep.equals(10).and.is.a('number') }) + it('getNumber requires a valid index', () => { + expect(() => { + prepopulatedInput.samples.getNumber('NAN', 'my_long') + }).to.throw(TypeError) + }) + + it('getNumber requires a valid field name', () => { + expect(() => { + prepopulatedInput.samples.getNumber(0, 1) + }).to.throw(TypeError) + }) + it('getString on a number field should return a string', () => { expect(sample.getString('my_long')).to.deep.equals('10').and.is.a('string') expect(sample.getString('my_double')).to.deep.equals('3.3').and.is.a('string') }) + it('getString requires a valid index', () => { + expect(() => { + prepopulatedInput.samples.getString('NAN', 'my_string') + }).to.throw(TypeError) + }) + + it('getString requires a valid field name', () => { + expect(() => { + prepopulatedInput.samples.getString(0, 1) + }).to.throw(TypeError) + }) + it('getBoolean should return a boolean', () => { expect(sample.getBoolean('my_optional_bool')).to.be.true.and.is.a('boolean') expect(sample.get('my_optional_bool')).to.be.true.and.is.a('boolean') }) + it('getBoolean requires a valid index', () => { + expect(() => { + prepopulatedInput.samples.getBoolean('NAN', 'my_optional_bool') + }).to.throw(TypeError) + }) + + it('getBoolean requires a valid field name', () => { + expect(() => { + prepopulatedInput.samples.getBoolean(0, 1) + }).to.throw(TypeError) + }) + + it('getValue requires a valid index', () => { + expect(() => { + prepopulatedInput.samples.getValue('NAN', 'my_optional_bool') + }).to.throw(TypeError) + }) + + it('getValue requires a valid field name', () => { + expect(() => { + prepopulatedInput.samples.getValue(0, 1) + }).to.throw(TypeError) + }) + it('getNumber on a boolean field should return a number', () => { expect(sample.getNumber('my_optional_bool')).to.deep.equals(1).and.is.a('number') }) @@ -199,6 +247,18 @@ describe('Data access tests with a pre-populated input', function () { }).to.throw(rti.DDSError) }) + it('getJson requires valid index', () => { + expect(() => { + prepopulatedInput.samples.getJson('NAN') + }).to.throw(TypeError) + }) + + it('if a member name is supplied to getJson, it must be a string', () => { + expect(() => { + prepopulatedInput.samples.getJson(1, 0) + }).to.throw(TypeError) + }) + it('attempt to get non-complex members with getJson', () => { expect(() => { sample.getJson('my_long') @@ -344,8 +404,14 @@ describe('Data access tests with a pre-populated input', function () { }) it('Obtain JSON string of dictionary', () => { - const jsonInstance = output.instance.getJson() - expect(jsonInstance).to.deep.equals(testJsonObject) + const jsonInstance = output.instance.getJson() + expect(jsonInstance).to.deep.equals(testJsonObject) + }) + + it('samples.getNative requires valid index', () => { + expect(() => { + prepopulatedInput.samples.getNative('NAN') + }).to.throw(TypeError) }) }) @@ -388,7 +454,7 @@ describe('Tests with a testOutput and testInput', () => { expect(newMatches).to.deep.equals(1) } catch (err) { console.log('Caught err ' + err) - throw(err) + throw (err) } }) @@ -512,7 +578,7 @@ describe('Tests with a testOutput and testInput', () => { await testInput.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } testInput.take() const received = testInput.samples.get(0).get('my_int_sequence') @@ -531,7 +597,7 @@ describe('Tests with a testOutput and testInput', () => { await testInput.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught error: ' + err) - throw(err) + throw (err) } testInput.take() const received = testInput.samples.get(0).get('my_point_sequence') @@ -545,7 +611,7 @@ describe('Tests with a testOutput and testInput', () => { await testInput.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught error: ' + err) - throw(err) + throw (err) } testInput.take() const sample = testInput.samples.get(0) @@ -864,6 +930,59 @@ describe('Tests with a testOutput and testInput', () => { expect(sample.getNumber('my_point_sequence#')).to.deep.equals(2) }) + it('Can clear an entire instance on an output', async () => { + testOutput.instance.setBoolean('my_optional_bool', true) + testOutput.instance.setNumber('my_optional_point.x', 44) + testOutput.clearMembers() + testOutput.write() + try { + await testInput.wait(testExpectSuccessTimeout) + } catch (err) { + // Fail the test + console.log('Error caught: ' + err) + expect(false).to.deep.equals(true) + } + testInput.take() + sample = testInput.samples.get(0) + expect(sample.getBoolean('my_optional_bool')).to.be.null + expect(sample.getBoolean('my_optional_point')).to.be.null + }) + + it('Can clear a value via the generic set function', async () => { + testOutput.instance.setBoolean('my_optional_bool', true) + testOutput.instance.setNumber('my_optional_point.x', 44) + testOutput.instance.set('my_optional_bool', null) + testOutput.instance.set('my_optional_point', null) + testOutput.write() + try { + await testInput.wait(testExpectSuccessTimeout) + } catch (err) { + // Fail the test + console.log('Error caught: ' + err) + expect(false).to.deep.equals(true) + } + testInput.take() + sample = testInput.samples.get(0) + expect(sample.getBoolean('my_optional_bool')).to.be.null + expect(sample.getBoolean('my_optional_point')).to.be.null + }) + + it('Can clear a value via setString', async () => { + testOutput.instance.setString('my_string', 'Hello, World!') + testOutput.instance.setString('my_string', null) + testOutput.write() + try { + await testInput.wait(testExpectSuccessTimeout) + } catch (err) { + // Fail the test + console.log('Error caught: ' + err) + expect(false).to.deep.equals(true) + } + testInput.take() + sample = testInput.samples.get(0) + expect(sample.getString('my_string')).to.deep.equals('') + }) + it('Check that setFromJson shrinks a sequence when it receives a smaller one', async () => { // Set the length to 3 testOutput.instance.setNumber('my_int_sequence[2]', 10) @@ -995,7 +1114,7 @@ describe('Tests with a testOutput and testInput', () => { testOutput.write() try { await testInput.wait(testExpectSuccessTimeout) - } catch(err) { + } catch (err) { console.log('Error caught: ' + err) expect(false).to.deep.equals(true) } @@ -1007,7 +1126,7 @@ describe('Tests with a testOutput and testInput', () => { testOutput.write() try { await testInput.wait(testExpectSuccessTimeout) - } catch(err) { + } catch (err) { console.log('Error caught: ' + err) expect(false).to.deep.equals(true) } @@ -1018,11 +1137,11 @@ describe('Tests with a testOutput and testInput', () => { }) it('Can set enum via name', async () => { - testOutput.instance.setFromJson({ 'my_enum': 'GREEN' }) + testOutput.instance.setFromJson({ my_enum: 'GREEN' }) testOutput.write() try { await testInput.wait(testExpectSuccessTimeout) - } catch(err) { + } catch (err) { console.log('Error caught: ' + err) expect(false).to.deep.equals(true) } @@ -1058,14 +1177,14 @@ describe('Tests with two readers and two writers', () => { expect(newMatches).to.deep.equals(1) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } try { const newMatches = await testOutput2.waitForSubscriptions(testExpectSuccessTimeout) expect(newMatches).to.deep.equals(1) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -1082,7 +1201,7 @@ describe('Tests with two readers and two writers', () => { try { await connector.wait(testExpectFailureTimeout) console.log('Expected connector.wait to timeout but it did not') - throw(err) + throw (err) } catch (err) { expect(err).to.be.an.instanceof(rti.TimeoutError) } @@ -1092,7 +1211,7 @@ describe('Tests with two readers and two writers', () => { try { await testInput1.wait(testExpectFailureTimeout) console.log('Expected testInput1.wait to timeout but it did not') - throw(err) + throw (err) } catch (err) { expect(err).to.be.an.instanceof(rti.TimeoutError) } @@ -1102,7 +1221,7 @@ describe('Tests with two readers and two writers', () => { try { await testInput2.wait(testExpectFailureTimeout) console.log('Expected testInput2.wait to timeout but it did not') - throw(err) + throw (err) } catch (err) { expect(err).to.be.an.instanceof(rti.TimeoutError) } @@ -1114,7 +1233,7 @@ describe('Tests with two readers and two writers', () => { await connector.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -1124,7 +1243,7 @@ describe('Tests with two readers and two writers', () => { await testInput1.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -1133,7 +1252,7 @@ describe('Tests with two readers and two writers', () => { try { await testInput2.wait(testExpectFailureTimeout) console.log('Expected testInput2.wait to timeout but it did not') - throw(err) + throw (err) } catch (err) { expect(err).to.be.an.instanceof(rti.TimeoutError) } @@ -1145,7 +1264,7 @@ describe('Tests with two readers and two writers', () => { await connector.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -1155,7 +1274,7 @@ describe('Tests with two readers and two writers', () => { await testInput2.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -1164,7 +1283,7 @@ describe('Tests with two readers and two writers', () => { try { await testInput1.wait(testExpectFailureTimeout) console.log('Expected testInput2.wait to timeout but it did not') - throw(err) + throw (err) } catch (err) { expect(err).to.be.an.instanceof(rti.TimeoutError) } diff --git a/test/nodejs/test_rticonnextdds_data_iterators.js b/test/nodejs/test_rticonnextdds_data_iterators.js index a6bb8a3b..3268697d 100644 --- a/test/nodejs/test_rticonnextdds_data_iterators.js +++ b/test/nodejs/test_rticonnextdds_data_iterators.js @@ -186,6 +186,7 @@ describe('Test the iteration of Input Samples', () => { input.take() expect(input.samples.length).to.deep.equals(0) let hasData = false + // eslint-disable-next-line no-unused-vars for (const sample of input.samples.validDataIter) { hasData = true } @@ -199,6 +200,7 @@ describe('Test the iteration of Input Samples', () => { input.take() expect(input.samples.length).to.deep.equals(0) let hasData = false + // eslint-disable-next-line no-unused-vars for (const sample of input.samples) { hasData = true } diff --git a/test/nodejs/test_rticonnextdds_dataflow.js b/test/nodejs/test_rticonnextdds_dataflow.js index d5e8b181..bdc5407a 100644 --- a/test/nodejs/test_rticonnextdds_dataflow.js +++ b/test/nodejs/test_rticonnextdds_dataflow.js @@ -24,7 +24,7 @@ const params = ['read', 'take'] params.forEach((retrievalMethod) => { describe('DataflowTests for ' + retrievalMethod, function () { - var input, output, testMsg + let input, output, testMsg // Initialization before all tests execute before(async function () { @@ -39,7 +39,7 @@ params.forEach((retrievalMethod) => { expect(matches).to.be.at.least(1) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -57,14 +57,14 @@ params.forEach((retrievalMethod) => { await input.wait(testExpectSuccessTimeout) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } input[retrievalMethod]() expect(input.samples.length).to.be.at.least(1) }) afterEach(function () { - // take any samples from middleware chache + // take any samples from middleware cache input.take() }) @@ -83,6 +83,8 @@ params.forEach((retrievalMethod) => { expect(validity).to.equal(1) }) + it('') + it('received JSON representation of data should be the same as ' + 'the JSON object sent', function () { const receivedJson = input.samples.getJSON(0) diff --git a/test/nodejs/test_rticonnextdds_discovery.js b/test/nodejs/test_rticonnextdds_discovery.js index 014868be..39bb19cb 100644 --- a/test/nodejs/test_rticonnextdds_discovery.js +++ b/test/nodejs/test_rticonnextdds_discovery.js @@ -21,10 +21,10 @@ const rti = require(path.join(__dirname, '/../../rticonnextdds-connector')) // Create the connector at this level so it can be automatically closed after // each test -var discoveryConnector = null -var discoveryConnectorNoEntityNames = null -var readerOnlyConnector = null -var writerOnlyConnector = null +let discoveryConnector = null +let discoveryConnectorNoEntityNames = null +let readerOnlyConnector = null +let writerOnlyConnector = null // We provide a timeout of 10s to operations that we expect to succeed. This // is so that if they fail, we know for sure something went wrong const testExpectSuccessTimeout = 10000 @@ -115,7 +115,7 @@ describe('Discovery tests', function () { cleanupConnectors() }) - it('Create a Connector object with an input and no ouput', async function () { + it('Create a Connector object with an input and no output', async function () { const input = getDiscoveryReaderOnlyInput() // At this point we should not have matched anything const matches = input.matchedPublications @@ -188,7 +188,7 @@ describe('Discovery tests', function () { } catch (err) { console.log('Caught error: ' + err) // Fail the test - throw(err) + throw (err) } } expect(totalMatches).to.be.at.least(2) @@ -223,7 +223,7 @@ describe('Discovery tests', function () { } catch (err) { console.log('Caught error: ' + err) // Fail the test - throw(err) + throw (err) } } expect(totalMatches).to.be.at.least(2) @@ -369,7 +369,7 @@ describe('Discovery tests', function () { } catch (err) { console.log('Caught error: ' + err) // Fail the test - throw(err) + throw (err) } // Get the entity names of the matched subs @@ -395,7 +395,7 @@ describe('Discovery tests', function () { } catch (err) { console.log('Caught error: ' + err) // Fail the test - throw(err) + throw (err) } const matches = output.matchedSubscriptions expect(matches.length).to.deep.equals(1) @@ -405,4 +405,32 @@ describe('Discovery tests', function () { // since they were all created from the same DomainParticipant as output, // which will have delete_contained_entities called on it. }) + + it('waitForPublications timeout defaults to infinity', async function () { + const input = getDiscoveryReaderOnlyInput() + // Create the writer in 600ms + setTimeout(() => { + getDiscoveryWriterOnlyOutput() + }, 600) + await input.waitForPublications() + }) + + it('waitForSubscriptions timeout defaults to infinity', async function () { + const output = getDiscoveryWriterOnlyOutput() + // Create the reader in 600ms + setTimeout(() => { + getDiscoveryReaderOnlyInput() + }, 600) + await output.waitForSubscriptions() + }) + + it('waitForPublications timeout must be a valid number', function () { + const input = getDiscoveryReaderOnlyInput() + return expect(input.waitForPublications('NAN')).to.be.rejectedWith(TypeError) + }) + + it('waitForSubscriptions timeout must be a valid number', function () { + const output = getDiscoveryWriterOnlyOutput() + return expect(output.waitForSubscriptions('NAN')).to.be.rejectedWith(TypeError) + }) }) diff --git a/test/nodejs/test_rticonnextdds_events.js b/test/nodejs/test_rticonnextdds_events.js index 14c0b1bb..221a5c88 100644 --- a/test/nodejs/test_rticonnextdds_events.js +++ b/test/nodejs/test_rticonnextdds_events.js @@ -53,7 +53,7 @@ describe('Connector EventEmitter tests', function () { }) it('Callback should be called when event is emitted', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) connector.emit('on_data_available') expect(spy.calledOnce).to.be.true @@ -62,7 +62,7 @@ describe('Connector EventEmitter tests', function () { }) it('When no data is written, no event should be emitted', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) setTimeout(() => { expect(spy.notCalled).to.be.true @@ -71,14 +71,14 @@ describe('Connector EventEmitter tests', function () { }) it('It should not be possible to register the event listener and have a Promise waiting for data simultaneously', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) // Internally, the connector's waitset is now busy connector.wait(500) .then(() => { // This should not have been possible console.log('Error occurred. Expected wait to fail due to waitSetBusy') - throw(err) + throw (err) }) .catch((err) => { expect(err.message).to.deep.equals('Can not concurrently wait on the same Connector object') @@ -87,8 +87,8 @@ describe('Connector EventEmitter tests', function () { }) it('Using .removeAllListeners() should remove all eventListeners', () => { - var spy1 = sinon.spy() - var spy2 = sinon.spy() + const spy1 = sinon.spy() + const spy2 = sinon.spy() connector.on('on_data_available', spy1) connector.on('on_data_available', spy2) expect(connector.listenerCount('on_data_available')).to.deep.equals(2) @@ -97,7 +97,7 @@ describe('Connector EventEmitter tests', function () { }) it('Should be possible to re-use a Connector after calling waitForCallbackFinalization', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) expect(connector.listenerCount('on_data_available')).to.deep.equals(1) connector.emit('on_data_available') @@ -119,7 +119,7 @@ describe('Connector EventEmitter tests', function () { // test conditionally if (typeof events.once === 'function') { it('Event should be emitted when data is available on an input', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) output.write() events.once(connector, 'on_data_available') @@ -130,7 +130,7 @@ describe('Connector EventEmitter tests', function () { }) it('Connector.once() should automatically unregister the callback after data is received', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.once('on_data_available', spy) output.write() events.once(connector, 'on_data_available') @@ -149,8 +149,8 @@ describe('Connector EventEmitter tests', function () { }) it('Should be possible to add multiple callbacks for the same event', (done) => { - var spy1 = sinon.spy() - var spy2 = sinon.spy() + const spy1 = sinon.spy() + const spy2 = sinon.spy() connector.on('on_data_available', spy1) connector.on('on_data_available', spy2) expect(connector.listenerCount('on_data_available')).to.deep.equals(2) @@ -164,7 +164,7 @@ describe('Connector EventEmitter tests', function () { }) it('Possible to uninstall the eventListener with .off()', (done) => { - var spy = sinon.spy() + const spy = sinon.spy() connector.on('on_data_available', spy) output.write() events.once(connector, 'on_data_available') @@ -183,8 +183,8 @@ describe('Connector EventEmitter tests', function () { }) it('Using .off() should only unregister the supplied callback, if multiple are registered', (done) => { - var spy1 = sinon.spy() - var spy2 = sinon.spy() + const spy1 = sinon.spy() + const spy2 = sinon.spy() connector.on('on_data_available', spy1) connector.on('on_data_available', spy2) expect(connector.listenerCount('on_data_available')).to.deep.equals(2) diff --git a/test/nodejs/test_rticonnextdds_input.js b/test/nodejs/test_rticonnextdds_input.js index b9575999..7d96c4f5 100644 --- a/test/nodejs/test_rticonnextdds_input.js +++ b/test/nodejs/test_rticonnextdds_input.js @@ -97,7 +97,7 @@ describe('Subscriber not automatically enabled tests', () => { expect(newMatches).to.deep.equals(1) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) }) diff --git a/test/nodejs/test_rticonnextdds_metadata.js b/test/nodejs/test_rticonnextdds_metadata.js index 7db32254..2b7c70f4 100644 --- a/test/nodejs/test_rticonnextdds_metadata.js +++ b/test/nodejs/test_rticonnextdds_metadata.js @@ -45,7 +45,7 @@ describe('Test operations involving meta data', () => { expect(newMatches).to.deep.equals(1) } catch (err) { console.log('Caught err: ' + err) - throw(err) + throw (err) } }) @@ -211,11 +211,11 @@ describe('Test operations involving meta data', () => { it('test getting sample_state', async () => { testOutput.write() try { - await testInput.wait(testExpectSuccessTimeout) + await testInput.wait(testExpectSuccessTimeout) } catch (err) { - // Fail the test - console.log('Error caught: ' + err) - expect(false).to.deep.equals(true) + // Fail the test + console.log('Error caught: ' + err) + expect(false).to.deep.equals(true) } // Since this is the first time that we are accessing the sample, it should @@ -319,428 +319,429 @@ describe('Test operations involving meta data', () => { }) describe('accessing key values after instance disposal', () => { - let connector = null - // Do not create inputs or outputs here since each of the tests - // requires a different type - - beforeEach(() => { - const participantProfile = 'MyParticipantLibrary::Zero' - const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') - connector = new rti.Connector(participantProfile, xmlProfile) - expect(connector).to.exist.and.be.an.instanceof(rti.Connector) - }) - - afterEach(() => { - connector.close() - }) - - // Uses the following type: - // struct ShapeType { - // @key string<128> color; - // long x; - // long y; - // bool z; - // long shapesize; - // }; - it('access key value of disposed instance', async () => { - let input = connector.getInput("MySubscriber::MySquareReader") - expect(input).to.exist - let output = connector.getOutput("MyPublisher::MySquareWriter") - expect(input).to.exist - // Wait for discovery between the 2 entities - try { - let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - newMatches = await input.waitForPublications(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - } catch (err) { - console.log('Caught err: ' + err) - throw(err) - } - // Set some of the fields within the shape type (including the key) - output.instance.setString('color', 'Yellow') - output.instance.setNumber('x', 2) - output.instance.setNumber('y', 5) - output.instance.setBoolean('z', true) - // Write the sample - output.write() - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // Now dispose the instance we just wrote - output.write({ action: 'dispose' }) - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - let sample = input.samples.get(0) - // Sample should contain invalid data, and instance state disposed - expect(sample.info.get('valid_data')).to.deep.equals(false) - expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') - // It should be possible to access the key field - expect(sample.get('color')).to.deep.equals('Yellow') - expect(sample.getString('color')).to.deep.equals('Yellow') - // All non key fields should not be accessed. - // Can also obtain the JSON representation of the sample. - const expectedJson = { - color: 'Yellow', - x: 0, - y: 0, - z: false, - shapesize: 0 - } - expect(sample.getJson()).to.deep.equals(expectedJson) - }) - - // Uses the following type: - // struct MultipleKeyedShapeType { - // @key string<128> color; - // @key string<128> other_color; - // long x; - // @key long y; - // @key bool z; - // long shapesize; - // }; - it('access key values of disposed instance with multiple keys', async () => { - let input = connector.getInput("MySubscriber::MyMultipleKeyedSquareReader") - expect(input).to.exist - let output = connector.getOutput("MyPublisher::MyMultipleKeyedSquareWriter") - expect(input).to.exist - // Wait for discovery between the 2 entities - try { - let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - newMatches = await input.waitForPublications(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - } catch (err) { - console.log('Caught err: ' + err) - throw(err) - } - // This type has multiple key fields, set them all - output.instance.setString('color', 'Brown') - output.instance.setString('other_color', 'Blue') - output.instance.setNumber('y', 9) - output.instance.setBoolean('z', false) - // Also set some of the non-key fields - output.instance.setNumber('x', 12) - output.instance.setNumber('shapesize', 0) - // Write the sample and take it on the input - output.write() - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // Now dispose the instance we just wrote - output.write({ action: 'dispose' }) - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - let sample = input.samples.get(0) - // Check key fields - expect(sample.get('color')).to.deep.equals('Brown') - expect(sample.get('other_color')).to.deep.equals('Blue') - expect(sample.get('y')).to.deep.equals(9) - expect(sample.get('z')).to.deep.equals(false) - expect(sample.getString('color')).to.deep.equals('Brown') - expect(sample.getString('other_color')).to.deep.equals('Blue') - expect(sample.getNumber('y')).to.deep.equals(9) - expect(sample.getBoolean('z')).to.deep.equals(false) - // Do not access non-key values - // Check access via JSON object - const expectedJson = { - color: 'Brown', - other_color: 'Blue', - y: 9, - x: 0, - z: false, - shapesize: 0 - } - expect(sample.getJson()).to.deep.equals(expectedJson) - }) - - // Uses the following type: - // struct ShapeType { - // @key string<128> color; - // long x; - // long y; - // bool z; - // long shapesize; - // }; - // - // struct UnkeyedShapeType { - // string<128> color; - // long x; - // long y; - // bool z; - // long shapesize; - // }; - // - // struct NestedKeyedShapeType { - // @key UnkeyedShapeType keyed_shape; - // UnkeyedShapeType unkeyed_shape; - // @key ShapeType keyed_nested_member; - // @default(12) long unkeyed_toplevel_member; - // @key long keyed_toplevel_member; - // }; - it('access the complex key of a disposed instance', async () => { - let input = connector.getInput("MySubscriber::MyNestedKeyedSquareReader") - expect(input).to.exist - let output = connector.getOutput("MyPublisher::MyNestedKeyedSquareWriter") - expect(input).to.exist - // Wait for discovery between the 2 entities - try { - let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - newMatches = await input.waitForPublications(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - } catch (err) { - console.log('Caught err: ' + err) - throw(err) - } - // Set the sample's fields - output.instance.setString('keyed_shape.color', 'Black') - output.instance.setNumber('keyed_shape.x', 2) - output.instance.setNumber('keyed_shape.y', 0) - output.instance.setNumber('keyed_shape.shapesize', 100) - output.instance.setBoolean('keyed_shape.z', true) - output.instance.setNumber('unkeyed_toplevel_member', 1) - output.instance.setNumber('keyed_toplevel_member', 1) - output.instance.setNumber('unkeyed_shape.shapesize', 100) - output.instance.setString('keyed_nested_member.color', 'White') - output.instance.setNumber('keyed_nested_member.x', 4) - // Write the sample and take it on the input - output.write() - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // Now dispose the instance we just wrote - output.write({ action: 'dispose' }) - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - let sample = input.samples.get(0) - expect(sample.info.get('valid_data')).to.deep.equals(false) - expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') - // Everything within keyed_shape is a key - expect(sample.getNumber('keyed_shape.x')).to.deep.equals(2) - expect(sample.getNumber('keyed_shape.y')).to.deep.equals(0) - expect(sample.getNumber('keyed_shape.shapesize')).to.deep.equals(100) - expect(sample.getBoolean('keyed_shape.z')).to.deep.equals(true) - expect(sample.get('keyed_shape.x')).to.deep.equals(2) - expect(sample.get('keyed_shape.y')).to.deep.equals(0) - expect(sample.get('keyed_shape.shapesize')).to.deep.equals(100) - expect(sample.get('keyed_shape.z')).to.deep.equals(true) - expect(sample.get('keyed_shape.color')).to.deep.equals('Black') - expect(sample.getString('keyed_shape.color')).to.deep.equals('Black') - // keyed_toplevel_member is also a key - expect(sample.getNumber('keyed_toplevel_member')).to.deep.equals(1) - expect(sample.get('keyed_toplevel_member')).to.deep.equals(1) - // Only the 'color' field in keyed_nested_member is keyed - expect(sample.get('keyed_nested_member.color')).to.deep.equals('White') - expect(sample.get('keyed_nested_member.x')).to.deep.equals(0) - // Do not access any of the non-key values - // The unkeyed_toplevel_member field has a default value explicitly set - // in the type. This should not effect the returned value (SamR confirm this) - expect(sample.get('unkeyed_toplevel_member')).to.deep.equals(0) - expect(sample.getNumber('unkeyed_toplevel_member')).to.deep.equals(0) - let expectedJson = { - keyed_shape: { - color: 'Black', - x: 2, - y: 0, - shapesize: 100, - z: true - }, - // unkeyed_shape not keyed -> default values - unkeyed_shape: { - color: '', - x: 0, - y: 0, - shapesize: 0, - z: false - }, - keyed_nested_member: { - color: 'White', - // All other members default value - x: 0, - y: 0, - shapesize: 0, - z: false - }, - // unkeyed_toplevel_member is unkeyed -> default value - unkeyed_toplevel_member: 0, - keyed_toplevel_member: 1 - } - expect(sample.getJson()).to.deep.equals(expectedJson) - // Can also obtain the keyed members as a JSON since they are complex - expectedJson = { - color: 'Black', - x: 2, - y: 0, - shapesize: 100, - z: true - } - expect(sample.getJson('keyed_shape')).to.deep.equals(expectedJson) - expectedJson = { - color: 'White', - x: 0, - y: 0, - shapesize: 0, - z: false - } - expect(sample.getJson('keyed_nested_member')).to.deep.equals(expectedJson) - }) - - it('access the key fields using an iterator', async () => { - let input = connector.getInput("MySubscriber::MySquareReader") - expect(input).to.exist - let output = connector.getOutput("MyPublisher::MySquareWriter") - expect(input).to.exist - // Wait for discovery between the 2 entities - try { - let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - newMatches = await input.waitForPublications(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - } catch (err) { - console.log('Caught err: ' + err) - throw(err) - } - // Set some of the fields within the shape type (including the key) - output.instance.setString('color', 'Yellow') - output.instance.setNumber('x', 2) - // Write the sample - output.write() - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // Now dispose the instance we just wrote - output.write({ action: 'dispose' }) - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // There should be no samples accessible within the validDataIter - let hadData = false - for (const sample of input.samples.validDataIter) { - hadData = true; - } - expect(hadData).to.deep.equals(false) - // Should be possible to access key fields in the dataIter - for (const sample of input.samples) { - expect(sample.info.get('valid_data')).to.deep.equals(false) - expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') - expect(sample.getString('color')).to.deep.equals('Yellow') - expect(sample.get('color')).to.deep.equals('Yellow') - const expectedJson = { - color: 'Yellow', - x: 0, - y: 0, - shapesize: 0, - z: false - } - expect(sample.getJson()).to.deep.equals(expectedJson) - } - }) - - // struct ShapeType { - // @key string<128> color; - // long x; - // long y; - // bool z; - // long shapesize; - // }; - // struct ShapeTypeWithoutToplevelKeyType { - // @key ShapeType keyed_shape; - // ShapeType unkeyed_shape; - // }; - it('keys within nested structures are not keys unless tagged as keys in top level', async () => { - let input = connector.getInput("MySubscriber::MySquareWithoutTopLevelKeyReader") - expect(input).to.exist - let output = connector.getOutput("MyPublisher::MySquareWithoutTopLevelKeyWriter") - expect(input).to.exist - // Wait for discovery between the 2 entities - try { - let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - newMatches = await input.waitForPublications(testExpectSuccessTimeout) - expect(newMatches).to.deep.equals(1) - } catch (err) { - console.log('Caught err: ' + err) - throw(err) - } - // Set some of the fields within the shape type (including the key) - output.instance.setString('unkeyed_shape.color', 'Yellow') - output.instance.setNumber('unkeyed_shape.x', 2) - output.instance.setString('keyed_shape.color', 'Yellow') - output.instance.setNumber('keyed_shape.x', 2) - // Write the sample - output.write() - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // Now dispose the instance we just wrote - output.write({ action: 'dispose' }) - try { - await input.wait(testExpectSuccessTimeout) - } catch (err) { - console.log('Error caught: ' + err) - throw(err) - } - input.take() - // The 'color' field we set is not actually a key. Fields need to be tagged - // in the top-level type in order to be part of the key. This means that - // nothing in this type should be non-default. - let sample = input.samples.get(0) - let expectedJson = { - keyed_shape: { - color: 'Yellow', - x: 0, - y: 0, - shapesize: 0, - z: false - }, - unkeyed_shape: { - color: '', - x: 0, - y: 0, - shapesize: 0, - z: false - } - } - expect(sample.getJson()).to.deep.equals(expectedJson) - }) + let connector = null + // Do not create inputs or outputs here since each of the tests + // requires a different type + + beforeEach(() => { + const participantProfile = 'MyParticipantLibrary::Zero' + const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') + connector = new rti.Connector(participantProfile, xmlProfile) + expect(connector).to.exist.and.be.an.instanceof(rti.Connector) + }) + + afterEach(async () => { + connector.close() + }) + + // Uses the following type: + // struct ShapeType { + // @key string<128> color; + // long x; + // long y; + // bool z; + // long shapesize; + // }; + it('access key value of disposed instance', async () => { + const input = connector.getInput('MySubscriber::MySquareReader') + expect(input).to.exist + const output = connector.getOutput('MyPublisher::MySquareWriter') + expect(input).to.exist + // Wait for discovery between the 2 entities + try { + let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + newMatches = await input.waitForPublications(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + } catch (err) { + console.log('Caught err: ' + err) + throw (err) + } + // Set some of the fields within the shape type (including the key) + output.instance.setString('color', 'Yellow') + output.instance.setNumber('x', 2) + output.instance.setNumber('y', 5) + output.instance.setBoolean('z', true) + // Write the sample + output.write() + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // Now dispose the instance we just wrote + output.write({ action: 'dispose' }) + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + const sample = input.samples.get(0) + // Sample should contain invalid data, and instance state disposed + expect(sample.info.get('valid_data')).to.deep.equals(false) + expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') + // It should be possible to access the key field + expect(sample.get('color')).to.deep.equals('Yellow') + expect(sample.getString('color')).to.deep.equals('Yellow') + // All non key fields should not be accessed. + // Can also obtain the JSON representation of the sample. + const expectedJson = { + color: 'Yellow', + x: 0, + y: 0, + z: false, + shapesize: 0 + } + expect(sample.getJson()).to.deep.equals(expectedJson) + }) + + // Uses the following type: + // struct MultipleKeyedShapeType { + // @key string<128> color; + // @key string<128> other_color; + // long x; + // @key long y; + // @key bool z; + // long shapesize; + // }; + it('access key values of disposed instance with multiple keys', async () => { + const input = connector.getInput('MySubscriber::MyMultipleKeyedSquareReader') + expect(input).to.exist + const output = connector.getOutput('MyPublisher::MyMultipleKeyedSquareWriter') + expect(input).to.exist + // Wait for discovery between the 2 entities + try { + let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + newMatches = await input.waitForPublications(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + } catch (err) { + console.log('Caught err: ' + err) + throw (err) + } + // This type has multiple key fields, set them all + output.instance.setString('color', 'Brown') + output.instance.setString('other_color', 'Blue') + output.instance.setNumber('y', 9) + output.instance.setBoolean('z', false) + // Also set some of the non-key fields + output.instance.setNumber('x', 12) + output.instance.setNumber('shapesize', 0) + // Write the sample and take it on the input + output.write() + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // Now dispose the instance we just wrote + output.write({ action: 'dispose' }) + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + const sample = input.samples.get(0) + // Check key fields + expect(sample.get('color')).to.deep.equals('Brown') + expect(sample.get('other_color')).to.deep.equals('Blue') + expect(sample.get('y')).to.deep.equals(9) + expect(sample.get('z')).to.deep.equals(false) + expect(sample.getString('color')).to.deep.equals('Brown') + expect(sample.getString('other_color')).to.deep.equals('Blue') + expect(sample.getNumber('y')).to.deep.equals(9) + expect(sample.getBoolean('z')).to.deep.equals(false) + // Do not access non-key values + // Check access via JSON object + const expectedJson = { + color: 'Brown', + other_color: 'Blue', + y: 9, + x: 0, + z: false, + shapesize: 0 + } + expect(sample.getJson()).to.deep.equals(expectedJson) + }) + + // Uses the following type: + // struct ShapeType { + // @key string<128> color; + // long x; + // long y; + // bool z; + // long shapesize; + // }; + // + // struct UnkeyedShapeType { + // string<128> color; + // long x; + // long y; + // bool z; + // long shapesize; + // }; + // + // struct NestedKeyedShapeType { + // @key UnkeyedShapeType keyed_shape; + // UnkeyedShapeType unkeyed_shape; + // @key ShapeType keyed_nested_member; + // @default(12) long unkeyed_toplevel_member; + // @key long keyed_toplevel_member; + // }; + it('access the complex key of a disposed instance', async () => { + const input = connector.getInput('MySubscriber::MyNestedKeyedSquareReader') + expect(input).to.exist + const output = connector.getOutput('MyPublisher::MyNestedKeyedSquareWriter') + expect(input).to.exist + // Wait for discovery between the 2 entities + try { + let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + newMatches = await input.waitForPublications(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + } catch (err) { + console.log('Caught err: ' + err) + throw (err) + } + // Set the sample's fields + output.instance.setString('keyed_shape.color', 'Black') + output.instance.setNumber('keyed_shape.x', 2) + output.instance.setNumber('keyed_shape.y', 0) + output.instance.setNumber('keyed_shape.shapesize', 100) + output.instance.setBoolean('keyed_shape.z', true) + output.instance.setNumber('unkeyed_toplevel_member', 1) + output.instance.setNumber('keyed_toplevel_member', 1) + output.instance.setNumber('unkeyed_shape.shapesize', 100) + output.instance.setString('keyed_nested_member.color', 'White') + output.instance.setNumber('keyed_nested_member.x', 4) + // Write the sample and take it on the input + output.write() + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // Now dispose the instance we just wrote + output.write({ action: 'dispose' }) + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + const sample = input.samples.get(0) + expect(sample.info.get('valid_data')).to.deep.equals(false) + expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') + // Everything within keyed_shape is a key + expect(sample.getNumber('keyed_shape.x')).to.deep.equals(2) + expect(sample.getNumber('keyed_shape.y')).to.deep.equals(0) + expect(sample.getNumber('keyed_shape.shapesize')).to.deep.equals(100) + expect(sample.getBoolean('keyed_shape.z')).to.deep.equals(true) + expect(sample.get('keyed_shape.x')).to.deep.equals(2) + expect(sample.get('keyed_shape.y')).to.deep.equals(0) + expect(sample.get('keyed_shape.shapesize')).to.deep.equals(100) + expect(sample.get('keyed_shape.z')).to.deep.equals(true) + expect(sample.get('keyed_shape.color')).to.deep.equals('Black') + expect(sample.getString('keyed_shape.color')).to.deep.equals('Black') + // keyed_toplevel_member is also a key + expect(sample.getNumber('keyed_toplevel_member')).to.deep.equals(1) + expect(sample.get('keyed_toplevel_member')).to.deep.equals(1) + // Only the 'color' field in keyed_nested_member is keyed + expect(sample.get('keyed_nested_member.color')).to.deep.equals('White') + expect(sample.get('keyed_nested_member.x')).to.deep.equals(0) + // Do not access any of the non-key values + // The unkeyed_toplevel_member field has a default value explicitly set + // in the type. This should not effect the returned value. + expect(sample.get('unkeyed_toplevel_member')).to.deep.equals(0) + expect(sample.getNumber('unkeyed_toplevel_member')).to.deep.equals(0) + let expectedJson = { + keyed_shape: { + color: 'Black', + x: 2, + y: 0, + shapesize: 100, + z: true + }, + // unkeyed_shape not keyed -> default values + unkeyed_shape: { + color: '', + x: 0, + y: 0, + shapesize: 0, + z: false + }, + keyed_nested_member: { + color: 'White', + // All other members default value + x: 0, + y: 0, + shapesize: 0, + z: false + }, + // unkeyed_toplevel_member is unkeyed -> default value + unkeyed_toplevel_member: 0, + keyed_toplevel_member: 1 + } + expect(sample.getJson()).to.deep.equals(expectedJson) + // Can also obtain the keyed members as a JSON since they are complex + expectedJson = { + color: 'Black', + x: 2, + y: 0, + shapesize: 100, + z: true + } + expect(sample.getJson('keyed_shape')).to.deep.equals(expectedJson) + expectedJson = { + color: 'White', + x: 0, + y: 0, + shapesize: 0, + z: false + } + expect(sample.getJson('keyed_nested_member')).to.deep.equals(expectedJson) + }) + + it('access the key fields using an iterator', async () => { + const input = connector.getInput('MySubscriber::MySquareReader') + expect(input).to.exist + const output = connector.getOutput('MyPublisher::MySquareWriter') + expect(input).to.exist + // Wait for discovery between the 2 entities + try { + let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + newMatches = await input.waitForPublications(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + } catch (err) { + console.log('Caught err: ' + err) + throw (err) + } + // Set some of the fields within the shape type (including the key) + output.instance.setString('color', 'Yellow') + output.instance.setNumber('x', 2) + // Write the sample + output.write() + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // Now dispose the instance we just wrote + output.write({ action: 'dispose' }) + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // There should be no samples accessible within the validDataIter + let hadData = false + // eslint-disable-next-line no-unused-vars + for (const sample of input.samples.validDataIter) { + hadData = true + } + expect(hadData).to.deep.equals(false) + // Should be possible to access key fields in the dataIter + for (const sample of input.samples) { + expect(sample.info.get('valid_data')).to.deep.equals(false) + expect(sample.info.get('instance_state')).to.deep.equals('NOT_ALIVE_DISPOSED') + expect(sample.getString('color')).to.deep.equals('Yellow') + expect(sample.get('color')).to.deep.equals('Yellow') + const expectedJson = { + color: 'Yellow', + x: 0, + y: 0, + shapesize: 0, + z: false + } + expect(sample.getJson()).to.deep.equals(expectedJson) + } + }) + + // struct ShapeType { + // @key string<128> color; + // long x; + // long y; + // bool z; + // long shapesize; + // }; + // struct ShapeTypeWithoutToplevelKeyType { + // @key ShapeType keyed_shape; + // ShapeType unkeyed_shape; + // }; + it('keys within nested structures are not keys unless tagged as keys in top level', async () => { + const input = connector.getInput('MySubscriber::MySquareWithoutTopLevelKeyReader') + expect(input).to.exist + const output = connector.getOutput('MyPublisher::MySquareWithoutTopLevelKeyWriter') + expect(input).to.exist + // Wait for discovery between the 2 entities + try { + let newMatches = await output.waitForSubscriptions(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + newMatches = await input.waitForPublications(testExpectSuccessTimeout) + expect(newMatches).to.deep.equals(1) + } catch (err) { + console.log('Caught err: ' + err) + throw (err) + } + // Set some of the fields within the shape type (including the key) + output.instance.setString('unkeyed_shape.color', 'Yellow') + output.instance.setNumber('unkeyed_shape.x', 2) + output.instance.setString('keyed_shape.color', 'Yellow') + output.instance.setNumber('keyed_shape.x', 2) + // Write the sample + output.write() + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // Now dispose the instance we just wrote + output.write({ action: 'dispose' }) + try { + await input.wait(testExpectSuccessTimeout) + } catch (err) { + console.log('Error caught: ' + err) + throw (err) + } + input.take() + // The 'color' field we set is not actually a key. Fields need to be tagged + // in the top-level type in order to be part of the key. This means that + // nothing in this type should be non-default. + const sample = input.samples.get(0) + const expectedJson = { + keyed_shape: { + color: 'Yellow', + x: 0, + y: 0, + shapesize: 0, + z: false + }, + unkeyed_shape: { + color: '', + x: 0, + y: 0, + shapesize: 0, + z: false + } + } + expect(sample.getJson()).to.deep.equals(expectedJson) + }) }) diff --git a/test/nodejs/test_rticonnextdds_output.js b/test/nodejs/test_rticonnextdds_output.js index 39b55725..e15981c0 100644 --- a/test/nodejs/test_rticonnextdds_output.js +++ b/test/nodejs/test_rticonnextdds_output.js @@ -15,18 +15,25 @@ const rti = require(path.join(__dirname, '/../../rticonnextdds-connector')) /* eslint-disable no-unused-expressions */ /* eslint-disable no-undef */ +// We provide a timeout of 10s to operations that we expect to succeed. This +// is so that if they fail, we know for sure something went wrong +const testExpectSuccessTimeout = 10000 + describe('Output Tests', function () { + this.timeout(testExpectSuccessTimeout) let connector = null - // Initialization before all tests execute - before(function () { + let output = null + let input = null + beforeEach(function () { const participantProfile = 'MyParticipantLibrary::Zero' const xmlProfile = path.join(__dirname, '/../xml/TestConnector.xml') connector = new rti.Connector(participantProfile, xmlProfile) + output = connector.getOutput('MyPublisher::MySquareWriter') + input = connector.getInput('MySubscriber::MySquareReader') }) - // Cleanup after all tests have executed - after(function () { - this.timeout(0) + afterEach(async () => { + input.take() connector.delete() }) @@ -39,146 +46,147 @@ describe('Output Tests', function () { it('Output object should get instantiated for valid ' + 'Publication::DataWriter name', function () { - const validDW = 'MyPublisher::MySquareWriter' - const output = connector.getOutput(validDW) expect(output).to.exist - expect(output.name).to.equal(validDW) + expect(output.name).to.equal('MyPublisher::MySquareWriter') expect(output.connector).to.equal(connector) }) - describe('Tests on Output\'s Instance', function () { - let output = null - // Initialization before all tests execute in this describe block - before(function () { - output = connector.getOutput('MyPublisher::MySquareWriter') - }) + it('Can wait for acknowledgements on a reliable DataWriter', async () => { + // Write data on the writer, and wait for it to be ACK'd by the reader + output.write() + // Since the writer is reliable transient local, no need to to wait for + // discovery + await output.wait(testExpectSuccessTimeout) + await input.wait(testExpectSuccessTimeout) + input.take() + expect(input.samples.length).to.deep.equals(1) + }) + + it('output\'s instance should exist', function () { + expect(output.instance).to.exist + }) - it('output\'s instance should exist', function () { - expect(output.instance).to.exist - }) + it('setNumber on non-existent field should throw error and ' + + 'subscriber should not get a message with default values', function () { + expect(function () { + output.instance.setNumber('invalid_field', 1) + }).to.throw(Error) + }) - it('setNumber on non-existent field should throw error and ' + + it('setString on non-existent field should throw error and ' + 'subscriber should not get a message with default values', function () { - expect(function () { - output.instance.setNumber('invalid_field', 1) - }).to.throw(Error) - }) + expect(function () { + output.instance.setString('invalid_field', 'value') + }).to.throw(Error) + }) - it('setString on non-existent field should throw error and ' + + it('setBoolean on non-existent field should throw error and ' + 'subscriber should not get a message with default values', function () { - expect(function () { - output.instance.setString('invalid_field', 'value') - }).to.throw(Error) - }) - - it('setBoolean on non-existent field should throw error and ' + - 'subscriber should not get a message with default values',function () { - expect(function () { - output.instance.setBoolean('invalid_field', true) - }).to.throw(Error) - }) - - it('setFromJSON should throw error for a JSON object ' + + expect(function () { + output.instance.setBoolean('invalid_field', true) + }).to.throw(Error) + }) + + it('setFromJSON should throw error for a JSON object ' + 'with non-existent fields and subscriber should not get ' + 'a message with default values', function () { - expect(function () { - const invalidData = '{"invalid_field":1}' - output.instance.setFromJSON(JSON.parse(invalidData)) - }).to.throw(Error) - }) - - it('setString with boolean value should throw Error', function () { - expect(function () { - const stringField = 'color' - output.instance.setString(stringField, true) - }).to.throw(Error) - }) - - it('setString with number value should throw Error', function () { - expect(function () { - const stringField = 'color' - output.instance.setString(stringField, 11) - }).to.throw(Error) - }) - - it('setString with JSON value should throw Error', function () { - expect(function () { - const stringField = 'color' - output.instance.setString(stringField, { key: 'value' }) - }).to.throw(Error) - }) - - it('setNumber with string value should throw Error and' + + expect(function () { + const invalidData = '{"invalid_field":1}' + output.instance.setFromJSON(JSON.parse(invalidData)) + }).to.throw(Error) + }) + + it('setString with boolean value should throw Error', function () { + expect(function () { + const stringField = 'color' + output.instance.setString(stringField, true) + }).to.throw(Error) + }) + + it('setString with number value should throw Error', function () { + expect(function () { + const stringField = 'color' + output.instance.setString(stringField, 11) + }).to.throw(Error) + }) + + it('setString with JSON value should throw Error', function () { + expect(function () { + const stringField = 'color' + output.instance.setString(stringField, { key: 'value' }) + }).to.throw(Error) + }) + + it('setNumber with string value should throw Error and' + 'subscriber should not get a message with erroneous field data', function () { - expect(function () { - const numberField = 'x' - output.instance.setNumber(numberField, 'value') - }).to.throw(Error) - }) - - it('Implicit type-conversion for setNumber with boolean value', function () { - expect(function () { - const numberField = 'x' - output.instance.setNumber(numberField, true) - }).to.throw(Error) - }) - - it('setNumber with JSON value should throw Error and ' + + expect(function () { + const numberField = 'x' + output.instance.setNumber(numberField, 'value') + }).to.throw(Error) + }) + + it('Implicit type-conversion for setNumber with boolean value', function () { + expect(function () { + const numberField = 'x' + output.instance.setNumber(numberField, true) + }).to.throw(Error) + }) + + it('setNumber with JSON value should throw Error and ' + 'subscriber should not get a message with erroneous field data', function () { - expect(function () { - const numberField = 'x' - output.instance.setNumber(numberField, { key: 'value' }) - }).to.throw(Error) - }) + expect(function () { + const numberField = 'x' + output.instance.setNumber(numberField, { key: 'value' }) + }).to.throw(Error) + }) - it('setBoolean with string value should throw Error and ' + + it('setBoolean with string value should throw Error and ' + 'subscriber should not get a message with erroneous field data', function () { - expect(function () { - const booleanField = 'z' - output.instance.setBoolean(booleanField, 'value') - }).to.throw(Error) - }) - - it('Implicit type-conversion for setBoolean with number value', function () { - expect(function () { - const booleanField = 'z' - output.instance.setBoolean(booleanField, 1) - }).to.throw(Error) - }) - - it('setBoolean with JSON value should throw Error and ' + + expect(function () { + const booleanField = 'z' + output.instance.setBoolean(booleanField, 'value') + }).to.throw(Error) + }) + + it('Implicit type-conversion for setBoolean with number value', function () { + expect(function () { + const booleanField = 'z' + output.instance.setBoolean(booleanField, 1) + }).to.throw(Error) + }) + + it('setBoolean with JSON value should throw Error and ' + 'subscriber should not get a message with erroneous field data', function () { - expect(function () { - const booleanField = 'z' - output.instance.setBoolean(booleanField, { key: 'value' }) - }).to.throw(Error) - }) + expect(function () { + const booleanField = 'z' + output.instance.setBoolean(booleanField, { key: 'value' }) + }).to.throw(Error) + }) - it('setFromJSON for JSON object with incompatible value types ' + + it('setFromJSON for JSON object with incompatible value types ' + 'should throw Error and subscriber should not get a message with ' + 'erroneous field data', function () { - expect(function () { - const str = '{"x":"5","y":true,"color":true,"shapesize":"5","z":"value"}' - output.instance.setFromJSON(JSON.parse(str)) - }).to.throw(Error) - }) - - it('Use the type independent set with invalid fieldName', function () { - expect(function () { - output.instance.set(123, 123) - }).to.throw(TypeError) - }) - - it('Calling the type-independent set with non-existent field name', function () { - expect(function () { - output.instance.set('non-existent-member', 123) - }).to.throw(rti.DDSError) - }) - - it('Try to set a bad JSON value', function () { - expect(function () { - output.instance.set('whatever', { x: 12, y: 30 }) - }).to.throw(rti.DDSError) - }) + expect(function () { + const str = '{"x":"5","y":true,"color":true,"shapesize":"5","z":"value"}' + output.instance.setFromJSON(JSON.parse(str)) + }).to.throw(Error) + }) + + it('Use the type independent set with invalid fieldName', function () { + expect(function () { + output.instance.set(123, 123) + }).to.throw(TypeError) + }) + + it('Calling the type-independent set with non-existent field name', function () { + expect(function () { + output.instance.set('non-existent-member', 123) + }).to.throw(rti.DDSError) + }) + + it('Try to set a bad JSON value', function () { + expect(function () { + output.instance.set('whatever', { x: 12, y: 30 }) + }).to.throw(rti.DDSError) }) })