diff --git a/.gitignore b/.gitignore index 236ce59..d7802a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ node_modules -/build \ No newline at end of file +/package-lock.json +/.vscode-test/ +/build/ \ No newline at end of file diff --git a/.vscode-test.js b/.vscode-test.js new file mode 100644 index 0000000..ecde832 --- /dev/null +++ b/.vscode-test.js @@ -0,0 +1,9 @@ +// .vscode-test.js +const { defineConfig } = require('@vscode/test-cli'); + +module.exports = defineConfig([ + { + label: 'unitTests', + files: 'build/src/test/**/*.test.js', + } +]); \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index c774552..d120b59 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,6 +5,7 @@ { "version": "0.2.0", "configurations": [ + { "name": "Run Extension", "type": "extensionHost", @@ -20,7 +21,9 @@ "args": [ "--extensionDevelopmentPath=${workspaceFolder}", "--extensionTestsPath=${workspaceFolder}/test/suite/index" - ] + ], + "outFiles": ["${workspaceFolder}/build/**.js"], + "preLaunchTask": "npm: test-compile" } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..cad7657 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "cmake.configureOnOpen": false +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore index a775644..a5b7de8 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -7,3 +7,4 @@ vsc-extension-quickstart.md **/jsconfig.json **/*.map **/.eslintrc.json +**/*.js.map diff --git a/package-lock.json b/package-lock.json index 342ca40..1e41227 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7,6 +7,7 @@ "": { "name": "react-labyrinth", "version": "0.0.1", + "license": "MIT", "dependencies": { "@babel/core": "^7.23.3", "@babel/parser": "^7.23.4", @@ -15,29 +16,35 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", + "ts-loader": "^9.5.1", "webpack": "^5.89.0" }, "devDependencies": { + "@types/glob": "^8.1.0", "@types/mocha": "^10.0.3", "@types/node": "18.x", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", - "@vscode/test-electron": "^2.3.6", + "@vscode/test-cli": "^0.0.4", + "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", "glob": "^10.3.10", "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", "tailwindcss": "^3.3.6", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "webpack-cli": "^5.1.4" }, "engines": { - "vscode": "^1.84.0" + "vscode": "^1.85.1" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -3413,11 +3420,27 @@ "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.13.tgz", "integrity": "sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ==" }, + "node_modules/@types/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==", + "dev": true, + "dependencies": { + "@types/minimatch": "^5.1.2", + "@types/node": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true + }, "node_modules/@types/mocha": { "version": "10.0.4", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-10.0.4.tgz", @@ -3432,10 +3455,42 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/prop-types": { + "version": "15.7.11", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz", + "integrity": "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.2.45", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.2.45.tgz", + "integrity": "sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==", + "dev": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.2.18", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.2.18.tgz", + "integrity": "sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/scheduler": { + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.8.tgz", + "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==", + "dev": true + }, "node_modules/@types/vscode": { - "version": "1.84.1", - "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.84.1.tgz", - "integrity": "sha512-DB10vBRLEPA/us7p3gQilU2Tq5HDu6JWTyCpD9qtb7MKWIvJS5In9HU3YgVGCXf/miwHJiY62aXwjtUSMpT8HA==", + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.85.0.tgz", + "integrity": "sha512-CF/RBon/GXwdfmnjZj0WTUMZN5H6YITOfBCP4iEZlOtVQXuzw6t7Le7+cR+7JzdMrnlm7Mfp49Oj2TuSXIWo3g==", "dev": true }, "node_modules/@ungap/structured-clone": { @@ -3444,10 +3499,142 @@ "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", "dev": true }, + "node_modules/@vscode/test-cli": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@vscode/test-cli/-/test-cli-0.0.4.tgz", + "integrity": "sha512-Tx0tfbxeSb2Xlo+jpd+GJrNLgKQHobhRHrYvOipZRZQYWZ82sKiK02VY09UjU1Czc/YnZnqyAnjUfaVGl3h09w==", + "dev": true, + "dependencies": { + "@types/mocha": "^10.0.2", + "chokidar": "^3.5.3", + "glob": "^10.3.10", + "minimatch": "^9.0.3", + "mocha": "^10.2.0", + "supports-color": "^9.4.0", + "yargs": "^17.7.2" + }, + "bin": { + "vscode-test": "out/bin.mjs" + } + }, + "node_modules/@vscode/test-cli/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@vscode/test-cli/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vscode/test-cli/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/@vscode/test-cli/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@vscode/test-cli/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@vscode/test-cli/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@vscode/test-cli/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@vscode/test-cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@vscode/test-electron": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.6.tgz", - "integrity": "sha512-M31xGH0RgqNU6CZ4/9g39oUMJ99nLzfjA+4UbtIQ6TcXQ6+2qkjOOxedmPBDDCg26/3Al5ubjY80hIoaMwKYSw==", + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz", + "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==", "dev": true, "dependencies": { "http-proxy-agent": "^4.0.1", @@ -3765,7 +3952,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -3993,7 +4179,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -4096,7 +4281,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4226,7 +4410,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -4237,8 +4420,7 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "node_modules/colorette": { "version": "2.0.20", @@ -4451,6 +4633,97 @@ "node": ">=4" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==", + "dev": true + }, + "node_modules/d3": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz", + "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==", + "dependencies": { + "d3-array": "3", + "d3-axis": "3", + "d3-brush": "3", + "d3-chord": "3", + "d3-color": "3", + "d3-contour": "4", + "d3-delaunay": "6", + "d3-dispatch": "3", + "d3-drag": "3", + "d3-dsv": "3", + "d3-ease": "3", + "d3-fetch": "3", + "d3-force": "3", + "d3-format": "3", + "d3-geo": "3", + "d3-hierarchy": "3", + "d3-interpolate": "3", + "d3-path": "3", + "d3-polygon": "3", + "d3-quadtree": "3", + "d3-random": "3", + "d3-scale": "4", + "d3-scale-chromatic": "3", + "d3-selection": "3", + "d3-shape": "3", + "d3-time": "3", + "d3-time-format": "4", + "d3-timer": "3", + "d3-transition": "3", + "d3-zoom": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-array": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz", + "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==", + "dependencies": { + "internmap": "1 - 2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-axis": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz", + "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-brush": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz", + "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-drag": "2 - 3", + "d3-interpolate": "1 - 3", + "d3-selection": "3", + "d3-transition": "3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-chord": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz", + "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==", + "dependencies": { + "d3-path": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-color": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", @@ -4459,6 +4732,28 @@ "node": ">=12" } }, + "node_modules/d3-contour": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz", + "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==", + "dependencies": { + "d3-array": "^3.2.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-delaunay": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz", + "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==", + "dependencies": { + "delaunator": "5" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-dispatch": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz", @@ -4479,6 +4774,38 @@ "node": ">=12" } }, + "node_modules/d3-dsv": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz", + "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==", + "dependencies": { + "commander": "7", + "iconv-lite": "0.6", + "rw": "1" + }, + "bin": { + "csv2json": "bin/dsv2json.js", + "csv2tsv": "bin/dsv2dsv.js", + "dsv2dsv": "bin/dsv2dsv.js", + "dsv2json": "bin/dsv2json.js", + "json2csv": "bin/json2dsv.js", + "json2dsv": "bin/json2dsv.js", + "json2tsv": "bin/json2dsv.js", + "tsv2csv": "bin/dsv2dsv.js", + "tsv2json": "bin/dsv2json.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-dsv/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/d3-ease": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz", @@ -4487,6 +4814,57 @@ "node": ">=12" } }, + "node_modules/d3-fetch": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz", + "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==", + "dependencies": { + "d3-dsv": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-force": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz", + "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==", + "dependencies": { + "d3-dispatch": "1 - 3", + "d3-quadtree": "1 - 3", + "d3-timer": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-format": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz", + "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-geo": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz", + "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==", + "dependencies": { + "d3-array": "2.5.0 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-hierarchy": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz", + "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==", + "engines": { + "node": ">=12" + } + }, "node_modules/d3-interpolate": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz", @@ -4498,6 +4876,65 @@ "node": ">=12" } }, + "node_modules/d3-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz", + "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-polygon": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz", + "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-quadtree": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz", + "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-random": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz", + "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==", + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz", + "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==", + "dependencies": { + "d3-array": "2.10.0 - 3", + "d3-format": "1 - 3", + "d3-interpolate": "1.2.0 - 3", + "d3-time": "2.1.1 - 3", + "d3-time-format": "2 - 4" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-scale-chromatic": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz", + "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==", + "dependencies": { + "d3-color": "1 - 3", + "d3-interpolate": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-selection": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz", @@ -4506,6 +4943,39 @@ "node": ">=12" } }, + "node_modules/d3-shape": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz", + "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==", + "dependencies": { + "d3-path": "^3.1.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz", + "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==", + "dependencies": { + "d3-array": "2 - 3" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/d3-time-format": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz", + "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==", + "dependencies": { + "d3-time": "1 - 3" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/d3-timer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz", @@ -4581,6 +5051,14 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/delaunator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz", + "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==", + "dependencies": { + "robust-predicates": "^3.0.0" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -4914,7 +5392,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -5200,6 +5677,17 @@ "node": ">= 6" } }, + "node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/icss-utils": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", @@ -5350,6 +5838,14 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internmap": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz", + "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==", + "engines": { + "node": ">=12" + } + }, "node_modules/interpret": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", @@ -5422,7 +5918,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -5760,7 +6255,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -6170,7 +6664,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, "engines": { "node": ">=8.6" }, @@ -7468,6 +7961,11 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/robust-predicates": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz", + "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -7491,11 +7989,21 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==" + }, "node_modules/safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + }, "node_modules/sass-loader": { "version": "13.3.2", "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-13.3.2.tgz", @@ -7848,7 +8356,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -8009,7 +8516,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8023,6 +8529,33 @@ "integrity": "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==", "dev": true }, + "node_modules/ts-loader": { + "version": "9.5.1", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.1.tgz", + "integrity": "sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg==", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8048,9 +8581,9 @@ } }, "node_modules/typescript": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", - "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", + "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "dev": true, "bin": { "tsc": "bin/tsc", diff --git a/package.json b/package.json index b392c05..df5c50b 100644 --- a/package.json +++ b/package.json @@ -3,22 +3,31 @@ "displayName": "React Labyrinth", "description": "React Server Components visualization tool", "version": "0.0.1", + "publisher": "ReactLabyrinthDev", "engines": { - "vscode": "^1.84.0" + "vscode": "^1.85.1" + }, + "repository": { + "type": "git", + "url": "https://github.com/oslabs-beta/React-Labyrinth" }, "categories": [ "Other" ], + "keywords": [ + "react", + "rsc", + "hierarchy tree", + "parent-child", + "visualizer", + "server component" + ], + "license": "MIT", "pricing": "Free", "activationEvents": [], - "main": "./extension.js", + "main": "./build/extension.js", "contributes": { "commands": [ - { - "command": "react-labyrinth.helloWorld", - "title": "Hello World", - "category": "React Labyrinth" - }, { "command": "myExtension.showPanel", "title": "Show Panel", @@ -61,22 +70,27 @@ "scripts": { "lint": "eslint .", "pretest": "npm run lint", - "test": "node ./test/runTest.js", + "test": "node ./build/src/test/runTest.js", + "test1": "vscode-test", "dev": "webpack --watch", "webpack": "webpack" }, "devDependencies": { + "@types/glob": "^8.1.0", "@types/mocha": "^10.0.3", "@types/node": "18.x", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", "@types/vscode": "^1.84.0", - "@vscode/test-electron": "^2.3.6", + "@vscode/test-cli": "^0.0.4", + "@vscode/test-electron": "^2.3.8", "eslint": "^8.54.0", "glob": "^10.3.10", "mocha": "^10.2.0", "postcss-loader": "^7.3.3", "postcss-preset-env": "^9.3.0", "tailwindcss": "^3.3.6", - "typescript": "^5.2.2", + "typescript": "^5.3.3", "webpack-cli": "^5.1.4" }, "dependencies": { @@ -87,11 +101,13 @@ "babel": "^6.23.0", "babel-loader": "^9.1.3", "css-loader": "^6.8.1", + "d3": "^7.8.5", "react": "^18.2.0", "react-dom": "^18.2.0", "reactflow": "^11.10.1", "sass-loader": "^13.3.2", "style-loader": "^3.3.3", + "ts-loader": "^9.5.1", "webpack": "^5.89.0" } } diff --git a/postcss.config.js b/postcss.config.cjs similarity index 99% rename from postcss.config.js rename to postcss.config.cjs index dbcca66..df3813f 100644 --- a/postcss.config.js +++ b/postcss.config.cjs @@ -1,4 +1,5 @@ const tailwindcss = require('tailwindcss'); + module.exports = { plugins: [ 'postcss-preset-env', diff --git a/extension.js b/src/extension.ts similarity index 62% rename from extension.js rename to src/extension.ts index fe5541b..0d034e6 100644 --- a/extension.js +++ b/src/extension.ts @@ -1,37 +1,43 @@ -const vscode = require('vscode'); -const { createPanel } = require('./src/panel'); -const { Parser } = require('./src/parser'); +import * as vscode from 'vscode'; +import {createPanel} from './panel'; +import { Parser } from './parser'; // This method is called when your extension is activated // Your extension is activated the very first time the command is executed -function activate(context) { +function activate(context: vscode.ExtensionContext) { let disposable = vscode.commands.registerCommand('react-labyrinth.helloWorld', function () { vscode.window.showInformationMessage('Hello World from React Labyrinth!'); }); // pass in the command we want to register (refer to package.json) - let result = vscode.commands.registerCommand('myExtension.showPanel', () => { - // call helper func - createPanel(context); - }); + // let result = vscode.commands.registerCommand('myExtension.showPanel', () => { + // // call helper func + // createPanel(context); + // }); vscode.commands.registerCommand('myExtension.pickFile', async () => { const fileArray = await vscode.window.showOpenDialog({ canSelectFolders: false, canSelectFiles: true, canSelectMany: false }); + + if (!fileArray || fileArray.length === 0) { + vscode.window.showErrorMessage('No file selected'); + return; + } + const tree = new Parser(fileArray[0].path); tree.parse(); const data = tree.getTree(); console.log('Data sent back: \n', data); createPanel(context, data); }); - context.subscriptions.push(disposable, result); + context.subscriptions.push(disposable); } // This method is called when your extension is deactivated -// function deactivate() {} +function deactivate() {} module.exports = { activate, - // deactivate + deactivate } diff --git a/src/getNonce.js b/src/getNonce.ts similarity index 69% rename from src/getNonce.js rename to src/getNonce.ts index bd01ad0..dafd778 100644 --- a/src/getNonce.js +++ b/src/getNonce.ts @@ -1,6 +1,6 @@ -function getNonce() { - let text = ""; - const possible = +export function getNonce() { + let text: string = ""; + const possible: string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; for (let i = 0; i < 32; i++) { text += possible.charAt(Math.floor(Math.random() * possible.length)); @@ -8,4 +8,3 @@ function getNonce() { return text; } -module.exports = { getNonce } \ No newline at end of file diff --git a/src/panel.js b/src/panel.ts similarity index 85% rename from src/panel.js rename to src/panel.ts index 2328f6c..606db1e 100644 --- a/src/panel.js +++ b/src/panel.ts @@ -1,8 +1,8 @@ -const vscode = require('vscode'); -const { getNonce } = require('./getNonce.js'); -const { Parser } = require('./parser.js'); +import * as vscode from 'vscode'; +import { getNonce } from './getNonce'; +import { Tree } from './types/tree'; -function createPanel(context, data) { +export function createPanel(context: vscode.ExtensionContext, data: Tree) { // if the current panel exists, then reveal the column, else make one? // utilize method on vscode.window object to create webview @@ -30,18 +30,17 @@ function createPanel(context, data) { // will need to use onDidDispose to clear cached data and reset tree when the webview and/or application is closed panel.webview.onDidReceiveMessage( - async (msg) => { + async (msg: any) => { switch (msg.type) { case 'onData': if (!msg.value) break; - context.workspaceState = context.workspaceState || {}; context.workspaceState.update('reactLabyrinth', msg.value); // console.log('msg.value from panel.js: ', msg.value); panel.webview.postMessage( { type: 'parsed-data', value: msg.value, // tree object - settings: await vscode.workspace.getConfiguration('reactLabyrinth') + settings: vscode.workspace.getConfiguration('reactLabyrinth') }); break; @@ -56,7 +55,7 @@ function createPanel(context, data) { const nonce = getNonce(); // function to create the HTML page for webview -function createWebviewHTML(URI, initialData) { +function createWebviewHTML(URI: vscode.Uri, initialData: Tree) { return ( ` @@ -83,5 +82,3 @@ function createWebviewHTML(URI, initialData) { ` ) } - -module.exports = { createPanel }; \ No newline at end of file diff --git a/src/parser.js b/src/parser.ts similarity index 86% rename from src/parser.js rename to src/parser.ts index 4b8982b..eb0bc32 100644 --- a/src/parser.js +++ b/src/parser.ts @@ -1,7 +1,10 @@ -const fs = require('fs') -const path = require('path') -const babel = require('@babel/parser'); -const { getNonce } = require('./getNonce.js'); +import * as fs from 'fs'; +import * as path from 'path'; +import * as babel from '@babel/parser'; +import { getNonce } from './getNonce'; +import { ImportObj } from './types/ImportObj'; +import { Tree } from "./types/tree"; +import { File } from '@babel/types'; // // function to determine server or client component (can look for 'use client' and 'hooks') // // input: ast node (object) @@ -25,8 +28,11 @@ const { getNonce } = require('./getNonce.js'); // return false; // } -class Parser { - constructor(filePath) { +export class Parser { + entryFile: string; + tree: Tree | undefined; + + constructor(filePath: string) { // Fix when selecting files in wsl file system this.entryFile = filePath; if (process.platform === 'linux' && this.entryFile.includes('wsl$')) { @@ -50,7 +56,7 @@ class Parser { } // method to generate component tree based on current entryFile - parse() { + public parse(): Tree { // Create root Tree node const root = { id: getNonce(), @@ -65,6 +71,7 @@ class Parser { reactRouter: false, reduxConnect: false, children: [], + parent: null, parentList: [], props: {}, error: '', @@ -75,25 +82,25 @@ class Parser { return this.tree; } - getTree() { + public getTree(): Tree { return this.tree; } // Set Sapling Parser with a specific Data Tree (from workspace state) - setTree(tree) { + public setTree(tree: Tree) { this.entryFile = tree.filePath; this.tree = tree; } - updateTree(filePath) { - let children = []; + public updateTree(filePath: string): Tree { + let children: any[] = []; - const getChildNodes = (node) => { + const getChildNodes = (node: Tree): void => { const { depth, filePath, expanded } = node; children.push({ depth, filePath, expanded }); }; - const matchExpand = (node) => { + const matchExpand = (node: Tree): void => { for (let i = 0; i < children.length; i += 1) { const oldNode = children[i]; if ( @@ -106,7 +113,7 @@ class Parser { } }; - const callback = (node) => { + const callback = (node: Tree): void => { if (node.filePath === filePath) { node.children.forEach((child) => { this.traverseTree(getChildNodes, child); @@ -121,23 +128,23 @@ class Parser { }; this.traverseTree(callback, this.tree); - return this.tree; + return this.tree!; } // Traverses the tree and changes expanded property of node whose id matches provided id - toggleNode(id, expanded) { - const callback = (node) => { + public toggleNode(id: string, expanded: boolean): Tree{ + const callback = (node: { id: string; expanded: boolean }) => { if (node.id === id) { node.expanded = expanded; } }; this.traverseTree(callback, this.tree); - return this.tree; + return this.tree!; } // Traverses all nodes of current component tree and applies callback to each node - traverseTree(callback, node = this.tree) { + private traverseTree(callback: Function, node: Tree | undefined = this.tree): void { if (!node) { return; } @@ -150,8 +157,7 @@ class Parser { } // Recursively builds the React component tree structure starting from root node - parser(componentTree) { - // console.log('componentTree:', componentTree); + private parser(componentTree: Tree): Tree | undefined { // If import is a node module, do not parse any deeper if (!['\\', '/', '.'].includes(componentTree.importPath[0])) { componentTree.thirdParty = true; @@ -167,7 +173,7 @@ class Parser { // Check that file has valid fileName/Path, if not found, add error to node and halt const fileName = this.getFileName(componentTree); if (!fileName) { - componentTree.error = 'File not found.'; + componentTree.error = 'File not found'; return; } @@ -175,9 +181,12 @@ class Parser { if (componentTree.parentList.includes(componentTree.filePath)) { return; } + // if (typeof componentTree.parentList === 'string' && componentTree.parentList.includes(componentTree.filePath)) { + // return; + // } // Create abstract syntax tree of current component tree file - let ast; + let ast: babel.ParseResult; try { ast = babel.parse( fs.readFileSync(path.resolve(componentTree.filePath), 'utf-8'), @@ -223,9 +232,9 @@ class Parser { } // Finds files where import string does not include a file extension - getFileName(componentTree) { + private getFileName(componentTree: Tree): string | undefined { const ext = path.extname(componentTree.filePath); - let fileName = componentTree.fileName; + let fileName: string | undefined = componentTree.fileName; if (!ext) { // Try and find file extension that exists in directory: @@ -242,7 +251,7 @@ class Parser { // import Page2 from './page2'; -> is parsed as 'VariableDeclaration' // input: array of objects: ast.program.body // output: object of imoprts - getImports(body) { + private getImports(body: { [key: string]: any }[]): ImportObj { const bodyImports = body.filter((item) => item.type === 'ImportDeclaration' || 'VariableDeclaration'); return bodyImports.reduce((accum, curr) => { @@ -268,7 +277,7 @@ class Parser { }, {}); } - findVarDecImports(ast) { + private findVarDecImports(ast: { [key: string]: any }): string | boolean { // find import path in variable declaration and return it, if (ast.hasOwnProperty('callee') && ast.callee.type === 'Import') { return ast.arguments[0].value; @@ -288,7 +297,7 @@ class Parser { // helper function to determine component type (client) // input: ast.program.body // output: boolean - getCallee(body) { + private getCallee(body: { [key: string]: any }[]): boolean { const defaultErr = (err,) => { return { method: 'Error in getCallee method of Parser:', @@ -296,11 +305,8 @@ class Parser { } }; - // console.log('ast.program.body', body); const bodyCallee = body.filter((item) => item.type === 'VariableDeclaration'); if (bodyCallee.length === 0) return false; - // console.log('bodyCallee', bodyCallee); - // console.log('bodyCallee.length', bodyCallee.length) const calleeHelper = (item) => { const hooksObj = { @@ -355,7 +361,6 @@ class Parser { const calleeArr = bodyCallee[0].declarations[0]?.init?.body?.body; if (calleeArr === undefined) return false; - // console.log('calleArr:', calleeArr); let checkTrue = false; for (let i = 0; i < calleeArr.length; i++) { if (checkTrue) return true; @@ -364,12 +369,11 @@ class Parser { return checkTrue; } else if (bodyCallee.length > 1) { - let calleeArr; + let calleeArr: []; for (let i = 0; i < bodyCallee.length; i++) { try { if (bodyCallee[i].declarations[0]?.init?.body?.body) { calleeArr = bodyCallee[i].declarations[0].init.body.body; - // console.log('calleeArr from body', calleeArr); } } catch (err) { @@ -389,13 +393,17 @@ class Parser { } // Finds JSX React Components in current file - getJSXChildren(astTokens, importsObj, parentNode) { - let childNodes = {}; - let props = {}; - let token; + private getJSXChildren( + astTokens: any[], + importsObj: ImportObj, + parentNode: Tree + ): Tree[] { - for (let i = 0; i < astTokens.length; i++) { + let childNodes: { [key: string]: Tree } = {}; + let props: { [key: string]: boolean } = {}; + let token: { [key: string]: any }; + for (let i = 0; i < astTokens.length; i++) { // Case for finding JSX tags eg if ( astTokens[i].type.label === 'jsxTagStart' && @@ -415,7 +423,7 @@ class Parser { // Case for finding components passed in as props e.g. } else if ( astTokens[i].type.label === 'jsxName' && - (astTokens[i].value === 'component' || + (astTokens[i].value === 'Component' || astTokens[i].value === 'children') && importsObj[astTokens[i + 3].value] ) { @@ -432,13 +440,13 @@ class Parser { return Object.values(childNodes); } - getChildNodes( - imports, - astToken, - props, - parent, - children, - ) { + private getChildNodes( + imports: ImportObj, + astToken: { [key: string]: any }, + props: { [key: string]: boolean }, + parent: Tree, + children: { [key: string]: Tree } + ): { [key: string]: Tree } { if (children[astToken.value]) { children[astToken.value].count += 1; children[astToken.value].props = { @@ -464,6 +472,8 @@ class Parser { count: 1, props: props, children: [], + parent: parent.id, + // consider adding the id to the parentList array somehow for D3 integration... parentList: [parent.filePath].concat(parent.parentList), error: '', isClientComponent: false @@ -473,8 +483,10 @@ class Parser { } // Extracts prop names from a JSX element - getJSXProps(astTokens, j) { - const props = {}; + private getJSXProps(astTokens: { [key: string]: any }[], + j: number + ): { [key: string]: boolean } { + const props: any = {}; while (astTokens[j].type.label !== 'jsxTagEnd') { if ( astTokens[j].type.label === 'jsxName' && @@ -488,7 +500,7 @@ class Parser { } // Checks if current Node is connected to React-Redux Store - checkForRedux(astTokens, importsObj) { + private checkForRedux(astTokens: any[], importsObj: ImportObj): boolean { // Check that react-redux is imported in this file (and we have a connect method or otherwise) let reduxImported = false; let connectAlias; @@ -519,5 +531,3 @@ class Parser { return false; } } - -module.exports = { Parser }; \ No newline at end of file diff --git a/test/runTest.js b/src/test/runTest.ts similarity index 58% rename from test/runTest.js rename to src/test/runTest.ts index 570e697..d673170 100644 --- a/test/runTest.js +++ b/src/test/runTest.ts @@ -1,17 +1,23 @@ -const path = require('path'); +import * as path from 'path'; -const { runTests } = require('@vscode/test-electron'); +import { runTests } from '@vscode/test-electron'; async function main() { + console.log('made it through the line before try block'); try { + console.log('inside try block'); // The folder containing the Extension Manifest package.json // Passed to `--extensionDevelopmentPath` - const extensionDevelopmentPath = path.resolve(__dirname, '../'); + const extensionDevelopmentPath = path.resolve(__dirname, '../../'); + + console.log('inside try block after first var declare'); // The path to the extension test script // Passed to --extensionTestsPath const extensionTestsPath = path.resolve(__dirname, './suite/index'); + console.log('inside try block after second var declare'); + // Download VS Code, unzip it and run the integration test await runTests({ extensionDevelopmentPath, extensionTestsPath }); } catch (err) { diff --git a/test/suite/extension.test.js b/src/test/suite/extension.test.ts similarity index 65% rename from test/suite/extension.test.js rename to src/test/suite/extension.test.ts index 69ead83..fc20674 100644 --- a/test/suite/extension.test.js +++ b/src/test/suite/extension.test.ts @@ -1,15 +1,16 @@ -const assert = require('assert'); +import * as assert from 'assert' // You can import and use all API from the 'vscode' module // as well as import your extension to test it -const vscode = require('vscode'); +import * as vscode from 'vscode' // const myExtension = require('../extension'); suite('Extension Test Suite', () => { vscode.window.showInformationMessage('Start all tests.'); test('Sample test', () => { - assert.strictEqual(-1, [1, 2, 3].indexOf(5)); + assert.strictEqual(-1, [1, 2, 3].indexOf(5)); // false assert.strictEqual(-1, [1, 2, 3].indexOf(0)); + assert.strictEqual(0, [1, 2, 3].indexOf(1)); // true }); }); diff --git a/test/suite/index.js b/src/test/suite/index.ts similarity index 75% rename from test/suite/index.js rename to src/test/suite/index.ts index 757fe1a..da70745 100644 --- a/test/suite/index.js +++ b/src/test/suite/index.ts @@ -1,10 +1,10 @@ -const path = require('path'); -const Mocha = require('mocha'); -const glob = require('glob'); +import * as path from 'path'; +import * as Mocha from 'mocha'; +import { glob } from 'glob'; -async function run() { +export async function run(): Promise { // Create the mocha test - const mocha = new Mocha({ + const mocha = new Mocha.default({ ui: 'tdd', color: true }); @@ -31,6 +31,3 @@ async function run() { } } -module.exports = { - run -}; diff --git a/src/treeTemplates/tree.js b/src/treeTemplates/tree.js deleted file mode 100644 index ae488b7..0000000 --- a/src/treeTemplates/tree.js +++ /dev/null @@ -1,11 +0,0 @@ -const Tree = { - id: undefined, - fileName: undefined, - filePath: undefined, - // children & parentList should be populated with other Tree objects - children: [], - parentList: [], - isClientComponent: false -} - -module.exports = { Tree }; \ No newline at end of file diff --git a/src/types/ImportObj.ts b/src/types/ImportObj.ts new file mode 100644 index 0000000..1d5932e --- /dev/null +++ b/src/types/ImportObj.ts @@ -0,0 +1,3 @@ +export type ImportObj = { + [key: string]: { importPath: string; importName: string; }; + }; \ No newline at end of file diff --git a/src/types/builder.ts b/src/types/builder.ts new file mode 100644 index 0000000..2517da9 --- /dev/null +++ b/src/types/builder.ts @@ -0,0 +1,10 @@ +export type Builder = { + parsedData: [object]; + id: number; + x: number; + y: number; + initialNodes: []; + viewData: any; + edgeId: number; + initialEdges: []; +} \ No newline at end of file diff --git a/src/types/connection.ts b/src/types/connection.ts new file mode 100644 index 0000000..cb70b7b --- /dev/null +++ b/src/types/connection.ts @@ -0,0 +1,7 @@ +export enum ConnectionLineType { + Bezier = 'default', + Straight = 'straight', + Step = 'step', + SmoothStep = 'smoothstep', + SimpleBezier = 'simplebezier', + } \ No newline at end of file diff --git a/src/types/hierarchyData.ts b/src/types/hierarchyData.ts new file mode 100644 index 0000000..036c271 --- /dev/null +++ b/src/types/hierarchyData.ts @@ -0,0 +1,18 @@ +import { Tree } from "./tree" + + +export interface hierarchyData { + id: string, + position: { x: number, y: number }, + type: string, + data: { label: string }, + style: { + borderRadius: string, + borderWidth: string, + borderColor: string, + display: string, + justifyContent: string, + placeItems: string, + backgroundColor: string, + } + } \ No newline at end of file diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..d65604a --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,2 @@ +declare module '*.jpg'; +declare module '*.jpeg'; \ No newline at end of file diff --git a/src/types/tree.ts b/src/types/tree.ts new file mode 100644 index 0000000..03506cb --- /dev/null +++ b/src/types/tree.ts @@ -0,0 +1,19 @@ +export type Tree = { + id: string; + name: string; + fileName: string; + filePath: string; + importPath: string; + expanded: boolean; + depth: number; + count: number; + thirdParty: boolean; + reactRouter: boolean; + reduxConnect: boolean; + children: Tree[]; + parent: string; + parentList: string[]; + props: { [key: string]: boolean; }; + error: string; + isClientComponent: boolean; +} diff --git a/src/webview/App.jsx b/src/webview/App.tsx similarity index 98% rename from src/webview/App.jsx rename to src/webview/App.tsx index 0f936b2..7d4fd8c 100644 --- a/src/webview/App.jsx +++ b/src/webview/App.tsx @@ -1,7 +1,5 @@ import React from "react"; - import Flow from "./Flow"; - import "./style.css"; export default function App() { diff --git a/src/webview/Flow.jsx b/src/webview/Flow.jsx deleted file mode 100644 index 96be6ec..0000000 --- a/src/webview/Flow.jsx +++ /dev/null @@ -1,91 +0,0 @@ -import React, { useCallback, useEffect } from "react"; -import ReactFlow, { - addEdge, - MiniMap, - Panel, - Controls, - Background, - useNodesState, - useEdgesState -} from "reactflow"; - -import "reactflow/dist/style.css"; - -import FlowBuilder from './flowBuilder.js'; - -const onInit = (reactFlowInstance) => - console.log("flow loaded:", reactFlowInstance); - -const OverviewFlow = () => { - const initialNodes = []; - const initialEdges = []; - - const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes); - const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges); - - const onConnect = useCallback( - (params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)), - [] - ); - - useEffect(() => { - window.addEventListener('message', (e) => { - const msg = e.data; // object containing type prop and value prop - switch (msg.type) { - case 'parsed-data': { - const results = new FlowBuilder(msg.value); - results.build(msg.settings) - // console.log('results: ', results); - // console.log('results.initialNodes: ', results.initialNodes); - // console.log('results.initialEdges: ', results.initialEdges); - setNodes(results.initialNodes); - setEdges(results.initialEdges); - break; - } - } - }); - }, []); - - return ( - - { - if (n.style?.background) return n.style.background; - if (n.data.label.props.className.includes('orange')) return "#fdba74"; - if (n.data.label.props.className.includes('blue')) return "#93C5FD"; - if (n.type === "default") return "#1a192b"; - - return "#eee"; - }} - nodeColor={(n) => { - if (n.style?.background) return n.style.background; - return "#fff"; - }} - nodeBorderRadius={2} - /> - -
-
-

