diff --git a/package-lock.json b/package-lock.json index 0d086fb68..5b94e2954 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,6 +18,7 @@ "packages/fdc3-get-agent", "packages/fdc3", "toolbox/fdc3-for-web/demo", + "toolbox/fdc3-for-web/reference-ui", "toolbox/fdc3-workbench" ], "dependencies": { @@ -227,8 +228,8 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.2", - "integrity": "sha512-LV76g+C502biUK6AyZ3LK10vDpDyCzZnhZFXkH1L75zHPj68+qc8Zfpx2th+gzwA2MzyK+1g/3EPl62yFnVttQ==", + "version": "0.6.3", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", "dev": true, "dependencies": { "@babel/helper-compilation-targets": "^7.22.6", @@ -3344,7 +3345,6 @@ "node_modules/@kite9/fdc3-common": { "version": "2.2.0-beta.6", "integrity": "sha512-JQa8WVXWIpHQRMt9CFsxqjfrw2Rq4tVUT8R6r2cJAg1y1Ns+zmpclo/bGi3DVqFyd5PfOEbbiAER/1ll0PXb3A==", - "dev": true, "dependencies": { "@kite9/fdc3": "2.2.0-beta.6" } @@ -3352,7 +3352,6 @@ "node_modules/@kite9/fdc3-common/node_modules/@kite9/fdc3": { "version": "2.2.0-beta.6", "integrity": "sha512-F/fC4Ayp3uBzhBs4x5rp8n4/JSbuGaAHdrfrm/HTipDqsQKdQon4uZsNdMK6USTX1gnpFVy8luSnIddFJey12g==", - "dev": true, "optionalDependencies": { "@rollup/rollup-linux-x64-gnu": "4.14.1" } @@ -3363,7 +3362,6 @@ "cpu": [ "x64" ], - "dev": true, "optional": true, "os": [ "linux" @@ -3695,8 +3693,8 @@ "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.24.4", - "integrity": "sha512-jfUJrFct/hTA0XDM5p/htWKoNNTbDLY0KRwEt6pyOA6k2fmk0WVwl65PdUdJZgzGEHWx+49LilkcSaumQRyNQw==", + "version": "4.26.0", + "integrity": "sha512-gJNwtPDGEaOEgejbaseY6xMFu+CPltsc8/T+diUTTbOQLqD+bnrJq9ulH6WD69TqwqWmrfRAtUv30cCFZlbGTQ==", "cpu": [ "arm" ], @@ -3707,8 +3705,8 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.24.4", - "integrity": "sha512-j4nrEO6nHU1nZUuCfRKoCcvh7PIywQPUCBa2UsootTHvTHIoIu2BzueInGJhhvQO/2FTRdNYpf63xsgEqH9IhA==", + "version": "4.26.0", + "integrity": "sha512-YJa5Gy8mEZgz5JquFruhJODMq3lTHWLm1fOy+HIANquLzfIOzE9RA5ie3JjCdVb9r46qfAQY/l947V0zfGJ0OQ==", "cpu": [ "arm64" ], @@ -3719,8 +3717,8 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.24.4", - "integrity": "sha512-GmU/QgGtBTeraKyldC7cDVVvAJEOr3dFLKneez/n7BvX57UdhOqDsVwzU7UOnYA7AAOt+Xb26lk79PldDHgMIQ==", + "version": "4.26.0", + "integrity": "sha512-ErTASs8YKbqTBoPLp/kA1B1Um5YSom8QAc4rKhg7b9tyyVqDBlQxy7Bf2wW7yIlPGPg2UODDQcbkTlruPzDosw==", "cpu": [ "arm64" ], @@ -3731,8 +3729,8 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.24.4", - "integrity": "sha512-N6oDBiZCBKlwYcsEPXGDE4g9RoxZLK6vT98M8111cW7VsVJFpNEqvJeIPfsCzbf0XEakPslh72X0gnlMi4Ddgg==", + "version": "4.26.0", + "integrity": "sha512-wbgkYDHcdWW+NqP2mnf2NOuEbOLzDblalrOWcPyY6+BRbVhliavon15UploG7PpBRQ2bZJnbmh8o3yLoBvDIHA==", "cpu": [ "x64" ], @@ -3743,8 +3741,8 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.24.4", - "integrity": "sha512-py5oNShCCjCyjWXCZNrRGRpjWsF0ic8f4ieBNra5buQz0O/U6mMXCpC1LvrHuhJsNPgRt36tSYMidGzZiJF6mw==", + "version": "4.26.0", + "integrity": "sha512-Y9vpjfp9CDkAG4q/uwuhZk96LP11fBz/bYdyg9oaHYhtGZp7NrbkQrj/66DYMMP2Yo/QPAsVHkV891KyO52fhg==", "cpu": [ "arm64" ], @@ -3755,8 +3753,8 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.24.4", - "integrity": "sha512-L7VVVW9FCnTTp4i7KrmHeDsDvjB4++KOBENYtNYAiYl96jeBThFfhP6HVxL74v4SiZEVDH/1ILscR5U9S4ms4g==", + "version": "4.26.0", + "integrity": "sha512-A/jvfCZ55EYPsqeaAt/yDAG4q5tt1ZboWMHEvKAH9Zl92DWvMIbnZe/f/eOXze65aJaaKbL+YeM0Hz4kLQvdwg==", "cpu": [ "x64" ], @@ -3767,8 +3765,8 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.24.4", - "integrity": "sha512-10ICosOwYChROdQoQo589N5idQIisxjaFE/PAnX2i0Zr84mY0k9zul1ArH0rnJ/fpgiqfu13TFZR5A5YJLOYZA==", + "version": "4.26.0", + "integrity": "sha512-paHF1bMXKDuizaMODm2bBTjRiHxESWiIyIdMugKeLnjuS1TCS54MF5+Y5Dx8Ui/1RBPVRE09i5OUlaLnv8OGnA==", "cpu": [ "arm" ], @@ -3779,8 +3777,8 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.24.4", - "integrity": "sha512-ySAfWs69LYC7QhRDZNKqNhz2UKN8LDfbKSMAEtoEI0jitwfAG2iZwVqGACJT+kfYvvz3/JgsLlcBP+WWoKCLcw==", + "version": "4.26.0", + "integrity": "sha512-cwxiHZU1GAs+TMxvgPfUDtVZjdBdTsQwVnNlzRXC5QzIJ6nhfB4I1ahKoe9yPmoaA/Vhf7m9dB1chGPpDRdGXg==", "cpu": [ "arm" ], @@ -3791,8 +3789,8 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.24.4", - "integrity": "sha512-uHYJ0HNOI6pGEeZ/5mgm5arNVTI0nLlmrbdph+pGXpC9tFHFDQmDMOEqkmUObRfosJqpU8RliYoGz06qSdtcjg==", + "version": "4.26.0", + "integrity": "sha512-4daeEUQutGRCW/9zEo8JtdAgtJ1q2g5oHaoQaZbMSKaIWKDQwQ3Yx0/3jJNmpzrsScIPtx/V+1AfibLisb3AMQ==", "cpu": [ "arm64" ], @@ -3803,8 +3801,8 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.24.4", - "integrity": "sha512-38yiWLemQf7aLHDgTg85fh3hW9stJ0Muk7+s6tIkSUOMmi4Xbv5pH/5Bofnsb6spIwD5FJiR+jg71f0CH5OzoA==", + "version": "4.26.0", + "integrity": "sha512-eGkX7zzkNxvvS05ROzJ/cO/AKqNvR/7t1jA3VZDi2vRniLKwAWxUr85fH3NsvtxU5vnUUKFHKh8flIBdlo2b3Q==", "cpu": [ "arm64" ], @@ -3815,8 +3813,8 @@ ] }, "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { - "version": "4.24.4", - "integrity": "sha512-q73XUPnkwt9ZNF2xRS4fvneSuaHw2BXuV5rI4cw0fWYVIWIBeDZX7c7FWhFQPNTnE24172K30I+dViWRVD9TwA==", + "version": "4.26.0", + "integrity": "sha512-Odp/lgHbW/mAqw/pU21goo5ruWsytP7/HCC/liOt0zcGG0llYWKrd10k9Fj0pdj3prQ63N5yQLCLiE7HTX+MYw==", "cpu": [ "ppc64" ], @@ -3827,8 +3825,8 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.24.4", - "integrity": "sha512-Aie/TbmQi6UXokJqDZdmTJuZBCU3QBDA8oTKRGtd4ABi/nHgXICulfg1KI6n9/koDsiDbvHAiQO3YAUNa/7BCw==", + "version": "4.26.0", + "integrity": "sha512-MBR2ZhCTzUgVD0OJdTzNeF4+zsVogIR1U/FsyuFerwcqjZGvg2nYe24SAHp8O5sN8ZkRVbHwlYeHqcSQ8tcYew==", "cpu": [ "riscv64" ], @@ -3839,8 +3837,8 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.24.4", - "integrity": "sha512-P8MPErVO/y8ohWSP9JY7lLQ8+YMHfTI4bAdtCi3pC2hTeqFJco2jYspzOzTUB8hwUWIIu1xwOrJE11nP+0JFAQ==", + "version": "4.26.0", + "integrity": "sha512-YYcg8MkbN17fMbRMZuxwmxWqsmQufh3ZJFxFGoHjrE7bv0X+T6l3glcdzd7IKLiwhT+PZOJCblpnNlz1/C3kGQ==", "cpu": [ "s390x" ], @@ -3851,8 +3849,8 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.24.4", - "integrity": "sha512-K03TljaaoPK5FOyNMZAAEmhlyO49LaE4qCsr0lYHUKyb6QacTNF9pnfPpXnFlFD3TXuFbFbz7tJ51FujUXkXYA==", + "version": "4.26.0", + "integrity": "sha512-ZuwpfjCwjPkAOxpjAEjabg6LRSfL7cAJb6gSQGZYjGhadlzKKywDkCUnJ+KEfrNY1jH5EEoSIKLCb572jSiglA==", "cpu": [ "x64" ], @@ -3863,8 +3861,8 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.24.4", - "integrity": "sha512-VJYl4xSl/wqG2D5xTYncVWW+26ICV4wubwN9Gs5NrqhJtayikwCXzPL8GDsLnaLU3WwhQ8W02IinYSFJfyo34Q==", + "version": "4.26.0", + "integrity": "sha512-+HJD2lFS86qkeF8kNu0kALtifMpPCZU80HvwztIKnYwym3KnA1os6nsX4BGSTLtS2QVAGG1P3guRgsYyMA0Yhg==", "cpu": [ "x64" ], @@ -3875,8 +3873,8 @@ ] }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.24.4", - "integrity": "sha512-ku2GvtPwQfCqoPFIJCqZ8o7bJcj+Y54cZSr43hHca6jLwAiCbZdBUOrqE6y29QFajNAzzpIOwsckaTFmN6/8TA==", + "version": "4.26.0", + "integrity": "sha512-WUQzVFWPSw2uJzX4j6YEbMAiLbs0BUysgysh8s817doAYhR5ybqTI1wtKARQKo6cGop3pHnrUJPFCsXdoFaimQ==", "cpu": [ "arm64" ], @@ -3887,8 +3885,8 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.24.4", - "integrity": "sha512-V3nCe+eTt/W6UYNr/wGvO1fLpHUrnlirlypZfKCT1fG6hWfqhPgQV/K/mRBXBpxc0eKLIF18pIOFVPh0mqHjlg==", + "version": "4.26.0", + "integrity": "sha512-D4CxkazFKBfN1akAIY6ieyOqzoOoBV1OICxgUblWxff/pSjCA2khXlASUx7mK6W1oP4McqhgcCsu6QaLj3WMWg==", "cpu": [ "ia32" ], @@ -3899,8 +3897,8 @@ ] }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.24.4", - "integrity": "sha512-LTw1Dfd0mBIEqUVCxbvTE/LLo+9ZxVC9k99v1v4ahg9Aak6FpqOfNu5kRkeTAn0wphoC4JU7No1/rL+bBCEwhg==", + "version": "4.26.0", + "integrity": "sha512-2x8MO1rm4PGEP0xWbubJW5RtbNLk3puzAMaLQd3B3JHVw4KcHlmXcO+Wewx9zCoo7EUFiMlu/aZbCJ7VjMzAag==", "cpu": [ "x64" ], @@ -3968,6 +3966,38 @@ "node": ">= 10" } }, + "node_modules/@ts-morph/common": { + "version": "0.25.0", + "integrity": "sha512-kMnZz+vGGHi4GoHnLmMhGNjm44kGtKUXGnOvrKmMwAuvNjM/PgKVGfUnL7IDvK7Jb2QQ82jq3Zmp04Gy+r3Dkg==", + "dev": true, + "dependencies": { + "minimatch": "^9.0.4", + "path-browserify": "^1.0.1", + "tinyglobby": "^0.2.9" + } + }, + "node_modules/@ts-morph/common/node_modules/brace-expansion": { + "version": "2.0.1", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@ts-morph/common/node_modules/minimatch": { + "version": "9.0.5", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tsconfig/node10": { "version": "1.0.11", "integrity": "sha512-DcRjDCujK/kCk/cUe8Xz8ZSpm8mS3mNNpta+jGCA6USEDfktlNvm1+IuZ9eTcDbNk41BHwpHHeW+N1lKCz4zOw==" @@ -4221,8 +4251,8 @@ "integrity": "sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA==" }, "node_modules/@types/qs": { - "version": "6.9.16", - "integrity": "sha512-7i+zxXdPD0T4cKDuxCUXJ4wHcsJLwENa6Z3dCu8cfCK743OGy5Nu1RmAGqDPsoTDINVEcdXKRvR/zre+P2Ku1A==", + "version": "6.9.17", + "integrity": "sha512-rX4/bPcfmvxHDv0XjfJELTTr+iB+tn032nPILqHm5wbthUUUuVtNGGqzhya9XUxjTP8Fpr0qYgSZZKxGY++svQ==", "dev": true }, "node_modules/@types/range-parser": { @@ -5356,12 +5386,12 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.11", - "integrity": "sha512-sMEJ27L0gRHShOh5G54uAAPaiCOygY/5ratXuiyb2G46FmlSpc9eFCzYVyDiPxfNbwzA7mYahmjQc5q+CZQ09Q==", + "version": "0.4.12", + "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", "dev": true, "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.2", + "@babel/helper-define-polyfill-provider": "^0.6.3", "semver": "^6.3.1" }, "peerDependencies": { @@ -5389,11 +5419,11 @@ } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.2", - "integrity": "sha512-2R25rQZWP63nGwaAswvDazbPXfrM3HwVoBXK6HcqeKrSrL/JqcC/rDcf95l4r7LXLyxDXc8uQDa064GubtCABg==", + "version": "0.6.3", + "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", "dev": true, "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2" + "@babel/helper-define-polyfill-provider": "^0.6.3" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -5719,8 +5749,8 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001677", - "integrity": "sha512-fmfjsOlJUpMWu+mAAtZZZHz7UEwsUxIIvu1TJfO1HqFQvB/B+ii0xr9B5HpbZY/mC4XZ8SvjHJqtAY6pDPQEog==", + "version": "1.0.30001680", + "integrity": "sha512-rPQy70G6AGUMnbwS1z6Xg+RkHYPAi18ihs47GH0jcxIG7wArmPgY3XbS2sRdBbxJljp3thdT8BIqv9ccCypiPA==", "funding": [ { "type": "opencollective", @@ -6000,6 +6030,11 @@ "node": ">= 0.12.0" } }, + "node_modules/code-block-writer": { + "version": "13.0.3", + "integrity": "sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==", + "dev": true + }, "node_modules/collect-v8-coverage": { "version": "1.0.2", "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", @@ -6118,8 +6153,8 @@ } }, "node_modules/command-line-usage/node_modules/typical": { - "version": "7.2.0", - "integrity": "sha512-W1+HdVRUl8fS3MZ9ogD51GOb46xMmhAZzR0WPw5jcgIZQJVvkddYzAl4YTU6g5w33Y1iRQLdIi2/1jhi2RNL0g==", + "version": "7.3.0", + "integrity": "sha512-ya4mg/30vm+DOWfBg4YK3j2WD6TWtRkCbasOJr40CseYENzCUby/7rIvXA99JGsQHeNxLbnXdyLLxKSv3tauFw==", "dev": true, "engines": { "node": ">=12.17" @@ -6288,8 +6323,8 @@ } }, "node_modules/cross-spawn": { - "version": "7.0.3", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "version": "7.0.5", + "integrity": "sha512-ZVJrKKYunU38/76t0RMOulHOnUcbU9GbpWKAOZ0mhjr7CX6FVrH+4FrAapSOekrgFQ3f/8gwMEuIft0aKq6Hug==", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -6706,8 +6741,8 @@ "integrity": "sha512-5YM9LFQgVYfuLNEoqMqVWIBuF2UNCA+xu/jz1TyryLN/wmBcQSb+GNAwvLKvEpGESwgGN8XA1nbLAt6rKlyHYQ==" }, "node_modules/electron-to-chromium": { - "version": "1.5.51", - "integrity": "sha512-kKeWV57KSS8jH4alKt/jKnvHPmJgBxXzGUSbMd4eQF+iOsVPl7bz2KUmu6eo80eMP8wVioTfTyTzdMgM15WXNg==" + "version": "1.5.58", + "integrity": "sha512-al2l4r+24ZFL7WzyPTlyD0fC33LLzvxqLCwurtBibVPghRGO9hSTl+tis8t1kD7biPiH/en4U0I7o/nQbYeoVA==" }, "node_modules/emittery": { "version": "0.13.1", @@ -6853,8 +6888,8 @@ } }, "node_modules/es-abstract": { - "version": "1.23.3", - "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "version": "1.23.4", + "integrity": "sha512-HR1gxH5OaiN7XH7uiWH0RLw0RcFySiSoW1ctxmD1ahTw3uGBtkmm/ng0tDU1OtYx5OK6EOL5Y6O21cDflG3Jcg==", "dependencies": { "array-buffer-byte-length": "^1.0.1", "arraybuffer.prototype.slice": "^1.0.3", @@ -6871,7 +6906,7 @@ "function.prototype.name": "^1.1.6", "get-intrinsic": "^1.2.4", "get-symbol-description": "^1.0.2", - "globalthis": "^1.0.3", + "globalthis": "^1.0.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2", "has-proto": "^1.0.3", @@ -6887,10 +6922,10 @@ "is-string": "^1.0.7", "is-typed-array": "^1.1.13", "is-weakref": "^1.0.2", - "object-inspect": "^1.13.1", + "object-inspect": "^1.13.3", "object-keys": "^1.1.1", "object.assign": "^4.1.5", - "regexp.prototype.flags": "^1.5.2", + "regexp.prototype.flags": "^1.5.3", "safe-array-concat": "^1.1.2", "safe-regex-test": "^1.0.3", "string.prototype.trim": "^1.2.9", @@ -7820,6 +7855,10 @@ "node": ">=10" } }, + "node_modules/fdc3-for-web-reference-ui": { + "resolved": "toolbox/fdc3-for-web/reference-ui", + "link": true + }, "node_modules/fdc3-workbench": { "resolved": "toolbox/fdc3-workbench", "link": true @@ -11472,8 +11511,8 @@ } }, "node_modules/object-inspect": { - "version": "1.13.2", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", + "version": "1.13.3", + "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", "engines": { "node": ">= 0.4" }, @@ -11833,6 +11872,11 @@ "node": ">= 0.8" } }, + "node_modules/path-browserify": { + "version": "1.0.1", + "integrity": "sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==", + "dev": true + }, "node_modules/path-equal": { "version": "1.2.5", "integrity": "sha512-i73IctDr3F2W+bsOWDyyVm/lqsXO47aY9nsFZUjTT/aljSbkxHxxCoyZ9UUrM8jK0JVod+An+rl48RCsvWM+9g==", @@ -11957,8 +12001,8 @@ } }, "node_modules/postcss": { - "version": "8.4.47", - "integrity": "sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==", + "version": "8.4.49", + "integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==", "dev": true, "funding": [ { @@ -11976,7 +12020,7 @@ ], "dependencies": { "nanoid": "^3.3.7", - "picocolors": "^1.1.0", + "picocolors": "^1.1.1", "source-map-js": "^1.2.1" }, "engines": { @@ -12146,8 +12190,8 @@ } }, "node_modules/process-on-spawn": { - "version": "1.0.0", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "version": "1.1.0", + "integrity": "sha512-JOnOPQ/8TZgjs1JIH/m9ni7FfimjNa/PRx7y/Wb5qdItsnhO0jE4AT7fC0HjC28DUQWDr50dwSYZLdRMlqDq3Q==", "dependencies": { "fromentries": "^1.2.0" }, @@ -12226,9 +12270,12 @@ } }, "node_modules/psl": { - "version": "1.9.0", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "version": "1.10.0", + "integrity": "sha512-KSKHEbjAnpUuAUserOq0FxGXCUrzC3WniuSJhvdbs102rL55266ZcHBqLWOsG30spQMlPdpy7icATiAQehg/iA==", + "dev": true, + "dependencies": { + "punycode": "^2.3.1" + } }, "node_modules/pstree.remy": { "version": "1.1.8", @@ -12977,8 +13024,8 @@ } }, "node_modules/rollup": { - "version": "4.24.4", - "integrity": "sha512-vGorVWIsWfX3xbcyAS+I047kFKapHYivmkaT63Smj77XwvLSJos6M1xGqZnBPFQFBRZDOcG1QnYEIxAvTr/HjA==", + "version": "4.26.0", + "integrity": "sha512-ilcl12hnWonG8f+NxU6BlgysVA0gvY2l8N0R84S1HcINbW20bvwuCngJkkInV6LXhwRpucsW5k1ovDwEdBVrNg==", "dev": true, "dependencies": { "@types/estree": "1.0.6" @@ -12991,24 +13038,24 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.24.4", - "@rollup/rollup-android-arm64": "4.24.4", - "@rollup/rollup-darwin-arm64": "4.24.4", - "@rollup/rollup-darwin-x64": "4.24.4", - "@rollup/rollup-freebsd-arm64": "4.24.4", - "@rollup/rollup-freebsd-x64": "4.24.4", - "@rollup/rollup-linux-arm-gnueabihf": "4.24.4", - "@rollup/rollup-linux-arm-musleabihf": "4.24.4", - "@rollup/rollup-linux-arm64-gnu": "4.24.4", - "@rollup/rollup-linux-arm64-musl": "4.24.4", - "@rollup/rollup-linux-powerpc64le-gnu": "4.24.4", - "@rollup/rollup-linux-riscv64-gnu": "4.24.4", - "@rollup/rollup-linux-s390x-gnu": "4.24.4", - "@rollup/rollup-linux-x64-gnu": "4.24.4", - "@rollup/rollup-linux-x64-musl": "4.24.4", - "@rollup/rollup-win32-arm64-msvc": "4.24.4", - "@rollup/rollup-win32-ia32-msvc": "4.24.4", - "@rollup/rollup-win32-x64-msvc": "4.24.4", + "@rollup/rollup-android-arm-eabi": "4.26.0", + "@rollup/rollup-android-arm64": "4.26.0", + "@rollup/rollup-darwin-arm64": "4.26.0", + "@rollup/rollup-darwin-x64": "4.26.0", + "@rollup/rollup-freebsd-arm64": "4.26.0", + "@rollup/rollup-freebsd-x64": "4.26.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.26.0", + "@rollup/rollup-linux-arm-musleabihf": "4.26.0", + "@rollup/rollup-linux-arm64-gnu": "4.26.0", + "@rollup/rollup-linux-arm64-musl": "4.26.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.26.0", + "@rollup/rollup-linux-riscv64-gnu": "4.26.0", + "@rollup/rollup-linux-s390x-gnu": "4.26.0", + "@rollup/rollup-linux-x64-gnu": "4.26.0", + "@rollup/rollup-linux-x64-musl": "4.26.0", + "@rollup/rollup-win32-arm64-msvc": "4.26.0", + "@rollup/rollup-win32-ia32-msvc": "4.26.0", + "@rollup/rollup-win32-x64-msvc": "4.26.0", "fsevents": "~2.3.2" } }, @@ -14000,6 +14047,42 @@ "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", "dev": true }, + "node_modules/tinyglobby": { + "version": "0.2.10", + "integrity": "sha512-Zc+8eJlFMvgatPZTl6A9L/yht8QqdmUNtURHaKZLmKBE12hNPSrqNkUp2cs3M/UKmNVVAMFQYSjYIVHDjW5zew==", + "dev": true, + "dependencies": { + "fdir": "^6.4.2", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/tinyglobby/node_modules/fdir": { + "version": "6.4.2", + "integrity": "sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ==", + "dev": true, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/tinyglobby/node_modules/picomatch": { + "version": "4.0.2", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/tmp": { "version": "0.2.3", "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", @@ -14154,6 +14237,15 @@ } } }, + "node_modules/ts-morph": { + "version": "24.0.0", + "integrity": "sha512-2OAOg/Ob5yx9Et7ZX4CvTCc0UFoZHwLEJ+dpDPSUi5TgwwlTlX47w+iFRrEwzUZwYACjq83cgjS/Da50Ga37uw==", + "dev": true, + "dependencies": { + "@ts-morph/common": "~0.25.0", + "code-block-writer": "^13.0.3" + } + }, "node_modules/ts-node": { "version": "10.9.2", "integrity": "sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==", @@ -14715,8 +14807,8 @@ } }, "node_modules/vite": { - "version": "5.4.10", - "integrity": "sha512-1hvaPshuPUtxeQ0hsVH3Mud0ZanOLwVTneA1EgbAM5LhaZEqyPWGRQ7BtaMvUrTDeEaC8pxtj6a6jku3x4z6SQ==", + "version": "5.4.11", + "integrity": "sha512-c7jFQRklXua0mTzneGW9QVyxFjUgwcihC4bXEtujIo2ouWCe1Ajt/amn2PCxYnhYfd5k09JX3SB7OYWFKYqj8Q==", "dev": true, "dependencies": { "esbuild": "^0.21.3", @@ -15597,7 +15689,6 @@ } }, "packages/fdc3": { - "name": "@kite9/fdc3", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -15608,7 +15699,6 @@ } }, "packages/fdc3-agent-proxy": { - "name": "@kite9/fdc3-agent-proxy", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -15643,7 +15733,6 @@ } }, "packages/fdc3-context": { - "name": "@kite9/fdc3-context", "version": "2.2.0-beta.29", "license": "Apache-2.0", "devDependencies": { @@ -16077,7 +16166,6 @@ } }, "packages/fdc3-get-agent": { - "name": "@kite9/fdc3-get-agent", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -16104,7 +16192,6 @@ } }, "packages/fdc3-schema": { - "name": "@kite9/fdc3-schema", "version": "2.2.0-beta.29", "license": "Apache-2.0", "devDependencies": { @@ -16121,6 +16208,7 @@ "quicktype": "23.0.78", "rimraf": "^6.0.1", "ts-jest": "29.2.5", + "ts-morph": "^24.0.0", "tslib": "^2.7.0", "typescript": "~5.5.0" } @@ -16538,7 +16626,6 @@ } }, "packages/fdc3-standard": { - "name": "@kite9/fdc3-standard", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -16981,7 +17068,6 @@ } }, "packages/testing": { - "name": "@kite9/testing", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -17015,7 +17101,6 @@ } }, "toolbox/fdc3-for-web/demo": { - "name": "@kite9/demo", "version": "2.2.0-beta.29", "dependencies": { "@kite9/fdc3": "2.2.0-beta.29", @@ -17038,7 +17123,6 @@ } }, "toolbox/fdc3-for-web/fdc3-web-impl": { - "name": "@kite9/fdc3-web-impl", "version": "2.2.0-beta.29", "license": "Apache-2.0", "dependencies": { @@ -17075,6 +17159,16 @@ "uuid": "^9.0.1" } }, + "toolbox/fdc3-for-web/reference-ui": { + "version": "2.1.1", + "dependencies": { + "@kite9/fdc3-common": "2.2.0-beta.6" + }, + "devDependencies": { + "typescript": "^5.3.2", + "vite": "^5.2.0" + } + }, "toolbox/fdc3-workbench": { "version": "2.2.0-beta.29", "license": "Apache-2.0", diff --git a/package.json b/package.json index 124279137..d610bd202 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "toolbox/fdc3-for-web/fdc3-web-impl", "packages/fdc3-get-agent", "packages/fdc3", + "toolbox/fdc3-for-web/reference-ui", "toolbox/fdc3-for-web/demo", "toolbox/fdc3-workbench" ], @@ -37,7 +38,7 @@ "report": "nyc report --reporter json-summary --report-dir nyc-coverage-report --exclude-after-remap false --temp-dir coverage", "lint": "npm run lint --workspaces --if-present", "syncpack": "npm exec syncpack fix-mismatches --types 'local'", - "dev": "concurrently \"cd toolbox/fdc3-workbench && npm run dev\" \"cd toolbox/fdc3-for-web/demo && npm run dev\"" + "dev": "concurrently \"cd toolbox/fdc3-workbench && npm run dev\" \"cd toolbox/fdc3-for-web/reference-ui && npm run dev\" \"cd toolbox/fdc3-for-web/demo && npm run dev\"" }, "prettier": { "semi": true, diff --git a/packages/addon/src/intent_resolver_orig.js b/packages/addon/src/intent_resolver_orig.js deleted file mode 100644 index b97d75086..000000000 --- a/packages/addon/src/intent_resolver_orig.js +++ /dev/null @@ -1,160 +0,0 @@ -const setup = (data, callback) => { - document.body.setAttribute("data-visible", "true"); - document.getElementById("displayContext").textContent = data.context ?? "*"; - console.log("setup: ", data); - const intentSelect = document.getElementById("displayIntent"); - data.intents.forEach(({intent, displayName}) => { - const option = document.createElement("option"); - option.textContent = displayName; - option.value = intent; - intentSelect.appendChild(option); - }); - intentSelect.addEventListener("change", (e) => fillList(data.options[e.target.value], e.target.value, callback)); - fillList(data.options[intentSelect.value], intentSelect.value, callback); - - const tabs = Array.from(document.querySelectorAll("[role='tab']")) - tabs.forEach((tab) => { - tab.addEventListener("click", () => { - // Remove selected state from every tab - tabs.forEach((t) => { - t.setAttribute("aria-selected", "false"); - }); - // Hide lists - Array.from(document.querySelectorAll(".list")).forEach((elem) => { - elem.setAttribute("data-visible", "false"); - }); - - tab.setAttribute("aria-selected", "true"); - const listRef = tab.getAttribute("data-list-ref"); - document.getElementById(listRef).setAttribute("data-visible", "true"); - }); - }); - - document.getElementById("cancel").addEventListener("click", () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - action: "cancel" - }); - }) -} - -const fillList = ({apps, openApps}, intent, callback) => { - const newList = document.getElementById('new-list'); - newList.innerHTML = ''; - apps.forEach(({ appId, title, icon }) => { - const node = document.createElement('div'); - node.setAttribute('tabIndex', '0'); - node.setAttribute("data-appId", appId); - - const span = document.createElement("span"); - span.textContent = title; - - const img = document.createElement("img"); - if(icon?.src){ - img.src = icon.src; - }else{ - img.style.opacity = 0; - } - - node.appendChild(img); - node.appendChild(span); - - node.addEventListener('mouseenter', () => callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - intent, - action: "hover", - newOrOpen: "new" - })); - node.addEventListener('click', () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - intent, - action: "click", - newOrOpen: "new" - }); - callback({ - type: "Fdc3UserInterfaceResolve", - appId, - intent, - newOrOpen: "new" - }); - }); - - newList.appendChild(node); - }); - document.getElementById("count-new-apps").textContent = `(${apps.length})`; - - const openList = document.getElementById('open-list'); - openList.innerHTML = ''; - openApps.forEach(({ appId, title, windowId }) => { - const appd = apps.find((app) => app.appId === appId); - const node = document.createElement('div'); - node.setAttribute('tabIndex', '0'); - node.setAttribute("data-appId", appId); - - const span = document.createElement("span"); - span.textContent = title; - - const img = document.createElement("img"); - if(appd.icon?.src){ - img.src = appd.icon.src; - }else{ - img.style.opacity = 0; - } - - node.appendChild(img); - node.appendChild(span); - - node.addEventListener('mouseenter', () => callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - windowId, - intent, - action: "hover", - newOrOpen: "open" - })); - node.addEventListener('click', () => { - callback({ - type: "Fdc3UserInterfaceResolveAction", - appId, - windowId, - intent, - action: "click", - newOrOpen: "open" - }); - callback({ - type: "Fdc3UserInterfaceResolve", - appId, - intent, - windowId, - newOrOpen: "open" - }) - }); - - openList.appendChild(node); - }); - document.getElementById("count-open-apps").textContent = `(${openApps.length})`; -}; - -// STEP 1B: Receive port from parent -// we may not know the origin of the parent in advance so disabling this check -// this might be improved if it s possible to get the origin of the parent window (cross-domain) and only respond to that -// nosemgrep: javascript.browser.security.insufficient-postmessage-origin-validation.insufficient-postmessage-origin-validation -window.addEventListener('message', ({ origin, ports }) => { - //only accept a port from the window we are embedded in: - if(window.location.ancestorOrigins.contains(origin)){ - // STEP 3B: Receive channel data from parent - ports[0].onmessage = ({ data }) => { - setup(data, msg => { - // STEP 4A: Send user selection information to parent - ports[0].postMessage(msg); - }); - }; - // STEP 2A: Send confirmation over port to parent - ports[0].postMessage({type: 'Fdc3UserInterfaceHandshake'}); - } else { - console.warn(`Ignoring postMessage from unknonw (non-ancestor) origin: ${origin}`); - } -}); diff --git a/packages/addon/src/main.ts b/packages/addon/src/main.ts deleted file mode 100644 index cdf263e30..000000000 --- a/packages/addon/src/main.ts +++ /dev/null @@ -1,198 +0,0 @@ -import { ResolverIntents } from "@kite9/fdc3-common"; -import "./style.css"; - -// Channel data -const recommendedChannels = [ - { - id: 'fdc3.channel.1', - type: 'user', - displayMetadata: { - name: 'Channel 1', - color: 'red', - glyph: '1', - }, - }, - { - id: 'fdc3.channel.2', - type: 'user', - displayMetadata: { - name: 'Channel 2', - color: 'orange', - glyph: '2', - }, - }, - { - id: 'fdc3.channel.3', - type: 'user', - displayMetadata: { - name: 'Channel 3', - color: 'yellow', - glyph: '3', - }, - }, - { - id: 'fdc3.channel.4', - type: 'user', - displayMetadata: { - name: 'Channel 4', - color: 'green', - glyph: '4', - }, - }, - { - id: 'fdc3.channel.5', - type: 'user', - displayMetadata: { - name: 'Channel 5', - color: 'cyan', - glyph: '5', - }, - }, - { - id: 'fdc3.channel.6', - type: 'user', - displayMetadata: { - name: 'Channel 6', - color: 'blue', - glyph: '6', - }, - }, - { - id: 'fdc3.channel.7', - type: 'user', - displayMetadata: { - name: 'Channel 7', - color: 'magenta', - glyph: '7', - }, - }, - { - id: 'fdc3.channel.8', - type: 'user', - displayMetadata: { - name: 'Channel 8', - color: 'purple', - glyph: '8', - }, - }, -]; - -// Example resolver data -const exampleResolverData: ResolverIntents = { - type: "ResolverIntents", - appIntents: [ - { - apps: [{ - appId: "trading-view-chart", - description: "TradingView is a social network for traders and investors on Stock, Futures and Forex markets!", - icons: [{ - src: "https://apps.connectifi-interop.com/tradingviewChart/icon.png" - }], - title: "TradingView Chart" - }, { - appId: "adaptabledemo", - instanceId: "324587329238y7r59824", - description: "AdapTable is a powerful data grid with a range of advanced features", - icons: [{ - src: "https://apps.connectifi-interop.com/adaptableDemo/icon.png" - }], - title: "AdapTable" - }], - intent: { - name: "ViewInstrument", - displayName: "View Instrument" - }, - }], - source: { - appId: "fdc3-demo", - instanceId: "fdc3-demo-instance" - } -}; - -let selected = recommendedChannels[2].id; -let expanded = true; - -const openChannelIframe = (e: MouseEvent) => { - const channel = new MessageChannel(); - - // STEP 2B: Receive confirmation over port from iframe - channel.port1.onmessage = ({ data }) => { - switch (data.type) { - - // User clicked on one of the channels in the channel selector - // @ts-ignore: Explicit fall-through to Fdc3UserInterfaceHandshake - case "Fdc3UserInterfaceChannelSelected": { - // STEP 4B: Receive user selection information from iframe - selected = data.channel; - } - - // Handshake completed. Send channel data to iframe - case "Fdc3UserInterfaceHandshake": { - // STEP 3A: Send channel data to iframe - channel.port1.postMessage({ - type: "Fdc3UserInterfaceChannels", - channels: recommendedChannels, - selected - }); - break; - } - - } - - }; - - const {target} = e; - if(target) (target as HTMLButtonElement).disabled = true; - - const iframe = document.querySelector("#channel-iframe")!; - iframe.parentElement?.setAttribute("data-visible", "true"); - - const resizeButton = document.getElementById("dimensions-btn-channel")!; - resizeButton.setAttribute("data-visible", "true"); - resizeButton.addEventListener("click", () => { - expanded = !expanded; - channel.port1.postMessage({ type: "Fdc3UserInterfaceChannelResize", expanded }) - iframe.setAttribute("data-expanded", `${expanded}`); - resizeButton.textContent = expanded ? "Collapse" : "Expand"; - }); - - // STEP 1A: Send port to iframe - iframe.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); -}; - -const openResolverIframe = (e: MouseEvent )=> { - const channel = new MessageChannel(); - - // STEP 2B: Receive confirmation over port from iframe - channel.port1.onmessage = ({ data }) => { - switch (data.type) { - case "Fdc3UserInterfaceHandshake": { - // STEP 3A: Send channel data to iframe - channel.port1.postMessage(exampleResolverData); - break; - } - case "Fdc3UserInterfaceResolveAction": - case "Fdc3UserInterfaceResolve": { - // STEP 4B: Receive user selection information from iframe - - // TODO - prettyPrintJson dependency is not referenced, re-enable when added - // document.getElementById('resolver-user-selection')!.innerHTML = prettyPrintJson.toHtml(data); - break; - } - } - - }; - const {target} = e; - if(target) (target as HTMLButtonElement).disabled = true; - - const iframe = document.querySelector("#resolver-iframe"); - iframe!.parentElement?.setAttribute("data-visible", "true"); - - // STEP 1A: Send port to iframe - iframe!.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); -}; - -window.addEventListener('load', () => { - document.getElementById('send-btn-channel')!.addEventListener('click', openChannelIframe); - document.getElementById('send-btn-resolver')!.addEventListener('click', openResolverIframe); -}); diff --git a/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts b/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts index 4786a1361..6ff5b4836 100644 --- a/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts +++ b/packages/fdc3-agent-proxy/src/listeners/HeartbeatListener.ts @@ -27,7 +27,7 @@ export class HeartbeatListener implements RegisterableListener { heartbeatEventUuid: (_m as HeartbeatEvent).meta.eventUuid } } as HeartbeatAcknowledgementRequest) - console.log("Heartbeat acknowledged") + //console.log("Heartbeat acknowledged") } async register(): Promise { diff --git a/packages/fdc3-context/generated/context/ContextTypes.ts b/packages/fdc3-context/generated/context/ContextTypes.ts index 8324b91c8..794687e52 100644 --- a/packages/fdc3-context/generated/context/ContextTypes.ts +++ b/packages/fdc3-context/generated/context/ContextTypes.ts @@ -119,7 +119,7 @@ export type ActionType = "broadcast" | "raiseIntent"; export interface AppIdentifier { /** * The unique application identifier located within a specific application directory - * instance. An example of an appId might be 'app@sub.root' + * instance. An example of an appId might be 'app@sub.root'. */ appId: string; /** diff --git a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts index bb2b24071..91708b09e 100644 --- a/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts +++ b/packages/fdc3-get-agent/src/ui/AbstractUIComponent.ts @@ -1,4 +1,4 @@ -import { Fdc3UserInterfaceHello, InitialCSS, UpdatedCSS } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, InitialCSS, UpdatedCSS } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; import { Connectable } from "@kite9/fdc3-standard"; export interface CSSPositioning { [key: string]: string } @@ -57,7 +57,7 @@ export abstract class AbstractUIComponent implements Connectable { async setupMessagePort(port: MessagePort): Promise { port.addEventListener("message", (e) => { const data = e.data - if (data.type == 'Fdc3UserInterfaceRestyle') { + if (data.type == FDC3_USER_INTERFACE_RESTYLE_TYPE) { // console.log(`Restyling ${JSON.stringify(data.payload)}`) const css = data.payload.updatedCSS this.themeContainer(css) @@ -67,14 +67,14 @@ export abstract class AbstractUIComponent implements Connectable { async messagePortReady(port: MessagePort) { // tells the iframe it can start posting - port.postMessage({ type: "Fdc3UserInterfaceHandshake" }) + port.postMessage({ type: FDC3_USER_INTERFACE_HANDSHAKE_TYPE, payload: {} }) } private awaitHello(): Promise { return new Promise((resolve, _reject) => { const ml = (e: MessageEvent) => { // console.log("Received UI Message: " + JSON.stringify(e.data)) - if ((e.source == this.iframe?.contentWindow) && (e.data.type == 'Fdc3UserInterfaceHello')) { + if ((e.source == this.iframe?.contentWindow) && (e.data.type == FDC3_USER_INTERFACE_HELLO_TYPE)) { const helloData = e.data as Fdc3UserInterfaceHello if (helloData.payload.initialCSS) { this.themeContainer(helloData.payload.initialCSS) diff --git a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts index faf0e849d..89593adee 100644 --- a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts +++ b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentChannelSelector.ts @@ -2,6 +2,7 @@ import { Channel } from "@kite9/fdc3-standard"; import { ChannelSelector } from "@kite9/fdc3-standard" import { AbstractUIComponent } from "./AbstractUIComponent"; import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type Fdc3UserInterfaceChannels = BrowserTypes.Fdc3UserInterfaceChannels type Fdc3UserInterfaceChannelSelected = BrowserTypes.Fdc3UserInterfaceChannelSelected @@ -25,7 +26,7 @@ export class DefaultDesktopAgentChannelSelector extends AbstractUIComponent impl this.port = port port.addEventListener("message", (e) => { - if (e.data.type == 'Fdc3UserInterfaceChannelSelected') { + if (e.data.type == FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE) { const choice = e.data as Fdc3UserInterfaceChannelSelected if (this.callback) { this.callback(choice.payload.selected) @@ -37,7 +38,7 @@ export class DefaultDesktopAgentChannelSelector extends AbstractUIComponent impl updateChannel(channelId: string | null, availableChannels: Channel[]): void { // also send to the iframe this.port!!.postMessage({ - type: 'Fdc3UserInterfaceChannels', + type: FDC3_USER_INTERFACE_CHANNELS_TYPE, payload: { selected: channelId, userChannels: availableChannels.map(ch => { diff --git a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts index f0c1910aa..d8f5272ee 100644 --- a/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts +++ b/packages/fdc3-get-agent/src/ui/DefaultDesktopAgentIntentResolver.ts @@ -3,6 +3,7 @@ import { IntentResolver, IntentResolutionChoice } from '@kite9/fdc3-standard' import { AbstractUIComponent } from "./AbstractUIComponent"; import { BrowserTypes } from "@kite9/fdc3-schema"; import { Context } from "@kite9/fdc3-context"; +import { FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESOLVE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type Fdc3UserInterfaceResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type Fdc3UserInterfaceResolve = BrowserTypes.Fdc3UserInterfaceResolve @@ -26,7 +27,7 @@ export class DefaultDesktopAgentIntentResolver extends AbstractUIComponent imple this.port.addEventListener("message", (e) => { console.log("Got resolve action") - if (e.data.type == 'Fdc3UserInterfaceResolveAction') { + if (e.data.type == FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE) { const choice = e.data as Fdc3UserInterfaceResolveAction if ((choice.payload.action == 'click') && (this.pendingResolve)) { this.pendingResolve({ @@ -49,7 +50,7 @@ export class DefaultDesktopAgentIntentResolver extends AbstractUIComponent imple this.port?.postMessage({ - type: 'Fdc3UserInterfaceResolve', + type: FDC3_USER_INTERFACE_RESOLVE_TYPE, payload: { appIntents, context diff --git a/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts b/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts index 2bc2cc7e1..cb5963dce 100644 --- a/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts +++ b/packages/fdc3-get-agent/test/step-definitions/intent-resolver.steps.ts @@ -3,6 +3,7 @@ import { CustomWorld } from "../world"; import { handleResolve } from "@kite9/testing"; import { DefaultDesktopAgentIntentResolver } from "../../src/ui/DefaultDesktopAgentIntentResolver"; import { INTENT_RESPOLVER_URL } from "../support/MockFDC3Server"; +import { FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const contextMap: Record = { @@ -76,7 +77,7 @@ Given('The intent resolver sends an intent selection message', async function (t const port = handleResolve("{document.iframes[0].messageChannels[0].port2}", this) port.postMessage({ - type: 'Fdc3UserInterfaceResolveAction', + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: 'click', appIdentifier: { @@ -91,7 +92,7 @@ Given('The intent resolver cancels the intent selection message', async function const port = handleResolve("{document.iframes[0].messageChannels[0].port2}", this) port.postMessage({ - type: 'Fdc3UserInterfaceResolveAction', + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: 'cancel' } diff --git a/packages/fdc3-get-agent/test/support/FrameTypes.ts b/packages/fdc3-get-agent/test/support/FrameTypes.ts index 1a2094267..443998425 100644 --- a/packages/fdc3-get-agent/test/support/FrameTypes.ts +++ b/packages/fdc3-get-agent/test/support/FrameTypes.ts @@ -2,6 +2,7 @@ import { CustomWorld } from "../world" import { MockWindow } from "./MockWindow" import { CHANNEL_SELECTOR_URL, EMBED_URL, INTENT_RESPOLVER_URL } from "./MockFDC3Server" import { BrowserTypes } from "@kite9/fdc3-schema" +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes" type Fdc3UserInterfaceHello = BrowserTypes.Fdc3UserInterfaceHello type WebConnectionProtocol3Handshake = BrowserTypes.WebConnectionProtocol3Handshake @@ -38,7 +39,7 @@ export function handleChannelSelectorComms(_value: string, parent: MockWindow, s parent.dispatchEvent({ type: "message", data: { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: { "width": "100px" @@ -52,10 +53,10 @@ export function handleChannelSelectorComms(_value: string, parent: MockWindow, s connection.port2.onmessage = (e) => { - if (e.data.type == 'Fdc3UserInterfaceHandshake') { + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { setTimeout(() => { connection.port2.postMessage({ - type: 'Fdc3UserInterfaceRestyle', + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { css: { "width": "100px" @@ -79,7 +80,7 @@ export function handleIntentResolverComms(_value: string, parent: MockWindow, so parent.dispatchEvent({ type: "message", data: { - type: "Fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: { "width": "100px" @@ -92,10 +93,10 @@ export function handleIntentResolverComms(_value: string, parent: MockWindow, so } as any as Event) connection.port2.onmessage = (e) => { - if (e.type == 'Fdc3UserInterfaceHandshake') { + if (e.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { setTimeout(() => { connection.port2.postMessage({ - type: 'Fdc3UserInterfaceRestyle', + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { css: { "width": "100px" diff --git a/packages/fdc3-schema/code-generation/generate-type-predicates.ts b/packages/fdc3-schema/code-generation/generate-type-predicates.ts new file mode 100644 index 000000000..1ed5801a4 --- /dev/null +++ b/packages/fdc3-schema/code-generation/generate-type-predicates.ts @@ -0,0 +1,74 @@ +import { InterfaceDeclaration, MethodDeclaration, Project, SyntaxKind } from "ts-morph" + +// open a new project with just BrowserTypes as the only source file +const project = new Project(); +const sourceFile = project.addSourceFileAtPath("./generated/api/BrowserTypes.ts") + +//get a list of all interfaces in the file +const interfaces = sourceFile.getChildrenOfKind(SyntaxKind.InterfaceDeclaration); + +// get a list of all conversion functions in the Convert class +const convert = sourceFile.getClass("Convert"); +const convertFunctions = (convert?.getChildrenOfKind(SyntaxKind.MethodDeclaration) ?? []).filter(func => func.getReturnType().getText() === "string"); + +// generate a list of Interfaces that have an associated conversion function +const matchedInterfaces = convertFunctions.map(func => { + const valueParameter = func.getParameter("value"); + + const matchingInterface = interfaces.find(interfaceNode => { + return valueParameter?.getType().getText(valueParameter) === interfaceNode.getName(); + }); + + + if (matchingInterface != null) { + return { func, matchingInterface }; + } + + return undefined; +}).filter(((value => value != null) as (value: T | null | undefined) => value is T)); + +// write a type predicate for each matched interface +matchedInterfaces.forEach(matched => { + writePredicate(matched.matchingInterface, matched.func) + writeTypeConstant(matched.matchingInterface) +}); + +writeUnionType("RequestMessage", interfaces, "Request"); +writeUnionType("ResponseMessage", interfaces, "Response"); +writeUnionType("EventMessage", interfaces, "Event"); + +function writePredicate(matchingInterface: InterfaceDeclaration, func: MethodDeclaration): void { + const predicateName = `is${matchingInterface.getName()}`; + + sourceFile.addStatements(` +export function ${predicateName}(value: any): value is ${matchingInterface.getName()} { + try{ + Convert.${func.getName()}(value); + return true; + } catch(_e: any){ + return false; + } +}`); +} + +function writeTypeConstant(matchingInterface: InterfaceDeclaration): void { + + sourceFile.addStatements(` + export const ${matchingInterface.getName().replaceAll(/([A-Z])/g, '_$1').toUpperCase().substring(1)}_TYPE = "${matchingInterface.getName()}"; + `); + +} + + +function writeUnionType(unionName: string, interfaces: InterfaceDeclaration[], nameEndsWith: string): void { + const matchingInterfaces = interfaces + .map(currentInterface => currentInterface.getName()) + .filter(interfaceName => interfaceName.length > nameEndsWith.length && interfaceName.indexOf(nameEndsWith) === interfaceName.length - nameEndsWith.length); + + sourceFile.addStatements(` + export type ${unionName} = ${matchingInterfaces.join(" | ")}; `); +} + +sourceFile.formatText(); + +project.saveSync(); diff --git a/packages/fdc3-schema/generated/api/BrowserTypes.ts b/packages/fdc3-schema/generated/api/BrowserTypes.ts index 98d3ef495..a924b0bdf 100644 --- a/packages/fdc3-schema/generated/api/BrowserTypes.ts +++ b/packages/fdc3-schema/generated/api/BrowserTypes.ts @@ -114,7 +114,7 @@ export interface WebConnectionProtocol1Hello { */ export interface WebConnectionProtocol1HelloMeta { connectionAttemptUuid: string; - timestamp: Date; + timestamp: Date; } /** @@ -603,7 +603,7 @@ export interface WebConnectionProtocolMessage { * Metadata for a Web Connection Protocol message. */ export interface ConnectionStepMetadata { - timestamp: Date; + timestamp: Date; connectionAttemptUuid?: string; } @@ -648,7 +648,7 @@ export interface AddContextListenerRequestMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -751,13 +751,13 @@ export interface AddContextListenerResponse { * Metadata for messages sent by a Desktop Agent to an app in response to an API call. */ export interface AddContextListenerResponseMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -767,7 +767,7 @@ export interface AddContextListenerResponseMeta { * unsuccessful. */ export interface AddContextListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; } @@ -857,7 +857,7 @@ export interface AddEventListenerResponse { * unsuccessful. */ export interface AddEventListenerResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; listenerUUID?: string; } @@ -942,7 +942,7 @@ export interface AddIntentListenerResponse { * unsuccessful. */ export interface AddIntentListenerResponsePayload { - error?: FluffyError; + error?: FluffyError; listenerUUID?: string; [property: string]: any; } @@ -1021,13 +1021,13 @@ export interface AgentResponseMessage { * Metadata for messages sent by a Desktop Agent to an app in response to an API call. */ export interface AgentResponseMessageMeta { - requestUuid: string; + requestUuid: string; responseUuid: string; /** * Field that represents the source application that the request being responded to was * received from, for debugging purposes. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -1077,7 +1077,7 @@ export interface AppRequestMessageMeta { * purposes but a Desktop Agent should make its own determination of the source of a message * to avoid spoofing. */ - source?: AppIdentifier; + source?: AppIdentifier; timestamp: Date; } @@ -1448,7 +1448,7 @@ export interface CreatePrivateChannelResponse { * unsuccessful. */ export interface CreatePrivateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; privateChannel?: Channel; } @@ -1868,7 +1868,7 @@ export interface Fdc3UserInterfaceResolvePayload { * An array of AppIntent objects defining the resolution options. */ appIntents: AppIntent[]; - context: Context; + context: Context; } /** @@ -2098,7 +2098,7 @@ export interface FindInstancesResponse { * resulted in an error and including a standardized error message. */ export interface FindInstancesResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIdentifiers?: AppMetadata[]; } @@ -2159,8 +2159,8 @@ export interface FindIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentRequestPayload { - context?: Context; - intent: string; + context?: Context; + intent: string; resultType?: string; } @@ -2199,7 +2199,7 @@ export interface FindIntentResponse { * unsuccessful. */ export interface FindIntentResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntent?: AppIntent; } @@ -2234,7 +2234,7 @@ export interface FindIntentsByContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface FindIntentsByContextRequestPayload { - context: Context; + context: Context; resultType?: string; } @@ -2273,7 +2273,7 @@ export interface FindIntentsByContextResponse { * unsuccessful. */ export interface FindIntentsByContextResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appIntents?: AppIntent[]; } @@ -2345,7 +2345,7 @@ export interface GetAppMetadataResponse { * unsuccessful. */ export interface GetAppMetadataResponsePayload { - error?: FindInstancesErrors; + error?: FindInstancesErrors; appMetadata?: AppMetadata; } @@ -2417,7 +2417,7 @@ export interface GetCurrentChannelResponse { * unsuccessful. */ export interface GetCurrentChannelResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; channel?: Channel | null; } @@ -2575,7 +2575,7 @@ export interface GetInfoResponse { * unsuccessful. */ export interface GetInfoResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; implementationMetadata?: ImplementationMetadata; } @@ -2651,7 +2651,7 @@ export interface GetOrCreateChannelResponse { * unsuccessful. */ export interface GetOrCreateChannelResponsePayload { - error?: PurpleError; + error?: PurpleError; channel?: Channel; } @@ -2722,7 +2722,7 @@ export interface GetUserChannelsResponse { * unsuccessful. */ export interface GetUserChannelsResponsePayload { - error?: PurpleError; + error?: PurpleError; userChannels?: Channel[]; } @@ -2945,7 +2945,7 @@ export interface IntentResultRequestPayload { * The eventUuid value of the intentEvent that the result being sent relates to. */ intentEventUuid: string; - intentResult: IntentResult; + intentResult: IntentResult; /** * The requestUuid value of the raiseIntentRequest that the result being sent relates to. */ @@ -3208,7 +3208,7 @@ export interface OpenResponse { * unsuccessful. */ export interface OpenResponsePayload { - error?: OpenErrorResponsePayload; + error?: OpenErrorResponsePayload; appIdentifier?: AppIdentifier; } @@ -3304,7 +3304,7 @@ export interface PrivateChannelAddEventListenerResponse { * unsuccessful. */ export interface PrivateChannelAddEventListenerResponsePayload { - error?: PurpleError; + error?: PurpleError; listenerUUID?: string; [property: string]: any; } @@ -3597,7 +3597,7 @@ export interface RaiseIntentForContextRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentForContextRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; } @@ -3736,9 +3736,9 @@ export interface RaiseIntentRequest { * The message payload typically contains the arguments to FDC3 API functions. */ export interface RaiseIntentRequestPayload { - app?: AppIdentifier; + app?: AppIdentifier; context: Context; - intent: string; + intent: string; } /** @@ -3841,7 +3841,7 @@ export interface RaiseIntentResultResponse { * unsuccessful. */ export interface RaiseIntentResultResponsePayload { - error?: ResponsePayloadError; + error?: ResponsePayloadError; intentResult?: IntentResult; } @@ -4554,7 +4554,7 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any const typ = typs[i]; try { return transform(val, typ, getProps); - } catch (_) {} + } catch (_) { } } return invalidValue(typs, val, key, parent); } @@ -4613,9 +4613,9 @@ function transform(val: any, typ: any, getProps: any, key: any = '', parent: any if (Array.isArray(typ)) return transformEnum(typ, val); if (typeof typ === "object") { return typ.hasOwnProperty("unionMembers") ? transformUnion(typ.unionMembers, val) - : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) - : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) - : invalidValue(typ, val, key, parent); + : typ.hasOwnProperty("arrayItems") ? transformArray(typ.arrayItems, val) + : typ.hasOwnProperty("props") ? transformObject(getProps(typ), typ.additional, val) + : invalidValue(typ, val, key, parent); } // Numbers can be parsed by Date but shouldn't be. if (typ === Date && typeof val !== "number") return transformDate(val); @@ -5857,3 +5857,981 @@ const typeMap: any = { "raiseIntentResultResponse", ], }; + +export function isWebConnectionProtocol1Hello(value: any): value is WebConnectionProtocol1Hello { + try { + Convert.webConnectionProtocol1HelloToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL1_HELLO_TYPE = "WebConnectionProtocol1Hello"; + +export function isWebConnectionProtocol2LoadURL(value: any): value is WebConnectionProtocol2LoadURL { + try { + Convert.webConnectionProtocol2LoadURLToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL2_LOAD_U_R_L_TYPE = "WebConnectionProtocol2LoadURL"; + +export function isWebConnectionProtocol3Handshake(value: any): value is WebConnectionProtocol3Handshake { + try { + Convert.webConnectionProtocol3HandshakeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL3_HANDSHAKE_TYPE = "WebConnectionProtocol3Handshake"; + +export function isWebConnectionProtocol4ValidateAppIdentity(value: any): value is WebConnectionProtocol4ValidateAppIdentity { + try { + Convert.webConnectionProtocol4ValidateAppIdentityToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL4_VALIDATE_APP_IDENTITY_TYPE = "WebConnectionProtocol4ValidateAppIdentity"; + +export function isWebConnectionProtocol5ValidateAppIdentityFailedResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentityFailedResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentityFailedResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL5_VALIDATE_APP_IDENTITY_FAILED_RESPONSE_TYPE = "WebConnectionProtocol5ValidateAppIdentityFailedResponse"; + +export function isWebConnectionProtocol5ValidateAppIdentitySuccessResponse(value: any): value is WebConnectionProtocol5ValidateAppIdentitySuccessResponse { + try { + Convert.webConnectionProtocol5ValidateAppIdentitySuccessResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL5_VALIDATE_APP_IDENTITY_SUCCESS_RESPONSE_TYPE = "WebConnectionProtocol5ValidateAppIdentitySuccessResponse"; + +export function isWebConnectionProtocol6Goodbye(value: any): value is WebConnectionProtocol6Goodbye { + try { + Convert.webConnectionProtocol6GoodbyeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL6_GOODBYE_TYPE = "WebConnectionProtocol6Goodbye"; + +export function isWebConnectionProtocolMessage(value: any): value is WebConnectionProtocolMessage { + try { + Convert.webConnectionProtocolMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const WEB_CONNECTION_PROTOCOL_MESSAGE_TYPE = "WebConnectionProtocolMessage"; + +export function isAddContextListenerRequest(value: any): value is AddContextListenerRequest { + try { + Convert.addContextListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_CONTEXT_LISTENER_REQUEST_TYPE = "AddContextListenerRequest"; + +export function isAddContextListenerResponse(value: any): value is AddContextListenerResponse { + try { + Convert.addContextListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_CONTEXT_LISTENER_RESPONSE_TYPE = "AddContextListenerResponse"; + +export function isAddEventListenerRequest(value: any): value is AddEventListenerRequest { + try { + Convert.addEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_EVENT_LISTENER_REQUEST_TYPE = "AddEventListenerRequest"; + +export function isAddEventListenerResponse(value: any): value is AddEventListenerResponse { + try { + Convert.addEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_EVENT_LISTENER_RESPONSE_TYPE = "AddEventListenerResponse"; + +export function isAddIntentListenerRequest(value: any): value is AddIntentListenerRequest { + try { + Convert.addIntentListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_INTENT_LISTENER_REQUEST_TYPE = "AddIntentListenerRequest"; + +export function isAddIntentListenerResponse(value: any): value is AddIntentListenerResponse { + try { + Convert.addIntentListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const ADD_INTENT_LISTENER_RESPONSE_TYPE = "AddIntentListenerResponse"; + +export function isAgentEventMessage(value: any): value is AgentEventMessage { + try { + Convert.agentEventMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const AGENT_EVENT_MESSAGE_TYPE = "AgentEventMessage"; + +export function isAgentResponseMessage(value: any): value is AgentResponseMessage { + try { + Convert.agentResponseMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const AGENT_RESPONSE_MESSAGE_TYPE = "AgentResponseMessage"; + +export function isAppRequestMessage(value: any): value is AppRequestMessage { + try { + Convert.appRequestMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const APP_REQUEST_MESSAGE_TYPE = "AppRequestMessage"; + +export function isBroadcastEvent(value: any): value is BroadcastEvent { + try { + Convert.broadcastEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const BROADCAST_EVENT_TYPE = "BroadcastEvent"; + +export function isBroadcastRequest(value: any): value is BroadcastRequest { + try { + Convert.broadcastRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const BROADCAST_REQUEST_TYPE = "BroadcastRequest"; + +export function isBroadcastResponse(value: any): value is BroadcastResponse { + try { + Convert.broadcastResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const BROADCAST_RESPONSE_TYPE = "BroadcastResponse"; + +export function isChannelChangedEvent(value: any): value is ChannelChangedEvent { + try { + Convert.channelChangedEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const CHANNEL_CHANGED_EVENT_TYPE = "ChannelChangedEvent"; + +export function isContextListenerUnsubscribeRequest(value: any): value is ContextListenerUnsubscribeRequest { + try { + Convert.contextListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const CONTEXT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "ContextListenerUnsubscribeRequest"; + +export function isContextListenerUnsubscribeResponse(value: any): value is ContextListenerUnsubscribeResponse { + try { + Convert.contextListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const CONTEXT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "ContextListenerUnsubscribeResponse"; + +export function isCreatePrivateChannelRequest(value: any): value is CreatePrivateChannelRequest { + try { + Convert.createPrivateChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const CREATE_PRIVATE_CHANNEL_REQUEST_TYPE = "CreatePrivateChannelRequest"; + +export function isCreatePrivateChannelResponse(value: any): value is CreatePrivateChannelResponse { + try { + Convert.createPrivateChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const CREATE_PRIVATE_CHANNEL_RESPONSE_TYPE = "CreatePrivateChannelResponse"; + +export function isEventListenerUnsubscribeRequest(value: any): value is EventListenerUnsubscribeRequest { + try { + Convert.eventListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const EVENT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "EventListenerUnsubscribeRequest"; + +export function isEventListenerUnsubscribeResponse(value: any): value is EventListenerUnsubscribeResponse { + try { + Convert.eventListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const EVENT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "EventListenerUnsubscribeResponse"; + +export function isFdc3UserInterfaceChannelSelected(value: any): value is Fdc3UserInterfaceChannelSelected { + try { + Convert.fdc3UserInterfaceChannelSelectedToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE = "Fdc3UserInterfaceChannelSelected"; + +export function isFdc3UserInterfaceChannels(value: any): value is Fdc3UserInterfaceChannels { + try { + Convert.fdc3UserInterfaceChannelsToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_CHANNELS_TYPE = "Fdc3UserInterfaceChannels"; + +export function isFdc3UserInterfaceDrag(value: any): value is Fdc3UserInterfaceDrag { + try { + Convert.fdc3UserInterfaceDragToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_DRAG_TYPE = "Fdc3UserInterfaceDrag"; + +export function isFdc3UserInterfaceHandshake(value: any): value is Fdc3UserInterfaceHandshake { + try { + Convert.fdc3UserInterfaceHandshakeToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_HANDSHAKE_TYPE = "Fdc3UserInterfaceHandshake"; + +export function isFdc3UserInterfaceHello(value: any): value is Fdc3UserInterfaceHello { + try { + Convert.fdc3UserInterfaceHelloToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_HELLO_TYPE = "Fdc3UserInterfaceHello"; + +export function isFdc3UserInterfaceMessage(value: any): value is Fdc3UserInterfaceMessage { + try { + Convert.fdc3UserInterfaceMessageToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_MESSAGE_TYPE = "Fdc3UserInterfaceMessage"; + +export function isFdc3UserInterfaceResolve(value: any): value is Fdc3UserInterfaceResolve { + try { + Convert.fdc3UserInterfaceResolveToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_RESOLVE_TYPE = "Fdc3UserInterfaceResolve"; + +export function isFdc3UserInterfaceResolveAction(value: any): value is Fdc3UserInterfaceResolveAction { + try { + Convert.fdc3UserInterfaceResolveActionToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE = "Fdc3UserInterfaceResolveAction"; + +export function isFdc3UserInterfaceRestyle(value: any): value is Fdc3UserInterfaceRestyle { + try { + Convert.fdc3UserInterfaceRestyleToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FDC3_USER_INTERFACE_RESTYLE_TYPE = "Fdc3UserInterfaceRestyle"; + +export function isFindInstancesRequest(value: any): value is FindInstancesRequest { + try { + Convert.findInstancesRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INSTANCES_REQUEST_TYPE = "FindInstancesRequest"; + +export function isFindInstancesResponse(value: any): value is FindInstancesResponse { + try { + Convert.findInstancesResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INSTANCES_RESPONSE_TYPE = "FindInstancesResponse"; + +export function isFindIntentRequest(value: any): value is FindIntentRequest { + try { + Convert.findIntentRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INTENT_REQUEST_TYPE = "FindIntentRequest"; + +export function isFindIntentResponse(value: any): value is FindIntentResponse { + try { + Convert.findIntentResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INTENT_RESPONSE_TYPE = "FindIntentResponse"; + +export function isFindIntentsByContextRequest(value: any): value is FindIntentsByContextRequest { + try { + Convert.findIntentsByContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INTENTS_BY_CONTEXT_REQUEST_TYPE = "FindIntentsByContextRequest"; + +export function isFindIntentsByContextResponse(value: any): value is FindIntentsByContextResponse { + try { + Convert.findIntentsByContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const FIND_INTENTS_BY_CONTEXT_RESPONSE_TYPE = "FindIntentsByContextResponse"; + +export function isGetAppMetadataRequest(value: any): value is GetAppMetadataRequest { + try { + Convert.getAppMetadataRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_APP_METADATA_REQUEST_TYPE = "GetAppMetadataRequest"; + +export function isGetAppMetadataResponse(value: any): value is GetAppMetadataResponse { + try { + Convert.getAppMetadataResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_APP_METADATA_RESPONSE_TYPE = "GetAppMetadataResponse"; + +export function isGetCurrentChannelRequest(value: any): value is GetCurrentChannelRequest { + try { + Convert.getCurrentChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_CURRENT_CHANNEL_REQUEST_TYPE = "GetCurrentChannelRequest"; + +export function isGetCurrentChannelResponse(value: any): value is GetCurrentChannelResponse { + try { + Convert.getCurrentChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_CURRENT_CHANNEL_RESPONSE_TYPE = "GetCurrentChannelResponse"; + +export function isGetCurrentContextRequest(value: any): value is GetCurrentContextRequest { + try { + Convert.getCurrentContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_CURRENT_CONTEXT_REQUEST_TYPE = "GetCurrentContextRequest"; + +export function isGetCurrentContextResponse(value: any): value is GetCurrentContextResponse { + try { + Convert.getCurrentContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_CURRENT_CONTEXT_RESPONSE_TYPE = "GetCurrentContextResponse"; + +export function isGetInfoRequest(value: any): value is GetInfoRequest { + try { + Convert.getInfoRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_INFO_REQUEST_TYPE = "GetInfoRequest"; + +export function isGetInfoResponse(value: any): value is GetInfoResponse { + try { + Convert.getInfoResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_INFO_RESPONSE_TYPE = "GetInfoResponse"; + +export function isGetOrCreateChannelRequest(value: any): value is GetOrCreateChannelRequest { + try { + Convert.getOrCreateChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_OR_CREATE_CHANNEL_REQUEST_TYPE = "GetOrCreateChannelRequest"; + +export function isGetOrCreateChannelResponse(value: any): value is GetOrCreateChannelResponse { + try { + Convert.getOrCreateChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_OR_CREATE_CHANNEL_RESPONSE_TYPE = "GetOrCreateChannelResponse"; + +export function isGetUserChannelsRequest(value: any): value is GetUserChannelsRequest { + try { + Convert.getUserChannelsRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_USER_CHANNELS_REQUEST_TYPE = "GetUserChannelsRequest"; + +export function isGetUserChannelsResponse(value: any): value is GetUserChannelsResponse { + try { + Convert.getUserChannelsResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const GET_USER_CHANNELS_RESPONSE_TYPE = "GetUserChannelsResponse"; + +export function isHeartbeatAcknowledgementRequest(value: any): value is HeartbeatAcknowledgementRequest { + try { + Convert.heartbeatAcknowledgementRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const HEARTBEAT_ACKNOWLEDGEMENT_REQUEST_TYPE = "HeartbeatAcknowledgementRequest"; + +export function isHeartbeatEvent(value: any): value is HeartbeatEvent { + try { + Convert.heartbeatEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const HEARTBEAT_EVENT_TYPE = "HeartbeatEvent"; + +export function isIntentEvent(value: any): value is IntentEvent { + try { + Convert.intentEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const INTENT_EVENT_TYPE = "IntentEvent"; + +export function isIntentListenerUnsubscribeRequest(value: any): value is IntentListenerUnsubscribeRequest { + try { + Convert.intentListenerUnsubscribeRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const INTENT_LISTENER_UNSUBSCRIBE_REQUEST_TYPE = "IntentListenerUnsubscribeRequest"; + +export function isIntentListenerUnsubscribeResponse(value: any): value is IntentListenerUnsubscribeResponse { + try { + Convert.intentListenerUnsubscribeResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const INTENT_LISTENER_UNSUBSCRIBE_RESPONSE_TYPE = "IntentListenerUnsubscribeResponse"; + +export function isIntentResultRequest(value: any): value is IntentResultRequest { + try { + Convert.intentResultRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const INTENT_RESULT_REQUEST_TYPE = "IntentResultRequest"; + +export function isIntentResultResponse(value: any): value is IntentResultResponse { + try { + Convert.intentResultResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const INTENT_RESULT_RESPONSE_TYPE = "IntentResultResponse"; + +export function isJoinUserChannelRequest(value: any): value is JoinUserChannelRequest { + try { + Convert.joinUserChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const JOIN_USER_CHANNEL_REQUEST_TYPE = "JoinUserChannelRequest"; + +export function isJoinUserChannelResponse(value: any): value is JoinUserChannelResponse { + try { + Convert.joinUserChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const JOIN_USER_CHANNEL_RESPONSE_TYPE = "JoinUserChannelResponse"; + +export function isLeaveCurrentChannelRequest(value: any): value is LeaveCurrentChannelRequest { + try { + Convert.leaveCurrentChannelRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const LEAVE_CURRENT_CHANNEL_REQUEST_TYPE = "LeaveCurrentChannelRequest"; + +export function isLeaveCurrentChannelResponse(value: any): value is LeaveCurrentChannelResponse { + try { + Convert.leaveCurrentChannelResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const LEAVE_CURRENT_CHANNEL_RESPONSE_TYPE = "LeaveCurrentChannelResponse"; + +export function isOpenRequest(value: any): value is OpenRequest { + try { + Convert.openRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const OPEN_REQUEST_TYPE = "OpenRequest"; + +export function isOpenResponse(value: any): value is OpenResponse { + try { + Convert.openResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const OPEN_RESPONSE_TYPE = "OpenResponse"; + +export function isPrivateChannelAddEventListenerRequest(value: any): value is PrivateChannelAddEventListenerRequest { + try { + Convert.privateChannelAddEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_ADD_EVENT_LISTENER_REQUEST_TYPE = "PrivateChannelAddEventListenerRequest"; + +export function isPrivateChannelAddEventListenerResponse(value: any): value is PrivateChannelAddEventListenerResponse { + try { + Convert.privateChannelAddEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_ADD_EVENT_LISTENER_RESPONSE_TYPE = "PrivateChannelAddEventListenerResponse"; + +export function isPrivateChannelDisconnectRequest(value: any): value is PrivateChannelDisconnectRequest { + try { + Convert.privateChannelDisconnectRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_DISCONNECT_REQUEST_TYPE = "PrivateChannelDisconnectRequest"; + +export function isPrivateChannelDisconnectResponse(value: any): value is PrivateChannelDisconnectResponse { + try { + Convert.privateChannelDisconnectResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_DISCONNECT_RESPONSE_TYPE = "PrivateChannelDisconnectResponse"; + +export function isPrivateChannelOnAddContextListenerEvent(value: any): value is PrivateChannelOnAddContextListenerEvent { + try { + Convert.privateChannelOnAddContextListenerEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_ON_ADD_CONTEXT_LISTENER_EVENT_TYPE = "PrivateChannelOnAddContextListenerEvent"; + +export function isPrivateChannelOnDisconnectEvent(value: any): value is PrivateChannelOnDisconnectEvent { + try { + Convert.privateChannelOnDisconnectEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_ON_DISCONNECT_EVENT_TYPE = "PrivateChannelOnDisconnectEvent"; + +export function isPrivateChannelOnUnsubscribeEvent(value: any): value is PrivateChannelOnUnsubscribeEvent { + try { + Convert.privateChannelOnUnsubscribeEventToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_ON_UNSUBSCRIBE_EVENT_TYPE = "PrivateChannelOnUnsubscribeEvent"; + +export function isPrivateChannelUnsubscribeEventListenerRequest(value: any): value is PrivateChannelUnsubscribeEventListenerRequest { + try { + Convert.privateChannelUnsubscribeEventListenerRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_UNSUBSCRIBE_EVENT_LISTENER_REQUEST_TYPE = "PrivateChannelUnsubscribeEventListenerRequest"; + +export function isPrivateChannelUnsubscribeEventListenerResponse(value: any): value is PrivateChannelUnsubscribeEventListenerResponse { + try { + Convert.privateChannelUnsubscribeEventListenerResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const PRIVATE_CHANNEL_UNSUBSCRIBE_EVENT_LISTENER_RESPONSE_TYPE = "PrivateChannelUnsubscribeEventListenerResponse"; + +export function isRaiseIntentForContextRequest(value: any): value is RaiseIntentForContextRequest { + try { + Convert.raiseIntentForContextRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const RAISE_INTENT_FOR_CONTEXT_REQUEST_TYPE = "RaiseIntentForContextRequest"; + +export function isRaiseIntentForContextResponse(value: any): value is RaiseIntentForContextResponse { + try { + Convert.raiseIntentForContextResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const RAISE_INTENT_FOR_CONTEXT_RESPONSE_TYPE = "RaiseIntentForContextResponse"; + +export function isRaiseIntentRequest(value: any): value is RaiseIntentRequest { + try { + Convert.raiseIntentRequestToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const RAISE_INTENT_REQUEST_TYPE = "RaiseIntentRequest"; + +export function isRaiseIntentResponse(value: any): value is RaiseIntentResponse { + try { + Convert.raiseIntentResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const RAISE_INTENT_RESPONSE_TYPE = "RaiseIntentResponse"; + +export function isRaiseIntentResultResponse(value: any): value is RaiseIntentResultResponse { + try { + Convert.raiseIntentResultResponseToJson(value); + return true; + } catch (_e: any) { + return false; + } +} + +export const RAISE_INTENT_RESULT_RESPONSE_TYPE = "RaiseIntentResultResponse"; + +export type RequestMessage = AddContextListenerRequest | AddEventListenerRequest | AddIntentListenerRequest | BroadcastRequest | ContextListenerUnsubscribeRequest | CreatePrivateChannelRequest | EventListenerUnsubscribeRequest | FindInstancesRequest | FindIntentRequest | FindIntentsByContextRequest | GetAppMetadataRequest | GetCurrentChannelRequest | GetCurrentContextRequest | GetInfoRequest | GetOrCreateChannelRequest | GetUserChannelsRequest | HeartbeatAcknowledgementRequest | IntentListenerUnsubscribeRequest | IntentResultRequest | JoinUserChannelRequest | LeaveCurrentChannelRequest | OpenRequest | PrivateChannelAddEventListenerRequest | PrivateChannelDisconnectRequest | PrivateChannelUnsubscribeEventListenerRequest | RaiseIntentForContextRequest | RaiseIntentRequest; + +export type ResponseMessage = WebConnectionProtocol5ValidateAppIdentityFailedResponse | WebConnectionProtocol5ValidateAppIdentitySuccessResponse | AddContextListenerResponse | AddEventListenerResponse | AddIntentListenerResponse | BroadcastResponse | ContextListenerUnsubscribeResponse | CreatePrivateChannelResponse | EventListenerUnsubscribeResponse | FindInstancesResponse | FindIntentResponse | FindIntentsByContextResponse | GetAppMetadataResponse | GetCurrentChannelResponse | GetCurrentContextResponse | GetInfoResponse | GetOrCreateChannelResponse | GetUserChannelsResponse | IntentListenerUnsubscribeResponse | IntentResultResponse | JoinUserChannelResponse | LeaveCurrentChannelResponse | OpenResponse | PrivateChannelAddEventListenerResponse | PrivateChannelDisconnectResponse | PrivateChannelUnsubscribeEventListenerResponse | RaiseIntentForContextResponse | RaiseIntentResponse | RaiseIntentResultResponse; + +export type EventMessage = BroadcastEvent | ChannelChangedEvent | HeartbeatEvent | IntentEvent | PrivateChannelOnAddContextListenerEvent | PrivateChannelOnDisconnectEvent | PrivateChannelOnUnsubscribeEvent; + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/fdc3-schema/package.json b/packages/fdc3-schema/package.json index efc9f94a9..436ec7960 100644 --- a/packages/fdc3-schema/package.json +++ b/packages/fdc3-schema/package.json @@ -19,8 +19,8 @@ "scripts": { "clean": "rimraf dist && rimraf generated", "mkdirs": "mkdirp generated/api && mkdirp generated/bridging", - "generate": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run lint", "generate-type-predicates": "ts-node code-generation/generate-type-predicates.ts", + "generate": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run generate-type-predicates && npm run lint", "generate-new": "npm run mkdirs && npm run typegen-browser && npm run typegen-bridging && npm run generate-type-predicates && npm run lint", "build": "npm run generate && tsc --module es2022", "lint": "eslint generated/ --fix", diff --git a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts index 8ece10b2b..f76850030 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/dummy-desktop-agent.ts @@ -5,7 +5,7 @@ import { DemoServerContext } from "./DemoServerContext"; import { FDC3_2_1_JSONDirectory } from "./FDC3_2_1_JSONDirectory"; import { AppRegistration, DefaultFDC3Server, DirectoryApp, ServerContext } from "@kite9/fdc3-web-impl"; import { ChannelState, ChannelType } from "@kite9/fdc3-web-impl/src/handlers/BroadcastHandler"; -import { link } from "./util"; +import { link, UI, UI_URLS } from "./util"; import { BrowserTypes } from "@kite9/fdc3-schema"; type WebConnectionProtocol2LoadURL = BrowserTypes.WebConnectionProtocol2LoadURL @@ -36,9 +36,9 @@ function getApproach(): Approach { return out; } -enum UI { DEFAULT, DEMO } -function getUi(): UI { + +function getUIKey(): UI { const cb = document.getElementById("ui") as HTMLInputElement; const val = cb.value var out: UI = UI[val as keyof typeof UI]; //Works with --noImplicitAny @@ -104,7 +104,7 @@ window.addEventListener("load", () => { timestamp: new Date() }, payload: { - iframeUrl: window.location.origin + `/static/da/embed.html?connectionAttemptUuid=${data.meta.connectionAttemptUuid}&desktopAgentId=${desktopAgentUUID}&instanceId=${instance?.instanceId}` + iframeUrl: window.location.origin + `/static/da/embed.html?connectionAttemptUuid=${data.meta.connectionAttemptUuid}&desktopAgentId=${desktopAgentUUID}&instanceId=${instance?.instanceId}&UI=${getUIKey()}` } } as WebConnectionProtocol2LoadURL, origin) } else { @@ -114,6 +114,8 @@ window.addEventListener("load", () => { socket.emit(APP_HELLO, desktopAgentUUID, instance.instanceId) + const ui = UI_URLS[getUIKey()] + // sned the other end of the channel to the app source.postMessage({ type: 'WCP3Handshake', @@ -123,8 +125,7 @@ window.addEventListener("load", () => { }, payload: { fdc3Version: "2.2", - intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", - channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + ...ui } }, origin, [channel.port1]) } diff --git a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts index 19ae26ae6..2b25c4976 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/embed.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/embed.ts @@ -1,5 +1,5 @@ import { io } from "socket.io-client" -import { link } from "./util"; +import { link, UI, UI_URLS } from "./util"; import { APP_HELLO } from "../../message-types"; const appWindow = window.parent; @@ -33,6 +33,11 @@ function getDeskopAgentId(): string { return id } +function getUIKey(): UI { + const ui = getQueryVariable("UI") + return parseInt(ui) as UI +} + window.addEventListener("load", () => { @@ -47,6 +52,8 @@ window.addEventListener("load", () => { socket.emit(APP_HELLO, desktopAgentUUID, source) + const ui = UI_URLS[getUIKey()] + // sned the other end of the channel to the app appWindow.postMessage({ type: 'WCP3Handshake', @@ -56,8 +63,7 @@ window.addEventListener("load", () => { }, payload: { fdc3Version: "2.2", - intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", - channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + ...ui } }, "*", [channel.port1]) diff --git a/toolbox/fdc3-for-web/demo/src/client/da/util.ts b/toolbox/fdc3-for-web/demo/src/client/da/util.ts index cedf0af40..716c256b5 100644 --- a/toolbox/fdc3-for-web/demo/src/client/da/util.ts +++ b/toolbox/fdc3-for-web/demo/src/client/da/util.ts @@ -2,15 +2,28 @@ import { InstanceID } from "@kite9/fdc3-web-impl" import { Socket } from "socket.io-client" import { FDC3_APP_EVENT, FDC3_DA_EVENT } from "../../message-types" +export enum UI { DEFAULT, DEMO } + +export const UI_URLS = { + [UI.DEMO]: { + intentResolverUrl: window.location.origin + "/static/da/intent-resolver.html", + channelSelectorUrl: window.location.origin + "/static/da/channel-selector.html", + }, + [UI.DEFAULT]: { + // TODO: REPLACE WITH FDC3.FINOS.ORG URLS AFTER GO-LIVE + intentResolverUrl: "http://localhost:4002/intent_resolver.html", + channelSelectorUrl: "http://localhost:4002/channel_selector.html", + } +} export function link(socket: Socket, channel: MessageChannel, source: InstanceID) { socket.on(FDC3_DA_EVENT, (data: any, to: InstanceID) => { - console.log(`DA Sent ${JSON.stringify(data)} from socket`) + //console.log(`DA Sent ${JSON.stringify(data)} from socket`) channel.port2.postMessage(data) }) channel.port2.onmessage = function (event) { - console.log(`App Sent ${JSON.stringify(event.data)} from message port`) + //console.log(`App Sent ${JSON.stringify(event.data)} from message port`) socket.emit(FDC3_APP_EVENT, event.data, source) } } diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts b/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts index 8f355e528..7446046d1 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/channel-selector.ts @@ -1,4 +1,5 @@ import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeChannels = BrowserTypes.Fdc3UserInterfaceChannels type IframeRestyle = BrowserTypes.Fdc3UserInterfaceRestyle @@ -10,7 +11,7 @@ var channelId: string | null = null const DEFAULT_COLLAPSED_CSS = { position: "fixed", - zIndex: 1000, + zIndex: "1000", right: "10px", bottom: "10px", width: "50px", @@ -19,11 +20,11 @@ const DEFAULT_COLLAPSED_CSS = { const DEFAULT_EXPANDED_CSS = { position: "fixed", - 'z-index': 1000, + zIndex: "1000", right: "10px", bottom: "10px", width: "450px", - 'max-height': "600px", + maxHeight: "600px", transition: "all 0.5s ease-out allow-discrete" } @@ -40,7 +41,7 @@ window.addEventListener("load", () => { parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: DEFAULT_COLLAPSED_CSS, implementationDetails: "Demo Channel Selector v1.0" @@ -49,15 +50,15 @@ window.addEventListener("load", () => { function changeSize(expanded: boolean) { document.body.setAttribute("data-expanded", "" + expanded); - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: expanded ? DEFAULT_EXPANDED_CSS : DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: expanded ? DEFAULT_EXPANDED_CSS : DEFAULT_COLLAPSED_CSS } } as IframeRestyle) } myPort.addEventListener("message", (e) => { console.log(e.data.type) - if (e.data.type == 'iframeHandshake') { + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { // ok, port is ready, send the iframe position detials - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) - } else if (e.data.type == 'fdc3UserInterfaceChannels') { + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + } else if (e.data.type == FDC3_USER_INTERFACE_CHANNELS_TYPE) { const details = e.data as IframeChannels console.log(JSON.stringify("CHANNEL DETAILS: " + JSON.stringify(details))) channels = details.payload.userChannels @@ -86,7 +87,7 @@ window.addEventListener("load", () => { a.onclick = () => { changeSize(false) channelId = channel.id - myPort.postMessage({ type: "fdc3UserInterfaceSelected", payload: { selected: channel.id } }) + myPort.postMessage({ type: FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, payload: { selected: channel.id } }) } }) diff --git a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts index d78df4957..c37bd9edb 100644 --- a/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts +++ b/toolbox/fdc3-for-web/demo/src/client/ui/intent-resolver.ts @@ -1,5 +1,6 @@ import { AppIdentifier } from "@kite9/fdc3-standard"; import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESOLVE_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE } from "@kite9/fdc3-schema/generated/api/BrowserTypes"; type IframeResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction type IframeResolvePayload = BrowserTypes.Fdc3UserInterfaceResolvePayload @@ -8,7 +9,7 @@ type IframeHello = BrowserTypes.Fdc3UserInterfaceHello const DEFAULT_COLLAPSED_CSS = { position: "fixed", - zIndex: 1000, + zIndex: "1000", right: "0", bottom: "0", width: "0", @@ -17,7 +18,7 @@ const DEFAULT_COLLAPSED_CSS = { const DEFAULT_EXPANDED_CSS = { position: "fixed", - 'z-index': 1000, + zIndex: "1000", left: "10%", top: "10%", right: "10%", @@ -34,7 +35,7 @@ window.addEventListener("load", () => { const list = document.getElementById("intent-list")!! parent.postMessage({ - type: "fdc3UserInterfaceHello", + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { initialCSS: DEFAULT_COLLAPSED_CSS, implementationDetails: "Demo Intent Resolver v1.0" @@ -42,11 +43,11 @@ window.addEventListener("load", () => { } as any as IframeHello, "*", [mc.port2]); function callback(intent: string | null, app: AppIdentifier | null) { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) if (intent && app) { myPort.postMessage({ - type: "Fdc3UserInterfaceResolveAction", + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: "click", appIdentifier: app, @@ -55,7 +56,7 @@ window.addEventListener("load", () => { } as IframeResolveAction) } else { myPort.postMessage({ - type: "Fdc3UserInterfaceResolveAction", + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, payload: { action: "cancel" } @@ -64,10 +65,10 @@ window.addEventListener("load", () => { } myPort.addEventListener("message", (e) => { - if (e.data.type == 'iframeHandshake') { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) - } else if (e.data.type == 'iframeResolve') { - myPort.postMessage({ type: "Fdc3UserInterfaceRestyle", payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) + if (e.data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_COLLAPSED_CSS } } as IframeRestyle) + } else if (e.data.type == FDC3_USER_INTERFACE_RESOLVE_TYPE) { + myPort.postMessage({ type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: DEFAULT_EXPANDED_CSS } } as IframeRestyle) Array.from(list.children).forEach(i => i.remove()) const details = e.data.payload as IframeResolvePayload details.appIntents.forEach(intent => { diff --git a/toolbox/fdc3-for-web/demo/src/server/main.ts b/toolbox/fdc3-for-web/demo/src/server/main.ts index bc1fa6f05..fa0855d1c 100644 --- a/toolbox/fdc3-for-web/demo/src/server/main.ts +++ b/toolbox/fdc3-for-web/demo/src/server/main.ts @@ -10,8 +10,8 @@ app.get("/iframe", (_, res) => { }); -const httpServer = ViteExpress.listen(app, 8095, () => - console.log("Server is listening on port 8095..."), +const httpServer = ViteExpress.listen(app, 4000, () => + console.log("Server is listening on port 4000. Head to http://localhost:4000/static/da/index.html"), ); const io = new Server(httpServer) diff --git a/toolbox/fdc3-for-web/demo/static/da/appd.json b/toolbox/fdc3-for-web/demo/static/da/appd.json index 96fea5108..1178bf7d9 100644 --- a/toolbox/fdc3-for-web/demo/static/da/appd.json +++ b/toolbox/fdc3-for-web/demo/static/da/appd.json @@ -7,7 +7,7 @@ "description": "App will connect to the desktop agent and broadcast on the red channel when you hit the button", "type": "web", "details": { - "url": "http://localhost:8095/static/app1/index.html" + "url": "http://localhost:4000/static/app1/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -21,7 +21,7 @@ "description": "App will connect to the desktop agent on startup and listen to messages on the red channel", "type": "web", "details": { - "url": "http://localhost:8095/static/app2/index.html" + "url": "http://localhost:4000/static/app2/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -35,7 +35,7 @@ "description": "App creates two APIs to the desktop agent, broadcasts in one and listens in the other.", "type": "web", "details": { - "url": "http://localhost:8095/static/app3/index.html" + "url": "http://localhost:4000/static/app3/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -46,10 +46,10 @@ "appId": "workbench", "name": "FDC3 Workbench", "title": "FDC3 Workbench", - "description": "Part of the WebFDC3 Demo - Port of the FDC3 Workbench. Must be started separately on localhost:3000", + "description": "Part of the WebFDC3 Demo - Port of the FDC3 Workbench. Must be started separately on localhost:4001", "type": "web", "details": { - "url": "http://localhost:3000/toolbox/fdc3-workbench/" + "url": "http://localhost:4001/toolbox/fdc3-workbench/" }, "hostManifests": {}, "version": "1.0.0", @@ -63,7 +63,7 @@ "description": "Listens for the ViewNews intent only", "type": "web", "details": { - "url": "http://localhost:8095/static/app4/index.html" + "url": "http://localhost:4000/static/app4/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -89,7 +89,7 @@ "description": "Listens for the ViewNews intent only", "type": "web", "details": { - "url": "http://localhost:8095/static/app5/index.html" + "url": "http://localhost:4000/static/app5/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -121,7 +121,7 @@ "description": "App asks for the result of a ViewQuote intent", "type": "web", "details": { - "url": "http://localhost:8095/static/app6/index.html" + "url": "http://localhost:4000/static/app6/index.html" }, "hostManifests": {}, "version": "1.0.0", @@ -135,7 +135,7 @@ "description": "App asks for the result of a ViewNews intent", "type": "web", "details": { - "url": "http://localhost:8095/static/app7/index.html" + "url": "http://localhost:4000/static/app7/index.html" }, "hostManifests": {}, "version": "1.0.0", diff --git a/packages/addon/.gitignore b/toolbox/fdc3-for-web/reference-ui/.gitignore similarity index 100% rename from packages/addon/.gitignore rename to toolbox/fdc3-for-web/reference-ui/.gitignore diff --git a/packages/addon/index.html b/toolbox/fdc3-for-web/reference-ui/index.html similarity index 100% rename from packages/addon/index.html rename to toolbox/fdc3-for-web/reference-ui/index.html diff --git a/packages/addon/package.json b/toolbox/fdc3-for-web/reference-ui/package.json similarity index 80% rename from packages/addon/package.json rename to toolbox/fdc3-for-web/reference-ui/package.json index 86db653ee..cc1f0cbb3 100644 --- a/packages/addon/package.json +++ b/toolbox/fdc3-for-web/reference-ui/package.json @@ -1,5 +1,5 @@ { - "name": "addon", + "name": "fdc3-for-web-reference-ui", "private": true, "version": "2.1.1", "type": "module", @@ -14,6 +14,6 @@ "vite": "^5.2.0" }, "dependencies": { - "@kite9/fdc3": "2.1.1" + "@kite9/fdc3": "2.2.0-beta.29" } } \ No newline at end of file diff --git a/packages/addon/public/channel_selector.html b/toolbox/fdc3-for-web/reference-ui/public/channel_selector.html similarity index 100% rename from packages/addon/public/channel_selector.html rename to toolbox/fdc3-for-web/reference-ui/public/channel_selector.html diff --git a/packages/addon/public/intent_resolver.html b/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html similarity index 99% rename from packages/addon/public/intent_resolver.html rename to toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html index 9c56f9112..b090ad3d5 100644 --- a/packages/addon/public/intent_resolver.html +++ b/toolbox/fdc3-for-web/reference-ui/public/intent_resolver.html @@ -15,7 +15,6 @@ scrollbar-color: #ace; border-radius: 8px; width: fit-content; - position: fixed; bottom: 4px; right: 0; diff --git a/packages/addon/src/channel_selector.ts b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts similarity index 63% rename from packages/addon/src/channel_selector.ts rename to toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts index 5968a277c..951dc4f41 100644 --- a/packages/addon/src/channel_selector.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/channel_selector.ts @@ -1,6 +1,5 @@ import { IframeChannelsPayload, Channel } from "@kite9/fdc3-common"; - - +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE, FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, Fdc3UserInterfaceHello, Fdc3UserInterfaceRestyle, isFdc3UserInterfaceChannels, isFdc3UserInterfaceHandshake } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; const fillChannels = (data: Channel[], selected: string | null, messageClickedChannel: (s: string | null) => void) => { const list = document.getElementById('list')!!; @@ -48,34 +47,32 @@ window.addEventListener("load", () => { myPort.start(); myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); - switch (data.type) { - case "iframeHandshake": { - collapse(); - break; - } - case "fdc3UserInterfaceChannels": { - logo.removeEventListener("click", expand); - const { userChannels, selected } = data.payload as IframeChannelsPayload; - fillChannels(userChannels, selected, (channelStr) => { - myPort.postMessage({ - type: "fdc3UserInterfaceSelected", - payload: { - selected: channelStr || null - } - }); - collapse(); + + if (data.type == FDC3_USER_INTERFACE_HANDSHAKE_TYPE) { + collapse(); + } else if (data.type == FDC3_USER_INTERFACE_CHANNELS_TYPE) { + logo.removeEventListener("click", expand); + const { userChannels, selected } = data.payload as IframeChannelsPayload; + fillChannels(userChannels, selected, (channelStr) => { + myPort.postMessage({ + type: FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, + payload: { + selected: channelStr || null + } }); - const selectedChannel = userChannels.find((c) => c.id === selected); - logo.style.fill = selectedChannel?.displayMetadata?.color ?? "white"; - logo.addEventListener("click", expand); - break; - } + collapse(); + }); + const selectedChannel = userChannels.find((c) => c.id === selected); + logo.style.fill = selectedChannel?.displayMetadata?.color ?? "white"; + console.log("Adding event listener") + logo.addEventListener("click", expand); } }; - parent.postMessage({ - type: "fdc3UserInterfaceHello", + const helloMessage: Fdc3UserInterfaceHello = { + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { + implementationDetails: "", initialCSS: { width: `${8 * 4}px`, height: `${8 * 5}px`, @@ -87,29 +84,31 @@ window.addEventListener("load", () => { } } - }, "*", [mc.port2]); + } + parent.postMessage(helloMessage, "*", [mc.port2]); const expand = () => { document.body.setAttribute("data-expanded", "true"); - myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { width: `100%`, height: `100%`, - top: 0, - left: 0, + top: "0", + left: "0", zIndex: "1000", "z-index": "1000", position: "fixed" } } - }); + } + myPort.postMessage(restyleMessage); } const collapse = () => { - myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { width: `${8 * 4}px`, @@ -121,7 +120,8 @@ window.addEventListener("load", () => { position: "fixed" } } - }); + } + myPort.postMessage(restyleMessage); // If you immediately change to the logo, before the iframe has a chance to finish restyling, // you see a flicker of a giant, colored logo. diff --git a/packages/addon/src/intent_resolver.ts b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts similarity index 66% rename from packages/addon/src/intent_resolver.ts rename to toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts index f8f0c92b2..a19b59924 100644 --- a/packages/addon/src/intent_resolver.ts +++ b/toolbox/fdc3-for-web/reference-ui/src/intent_resolver.ts @@ -1,16 +1,21 @@ import { Icon } from "@kite9/fdc3"; import { AppIntent } from "@kite9/fdc3"; -import { IframeResolveActionPayload, IframeResolvePayload } from "@kite9/fdc3-common"; +import { BrowserTypes } from "@kite9/fdc3-schema"; +import { FDC3_USER_INTERFACE_HELLO_TYPE, FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, FDC3_USER_INTERFACE_RESTYLE_TYPE, isFdc3UserInterfaceResolve } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; -const setup = (data: IframeResolvePayload, callback: (s: IframeResolveActionPayload) => void) => { +type Fdc3UserInterfaceHello = BrowserTypes.Fdc3UserInterfaceHello; +type Fdc3UserInterfaceRestyle = BrowserTypes.Fdc3UserInterfaceRestyle; +type Fdc3UserInterfaceResolve = BrowserTypes.Fdc3UserInterfaceResolve; +type Fdc3UserInterfaceResolveAction = BrowserTypes.Fdc3UserInterfaceResolveAction; + + +const setup = (data: Fdc3UserInterfaceResolve["payload"], callback: (payload: Fdc3UserInterfaceResolveAction["payload"]) => void) => { document.body.setAttribute("data-visible", "true"); document.querySelector("dialog")?.showModal(); - console.log("setup data:", data); - const intentSelect = document.getElementById("displayIntent") as HTMLSelectElement - const justIntents = data.appIntents.map(({intent}) => intent) + const justIntents = data.appIntents.map(({ intent }) => intent) const doneIntents = new Set() justIntents.forEach(({ name, displayName }) => { @@ -51,8 +56,6 @@ const setup = (data: IframeResolvePayload, callback: (s: IframeResolveActionPayl action: "cancel" }); }); - - console.log(document.body); } function createIcon(icons: Icon[] | undefined): HTMLElement { @@ -66,7 +69,7 @@ function createIcon(icons: Icon[] | undefined): HTMLElement { return img } -const fillList = (ai: AppIntent[], intent: string, callback: (s: IframeResolveActionPayload) => void) => { +const fillList = (ai: AppIntent[], intent: string, callback: (payload: Fdc3UserInterfaceResolveAction["payload"]) => void) => { const allApps = ai.flatMap(a => a.apps) const openApps = allApps.filter(a => a.instanceId) const newApps = allApps.filter(a => !a.instanceId) @@ -116,7 +119,7 @@ const fillList = (ai: AppIntent[], intent: string, callback: (s: IframeResolveAc const openList = document.getElementById('open-list')!! openList.innerHTML = ''; - openApps.forEach(({ appId, title, icons, instanceId }) => { + openApps.forEach(({ appId, title, icons }) => { const node = document.createElement('div'); node.setAttribute('tabIndex', '0'); node.setAttribute("data-appId", appId); @@ -160,56 +163,57 @@ window.addEventListener("load", () => { const mc = new MessageChannel(); const myPort = mc.port1; myPort.start(); - myPort.onmessage = ({data}) => { + myPort.onmessage = ({ data }) => { console.debug("Received message: ", data); - switch(data.type){ - case Fdc3UserInterfaceHandshake": { - break; + if (isFdc3UserInterfaceResolve(data)) { + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, + payload: { + updatedCSS: { + width: "100%", + height: "100%", + top: "0", + left: "0", + position: "fixed" + } + } } - case "iframeResolve": { - myPort.postMessage({ - type: "iframeRestyle", + myPort.postMessage(restyleMessage); + + setup(data.payload, (payload) => { + document.querySelector("dialog")?.close(); + const resolveAction: Fdc3UserInterfaceResolveAction = { + type: FDC3_USER_INTERFACE_RESOLVE_ACTION_TYPE, + payload + } + myPort.postMessage(resolveAction); + + const restyleMessage: Fdc3UserInterfaceRestyle = { + type: FDC3_USER_INTERFACE_RESTYLE_TYPE, payload: { updatedCSS: { - width: "100%", - height: "100%", - top: "0", - left: "0", - position: "fixed" + width: "0", + height: "0" } } - }); - - setup(data.payload, (s) => { - document.querySelector("dialog")?.close(); - myPort.postMessage({ - type: "iframeResolveAction", - payload: s - }); - - myPort.postMessage({ - type: "fdc3UserInterfaceRestyle", - payload: { - updatedCSS: { - width: "0", - height: "0" - } - } - }); + } - }) - } + myPort.postMessage(restyleMessage); + + }) } + }; - parent.postMessage({ - type: "fdc3UserInterfaceHello", + const helloMessage: Fdc3UserInterfaceHello = { + type: FDC3_USER_INTERFACE_HELLO_TYPE, payload: { + implementationDetails: "", initialCSS: { width: "0", height: "0" } } - }, "*", [mc.port2]); - + } + parent.postMessage(helloMessage, "*", [mc.port2]); }); \ No newline at end of file diff --git a/toolbox/fdc3-for-web/reference-ui/src/main.ts b/toolbox/fdc3-for-web/reference-ui/src/main.ts new file mode 100644 index 000000000..eee97452c --- /dev/null +++ b/toolbox/fdc3-for-web/reference-ui/src/main.ts @@ -0,0 +1,198 @@ +import { FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE, FDC3_USER_INTERFACE_CHANNELS_TYPE, FDC3_USER_INTERFACE_HANDSHAKE_TYPE } from "@kite9/fdc3-schema/dist/generated/api/BrowserTypes"; +import "./style.css"; + +// Channel data +const recommendedChannels = [ + { + id: 'fdc3.channel.1', + type: 'user', + displayMetadata: { + name: 'Channel 1', + color: 'red', + glyph: '1', + }, + }, + { + id: 'fdc3.channel.2', + type: 'user', + displayMetadata: { + name: 'Channel 2', + color: 'orange', + glyph: '2', + }, + }, + { + id: 'fdc3.channel.3', + type: 'user', + displayMetadata: { + name: 'Channel 3', + color: 'yellow', + glyph: '3', + }, + }, + { + id: 'fdc3.channel.4', + type: 'user', + displayMetadata: { + name: 'Channel 4', + color: 'green', + glyph: '4', + }, + }, + { + id: 'fdc3.channel.5', + type: 'user', + displayMetadata: { + name: 'Channel 5', + color: 'cyan', + glyph: '5', + }, + }, + { + id: 'fdc3.channel.6', + type: 'user', + displayMetadata: { + name: 'Channel 6', + color: 'blue', + glyph: '6', + }, + }, + { + id: 'fdc3.channel.7', + type: 'user', + displayMetadata: { + name: 'Channel 7', + color: 'magenta', + glyph: '7', + }, + }, + { + id: 'fdc3.channel.8', + type: 'user', + displayMetadata: { + name: 'Channel 8', + color: 'purple', + glyph: '8', + }, + }, +]; + +// Example resolver data +const exampleResolverData = { + type: "ResolverIntents", + appIntents: [ + { + apps: [{ + appId: "trading-view-chart", + description: "TradingView is a social network for traders and investors on Stock, Futures and Forex markets!", + icons: [{ + src: "https://apps.connectifi-interop.com/tradingviewChart/icon.png" + }], + title: "TradingView Chart" + }, { + appId: "adaptabledemo", + instanceId: "324587329238y7r59824", + description: "AdapTable is a powerful data grid with a range of advanced features", + icons: [{ + src: "https://apps.connectifi-interop.com/adaptableDemo/icon.png" + }], + title: "AdapTable" + }], + intent: { + name: "ViewInstrument", + displayName: "View Instrument" + }, + }], + source: { + appId: "fdc3-demo", + instanceId: "fdc3-demo-instance" + } +}; + +let selected = recommendedChannels[2].id; +let expanded = true; + +const openChannelIframe = (e: MouseEvent) => { + const channel = new MessageChannel(); + + // STEP 2B: Receive confirmation over port from iframe + channel.port1.onmessage = ({ data }) => { + switch (data.type) { + + // User clicked on one of the channels in the channel selector + // @ts-ignore: Explicit fall-through to Fdc3UserInterfaceHandshake + case FDC3_USER_INTERFACE_CHANNEL_SELECTED_TYPE: { + // STEP 4B: Receive user selection information from iframe + selected = data.channel; + } + + // Handshake completed. Send channel data to iframe + case FDC3_USER_INTERFACE_HANDSHAKE_TYPE: { + // STEP 3A: Send channel data to iframe + channel.port1.postMessage({ + type: FDC3_USER_INTERFACE_CHANNELS_TYPE, + channels: recommendedChannels, + selected + }); + break; + } + + } + + }; + + const { target } = e; + if (target) (target as HTMLButtonElement).disabled = true; + + const iframe = document.querySelector("#channel-iframe")!; + iframe.parentElement?.setAttribute("data-visible", "true"); + + const resizeButton = document.getElementById("dimensions-btn-channel")!; + resizeButton.setAttribute("data-visible", "true"); + resizeButton.addEventListener("click", () => { + expanded = !expanded; + channel.port1.postMessage({ type: "Fdc3UserInterfaceChannelResize", expanded }) + iframe.setAttribute("data-expanded", `${expanded}`); + resizeButton.textContent = expanded ? "Collapse" : "Expand"; + }); + + // STEP 1A: Send port to iframe + iframe.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); +}; + +const openResolverIframe = (e: MouseEvent) => { + const channel = new MessageChannel(); + + // STEP 2B: Receive confirmation over port from iframe + channel.port1.onmessage = ({ data }) => { + switch (data.type) { + case "Fdc3UserInterfaceHandshake": { + // STEP 3A: Send channel data to iframe + channel.port1.postMessage(exampleResolverData); + break; + } + case "Fdc3UserInterfaceResolveAction": + case "Fdc3UserInterfaceResolve": { + // STEP 4B: Receive user selection information from iframe + + // TODO - prettyPrintJson dependency is not referenced, re-enable when added + // document.getElementById('resolver-user-selection')!.innerHTML = prettyPrintJson.toHtml(data); + break; + } + } + + }; + const { target } = e; + if (target) (target as HTMLButtonElement).disabled = true; + + const iframe = document.querySelector("#resolver-iframe"); + iframe!.parentElement?.setAttribute("data-visible", "true"); + + // STEP 1A: Send port to iframe + iframe!.contentWindow?.postMessage({ type: 'Fdc3UserInterfaceHello' }, '*', [channel.port2]); +}; + +window.addEventListener('load', () => { + document.getElementById('send-btn-channel')!.addEventListener('click', openChannelIframe); + document.getElementById('send-btn-resolver')!.addEventListener('click', openResolverIframe); +}); \ No newline at end of file diff --git a/packages/addon/src/style.css b/toolbox/fdc3-for-web/reference-ui/src/style.css similarity index 100% rename from packages/addon/src/style.css rename to toolbox/fdc3-for-web/reference-ui/src/style.css diff --git a/packages/addon/src/vite-env.d.ts b/toolbox/fdc3-for-web/reference-ui/src/vite-env.d.ts similarity index 100% rename from packages/addon/src/vite-env.d.ts rename to toolbox/fdc3-for-web/reference-ui/src/vite-env.d.ts diff --git a/packages/addon/tsconfig.json b/toolbox/fdc3-for-web/reference-ui/tsconfig.json similarity index 100% rename from packages/addon/tsconfig.json rename to toolbox/fdc3-for-web/reference-ui/tsconfig.json diff --git a/packages/addon/vite.config.ts b/toolbox/fdc3-for-web/reference-ui/vite.config.ts similarity index 64% rename from packages/addon/vite.config.ts rename to toolbox/fdc3-for-web/reference-ui/vite.config.ts index cd4d40fc9..cbce46b87 100644 --- a/packages/addon/vite.config.ts +++ b/toolbox/fdc3-for-web/reference-ui/vite.config.ts @@ -2,5 +2,8 @@ import { defineConfig } from "vite"; // https://vitejs.dev/config/ export default defineConfig({ - server: { port: 4000 }, + server: { port: 4002 }, + build: { + outDir: "dist" + } }); diff --git a/toolbox/fdc3-workbench/vite.config.ts b/toolbox/fdc3-workbench/vite.config.ts index bdd86f646..635920097 100644 --- a/toolbox/fdc3-workbench/vite.config.ts +++ b/toolbox/fdc3-workbench/vite.config.ts @@ -22,5 +22,5 @@ export default defineConfig({ targets: ["defaults", "not IE 11"], }), ], - server: { port: 3000 }, + server: { port: 4001 }, });