diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 393f5de..a4684f1 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,8 @@ blank_issues_enabled: false contact_links: - - name: Enmeshed Issue Tracker + - name: enmeshed Issue Tracker url: https://github.com/nmshd/feedback/issues about: Open bug reports and feature requests. - - name: Enmeshed Discussions + - name: enmeshed Discussions url: https://github.com/nmshd/feedback/discussions - about: Share your feedback with the Enmeshed team. + about: Share your feedback with the enmeshed team. diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d4cb3cb..09fdd43 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -2,7 +2,7 @@ name: Test on: push: - branches-ignore: [main, release/**] + branches-ignore: [main] jobs: test: diff --git a/README.md b/README.md index 229b028..bf82dd4 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ > A terminal user interface for Demos. > -> Showcase how to integrate Enmeshed and use the TypeScript Connector SDK. +> Showcase how to integrate enmeshed and use the TypeScript Connector SDK. > -> This TUI only works with Enmeshed v2 (Connector version 3.0.0+) +> This TUI only works with enmeshed v5 (Connector version 5.0.0+) ## Installation diff --git a/package-lock.json b/package-lock.json index 35faeeb..eaa4b9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "@nmshd/connector-tui", - "version": "1.2.5", + "version": "2.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@nmshd/connector-tui", - "version": "1.2.5", + "version": "2.0.0", "license": "MIT", "dependencies": { - "@nmshd/connector-sdk": "^4.6.1", + "@nmshd/connector-sdk": "^5.0.1", "chalk": "^5.3.0", "dotenv": "^16.4.5", - "luxon": "^3.4.4", + "luxon": "^3.5.0", "prompts": "^2.4.2", "qrcode-terminal": "^0.12.0", "yargs": "^17.7.2" @@ -26,14 +26,14 @@ "@js-soft/eslint-config-ts": "^1.6.9", "@js-soft/license-check": "^1.0.9", "@types/luxon": "^3.4.2", - "@types/node": "^20.14.11", + "@types/node": "^22.5.3", "@types/prompts": "^2.4.9", "@types/qrcode-terminal": "^0.12.2", - "@types/yargs": "^17.0.32", + "@types/yargs": "^17.0.33", "eslint": "^8.57.0", "prettier": "^3.3.3", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=19.0.0" @@ -204,16 +204,65 @@ "license-check": "bin/licenseCheck.js" } }, + "node_modules/@js-soft/logging-abstractions": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@js-soft/logging-abstractions/-/logging-abstractions-1.0.1.tgz", + "integrity": "sha512-giFnUcpfq07vNmMFetvI1bfKo8g5slIiQbSnwLF1dHU8gLE/hJmL3jTnchXFRTwSeMhTFCNg0GudsNMw1esMVQ==", + "license": "MIT" + }, + "node_modules/@js-soft/ts-serval": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/@js-soft/ts-serval/-/ts-serval-2.0.10.tgz", + "integrity": "sha512-TMeVmDaHs1zk5JPXR6LBY1EXwukHCB7MgBgMbxf/bbauDNMw54t9nH+gE7xXFxBTovL4RWIw5NSIHk7n3T+wYg==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.21", + "reflect-metadata": "^0.1.13" + } + }, "node_modules/@nmshd/connector-sdk": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/@nmshd/connector-sdk/-/connector-sdk-4.6.1.tgz", - "integrity": "sha512-1cmeWVU1GBxTU22MR8daw+ob2bEDsYmMB1AbXUpolh49UhAJFvQwKm2OtjAWJC4tWHp7kyaFEJTh7D9tS/ZzWg==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@nmshd/connector-sdk/-/connector-sdk-5.0.1.tgz", + "integrity": "sha512-OMhB8Pyybv2xylZdhXV10M5RN4ltKr6gtgXaTFtjWvY0qZXizZBHAJjivwkjc1H4SQOLVtP4ENjWqIDIDWr9pw==", + "license": "MIT", "dependencies": { - "axios": "^1.7.2", + "@nmshd/content": "^5.3.0", + "axios": "^1.7.5", "form-data": "^4.0.0", - "qs": "^6.12.3" + "qs": "^6.13.0" + } + }, + "node_modules/@nmshd/content": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@nmshd/content/-/content-5.4.0.tgz", + "integrity": "sha512-3XuZA2XRoguA6+BWGDyMV3/R0WLnsDRmODKJ6iB6r5QxXheRfmruj9LqLGZPKKEMlAGM+f6vaJRIfyNvcpxipw==", + "license": "MIT", + "dependencies": { + "@js-soft/ts-serval": "2.0.10", + "@nmshd/core-types": "5.4.0", + "@nmshd/iql": "^1.0.2", + "luxon": "^3.5.0", + "ts-simple-nameof": "^1.3.1" } }, + "node_modules/@nmshd/core-types": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/@nmshd/core-types/-/core-types-5.4.0.tgz", + "integrity": "sha512-5lS4OJOCyoD0WAbSZTel9J3uwEiWiDnGrIX7E0GY1XBGkT8xK37Xg2dtKKPNNr1Q2g2kTNXUzsL3Igh+DtJhDg==", + "license": "MIT", + "dependencies": { + "@js-soft/logging-abstractions": "^1.0.1", + "@js-soft/ts-serval": "2.0.10", + "json-stringify-safe": "^5.0.1", + "luxon": "^3.5.0" + } + }, + "node_modules/@nmshd/iql": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@nmshd/iql/-/iql-1.0.2.tgz", + "integrity": "sha512-fRUIDoZeAKDJ99/yjbjlKryMv1poNaiRDTC8eNltZJSPSkQgchlt0yrWHBDl+CZEPF2Ae0hDj7vpo2n0c6R6JA==", + "license": "MIT" + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -280,12 +329,13 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.14.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz", - "integrity": "sha512-kprQpL8MMeszbz6ojB5/tU8PLN4kesnN8Gjzw349rDlNgsSzg90lAVj3llK99Dh7JON+t9AuscPPFW6mPbTnSA==", + "version": "22.5.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.3.tgz", + "integrity": "sha512-njripolh85IA9SQGTAqbmnNZTdxv7X/4OYGPz8tgy5JDr8MP+uDBa921GpYEoDDnwm0Hmn5ZPeJgiiSTPoOzkQ==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.19.2" } }, "node_modules/@types/prompts": { @@ -305,10 +355,11 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.32", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", - "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", + "version": "17.0.33", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz", + "integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } @@ -647,12 +698,14 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" }, "node_modules/axios": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz", - "integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==", + "version": "1.7.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.7.tgz", + "integrity": "sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==", + "license": "MIT", "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.0", @@ -691,6 +744,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -758,6 +812,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -828,6 +883,7 @@ "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", @@ -844,6 +900,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -911,6 +968,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.2.4" }, @@ -922,6 +980,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", "engines": { "node": ">= 0.4" } @@ -1313,15 +1372,16 @@ "dev": true }, "node_modules/follow-redirects": { - "version": "1.15.6", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", - "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.8.tgz", + "integrity": "sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -1335,6 +1395,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -1370,6 +1431,7 @@ "version": "1.2.4", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2", @@ -1455,6 +1517,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", "dependencies": { "get-intrinsic": "^1.1.3" }, @@ -1487,6 +1550,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { "es-define-property": "^1.0.0" }, @@ -1498,6 +1562,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1509,6 +1574,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -1684,6 +1750,12 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC" + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -1839,6 +1911,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", @@ -1846,9 +1924,10 @@ "dev": true }, "node_modules/luxon": { - "version": "3.4.4", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.4.4.tgz", - "integrity": "sha512-zobTr7akeGHnv7eBOXcRgMeCP6+uyYsczwmeRCauvpvaAltgNyTbLH/+VaEAPUeWBT+1GuNmz4wC/6jtQzbbVA==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.5.0.tgz", + "integrity": "sha512-rh+Zjr6DNfUYR3bPwJEnuwDdqMbxZW7LOQfUN4B54+Cl+0o5zaU9RJ6bcidfDtC1cWCZXQ+nvX8bf6bAji37QQ==", + "license": "MIT", "engines": { "node": ">=12" } @@ -1869,10 +1948,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", - "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dev": true, + "license": "MIT", "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" @@ -1885,6 +1965,7 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -1893,6 +1974,7 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { "mime-db": "1.52.0" }, @@ -1989,6 +2071,7 @@ "version": "1.13.2", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -2185,7 +2268,8 @@ "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" }, "node_modules/punycode": { "version": "2.3.1", @@ -2205,9 +2289,10 @@ } }, "node_modules/qs": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.3.tgz", - "integrity": "sha512-AWJm14H1vVaO/iNZ4/hO+HyaTehuy9nRqVdkTqlJt0HWvBiBIEXFmb4C0DGeYo3Xes9rrEW+TxHsaigCbN5ICQ==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.0.6" }, @@ -2295,6 +2380,12 @@ "once": "^1.3.0" } }, + "node_modules/reflect-metadata": { + "version": "0.1.14", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.1.14.tgz", + "integrity": "sha512-ZhYeb6nRaXCfhnndflDK8qI6ZQ/YcWZCISRAWICW9XYqMUwjZM9Z0DveWX/ABN01oxSHwVxKQmxeYZSsm0jh5A==", + "license": "Apache-2.0" + }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -2393,6 +2484,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", @@ -2430,6 +2522,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { "call-bind": "^1.0.7", "es-errors": "^1.3.0", @@ -2668,6 +2761,12 @@ } } }, + "node_modules/ts-simple-nameof": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/ts-simple-nameof/-/ts-simple-nameof-1.3.1.tgz", + "integrity": "sha512-E0xwaLwDmKmSmo4DE4i+Rp0CuixeZ6wJcn4+2OugzSoPxWW27aNRHhfhcfAELavHHS077dt998oXIMFq+MqeBw==", + "license": "MIT" + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -2693,10 +2792,11 @@ } }, "node_modules/typescript": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.3.tgz", - "integrity": "sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -2706,10 +2806,11 @@ } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.19.8", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", + "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", + "dev": true, + "license": "MIT" }, "node_modules/uri-js": { "version": "4.4.1", diff --git a/package.json b/package.json index f8dfe85..9811d03 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@nmshd/connector-tui", - "version": "1.2.5", + "version": "2.0.0", "repository": "github:nmshd/connector-tui", "license": "MIT", "author": "j&s-soft GmbH", @@ -23,15 +23,15 @@ "lint:tsc": "tsc --noEmit", "lint:eslint": "eslint --ext .ts ./src", "lint:prettier": "prettier --check ./src", - "start": "node --loader ts-node/esm src/index.ts", + "start": "node --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' src/index.ts", "test": "echo 'no test specified'", - "watch": "node --watch --loader ts-node/esm src/index.ts" + "watch": "node --watch --import 'data:text/javascript,import { register } from \"node:module\"; import { pathToFileURL } from \"node:url\"; register(\"ts-node/esm\", pathToFileURL(\"./\"));' src/index.ts" }, "dependencies": { - "@nmshd/connector-sdk": "^4.6.1", + "@nmshd/connector-sdk": "^5.0.1", "chalk": "^5.3.0", "dotenv": "^16.4.5", - "luxon": "^3.4.4", + "luxon": "^3.5.0", "prompts": "^2.4.2", "qrcode-terminal": "^0.12.0", "yargs": "^17.7.2" @@ -40,14 +40,14 @@ "@js-soft/eslint-config-ts": "^1.6.9", "@js-soft/license-check": "^1.0.9", "@types/luxon": "^3.4.2", - "@types/node": "^20.14.11", + "@types/node": "^22.5.3", "@types/prompts": "^2.4.9", "@types/qrcode-terminal": "^0.12.2", - "@types/yargs": "^17.0.32", + "@types/yargs": "^17.0.33", "eslint": "^8.57.0", "prettier": "^3.3.3", "ts-node": "^10.9.2", - "typescript": "^5.5.3" + "typescript": "^5.5.4" }, "engines": { "node": ">=19.0.0" diff --git a/src/ConnectorTUI.ts b/src/ConnectorTUI.ts index d0214bf..7f690bc 100644 --- a/src/ConnectorTUI.ts +++ b/src/ConnectorTUI.ts @@ -44,8 +44,8 @@ export class ConnectorTUI extends ConnectorTUIBaseWithMixins { // allow connector in debugging mode to be used if (connectorVersionInfo.version === "{{version}}") return connectorVersionInfo - if (!(connectorVersionInfo.version.startsWith("3.") || connectorVersionInfo.version.startsWith("4."))) { - console.log(`This TUI is made for Enmeshed V2 connectors (starting with version 3.0.0 of the connector). Current version: ${connectorVersionInfo.version}`) + if (!connectorVersionInfo.version.startsWith("5.")) { + console.log(`This TUI is made for enmeshed V5 connectors (starting with version 5.0.0 of the connector). Current version: ${connectorVersionInfo.version}`) return } @@ -60,7 +60,7 @@ export class ConnectorTUI extends ConnectorTUIBaseWithMixins { const support = await this.connectorClient.monitoring.getSupport() const baseUrl = (support.configuration.transportLibrary as any)?.baseUrl - console.log(`Welcome to the ${chalk.blue("Enmeshed V2 TUI")}!`) + console.log(`Welcome to the ${chalk.blue("enmeshed V2 TUI")}!`) console.log(`TUI Version: ${chalk.yellow(packageJson.version)}`) console.log(`Connector version: ${chalk.yellow(connectorVersionInfo.version)}`) console.log(`Connector Address: ${chalk.yellow(this.connectorAddress)}`) diff --git a/src/ConnectorTUIBase.ts b/src/ConnectorTUIBase.ts index 394b36d..a7f350f 100644 --- a/src/ConnectorTUIBase.ts +++ b/src/ConnectorTUIBase.ts @@ -1,4 +1,5 @@ import { ConnectorClient, ConnectorFile, ConnectorRelationship, ConnectorRelationshipStatus } from "@nmshd/connector-sdk" +import { DisplayNameJSON, GivenNameJSON, SurnameJSON } from "@nmshd/content" import prompts from "prompts" export type ConnectorTUIBaseConstructor = new (...args: any[]) => ConnectorTUIBase @@ -15,7 +16,9 @@ export class ConnectorTUIBase { protected connectorAddress: string ) {} - protected async selectRelationship(prompt: string, status: ConnectorRelationshipStatus = ConnectorRelationshipStatus.ACTIVE): Promise { + protected async selectRelationship(prompt: string, ...status: ConnectorRelationshipStatus[]): Promise { + if (status.length === 0) status.push(ConnectorRelationshipStatus.Active) + const choices = await this.getRelationshipChoices(status, true) if (!choices) return @@ -24,7 +27,9 @@ export class ConnectorTUIBase { return recipientsResult.recipient as ConnectorRelationship | undefined } - protected async selectRelationships(prompt: string, status: ConnectorRelationshipStatus = ConnectorRelationshipStatus.ACTIVE): Promise { + protected async selectRelationships(prompt: string, ...status: ConnectorRelationshipStatus[]): Promise { + if (status.length === 0) status.push(ConnectorRelationshipStatus.Active) + const choices = await this.getRelationshipChoices(status, false) if (!choices) return @@ -39,7 +44,7 @@ export class ConnectorTUIBase { return recipients } - private async getRelationshipChoices(status: ConnectorRelationshipStatus, returnRelationship: boolean) { + private async getRelationshipChoices(status: ConnectorRelationshipStatus[], returnRelationship: boolean) { const relationshipsResult = await this.connectorClient.relationships.getRelationships({ status }) if (relationshipsResult.isError) { console.error(relationshipsResult.error) @@ -47,7 +52,7 @@ export class ConnectorTUIBase { } const relationships = relationshipsResult.result if (relationships.length === 0) { - console.log(`No relationships with status '${status}' found`) + console.log(`No relationships with status ${new Intl.ListFormat("en", { style: "long", type: "disjunction" }).format(status.map((s) => `'${s}'`))} found`) return } @@ -62,13 +67,13 @@ export class ConnectorTUIBase { const displayName = relationshipAttributes.find((a) => a.content.value["@type"] === "DisplayName") if (displayName) { - return { title: `${relationship.peer} (${displayName.content.value.value})`, value } + return { title: `${relationship.peer} (${(displayName.content.value as DisplayNameJSON).value})`, value } } const surname = relationshipAttributes.find((a) => a.content.value["@type"] === "Surname") const givenName = relationshipAttributes.find((a) => a.content.value["@type"] === "GivenName") if (!!surname || givenName) { - const name = `${surname?.content.value.value || ""} ${givenName?.content.value.value || ""}`.trim() + const name = `${(surname?.content.value as SurnameJSON).value || ""} ${(givenName?.content.value as GivenNameJSON).value || ""}`.trim() return { title: `${relationship.peer} (${name})`, value, diff --git a/src/mixins/AddAcceptPendingRelationships.ts b/src/mixins/AddAcceptPendingRelationships.ts index 21e4c09..6ada2f0 100644 --- a/src/mixins/AddAcceptPendingRelationships.ts +++ b/src/mixins/AddAcceptPendingRelationships.ts @@ -3,7 +3,7 @@ import prompts from "prompts" import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" export function AddAcceptPendingRelationships(Base: TBase) { - return class Sync extends Base { + return class AcceptPendingRelationships extends Base { public constructor(...args: any[]) { super(...args) this.choices.push({ title: "Accept Pending Relationships", value: this.acceptPendingRelationships }) @@ -20,15 +20,11 @@ export function AddAcceptPendingRelationships(Base: TBase) { - return class Sync extends Base { + return class AcceptPendingRequests extends Base { public constructor(...args: any[]) { super(...args) this.choices.push({ title: "Accept Pending Requests", value: this.acceptPendingRequests }) @@ -34,7 +35,7 @@ export function AddAcceptPendingRequests(Base: TBase) { + return class DecomposeRelationship extends Base { + public constructor(...args: any[]) { + super(...args) + this.choices.push({ title: "Decompose Relationship", value: this.decomposeRelationship }) + } + + protected async decomposeRelationship() { + await this.connectorClient.account.sync() + + const relationship = await this.selectRelationship("Select relationship to decompose", ConnectorRelationshipStatus.Terminated, ConnectorRelationshipStatus.DeletionProposed) + if (!relationship) return + + console.log(`Decomposing relationship ${relationship.id}`) + const decomposeResult = await this.connectorClient.relationships.decomposeRelationship(relationship.id) + if (decomposeResult.isError) { + console.error(`Failed to decompose relationship ${relationship.id}: ${JSON.stringify(decomposeResult.error)}`) + return + } + } + } +} diff --git a/src/mixins/AddExit.ts b/src/mixins/AddExit.ts index f5badf5..e292615 100644 --- a/src/mixins/AddExit.ts +++ b/src/mixins/AddExit.ts @@ -1,7 +1,7 @@ import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" export function AddExit(Base: TBase) { - return class Sync extends Base { + return class Exit extends Base { public constructor(...args: any[]) { super(...args) this.choices.push({ title: "Exit", value: this.exit }) diff --git a/src/mixins/AddGetAttributesOfRelationship.ts b/src/mixins/AddGetAttributesOfRelationship.ts index abc1488..c3277e1 100644 --- a/src/mixins/AddGetAttributesOfRelationship.ts +++ b/src/mixins/AddGetAttributesOfRelationship.ts @@ -1,14 +1,21 @@ +import { ConnectorRelationshipStatus } from "@nmshd/connector-sdk" import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" export function AddGetAttributesOfRelationship(Base: TBase) { - return class AddGetAttributesOfRelationship extends Base { + return class GetAttributesOfRelationship extends Base { public constructor(...args: any[]) { super(...args) this.choices.push({ title: "Get Attributes Of Relationship", value: this.getAttributesOfRelationship }) } protected async getAttributesOfRelationship() { - const relationship = await this.selectRelationship("From which relationship do you want to get the attributes?") + const relationship = await this.selectRelationship( + "From which relationship do you want to get the attributes?", + ConnectorRelationshipStatus.Active, + ConnectorRelationshipStatus.Pending, + ConnectorRelationshipStatus.Terminated, + ConnectorRelationshipStatus.DeletionProposed + ) if (!relationship) return console.log("No recipient selected") const attributeResult = await this.connectorClient.relationships.getAttributesForRelationship(relationship.id) diff --git a/src/mixins/AddSendMail.ts b/src/mixins/AddSendMail.ts index 3e015d8..bb52c91 100644 --- a/src/mixins/AddSendMail.ts +++ b/src/mixins/AddSendMail.ts @@ -1,3 +1,4 @@ +import { MailJSON } from "@nmshd/content" import prompts from "prompts" import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" @@ -29,7 +30,7 @@ export function AddSendMail(Base: TBa }, ]) - const content = { + const content: MailJSON = { "@type": "Mail", to: recipients, subject: result.subject, diff --git a/src/mixins/AddSendRequestByMessage.ts b/src/mixins/AddSendRequestByMessage.ts index 5476736..a84da6f 100644 --- a/src/mixins/AddSendRequestByMessage.ts +++ b/src/mixins/AddSendRequestByMessage.ts @@ -1,13 +1,14 @@ import { - AuthenticationRequestItem, - ConnectorRequestContentItemGroup, - ConnectorRequestItemDerivation, - ConsentRequestItem, - CreateAttributeRequestItem, - ProposeAttributeRequestItem, - ReadAttributeRequestItem, - RegisterAttributeListenerRequestItem, -} from "@nmshd/connector-sdk" + AuthenticationRequestItemJSON, + ConsentRequestItemJSON, + CreateAttributeRequestItemJSON, + ProposeAttributeRequestItemJSON, + ReadAttributeRequestItemJSON, + RegisterAttributeListenerRequestItemJSON, + RelationshipAttributeConfidentiality, + RequestItemGroupJSON, + RequestItemJSON, +} from "@nmshd/content" import prompts from "prompts" import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" @@ -24,7 +25,7 @@ export function AddSendRequestByMessage address.trim()) .filter((address: string) => address.length > 0) - const requestItem: ReadAttributeRequestItem = { + const requestItem: ReadAttributeRequestItemJSON = { "@type": "ReadAttributeRequestItem", mustBeAccepted: true, query: { @@ -268,7 +274,7 @@ export function AddSendRequestByMessage(Base: TBase) { - return class Sync extends Base { + return class ShareRequestByTemplate extends Base { public constructor(...args: any[]) { super(...args) this.choices.push({ title: "Share Request By Template", value: this.shareRequestByTemplate }) } public async shareRequestByTemplate() { - const name = process.env.CONNECTOR_DISPLAY_NAME ?? "ConnectorV2 Demo" + const name = process.env.CONNECTOR_DISPLAY_NAME ?? "Connector TUI" const displayName = await this.getOrCreateConnectorDisplayName(name) - const request: ConnectorRequestContent = { + const sharedAttributes: RequestItemGroupJSON = { + "@type": "RequestItemGroup", + title: "Shared Attributes", items: [ { - "@type": "RequestItemGroup", + "@type": "ShareAttributeRequestItem", mustBeAccepted: true, - title: "Shared Attributes", - items: [ - { - "@type": "ShareAttributeRequestItem", - mustBeAccepted: true, - attribute: displayName.content, - sourceAttributeId: displayName.id, - }, - ], + attribute: displayName.content, + sourceAttributeId: displayName.id, + }, + ], + } + + const requestedAttributes: RequestItemGroupJSON = { + "@type": "RequestItemGroup", + title: "Requested Attributes", + items: [ + { + "@type": "ReadAttributeRequestItem", + mustBeAccepted: true, + query: { + "@type": "IdentityAttributeQuery", + valueType: "Surname", + }, }, { - "@type": "RequestItemGroup", + "@type": "ReadAttributeRequestItem", mustBeAccepted: true, - title: "Requested Attributes", - items: [ - { - "@type": "ReadAttributeRequestItem", - mustBeAccepted: true, - query: { - "@type": "IdentityAttributeQuery", - valueType: "Surname", - }, - }, - { - "@type": "ReadAttributeRequestItem", - mustBeAccepted: true, - query: { - "@type": "IdentityAttributeQuery", - valueType: "GivenName", - }, - }, - { - "@type": "ReadAttributeRequestItem", - mustBeAccepted: false, - query: { - "@type": "IdentityAttributeQuery", - valueType: "EMailAddress", - }, - }, - ], + query: { + "@type": "IdentityAttributeQuery", + valueType: "GivenName", + }, + }, + { + "@type": "ReadAttributeRequestItem", + mustBeAccepted: false, + query: { + "@type": "IdentityAttributeQuery", + valueType: "EMailAddress", + }, }, ], } + const request: RequestJSON = { "@type": "Request", items: [] } + + const result = await prompts({ + message: "Do you want to send your connector's name?", + type: "confirm", + name: "includeName", + initial: true, + }) + + if (result.includeName) request.items.push(sharedAttributes) + request.items.push(requestedAttributes) + await this.createQRCodeForRelationshipTemplate(request, name) } @@ -95,8 +103,8 @@ export function AddShareRequestByTemplate(Base: TBase) console.error(syncRequest.error) return } - console.log(syncRequest.result) + + console.log("Successfully synced the connector.") } } } diff --git a/src/mixins/AddTerminateRelationship.ts b/src/mixins/AddTerminateRelationship.ts new file mode 100644 index 0000000..7644040 --- /dev/null +++ b/src/mixins/AddTerminateRelationship.ts @@ -0,0 +1,25 @@ +import { ConnectorRelationshipStatus } from "@nmshd/connector-sdk" +import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" + +export function AddTerminateRelationship(Base: TBase) { + return class TerminateRelationship extends Base { + public constructor(...args: any[]) { + super(...args) + this.choices.push({ title: "Terminate Relationship", value: this.terminateRelationship }) + } + + protected async terminateRelationship() { + await this.connectorClient.account.sync() + + const relationship = await this.selectRelationship("Select relationship to terminate", ConnectorRelationshipStatus.Active) + if (!relationship) return + + console.log(`Terminating relationship ${relationship.id}`) + const terminationResult = await this.connectorClient.relationships.terminateRelationship(relationship.id) + if (terminationResult.isError) { + console.error(`Failed to terminate relationship ${relationship.id}: ${JSON.stringify(terminationResult.error)}`) + return + } + } + } +} diff --git a/src/mixins/AddUploadFile.ts b/src/mixins/AddUploadFile.ts index b6aaa86..54c9b5b 100644 --- a/src/mixins/AddUploadFile.ts +++ b/src/mixins/AddUploadFile.ts @@ -7,7 +7,7 @@ import url from "url" import { ConnectorTUIBaseConstructor } from "../ConnectorTUIBase.js" export function AddUploadFile(Base: TBase) { - return class Sync extends Base { + return class UploadFile extends Base { private readonly assetFolder = path.resolve(url.fileURLToPath(new URL(".", import.meta.url)), "../../__assets__") public constructor(...args: any[]) { diff --git a/src/mixins/ConnectorTUIBaseWithMixins.ts b/src/mixins/ConnectorTUIBaseWithMixins.ts index 04429d9..1d13175 100644 --- a/src/mixins/ConnectorTUIBaseWithMixins.ts +++ b/src/mixins/ConnectorTUIBaseWithMixins.ts @@ -4,12 +4,14 @@ import { AddAcceptPendingRequests, AddConnectorInfo, AddCreateAndShowTemplate, + AddDecomposeRelationship, AddExit, AddGetAttributesOfRelationship, AddSendMail, AddSendRequestByMessage, AddShareRequestByTemplate, AddSync, + AddTerminateRelationship, AddUploadFile, } from "./index.js" @@ -17,17 +19,21 @@ export class ConnectorTUIBaseWithMixins // extends AddExit( AddConnectorInfo( - AddCreateAndShowTemplate( - AddAcceptPendingRelationships( - AddAcceptPendingRequests( - AddGetAttributesOfRelationship( - AddSendMail( - AddSendRequestByMessage( - AddShareRequestByTemplate( - AddSync( - AddUploadFile( - // - ConnectorTUIBase + AddDecomposeRelationship( + AddTerminateRelationship( + AddCreateAndShowTemplate( + AddAcceptPendingRelationships( + AddAcceptPendingRequests( + AddGetAttributesOfRelationship( + AddSendMail( + AddSendRequestByMessage( + AddShareRequestByTemplate( + AddSync( + AddUploadFile( + // + ConnectorTUIBase + ) + ) ) ) ) diff --git a/src/mixins/index.ts b/src/mixins/index.ts index 96c365e..35f7f33 100644 --- a/src/mixins/index.ts +++ b/src/mixins/index.ts @@ -2,11 +2,13 @@ export * from "./AddAcceptPendingRelationships.js" export * from "./AddAcceptPendingRequests.js" export * from "./AddConnectorInfo.js" export * from "./AddCreateAndShowTemplate.js" +export * from "./AddDecomposeRelationship.js" export * from "./AddExit.js" export * from "./AddGetAttributesOfRelationship.js" export * from "./AddSendMail.js" export * from "./AddSendRequestByMessage.js" export * from "./AddShareRequestByTemplate.js" export * from "./AddSync.js" +export * from "./AddTerminateRelationship.js" export * from "./AddUploadFile.js" export * from "./ConnectorTUIBaseWithMixins.js"