Client: 00

-
-
-

Server: 00

-
-
-
- - -
- ); -}; - -export default OverviewFlow; diff --git a/src/webview/Flow.tsx b/src/webview/Flow.tsx new file mode 100644 index 0000000..799a8aa --- /dev/null +++ b/src/webview/Flow.tsx @@ -0,0 +1,167 @@ +import React, { useCallback, useEffect, useRef } from "react"; +import ReactFlow, { + addEdge, + MiniMap, + Panel, + Controls, + Background, + useNodesState, + useEdgesState, + ReactFlowInstance, + Node, + Edge +} from "reactflow"; +import "reactflow/dist/style.css"; +import { ConnectionLineType } from "../types/connection"; +import FlowBuilder from './flowBuilder'; +import * as d3 from 'd3'; +import { Tree } from "../types/tree"; +import { hierarchyData } from "../types/hierarchyData"; +import { getNonce } from "../getNonce"; +import { FlowNode } from "typescript"; + +const onInit = (reactFlowInstance: ReactFlowInstance) => + console.log("flow loaded:", reactFlowInstance); + +const OverviewFlow = () => { + const reactFlowWrapper = useRef(null); + const initialNodes : Node[] = []; + const initialEdges : Edge[] = []; + + const [nodes, setNodes, onNodesChange] = useNodesState([]); + const [edges, setEdges, onEdgesChange] = useEdgesState([]); + + const onConnect = useCallback( + (params) => setEdges((eds) => addEdge({ ...params, type: ConnectionLineType.Bezier, animated: true }, eds)), + [] + ); + + + useEffect(() => { + window.addEventListener('message', (e: MessageEvent) => { + // object containing type prop and value prop + const msg : MessageEvent = e; + console.log(e) + + switch (msg.data.type) { + case 'parsed-data': { + let data : Tree | undefined = msg.data.value; + mappedData(data) + setEdges(initialEdges); + setNodes(initialNodes) + break; + } + } + }); + }, []); + + + // Function that creates Tree Structure + function mappedData (data: Tree) : void { + + // Create a holder for the heirarchical data (msg.value), data comes in an object of all the Trees + const root : d3.HierarchyNode = d3.hierarchy(data) + + // Dynamically adjust height and width of display depending on the amount of nodes + const totalNodes : number = root.descendants().length; + const width : number = Math.max(totalNodes * 100, 800); + const height = Math.max(totalNodes * 20, 500) + + + //create tree layout and give nodes their positions and + const treeLayout : d3.TreeLayout = d3.tree() + .size([ width, height ]) + .separation((a: d3.HierarchyPointNode, b: d3.HierarchyPointNode) => (a.parent == b.parent ? 2 : 2.5)) + + + treeLayout(root); + // Iterate through each Tree and create a node + root.each((node: any) : void => { + console.log('Node', node) + // Create a Node from the current Root and add it to our nodes array + initialNodes.push({ + id: node.data.id, + position: { x: node.x ? node.x : 0, y: node.y ? node.y : 0 }, + type: 'default', + data: { label: node.data.name }, + style: { + borderRadius: '6px', + borderWidth: '2px', + borderColor: '#6b7280', + display: 'flex', + justifyContent: 'center', + placeItems: 'center', + backgroundColor: `${(node.data.isClientComponent) ? '#fdba74' : '#93C5FD'}`, + } + }); + + // If the current node has a parent, create an edge to show relationship + if (node.data.parent) { + const newEdge : Edge = { + id: `${getNonce()}`, + source: node.data.parent, + target: node.data.id, + type: ConnectionLineType.Bezier, + animated: true, + }; + + + // Check if the edge already exists before adding + const edgeExists : boolean = initialEdges.some( + edge => edge.source === newEdge.source && edge.target === newEdge.target + ); + + // If edge does not exist, add to our edges array + if (!edgeExists) { + initialEdges.push(newEdge) + } + } + } + ) + + } + + return ( +
+ + { + if (n.style?.backgroundColor) return n.style.backgroundColor; + if (n.type === "default") return "#1a192b"; + + return "#eee"; + }} + nodeColor={(n): string => { + if (n.style?.backgroundColor) return n.style.backgroundColor; + return "#fff"; + }} + nodeBorderRadius={2} + /> + +
+
+

Client: 00

+
+
+

Server: 00

+
+
+
+ + +
+
+ ); +}; + +export default OverviewFlow; diff --git a/src/webview/flowBuilder.js b/src/webview/flowBuilder.tsx similarity index 61% rename from src/webview/flowBuilder.js rename to src/webview/flowBuilder.tsx index 62fd030..1db07e8 100644 --- a/src/webview/flowBuilder.js +++ b/src/webview/flowBuilder.tsx @@ -2,24 +2,71 @@ import React from 'react'; // will create a build func and then call the helper funcs to return an object // make a new instance of this class in flow, call the build method, and pass this as state +interface Node { + id: string; + data: { + label: React.ReactNode; + }; + type: string; + position: { x: number, y: number }; + style: { + borderRadius: string; + borderWidth: string; + borderColor: string; + display: string; + justifyContent: string; + placeItems: string; + backgroundColor: string; + }; +} + +interface Edge { + id: string; + source: string; + target: string; + type: string; + animated: boolean; +} + +interface ParsedDataItem { + fileName: string; + isClientComponent: boolean; + children?: ParsedDataItem[]; + thirdParty?: boolean; + reactRouter?: boolean; +} + +interface Settings { + thirdParty: boolean; + reactRouter: boolean; +} + class FlowBuilder { - constructor(data) { + private parsedData: ParsedDataItem[]; + private viewData: ParsedDataItem[]; + private id: number; + private x: number; + private y: number; + private edgeId: number; + public initialEdges: Edge[]; + public initialNodes: Node[]; + + constructor(data: ParsedDataItem) { this.parsedData = [data]; this.id = 0; this.x = 0; this.y = 0; this.initialNodes = []; - this.viewData; - this.edgeId = 0; this.initialEdges = []; + this.viewData = []; + this.edgeId = 0; } - buildNodesArray(parsedData, x = this.x, y = this.y) { + private buildNodesArray(parsedData: ParsedDataItem[] | undefined, x: number = this.x, y: number = this.y): void { if (!parsedData) return; - parsedData.forEach((item) => { - const node = { + const node: Node = { id: (++this.id).toString(), data: { label: ( @@ -28,7 +75,7 @@ class FlowBuilder { }, // type: item.depth === 0 ? 'input' : '', type: 'default', - position: { x: x += 40, y: y += 30 }, + position: { x: (x += 40), y: (y += 30) }, style: { borderRadius: '6px', borderWidth: '2px', @@ -41,18 +88,18 @@ class FlowBuilder { }; this.initialNodes.push(node); if (item.children) { - this.buildNodesArray(item.children, this.x += 40, this.y += 30); + this.buildNodesArray(item.children, (this.x += 40), (this.y += 30)); } }); }; - buildEdgesArray(parsedData, parentID) { + private buildEdgesArray(parsedData: ParsedDataItem[] | undefined, parentID?: number): void { if (!parsedData) return; parsedData.forEach((item) => { const nodeID = ++this.edgeId; if (parentID) { - const edge = { + const edge: Edge = { id: `e${parentID}-${nodeID}`, source: parentID.toString(), target: nodeID.toString(), @@ -67,13 +114,13 @@ class FlowBuilder { }); } - build(settings) { + public build(settings: Settings): void { const treeParsed = JSON.parse(JSON.stringify(this.parsedData[0])); - console.log('settings: ', settings); - const traverse = (node) => { - let validChildren = []; + // console.log('settings: ', settings); + const traverse = (node: ParsedDataItem): void => { + let validChildren: ParsedDataItem[] = []; - for (let i = 0; i < node.children.length; i++) { + for (let i = 0; i < node.children?.length; i++) { if ( node.children[i].thirdParty && settings.thirdParty && diff --git a/src/webview/index.jsx b/src/webview/index.tsx similarity index 89% rename from src/webview/index.jsx rename to src/webview/index.tsx index 45645f4..45e01f7 100644 --- a/src/webview/index.jsx +++ b/src/webview/index.tsx @@ -1,8 +1,7 @@ import React from "react"; import { createRoot } from "react-dom/client"; import './style.css'; - -import App from "./App.jsx"; +import App from "./App"; const rootElement = document.getElementById("root"); const root = createRoot(rootElement); diff --git a/tailwind.config.js b/tailwind.config.js index a7e47f5..db6d9c1 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,7 +1,12 @@ module.exports = { content: ['./build/bundle.js'], theme: { - extend: {}, + extend: { + backgroundColor: { + orange: '#fdba74', + blue: '#93C5FD', + }, + }, }, variants: { extend: {}, diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..793ea1c --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "target": "es6", + "module": "commonjs", + "outDir": "./build/src", + "esModuleInterop": true, + "lib": ["es6", "dom"], + "jsx": "react", + "sourceMap": true, + "rootDir": "./src", + "allowJs": true, + "strict": false, + "inlineSources": true, + }, + "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/**/*.tsx", "src/**/**/*.ts"], + "exclude": [ + "node_modules", + ".vscode-test", + "src/webviews", + "src/test/test_apps" + ] +} \ No newline at end of file diff --git a/webpack.config.cjs b/webpack.config.cjs deleted file mode 100644 index 26f1700..0000000 --- a/webpack.config.cjs +++ /dev/null @@ -1,31 +0,0 @@ -const path = require('path') - -module.exports = { - entry: './src/webview/index.jsx', - output: { - filename: 'bundle.js', - path: path.resolve(__dirname, './build'), - }, - resolve: { - extensions: ['.js', '.jsx', '.css'], - }, - module: { - rules: [ - { - test: /\.jsx?/, - exclude: /node_modules/, - use: { - loader: "babel-loader", - options: { - presets: ['@babel/preset-env', '@babel/preset-react'] - } - } - }, - { - test: /\.(css|scss)$/, - use: ["style-loader", "css-loader", "postcss-loader"], - }, - ] - }, - mode: "development" -} diff --git a/webpack.config.ts b/webpack.config.ts new file mode 100644 index 0000000..8694901 --- /dev/null +++ b/webpack.config.ts @@ -0,0 +1,41 @@ + +import * as path from 'path'; +import * as webpack from 'webpack'; + +const extConfig: webpack.Configuration = { + target: 'node', + entry: './src/extension.ts', + output: { + filename: 'extension.js', + libraryTarget: 'commonjs2', + path: path.resolve(__dirname, 'build'), + }, + resolve: { extensions: ['.ts', '.js'] }, + module: { rules: [{ test: /\.ts$/, loader: 'ts-loader' }] }, + externals: { vscode: 'vscode' }, + mode: 'development' +}; + +const webviewConfig: webpack.Configuration = { + target: 'web', + entry: './src/webview/index.tsx', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'build'), + }, + resolve: { + extensions: ['.js', '.ts', '.tsx', 'scss'], + }, + module: { + rules: [ + { test: /\.tsx?$/, use: ['babel-loader', 'ts-loader'] }, + { + test: /\.css$/, + use: ['style-loader', 'css-loader', 'postcss-loader'], + }, + ], + }, + mode: 'development' +}; + +export default [webviewConfig, extConfig]; \ No newline at end of file