diff --git a/.gitignore b/.gitignore index 6b4e1209a..0579796ec 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ dist-ssr *.njsproj *.sln *.sw? +components.d.ts # Ignore test data. tests-ui/data/* diff --git a/index.html b/index.html index 75389940c..39dac8fe0 100644 --- a/index.html +++ b/index.html @@ -1,55 +1,55 @@ - - - ComfyUI - - - - - - - - - - -
- - + + + ComfyUI + + + + + + + + + + +
+ + diff --git a/package-lock.json b/package-lock.json index 4237f2ad9..eda5253b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,6 +24,7 @@ "reflect-metadata": "^0.2.2", "vue": "^3.4.31", "vue-i18n": "^9.13.1", + "vue-router": "^4.4.3", "zod": "^3.23.8", "zod-validation-error": "^3.3.0" }, @@ -31,6 +32,7 @@ "@babel/core": "^7.24.7", "@babel/preset-env": "^7.22.20", "@eslint/js": "^9.8.0", + "@iconify/json": "^2.2.245", "@playwright/test": "^1.44.1", "@types/jest": "^29.5.12", "@types/lodash": "^4.17.6", @@ -59,6 +61,8 @@ "tsx": "^4.15.6", "typescript": "^5.4.5", "typescript-eslint": "^8.0.0", + "unplugin-icons": "^0.19.3", + "unplugin-vue-components": "^0.27.4", "vite": "^5.2.0", "vite-plugin-static-copy": "^1.0.5", "vitest": "^2.0.5", @@ -112,6 +116,28 @@ "node": ">=6.0.0" } }, + "node_modules/@antfu/install-pkg": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@antfu/install-pkg/-/install-pkg-0.4.1.tgz", + "integrity": "sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==", + "dev": true, + "dependencies": { + "package-manager-detector": "^0.2.0", + "tinyexec": "^0.3.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, + "node_modules/@antfu/utils": { + "version": "0.7.10", + "resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-0.7.10.tgz", + "integrity": "sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/@atlaskit/pragmatic-drag-and-drop": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@atlaskit/pragmatic-drag-and-drop/-/pragmatic-drag-and-drop-1.2.1.tgz", @@ -2414,6 +2440,37 @@ "url": "https://github.com/sponsors/nzakas" } }, + "node_modules/@iconify/json": { + "version": "2.2.245", + "resolved": "https://registry.npmjs.org/@iconify/json/-/json-2.2.245.tgz", + "integrity": "sha512-JbruddbGKghBe6fE1mzuo5hhUkisIW4mAdQGAyx0Q6sI52ukeQJHakolc2RQD/yWC3xp7rARNXMzWSXJynJ1vw==", + "dev": true, + "dependencies": { + "@iconify/types": "*", + "pathe": "^1.1.2" + } + }, + "node_modules/@iconify/types": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@iconify/types/-/types-2.0.0.tgz", + "integrity": "sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==", + "dev": true + }, + "node_modules/@iconify/utils": { + "version": "2.1.32", + "resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.1.32.tgz", + "integrity": "sha512-LeifFZPPKu28O3AEDpYJNdEbvS4/ojAPyIW+pF/vUpJTYnbTiXUHkCh0bwgFRzKvdpb8H4Fbfd/742++MF4fPQ==", + "dev": true, + "dependencies": { + "@antfu/install-pkg": "^0.4.0", + "@antfu/utils": "^0.7.10", + "@iconify/types": "^2.0.0", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "mlly": "^1.7.1" + } + }, "node_modules/@intlify/core-base": { "version": "9.13.1", "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.13.1.tgz", @@ -3237,9 +3294,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.15", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", - "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" }, "node_modules/@jridgewell/trace-mapping": { "version": "0.3.25", @@ -3380,6 +3437,28 @@ "node": ">=12.11.0" } }, + "node_modules/@rollup/pluginutils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.1.0.tgz", + "integrity": "sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==", + "dev": true, + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^2.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + } + } + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.18.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.18.0.tgz", @@ -5327,6 +5406,12 @@ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, + "node_modules/confbox": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.7.tgz", + "integrity": "sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==", + "dev": true + }, "node_modules/config-chain": { "version": "1.1.13", "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", @@ -5544,12 +5629,12 @@ } }, "node_modules/debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", "dev": true, "dependencies": { - "ms": "2.1.2" + "ms": "^2.1.3" }, "engines": { "node": ">=6.0" @@ -9024,6 +9109,12 @@ "node": ">=6" } }, + "node_modules/kolorist": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz", + "integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==", + "dev": true + }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -9252,6 +9343,22 @@ "node": ">=18.0.0" } }, + "node_modules/local-pkg": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-0.5.0.tgz", + "integrity": "sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==", + "dev": true, + "dependencies": { + "mlly": "^1.4.2", + "pkg-types": "^1.0.3" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -9409,11 +9516,11 @@ } }, "node_modules/magic-string": { - "version": "0.30.10", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.10.tgz", - "integrity": "sha512-iIRwTIf0QKV3UAnYK4PU8uiEc4SRh5jX0mwpIwETPpHdhVM4f53RSwS/vXvN1JhGX+Cs7B8qIq3d6AH49O5fAQ==", + "version": "0.30.11", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.11.tgz", + "integrity": "sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" + "@jridgewell/sourcemap-codec": "^1.5.0" } }, "node_modules/make-dir": { @@ -9542,10 +9649,22 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/mlly": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.1.tgz", + "integrity": "sha512-rrVRZRELyQzrIUAVMHxP97kv+G786pHmOKzuFII8zDYahFBS7qnHh2AlYSl1GAHhaMPCz6/oHjVMcfFYgFYHgA==", + "dev": true, + "dependencies": { + "acorn": "^8.11.3", + "pathe": "^1.1.2", + "pkg-types": "^1.1.1", + "ufo": "^1.5.3" + } + }, "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", "dev": true }, "node_modules/mz": { @@ -9776,6 +9895,12 @@ "integrity": "sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==", "dev": true }, + "node_modules/package-manager-detector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-0.2.0.tgz", + "integrity": "sha512-E385OSk9qDcXhcM9LNSe4sdhx8a9mAPrZ4sMLW+tmxl5ZuGtPUcdFu+MPP2jbgiWAZ6Pfe5soGFMd+0Db5Vrog==", + "dev": true + }, "node_modules/pako": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", @@ -10019,6 +10144,17 @@ "node": ">=8" } }, + "node_modules/pkg-types": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.2.0.tgz", + "integrity": "sha512-+ifYuSSqOQ8CqP4MbZA5hDpb97n3E8SVWdJe+Wms9kj745lmd3b7EZJiqvmLwAlmRfjrI7Hi5z3kdBJ93lFNPA==", + "dev": true, + "dependencies": { + "confbox": "^0.1.7", + "mlly": "^1.7.1", + "pathe": "^1.1.2" + } + }, "node_modules/playwright": { "version": "1.45.1", "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.45.1.tgz", @@ -11207,6 +11343,12 @@ "dev": true, "license": "MIT" }, + "node_modules/tinyexec": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.0.tgz", + "integrity": "sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==", + "dev": true + }, "node_modules/tinypool": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.0.1.tgz", @@ -11541,6 +11683,12 @@ } } }, + "node_modules/ufo": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.5.4.tgz", + "integrity": "sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==", + "dev": true + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -11596,6 +11744,130 @@ "node": ">= 4.0.0" } }, + "node_modules/unplugin": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/unplugin/-/unplugin-1.13.1.tgz", + "integrity": "sha512-6Kq1iSSwg7KyjcThRUks9LuqDAKvtnioxbL9iEtB9ctTyBA5OmrB8gZd/d225VJu1w3UpUsKV7eGrvf59J7+VA==", + "dev": true, + "dependencies": { + "acorn": "^8.12.1", + "webpack-virtual-modules": "^0.6.2" + }, + "engines": { + "node": ">=14.0.0" + }, + "peerDependencies": { + "webpack-sources": "^3" + }, + "peerDependenciesMeta": { + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/unplugin-icons": { + "version": "0.19.3", + "resolved": "https://registry.npmjs.org/unplugin-icons/-/unplugin-icons-0.19.3.tgz", + "integrity": "sha512-EUegRmsAI6+rrYr0vXjFlIP+lg4fSC4zb62zAZKx8FGXlWAGgEGBCa3JDe27aRAXhistObLPbBPhwa/0jYLFkQ==", + "dev": true, + "dependencies": { + "@antfu/install-pkg": "^0.4.1", + "@antfu/utils": "^0.7.10", + "@iconify/utils": "^2.1.29", + "debug": "^4.3.6", + "kolorist": "^1.8.0", + "local-pkg": "^0.5.0", + "unplugin": "^1.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@svgr/core": ">=7.0.0", + "@svgx/core": "^1.0.1", + "@vue/compiler-sfc": "^3.0.2 || ^2.7.0", + "vue-template-compiler": "^2.6.12", + "vue-template-es2015-compiler": "^1.9.0" + }, + "peerDependenciesMeta": { + "@svgr/core": { + "optional": true + }, + "@svgx/core": { + "optional": true + }, + "@vue/compiler-sfc": { + "optional": true + }, + "vue-template-compiler": { + "optional": true + }, + "vue-template-es2015-compiler": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components": { + "version": "0.27.4", + "resolved": "https://registry.npmjs.org/unplugin-vue-components/-/unplugin-vue-components-0.27.4.tgz", + "integrity": "sha512-1XVl5iXG7P1UrOMnaj2ogYa5YTq8aoh5jwDPQhemwO/OrXW+lPQKDXd1hMz15qxQPxgb/XXlbgo3HQ2rLEbmXQ==", + "dev": true, + "dependencies": { + "@antfu/utils": "^0.7.10", + "@rollup/pluginutils": "^5.1.0", + "chokidar": "^3.6.0", + "debug": "^4.3.6", + "fast-glob": "^3.3.2", + "local-pkg": "^0.5.0", + "magic-string": "^0.30.11", + "minimatch": "^9.0.5", + "mlly": "^1.7.1", + "unplugin": "^1.12.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@babel/parser": "^7.15.8", + "@nuxt/kit": "^3.2.2", + "vue": "2 || 3" + }, + "peerDependenciesMeta": { + "@babel/parser": { + "optional": true + }, + "@nuxt/kit": { + "optional": true + } + } + }, + "node_modules/unplugin-vue-components/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/unplugin-vue-components/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "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/update-browserslist-db": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz", @@ -12108,6 +12380,20 @@ "vue": "^3.0.0" } }, + "node_modules/vue-router": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.4.3.tgz", + "integrity": "sha512-sv6wmNKx2j3aqJQDMxLFzs/u/mjA9Z5LCgy6BE0f7yFWMjrPLnS/sPNn8ARY/FXw6byV18EFutn5lTO6+UsV5A==", + "dependencies": { + "@vue/devtools-api": "^6.6.3" + }, + "funding": { + "url": "https://github.com/sponsors/posva" + }, + "peerDependencies": { + "vue": "^3.2.0" + } + }, "node_modules/w3c-xmlserializer": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", @@ -12138,6 +12424,12 @@ "node": ">=12" } }, + "node_modules/webpack-virtual-modules": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/webpack-virtual-modules/-/webpack-virtual-modules-0.6.2.tgz", + "integrity": "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==", + "dev": true + }, "node_modules/whatwg-encoding": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", diff --git a/package.json b/package.json index b80d57144..a4abea1e2 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "@babel/core": "^7.24.7", "@babel/preset-env": "^7.22.20", "@eslint/js": "^9.8.0", + "@iconify/json": "^2.2.245", "@playwright/test": "^1.44.1", "@types/jest": "^29.5.12", "@types/lodash": "^4.17.6", @@ -52,6 +53,8 @@ "tsx": "^4.15.6", "typescript": "^5.4.5", "typescript-eslint": "^8.0.0", + "unplugin-icons": "^0.19.3", + "unplugin-vue-components": "^0.27.4", "vite": "^5.2.0", "vite-plugin-static-copy": "^1.0.5", "vitest": "^2.0.5", @@ -74,6 +77,7 @@ "reflect-metadata": "^0.2.2", "vue": "^3.4.31", "vue-i18n": "^9.13.1", + "vue-router": "^4.4.3", "zod": "^3.23.8", "zod-validation-error": "^3.3.0" }, diff --git a/src/App.vue b/src/App.vue index c8b249fba..e3534e3b2 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,10 +1,10 @@ diff --git a/src/views/layouts/LayoutDefault.vue b/src/views/layouts/LayoutDefault.vue new file mode 100644 index 000000000..331f71a38 --- /dev/null +++ b/src/views/layouts/LayoutDefault.vue @@ -0,0 +1,5 @@ + diff --git a/tailwind.config.js b/tailwind.config.js index 956bbf460..4eaa6ac82 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,11 +1,182 @@ /** @type {import('tailwindcss').Config} */ export default { content: ['./index.html', './src/**/*.{vue,js,ts,jsx,tsx}'], + corePlugins: { preflight: false // This disables Tailwind's base styles }, + theme: { - extend: {} + fontSize: { + xs: '0.75rem', + sm: '0.875rem', + base: '1rem', + lg: '1.125rem', + xl: '1.25rem', + '2xl': '1.5rem', + '3xl': '1.875rem', + '4xl': '2.25rem', + '5xl': '3rem', + '6xl': '4rem' + }, + + screens: { + sm: '640px', + md: '768px', + lg: '1024px', + xl: '1280px', + '2xl': '1536px', + '3xl': '1800px', + '4xl': '2500px', + '5xl': '3200px' + }, + + spacing: { + px: '1px', + 0: '0px', + 0.5: '0.125rem', + 1: '0.25rem', + 1.5: '0.375rem', + 2: '0.5rem', + 2.5: '0.625rem', + 3: '0.75rem', + 3.5: '0.875rem', + 4: '1rem', + 4.5: '1.125rem', + 5: '1.25rem', + 6: '1.5rem', + 7: '1.75rem', + 8: '2rem', + 9: '2.25rem', + 10: '2.5rem', + 11: '2.75rem', + 12: '3rem', + 14: '3.5rem', + 16: '4rem', + 18: '4.5rem', + 20: '5rem', + 24: '6rem', + 28: '7rem', + 32: '8rem', + 36: '9rem', + 40: '10rem', + 44: '11rem', + 48: '12rem', + 52: '13rem', + 56: '14rem', + 60: '15rem', + 64: '16rem', + 72: '18rem', + 80: '20rem', + 84: '22rem', + 90: '24rem', + 96: '26rem', + 100: '28rem', + 110: '32rem' + }, + + extend: { + colors: { + zinc: { + 50: '#fafafa', + 100: '#f4f4f5', + 200: '#e4e4e7', + 300: '#d4d4d8', + 400: '#a1a1aa', + 500: '#71717a', + 600: '#52525b', + 700: '#3f3f46', + 800: '#27272a', + 900: '#18181b', + 950: '#09090b' + }, + + gray: { + 50: '#f8fbfc', + 100: '#f3f6fa', + 200: '#edf2f7', + 300: '#e2e8f0', + 400: '#cbd5e0', + 500: '#a0aec0', + 600: '#718096', + 700: '#4a5568', + 800: '#2d3748', + 900: '#1a202c', + 950: '#0a1016' + }, + + teal: { + 50: '#f0fdfa', + 100: '#e0fcff', + 200: '#bef8fd', + 300: '#87eaf2', + 400: '#54d1db', + 500: '#38bec9', + 600: '#2cb1bc', + 700: '#14919b', + 800: '#0e7c86', + 900: '#005860', + 950: '#022c28' + }, + + blue: { + 50: '#eff6ff', + 100: '#ebf8ff', + 200: '#bee3f8', + 300: '#90cdf4', + 400: '#63b3ed', + 500: '#4299e1', + 600: '#3182ce', + 700: '#2b6cb0', + 800: '#2c5282', + 900: '#2a4365', + 950: '#172554' + }, + + green: { + 50: '#fcfff5', + 100: '#fafff3', + 200: '#eaf9c9', + 300: '#d1efa0', + 400: '#b2e16e', + 500: '#96ce4c', + 600: '#7bb53d', + 700: '#649934', + 800: '#507b2e', + 900: '#456829', + 950: '#355819' + }, + + fuchsia: { + 50: '#fdf4ff', + 100: '#fae8ff', + 200: '#f5d0fe', + 300: '#f0abfc', + 400: '#e879f9', + 500: '#d946ef', + 600: '#c026d3', + 700: '#a21caf', + 800: '#86198f', + 900: '#701a75', + 950: '#4a044e' + }, + + orange: { + 50: '#fff7ed', + 100: '#ffedd5', + 200: '#fedbb8', + 300: '#fbd38d', + 400: '#f6ad55', + 500: '#ed8936', + 600: '#dd6b20', + 700: '#c05621', + 800: '#9c4221', + 900: '#7b341e', + 950: '#431407' + } + } + } }, + plugins: [] } diff --git a/vite.config.mts b/vite.config.mts index 9c1edf3b5..b201251c9 100644 --- a/vite.config.mts +++ b/vite.config.mts @@ -1,92 +1,95 @@ -import { defineConfig, Plugin } from 'vite'; -import type { UserConfigExport } from 'vitest/config'; -import vue from '@vitejs/plugin-vue'; -import path from 'path'; -import dotenv from "dotenv"; -dotenv.config(); +import { defineConfig, Plugin } from 'vite' +import type { UserConfigExport } from 'vitest/config' +import vue from '@vitejs/plugin-vue' +import path from 'path' +import dotenv from "dotenv" +import Icons from 'unplugin-icons/vite' +import IconsResolver from 'unplugin-icons/resolver' +import Components from 'unplugin-vue-components/vite' -const IS_DEV = process.env.NODE_ENV === 'development'; -const SHOULD_MINIFY = process.env.ENABLE_MINIFY === 'true'; +dotenv.config() + +const IS_DEV = process.env.NODE_ENV === 'development' +const SHOULD_MINIFY = process.env.ENABLE_MINIFY === 'true' interface ShimResult { - code: string; - exports: string[]; + code: string + exports: string[] } function isLegacyFile(id: string): boolean { return id.endsWith('.ts') && ( id.includes("src/extensions/core") || id.includes("src/scripts") - ); + ) } function comfyAPIPlugin(): Plugin { return { name: 'comfy-api-plugin', transform(code: string, id: string) { - if (IS_DEV) - return null; + if (IS_DEV) return null if (isLegacyFile(id)) { - const result = transformExports(code, id); + const result = transformExports(code, id) if (result.exports.length > 0) { - const projectRoot = process.cwd(); - const relativePath = path.relative(path.join(projectRoot, 'src'), id); - const shimFileName = relativePath.replace(/\.ts$/, '.js'); + const projectRoot = process.cwd() + const relativePath = path.relative(path.join(projectRoot, 'src'), id) + const shimFileName = relativePath.replace(/\.ts$/, '.js') - const shimComment = `// Shim for ${relativePath}\n`; + const shimComment = `// Shim for ${relativePath}\n` this.emitFile({ type: "asset", fileName: shimFileName, - source: shimComment + result.exports.join(""), - }); + source: shimComment + result.exports.join("") + }) } return { code: result.code, map: null // If you're not modifying the source map, return null - }; + } } } - }; + } } function transformExports(code: string, id: string): ShimResult { - const moduleName = getModuleName(id); - const exports: string[] = []; - let newCode = code; + const moduleName = getModuleName(id) + const exports: string[] = [] + let newCode = code // Regex to match different types of exports - const regex = /export\s+(const|let|var|function|class|async function)\s+([a-zA-Z$_][a-zA-Z\d$_]*)(\s|\()/g; - let match; + const regex = /export\s+(const|let|var|function|class|async function)\s+([a-zA-Z$_][a-zA-Z\d$_]*)(\s|\()/g + let match while ((match = regex.exec(code)) !== null) { - const name = match[2]; + const name = match[2] // All exports should be bind to the window object as new API endpoint. if (exports.length == 0) { - newCode += `\nwindow.comfyAPI = window.comfyAPI || {};`; - newCode += `\nwindow.comfyAPI.${moduleName} = window.comfyAPI.${moduleName} || {};`; + newCode += `\nwindow.comfyAPI = window.comfyAPI || {};` + newCode += `\nwindow.comfyAPI.${moduleName} = window.comfyAPI.${moduleName} || {};` } - newCode += `\nwindow.comfyAPI.${moduleName}.${name} = ${name};`; - exports.push(`export const ${name} = window.comfyAPI.${moduleName}.${name};\n`); + newCode += `\nwindow.comfyAPI.${moduleName}.${name} = ${name};` + exports.push(`export const ${name} = window.comfyAPI.${moduleName}.${name};\n`) } return { code: newCode, - exports, - }; + exports + } } function getModuleName(id: string): string { // Simple example to derive a module name from the file path - const parts = id.split('/'); - const fileName = parts[parts.length - 1]; - return fileName.replace(/\.\w+$/, ''); // Remove file extension + const parts = id.split('/') + const fileName = parts[parts.length - 1] + return fileName.replace(/\.\w+$/, '') // Remove file extension } -const DEV_SERVER_COMFYUI_URL = process.env.DEV_SERVER_COMFYUI_URL || 'http://127.0.0.1:8188'; +const DEV_SERVER_COMFYUI_URL = process.env.DEV_SERVER_COMFYUI_URL || 'http://127.0.0.1:8188' export default defineConfig({ base: '', @@ -95,27 +98,43 @@ export default defineConfig({ '/internal': { target: DEV_SERVER_COMFYUI_URL, }, + '/api': { target: DEV_SERVER_COMFYUI_URL, // Return empty array for extensions API as these modules // are not on vite's dev server. bypass: (req, res, options) => { if (req.url === '/api/extensions') { - res.end(JSON.stringify([])); + res.end(JSON.stringify([])) } - return null; + return null }, }, + '/ws': { target: DEV_SERVER_COMFYUI_URL, - ws: true, - }, + ws: true + } } }, + plugins: [ vue(), comfyAPIPlugin(), + + Icons({ + 'compiler': 'vue3' + }), + + Components({ + dts: true, + resolvers: [IconsResolver()], + dirs: ['src/components', 'src/layout', 'src/views'], + deep: true, + extensions: ['vue'] + }) ], + build: { minify: SHOULD_MINIFY ? 'esbuild' : false, target: 'es2022', @@ -126,23 +145,27 @@ export default defineConfig({ treeshake: false } }, + esbuild: { minifyIdentifiers: false, keepNames: true, minifySyntax: SHOULD_MINIFY, - minifyWhitespace: SHOULD_MINIFY, + minifyWhitespace: SHOULD_MINIFY }, + test: { globals: true, environment: 'happy-dom', - setupFiles: ['./vitest.setup.ts'], + setupFiles: ['./vitest.setup.ts'] }, + define: { - '__COMFYUI_FRONTEND_VERSION__': JSON.stringify(process.env.npm_package_version), + '__COMFYUI_FRONTEND_VERSION__': JSON.stringify(process.env.npm_package_version) }, + resolve: { alias: { '@': '/src' } } -}) as UserConfigExport; +}) as UserConfigExport