diff --git a/README.md b/README.md index ff9332c2..bbaa80d9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![NPM Publish](https://ci.centos.org/job/devtools-fabric8-analytics-lsp-server-npm-publish-build-master/badge/icon)](https://ci.centos.org/job/devtools-fabric8-analytics-lsp-server-npm-publish-build-master/) [![NPM Version](https://img.shields.io/npm/v/fabric8-analytics-lsp-server.svg)](https://www.npmjs.com/package/fabric8-analytics-lsp-server) -![CI Build](https://github.com/fabric8-analytics/fabric8-analytics-lsp-server/workflows/CI%20Build/badge.svg) +![CI Build](https://github.com/fabric8-analytics/fabric8-analytics-lsp-server/workflows/CI%20Build/badge.svg?branch=master) [![codecov](https://codecov.io/gh/fabric8-analytics/fabric8-analytics-lsp-server/branch/master/graph/badge.svg?token=aVThXjheDf)](https://codecov.io/gh/fabric8-analytics/fabric8-analytics-lsp-server) Language Server(LSP) that can analyze your dependencies specified in `package.json` and `pom.xml`. diff --git a/package-lock.json b/package-lock.json index ac6a6a11..50c50482 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,57 +142,63 @@ } }, "@octokit/auth-token": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.3.tgz", - "integrity": "sha512-fdGoOQ3kQJh+hrilc0Plg50xSfaCKOeYN9t6dpJKXN9BxhhfquL0OzoQXg3spLYymL5rm29uPeI3KEXRaZQ9zg==", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.4.4.tgz", + "integrity": "sha512-LNfGu3Ro9uFAYh10MUZVaT7X2CnNm2C8IDQmabx+3DygYIQjs9FwzFAHN/0t6mu5HEPhxcb1XOuxdpY82vCg2Q==", "dev": true, "requires": { - "@octokit/types": "^5.0.0" + "@octokit/types": "^6.0.0" } }, "@octokit/core": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.2.1.tgz", - "integrity": "sha512-XfFSDDwv6tclUenS0EmB6iA7u+4aOHBT1Lz4PtQNQQg3hBbNaR/+Uv5URU+egeIuuGAiMRiDyY92G4GBOWOqDA==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.2.4.tgz", + "integrity": "sha512-d9dTsqdePBqOn7aGkyRFe7pQpCXdibSJ5SFnrTr0axevObZrpz3qkWm7t/NjYv5a66z6vhfteriaq4FRz3e0Qg==", "dev": true, "requires": { - "@octokit/auth-token": "^2.4.0", - "@octokit/graphql": "^4.3.1", - "@octokit/request": "^5.4.0", - "@octokit/types": "^5.0.0", + "@octokit/auth-token": "^2.4.4", + "@octokit/graphql": "^4.5.8", + "@octokit/request": "^5.4.12", + "@octokit/types": "^6.0.3", "before-after-hook": "^2.1.0", "universal-user-agent": "^6.0.0" } }, "@octokit/endpoint": { - "version": "6.0.9", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.9.tgz", - "integrity": "sha512-3VPLbcCuqji4IFTclNUtGdp9v7g+nspWdiCUbK3+iPMjJCZ6LEhn1ts626bWLOn0GiDb6j+uqGvPpqLnY7pBgw==", + "version": "6.0.10", + "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.10.tgz", + "integrity": "sha512-9+Xef8nT7OKZglfkOMm7IL6VwxXUQyR7DUSU0LH/F7VNqs8vyd7es5pTfz9E7DwUIx7R3pGscxu1EBhYljyu7Q==", "dev": true, "requires": { - "@octokit/types": "^5.0.0", + "@octokit/types": "^6.0.0", "is-plain-object": "^5.0.0", "universal-user-agent": "^6.0.0" } }, "@octokit/graphql": { - "version": "4.5.7", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.7.tgz", - "integrity": "sha512-Gk0AR+DcwIK/lK/GX+OQ99UqtenQhcbrhHHfOYlrCQe17ADnX3EKAOKRsAZ9qZvpi5MuwWm/Nm+9aO2kTDSdyA==", + "version": "4.5.8", + "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.5.8.tgz", + "integrity": "sha512-WnCtNXWOrupfPJgXe+vSmprZJUr0VIu14G58PMlkWGj3cH+KLZEfKMmbUQ6C3Wwx6fdhzVW1CD5RTnBdUHxhhA==", "dev": true, "requires": { "@octokit/request": "^5.3.0", - "@octokit/types": "^5.0.0", + "@octokit/types": "^6.0.0", "universal-user-agent": "^6.0.0" } }, + "@octokit/openapi-types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-2.0.0.tgz", + "integrity": "sha512-J4bfM7lf8oZvEAdpS71oTvC1ofKxfEZgU5vKVwzZKi4QPiL82udjpseJwxPid9Pu2FNmyRQOX4iEj6W1iOSnPw==", + "dev": true + }, "@octokit/plugin-paginate-rest": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.6.0.tgz", - "integrity": "sha512-o+O8c1PqsC5++BHXfMZabRRsBIVb34tXPWyQLyp2IXq5MmkxdipS7TXM4Y9ldL1PzY9CTrCsn/lzFFJGM3oRRA==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.6.2.tgz", + "integrity": "sha512-3Dy7/YZAwdOaRpGQoNHPeT0VU1fYLpIUdPyvR37IyFLgd6XSij4j9V/xN/+eSjF2KKvmfIulEh9LF1tRPjIiDA==", "dev": true, "requires": { - "@octokit/types": "^5.5.0" + "@octokit/types": "^6.0.1" } }, "@octokit/plugin-request-log": { @@ -202,24 +208,24 @@ "dev": true }, "@octokit/plugin-rest-endpoint-methods": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.2.1.tgz", - "integrity": "sha512-QyFr4Bv807Pt1DXZOC5a7L5aFdrwz71UHTYoHVajYV5hsqffWm8FUl9+O7nxRu5PDMtB/IKrhFqTmdBTK5cx+A==", + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-4.4.1.tgz", + "integrity": "sha512-+v5PcvrUcDeFXf8hv1gnNvNLdm4C0+2EiuWt9EatjjUmfriM1pTMM+r4j1lLHxeBQ9bVDmbywb11e3KjuavieA==", "dev": true, "requires": { - "@octokit/types": "^5.5.0", + "@octokit/types": "^6.1.0", "deprecation": "^2.3.1" } }, "@octokit/request": { - "version": "5.4.10", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.10.tgz", - "integrity": "sha512-egA49HkqEORVGDZGav1mh+VD+7uLgOxtn5oODj6guJk0HCy+YBSYapFkSLFgeYj3Fr18ZULKGURkjyhkAChylw==", + "version": "5.4.12", + "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.4.12.tgz", + "integrity": "sha512-MvWYdxengUWTGFpfpefBBpVmmEYfkwMoxonIB3sUGp5rhdgwjXL1ejo6JbgzG/QD9B/NYt/9cJX1pxXeSIUCkg==", "dev": true, "requires": { "@octokit/endpoint": "^6.0.1", "@octokit/request-error": "^2.0.0", - "@octokit/types": "^5.0.0", + "@octokit/types": "^6.0.3", "deprecation": "^2.0.0", "is-plain-object": "^5.0.0", "node-fetch": "^2.6.1", @@ -228,34 +234,35 @@ } }, "@octokit/request-error": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.3.tgz", - "integrity": "sha512-GgD5z8Btm301i2zfvJLk/mkhvGCdjQ7wT8xF9ov5noQY8WbKZDH9cOBqXzoeKd1mLr1xH2FwbtGso135zGBgTA==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.0.4.tgz", + "integrity": "sha512-LjkSiTbsxIErBiRh5wSZvpZqT4t0/c9+4dOe0PII+6jXR+oj/h66s7E4a/MghV7iT8W9ffoQ5Skoxzs96+gBPA==", "dev": true, "requires": { - "@octokit/types": "^5.0.1", + "@octokit/types": "^6.0.0", "deprecation": "^2.0.0", "once": "^1.4.0" } }, "@octokit/rest": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.0.9.tgz", - "integrity": "sha512-CC5+cIx974Ygx9lQNfUn7/oXDQ9kqGiKUC6j1A9bAVZZ7aoTF8K6yxu0pQhQrLBwSl92J6Z3iVDhGhGFgISCZg==", + "version": "18.0.12", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.0.12.tgz", + "integrity": "sha512-hNRCZfKPpeaIjOVuNJzkEL6zacfZlBPV8vw8ReNeyUkVvbuCvvrrx8K8Gw2eyHHsmd4dPlAxIXIZ9oHhJfkJpw==", "dev": true, "requires": { - "@octokit/core": "^3.0.0", - "@octokit/plugin-paginate-rest": "^2.2.0", - "@octokit/plugin-request-log": "^1.0.0", - "@octokit/plugin-rest-endpoint-methods": "4.2.1" + "@octokit/core": "^3.2.3", + "@octokit/plugin-paginate-rest": "^2.6.2", + "@octokit/plugin-request-log": "^1.0.2", + "@octokit/plugin-rest-endpoint-methods": "4.4.1" } }, "@octokit/types": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-5.5.0.tgz", - "integrity": "sha512-UZ1pErDue6bZNjYOotCNveTXArOMZQFG6hKJfOnGnulVCMcVVi7YIIuuR4WfBhjo7zgpmzn/BkPDnUXtNx+PcQ==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.1.1.tgz", + "integrity": "sha512-btm3D6S7VkRrgyYF31etUtVY/eQ1KzrNRqhFt25KSe2mKlXuLXJilglRC6eDA2P6ou94BUnk/Kz5MPEolXgoiw==", "dev": true, "requires": { + "@octokit/openapi-types": "^2.0.0", "@types/node": ">= 8" } }, @@ -319,14 +326,14 @@ } }, "@semantic-release/npm": { - "version": "7.0.8", - "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-7.0.8.tgz", - "integrity": "sha512-8c1TLwKB/xT5E1FNs5l4GFtaNTznHesJk7tw3pGSlVxRqDXa1EZI+DfziZlO58Wk3PpS2ecu661kvBdz9aMgYQ==", + "version": "7.0.9", + "resolved": "https://registry.npmjs.org/@semantic-release/npm/-/npm-7.0.9.tgz", + "integrity": "sha512-VsmmQF3/n7mDbm6AGL0yPD3QNTGsHdinBtkyyerN1eLgvhdGJ/vEeAvmDMARiuf5Ev9cFeCheF0wLyUZNlAkeA==", "dev": true, "requires": { "@semantic-release/error": "^2.2.0", "aggregate-error": "^3.0.0", - "execa": "^4.0.0", + "execa": "^5.0.0", "fs-extra": "^9.0.0", "lodash": "^4.17.15", "nerf-dart": "^1.0.0", @@ -339,6 +346,50 @@ "tempy": "^1.0.0" }, "dependencies": { + "execa": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", + "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", + "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "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 + }, + "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" + } + }, "read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -352,16 +403,25 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "type-fest": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "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 } } }, @@ -514,6 +574,46 @@ "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", "dev": true }, + "@xml-tools/ast": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@xml-tools/ast/-/ast-5.0.0.tgz", + "integrity": "sha512-NLMBbvW1S6bG+pHvPfQeM3ci+le9LexuA4E+obqoRpTWqlJSQGiPKxq8p+HauQmdlF4UC9GUIGsa+9FNFefKyg==", + "requires": { + "@xml-tools/common": "^0.1.2", + "@xml-tools/parser": "^1.0.7", + "lodash": "4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + } + } + }, + "@xml-tools/common": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@xml-tools/common/-/common-0.1.2.tgz", + "integrity": "sha512-5U0CbB3u5WDRKX+oPjHEm6ZkJk8z5LZMpEI6uzBzcnP+3dIxahCF90lhwljQ/rPVSLMLxLfv72xru6RbePeLWA==", + "requires": { + "lodash": "4.17.15" + }, + "dependencies": { + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + } + } + }, + "@xml-tools/parser": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@xml-tools/parser/-/parser-1.0.7.tgz", + "integrity": "sha512-mdjG4dWj4zaubxWAgr0YMNkZr182aHek5xrpDqgITNnGf+E8FhvAmCU95QiL9+pGjqK8Qfd+qnuer9f8KELRyQ==", + "requires": { + "chevrotain": "7.0.1" + } + }, "JSONStream": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", @@ -798,6 +898,14 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chevrotain": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-7.0.1.tgz", + "integrity": "sha512-B/44jrdw5GAzy483LEeVSgXSX0qOYM8lUd3l5+yf6Vl6OQjEUCm2BUiYbHRCIK6xCEvCLAFe1kj8uyV6+zdaVw==", + "requires": { + "regexp-to-ast": "0.5.0" + } + }, "clean-stack": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", @@ -805,19 +913,52 @@ "dev": true }, "cli-table": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz", - "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.4.tgz", + "integrity": "sha512-1vinpnX/ZERcmE443i3SZTmU5DF0rPO9DrL4I2iVAllhxzCM9SzPlHnz19fsZB78htkKZvYBvj6SZ6vXnaxmTA==", "dev": true, "requires": { - "colors": "1.0.3" + "chalk": "^2.4.1", + "string-width": "^4.2.0" }, "dependencies": { - "colors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", - "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "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 + }, + "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 + }, + "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 + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "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" + } } } }, @@ -1392,9 +1533,9 @@ "dev": true }, "execa": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.0.3.tgz", - "integrity": "sha512-WFDXGHckXPWZX19t1kCsXzOpqX9LWYNqn4C+HqZlk/V0imTkzJZqf87ZBhvpHaftERYknpk0fjSylnXVlVgI0A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", + "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", "dev": true, "requires": { "cross-spawn": "^7.0.0", @@ -2425,9 +2566,9 @@ "dev": true }, "marked": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.4.tgz", - "integrity": "sha512-6x5TFGCTKSQBLTZtOburGxCxFEBJEGYVLwCMTBCxzvyuisGcC20UNzDSJhCr/cJ/Kmh6ulfJm10g6WWEAJ3kvg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.6.tgz", + "integrity": "sha512-7vVuSEZ8g/HH3hK/BH/+7u/NJj7x9VY4EHzujLDcqAQLiOUeFJYAsfSAyoWtR17lKrx7b08qyIno4lffwrzTaA==", "dev": true }, "marked-terminal": { @@ -2642,10 +2783,13 @@ } }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "yallist": { "version": "4.0.0", @@ -2906,9 +3050,9 @@ "dev": true }, "npm": { - "version": "6.14.8", - "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.8.tgz", - "integrity": "sha512-HBZVBMYs5blsj94GTeQZel7s9odVuuSUHy1+AlZh7rPVux1os2ashvEGLy/STNK7vUjbrCg5Kq9/GXisJgdf6A==", + "version": "6.14.9", + "resolved": "https://registry.npmjs.org/npm/-/npm-6.14.9.tgz", + "integrity": "sha512-yHi1+i9LyAZF1gAmgyYtVk+HdABlLy94PMIDoK1TRKWvmFQAt5z3bodqVwKvzY0s6dLqQPVsRLiwhJfNtiHeCg==", "dev": true, "requires": { "JSONStream": "^1.3.5", @@ -2991,7 +3135,7 @@ "npm-pick-manifest": "^3.0.2", "npm-profile": "^4.0.4", "npm-registry-fetch": "^4.0.7", - "npm-user-validate": "~1.0.0", + "npm-user-validate": "^1.0.1", "npmlog": "~4.1.2", "once": "~1.4.0", "opener": "^1.5.1", @@ -3066,17 +3210,6 @@ "humanize-ms": "^1.2.1" } }, - "ajv": { - "version": "5.5.2", - "bundled": true, - "dev": true, - "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" - } - }, "ansi-align": { "version": "2.0.0", "bundled": true, @@ -3407,11 +3540,6 @@ "mkdirp": "~0.5.0" } }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true - }, "code-point-at": { "version": "1.1.0", "bundled": true, @@ -3860,11 +3988,6 @@ "bundled": true, "dev": true }, - "fast-deep-equal": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, "fast-json-stable-stringify": { "version": "2.0.0", "bundled": true, @@ -4185,12 +4308,35 @@ "dev": true }, "har-validator": { - "version": "5.1.0", + "version": "5.1.5", "bundled": true, "dev": true, "requires": { - "ajv": "^5.3.0", + "ajv": "^6.12.3", "har-schema": "^2.0.0" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "bundled": true, + "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" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "bundled": true, + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "bundled": true, + "dev": true + } } }, "has": { @@ -4472,11 +4618,6 @@ "bundled": true, "dev": true }, - "json-schema-traverse": { - "version": "0.3.1", - "bundled": true, - "dev": true - }, "json-stringify-safe": { "version": "5.0.1", "bundled": true, @@ -5119,7 +5260,7 @@ } }, "npm-user-validate": { - "version": "1.0.0", + "version": "1.0.1", "bundled": true, "dev": true }, @@ -6123,6 +6264,21 @@ "xdg-basedir": "^3.0.0" } }, + "uri-js": { + "version": "4.4.0", + "bundled": true, + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "bundled": true, + "dev": true + } + } + }, "url-parse-lax": { "version": "1.0.0", "bundled": true, @@ -6840,6 +6996,11 @@ "esprima": "~4.0.0" } }, + "regexp-to-ast": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regexp-to-ast/-/regexp-to-ast-0.5.0.tgz", + "integrity": "sha512-tlbJqcMHnPKI9zSrystikWKwHkBqu2a/Sgw01h3zFjvYrMxEDYHzzoMZnUrbIfpTFEsoRnnviOXNCzFiSc54Qw==" + }, "registry-auth-token": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.2.1.tgz", @@ -6923,15 +7084,10 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, "semantic-release": { - "version": "17.2.3", - "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.2.3.tgz", - "integrity": "sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==", + "version": "17.3.0", + "resolved": "https://registry.npmjs.org/semantic-release/-/semantic-release-17.3.0.tgz", + "integrity": "sha512-enhDayMZRP4nWcWAMBFHHB7THRaIcRdUAZv3lxd65pXs2ttzay7IeCvRRrGayRWExtnY0ulwRz5Ycp88Dv/UeQ==", "dev": true, "requires": { "@semantic-release/commit-analyzer": "^8.0.0", @@ -7107,10 +7263,13 @@ "dev": true }, "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", + "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "string-width": { "version": "4.2.0", @@ -7737,9 +7896,9 @@ "dev": true }, "uglify-js": { - "version": "3.11.6", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.11.6.tgz", - "integrity": "sha512-oASI1FOJ7BBFkSCNDZ446EgkSuHkOZBuqRFrwXIKWCoXw8ZXQETooTQjkAcBS03Acab7ubCKsXnwuV2svy061g==", + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.1.tgz", + "integrity": "sha512-o8lHP20KjIiQe5b/67Rh68xEGRrc2SRsCuuoYclXXoC74AfSRGblU1HKzJWH3HxPZ+Ort85fWHpSX7KwBUC9CQ==", "dev": true, "optional": true }, @@ -7964,14 +8123,6 @@ "signal-exit": "^3.0.2" } }, - "xml2object": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/xml2object/-/xml2object-0.1.2.tgz", - "integrity": "sha1-hylkKI6BgaUP3UT3iRCX/lyYK0U=", - "requires": { - "sax": ">=0.3.5" - } - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", diff --git a/package.json b/package.json index 20b36625..c17590e9 100644 --- a/package.json +++ b/package.json @@ -30,12 +30,13 @@ "url": "https://github.com/fabric8-analytics/fabric8-analytics-lsp-server.git" }, "dependencies": { + "@xml-tools/ast": "^5.0.0", + "@xml-tools/parser": "^1.0.7", + "compare-versions": "3.6.0", "json-to-ast": "^2.1.0", "node-fetch": "^2.6.0", "vscode-languageserver": "^5.3.0-next.9", - "winston": "3.2.1", - "xml2object": "0.1.2", - "compare-versions": "3.6.0" + "winston": "3.2.1" }, "devDependencies": { "@semantic-release/exec": "^5.0.0", diff --git a/src/collector.ts b/src/collector.ts index c0f525c8..d9a16184 100644 --- a/src/collector.ts +++ b/src/collector.ts @@ -4,12 +4,13 @@ * ------------------------------------------------------------------------------------------ */ 'use strict'; import { Stream } from 'stream'; -import * as Xml2Object from 'xml2object'; import * as jsonAst from 'json-to-ast'; -import { IPosition, IKeyValueEntry, KeyValueEntry, Variant, ValueType } from './types'; +import { IPosition, IKeyValueEntry, KeyValueEntry, Variant, ValueType, IDependency, IPositionedString, IDependencyCollector, Dependency } from './types'; import { stream_from_string, getGoLangImportsCmd } from './utils'; import { config } from './config'; import { exec } from 'child_process'; +import { parse, DocumentCstNode } from "@xml-tools/parser"; +import { buildAst, accept, XMLElement, XMLDocument } from "@xml-tools/ast"; /* Please note :: There was issue with semverRegex usage in the code. During run time, it extracts * version with 'v' prefix, but this is not be behavior of semver in CLI and test environment. @@ -20,40 +21,6 @@ function semVerRegExp(line: string): RegExpExecArray { return regExp.exec(line); } -/* String value with position */ -interface IPositionedString { - value: string; - position: IPosition; -} - -/* Dependency specification */ -interface IDependency { - name: IPositionedString; - version: IPositionedString; -} - -/* Dependency collector interface */ -interface IDependencyCollector { - classes: Array; - collect(contents: string): Promise>; -} - -/* Dependency class that can be created from `IKeyValueEntry` */ -class Dependency implements IDependency { - name: IPositionedString; - version: IPositionedString; - constructor(dependency: IKeyValueEntry) { - this.name = { - value: dependency.key, - position: dependency.key_position - }; - this.version = { - value: dependency.value.object, - position: dependency.value_position - }; - } -} - class NaivePyParser { constructor(contents: string) { this.dependencies = NaivePyParser.parseDependencies(contents); @@ -245,87 +212,6 @@ class GomodDependencyCollector implements IDependencyCollector { } -class NaivePomXmlSaxParser { - constructor(stream: Stream) { - this.stream = stream; - this.parser = this.createParser(); - } - - stream: Stream; - parser: Xml2Object; - dependencies: Array = []; - isDependency: boolean = false; - versionStartLine: number = 0; - versionStartColumn: number = 0; - - createParser(): Xml2Object { - let parser = new Xml2Object([ "dependency" ], {strict: true, trackPosition: true}); - let deps = this.dependencies; - let versionLine = this.versionStartLine; - let versionColumn = this.versionStartColumn; - - parser.on("object", function (name, obj) { - if (obj.hasOwnProperty("groupId") && obj.hasOwnProperty("artifactId") && obj.hasOwnProperty("version") && - (!obj.hasOwnProperty("scope") || (obj.hasOwnProperty("scope") && obj["scope"] != "test"))) { - let ga = `${obj["groupId"]}:${obj["artifactId"]}`; - let entry: IKeyValueEntry = new KeyValueEntry(ga, {line: 0, column: 0}); - entry.value = new Variant(ValueType.String, obj["version"]); - entry.value_position = {line: versionLine, column: versionColumn}; - let dep: IDependency = new Dependency(entry); - deps.push(dep) - } - }); - parser.saxStream.on("opentag", function (node) { - if (node.name == "dependency") { - this.isDependency = true; - } - if (this.isDependency && node.name == "version") { - versionLine = parser.saxStream._parser.line + 1; - versionColumn = parser.saxStream._parser.column +1; - } - }); - parser.saxStream.on("closetag", function (nodeName) { - // TODO: nested deps! - if (nodeName == "dependency") { - this.isDependency = false; - } - }); - parser.on("error", function (e) { - // the XML document doesn't have to be well-formed, that's fine - parser.error = null; - }); - parser.on("end", function () { - // the XML document doesn't have to be well-formed, that's fine - // parser.error = null; - this.dependencies = deps; - }); - return parser - } - - async parse() { - return new Promise(resolve => { - this.stream.pipe(this.parser.saxStream).on('end', (data) => { - resolve(this.dependencies); - }); - }); - - } -} - -class PomXmlDependencyCollector implements IDependencyCollector { - constructor(public classes: Array = ["dependencies"]) {} - - async collect(contents: string): Promise> { - const file = stream_from_string(contents); - let parser = new NaivePomXmlSaxParser(file); - let dependencies; - await parser.parse().then(data => { - dependencies = data; - }); - return dependencies || []; - } -} - class PackageJsonCollector implements IDependencyCollector { constructor(public classes: Array = ["dependencies"]) {} @@ -343,4 +229,4 @@ class PackageJsonCollector implements IDependencyCollector { } } -export { IDependencyCollector, PackageJsonCollector, PomXmlDependencyCollector, ReqDependencyCollector, GomodDependencyCollector, IPositionedString, IDependency }; +export { IDependencyCollector, PackageJsonCollector, ReqDependencyCollector, GomodDependencyCollector, IPositionedString, IDependency }; diff --git a/src/maven.collector.ts b/src/maven.collector.ts new file mode 100644 index 00000000..b13d548d --- /dev/null +++ b/src/maven.collector.ts @@ -0,0 +1,100 @@ +'use strict'; +import { IKeyValueEntry, KeyValueEntry, Variant, ValueType, IDependency, IDependencyCollector, Dependency, IPositionedString, IPosition } from './types'; +import { parse, DocumentCstNode } from "@xml-tools/parser"; +import { buildAst, accept, XMLElement, XMLDocument } from "@xml-tools/ast"; + +export class PomXmlDependencyCollector implements IDependencyCollector { + private xmlDocAst: XMLDocument; + + constructor(public classes: Array = ["dependencies"]) {} + + private findRootNodes(rootElementName: string): Array { + const properties: Array = []; + const propertiesElement = { + // Will be invoked once for each Element node in the AST. + visitXMLElement: (node: XMLElement) => { + if (node.name === rootElementName) { + properties.push(node); + } + }, + }; + accept(this.xmlDocAst, propertiesElement); + return properties; + } + + private parseXml(contents: string): void { + const { cst, tokenVector } = parse(contents); + this.xmlDocAst = buildAst(cst as DocumentCstNode, tokenVector); + } + + private mapToDependency(dependenciesNode: XMLElement): Array { + class PomDependency { + public groupId: XMLElement; + public artifactId: XMLElement; + public version: XMLElement; + constructor(e: XMLElement) { + this.groupId = e.subElements.find(e => e.name === 'groupId'); + this.artifactId = e.subElements.find(e => e.name === 'artifactId'); + this.version = e.subElements.find(e => e.name === 'version'); + } + + isValid(): boolean { + // none should have a empty text. + return [this.groupId, this.artifactId, this.version].find(e => !e.textContents[0]?.text) === undefined; + } + + toDependency(): Dependency { + const dep: IKeyValueEntry = new KeyValueEntry(`${this.groupId.textContents[0].text}:${this.artifactId.textContents[0].text}`, {line: 0, column: 0}); + const versionVal = this.version.textContents[0]; + dep.value = new Variant(ValueType.String, versionVal.text); + dep.value_position = {line: versionVal.position.startLine, column: versionVal.position.startColumn}; + return new Dependency(dep); + } + }; + const validElementNames = ['groupId', 'artifactId', 'version']; + const dependencies = dependenciesNode?. + subElements. + filter(e => e.name === 'dependency'). + // must include all validElementNames + filter(e => e.subElements.filter(e => validElementNames.includes(e.name)).length == validElementNames.length). + // no test dependencies + filter(e => !e.subElements.find(e => (e.name === 'scope' && e.textContents[0].text === 'test'))). + map(e => new PomDependency(e)). + filter(d => d.isValid()). + map(d => d.toDependency()); + return dependencies || []; + } + + private createPropertySubstitution(e: XMLElement): Map { + return new Map(e?.subElements?. + filter(e => e.textContents[0]?.text). + map(e => { + const propertyValue = e.textContents[0]; + const position: IPosition = {line: propertyValue.position.startLine, column: propertyValue.position.startColumn}; + const value = {value: propertyValue.text, position: position} as IPositionedString; + // key should be equivalent to pom.xml property format. i.e ${property.value} + return [`\$\{${e.name}\}`, value]; + })); + } + + private applyProperty(dependency: IDependency, map: Map): IDependency { + // FIXME: Do the groupId and artifactId will also be expressed through properties? + dependency.version = map.get(dependency.version.value) ?? dependency.version; + return dependency; + } + + async collect(contents: string): Promise> { + this.parseXml(contents); + const deps = this.findRootNodes("dependencies"); + // lazy eval + const getPropertyMap = (() => { + let propertyMap = null; + return () => { + propertyMap = propertyMap ?? this.createPropertySubstitution(this.findRootNodes("properties")[0]); + return propertyMap; + }; + })(); + + return deps.flatMap(dep => this.mapToDependency(dep)).map(d => this.applyProperty(d, getPropertyMap())); + } +} diff --git a/src/server.ts b/src/server.ts index 37e0c331..721ff364 100644 --- a/src/server.ts +++ b/src/server.ts @@ -8,7 +8,8 @@ import * as fs from 'fs'; import { IPCMessageReader, IPCMessageWriter, createConnection, IConnection, TextDocuments, InitializeResult, CodeLens, CodeAction, CodeActionKind} from 'vscode-languageserver'; -import { IDependencyCollector, PackageJsonCollector, PomXmlDependencyCollector, ReqDependencyCollector, GomodDependencyCollector } from './collector'; +import { IDependencyCollector, PackageJsonCollector, ReqDependencyCollector, GomodDependencyCollector } from './collector'; +import { PomXmlDependencyCollector } from './maven.collector'; import { SecurityEngine, DiagnosticsPipeline, codeActionsMap } from './consumers'; import { NoopVulnerabilityAggregator, GolangVulnerabilityAggregator } from './aggregators'; import { AnalyticsSource } from './vulnerability'; @@ -250,11 +251,14 @@ const sendDiagnostics = async (ecosystem: string, diagnosticFilePath: string, co connection.sendNotification('caNotification', {data: caDefaultMsg, done: false, uri: diagnosticFilePath}); let deps = null; try { + const start = new Date().getTime(); deps = await collector.collect(contents); + const end = new Date().getTime(); + connection.console.log(`manifest parse took ${end - start} ms`); } catch (error) { // Error can be raised during golang `go list ` command only. if (ecosystem == "golang") { - connection.console.error(`Command execution failed with error: ${error}`); + connection.console.warn(`Command execution failed with error: ${error}`); connection.sendNotification('caError', {data: error, uri: diagnosticFilePath}); connection.sendDiagnostics({ uri: diagnosticFilePath, diagnostics: [] }); return; @@ -282,7 +286,7 @@ const sendDiagnostics = async (ecosystem: string, diagnosticFilePath: string, co await Promise.allSettled(allRequests); const end = new Date().getTime(); - connection.console.log('Time taken to fetch vulnerabilities: ' + ((end - start) / 1000).toFixed(1) + ' sec.'); + connection.console.log(`fetch vulns took ${end - start} ms`); connection.sendNotification('caNotification', {data: getCAmsg(deps, diagnostics, totalCount), diagCount : diagnostics.length || 0, vulnCount: totalCount, depCount: deps.length || 0, done: true, uri: diagnosticFilePath}); }; diff --git a/src/types.ts b/src/types.ts index 7fb8dbba..149ce6bb 100644 --- a/src/types.ts +++ b/src/types.ts @@ -53,6 +53,38 @@ class Variant implements IVariant { constructor(public type: ValueType, public object: any) {} } +/* String value with position */ +interface IPositionedString { + value: string; + position: IPosition; +} + +/* Dependency specification */ +interface IDependency { + name: IPositionedString; + version: IPositionedString; +} -export { IPosition, IKeyValueEntry, KeyValueEntry, Variant, ValueType }; +/* Dependency collector interface */ +interface IDependencyCollector { + classes: Array; + collect(contents: string): Promise>; +} + +/* Dependency class that can be created from `IKeyValueEntry` */ +class Dependency implements IDependency { + name: IPositionedString; + version: IPositionedString; + constructor(dependency: IKeyValueEntry) { + this.name = { + value: dependency.key, + position: dependency.key_position + }; + this.version = { + value: dependency.value.object, + position: dependency.value_position + }; + } +} +export { IPosition, IKeyValueEntry, KeyValueEntry, Variant, ValueType, IDependency, IPositionedString, IDependencyCollector, Dependency }; diff --git a/test/maven.collector.test.ts b/test/maven.collector.test.ts index 45331628..4a455282 100644 --- a/test/maven.collector.test.ts +++ b/test/maven.collector.test.ts @@ -1,5 +1,6 @@ import { expect } from 'chai'; -import { PomXmlDependencyCollector } from '../src/collector'; +import { PomXmlDependencyCollector } from '../src/maven.collector'; +import parse = require("@xml-tools/parser"); describe('Maven pom.xml parser test', () => { const collector:PomXmlDependencyCollector = new PomXmlDependencyCollector(); @@ -43,19 +44,16 @@ describe('Maven pom.xml parser test', () => { `); - expect(deps.length).equal(3); - expect(deps[0]).is.eql({ - name: {value: '{a.groupId}:bc', position: {line: 0, column: 0}}, - version: {value: '{a.version}', position: {line: 7, column: 30}} - }); - expect(deps[1]).is.eql({ - name: {value: 'b:c-d', position: {line: 0, column: 0}}, - version: {value: '1.2.3', position: {line: 14, column: 30}} - }); - expect(deps[2]).is.eql({ - name: {value: 'c:ab-cd', position: {line: 0, column: 0}}, - version: {value: '2.3', position: {line: 22, column: 30}} - }); + expect(deps).is.eql([{ + name: {value: '{a.groupId}:bc', position: {line: 0, column: 0}}, + version: {value: '{a.version}', position: {line: 7, column: 30}} + },{ + name: {value: 'b:c-d', position: {line: 0, column: 0}}, + version: {value: '1.2.3', position: {line: 14, column: 30}} + },{ + name: {value: 'c:ab-cd', position: {line: 0, column: 0}}, + version: {value: '2.3', position: {line: 22, column: 30}} + }]); }); it('tests pom.xml without any scope', async () => { @@ -86,19 +84,16 @@ describe('Maven pom.xml parser test', () => { `); - expect(deps.length).equal(3); - expect(deps[0]).is.eql({ - name: {value: '{a.groupId}:bc', position: {line: 0, column: 0}}, - version: {value: '{a.version}', position: {line: 7, column: 30}} - }); - expect(deps[1]).is.eql({ - name: {value: 'b:c-d', position: {line: 0, column: 0}}, - version: {value: '1.2.3', position: {line: 14, column: 30}} - }); - expect(deps[2]).is.eql({ - name: {value: 'c:ab-cd', position: {line: 0, column: 0}}, - version: {value: '2.3', position: {line: 21, column: 30}} - }); + expect(deps).is.eql([{ + name: {value: '{a.groupId}:bc', position: {line: 0, column: 0}}, + version: {value: '{a.version}', position: {line: 7, column: 30}} + },{ + name: {value: 'b:c-d', position: {line: 0, column: 0}}, + version: {value: '1.2.3', position: {line: 14, column: 30}} + },{ + name: {value: 'c:ab-cd', position: {line: 0, column: 0}}, + version: {value: '2.3', position: {line: 21, column: 30}} + }]); }); it('tests pom.xml with only test scope', async () => { @@ -161,4 +156,135 @@ describe('Maven pom.xml parser test', () => { `); expect(deps.length).equal(0); }); + + it('tests pom.xml with invalid dependencies', async () => { + const deps = await collector.collect( + ` + + + + + c + ab-cd + 2.3 + test + true + + + foo + bar + 2.4 + + + c + ab-cd + + + c + + + bala + + + + + `); + expect(deps).is.eql([{ + name: {value: 'foo:bar', position: {line: 0, column: 0}}, + version: {value: '2.4', position: {line: 15, column: 30}} + }]); + }); + + it('tests pom.xml without dependencyManagement', async () => { + const deps = await collector.collect( + ` + + + + c + ab-cd + 2.3 + test + true + + + foo + bar + 2.4 + + + + `); + expect(deps).is.eql([{ + name: {value: 'foo:bar', position: {line: 0, column: 0}}, + version: {value: '2.4', position: {line: 14, column: 30}} + }]); + }); + + it('tests pom.xml multiple dependencies', async () => { + const deps = await collector.collect( + ` + + + + + plugins + a + 2.3 + + + + + + dep + a + 10.1 + + + + `); + expect(deps).is.eql([{ + name: {value: 'plugins:a', position: {line: 0, column: 0}}, + version: {value: '2.3', position: {line: 8, column: 34}} + }, { + name: {value: 'dep:a', position: {line: 0, column: 0}}, + version: {value: '10.1', position: {line: 16, column: 30}} + }]); + }); + + it('tests pom.xml with properties', async () => { + const deps = await collector.collect( + ` + + + 1.0 + + + + + + foo + foo-hello + \$\{foo.dep.version\} + true + + + bar + bar-hello + \$\{bar.dep.version\} + true + + + + + `); + expect(deps).is.eql([{ + name: {value: 'foo:foo-hello', position: {line: 0, column: 0}}, + version: {value: '1.0', position: {line: 4, column: 30}} + }, { + name: {value: 'bar:bar-hello', position: {line: 0, column: 0}}, + // empty property won't be sustituted + version: {value: '${bar.dep.version}', position: {line: 18, column: 30}} + }]); + }); }); diff --git a/tsconfig.json b/tsconfig.json index 92752747..4a8099e3 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,10 +1,14 @@ { "compilerOptions": { - "target": "ES2020", + "target": "es6", "module": "commonjs", "moduleResolution": "node", "sourceMap": true, - "outDir": "output" + "outDir": "output", + "lib": [ + "ES2019.array", + "ES2020.Promise" + ] }, "exclude": [ "node_modules",