[TS] Enable strict mode (#3136)

This commit is contained in:
Chenlei Hu
2025-03-18 22:57:17 -04:00
committed by GitHub
parent 44edec7ad2
commit a049e9ae2d
64 changed files with 924 additions and 781 deletions

View File

@@ -4,8 +4,7 @@ export default {
'./**/*.{ts,tsx,vue,mts}': (stagedFiles) => [
...formatAndEslint(stagedFiles),
'vue-tsc --noEmit',
'tsc --noEmit',
'tsc-strict'
'tsc --noEmit'
]
}

704
package-lock.json generated
View File

@@ -75,7 +75,6 @@
"tsx": "^4.15.6",
"typescript": "^5.4.5",
"typescript-eslint": "^8.0.0",
"typescript-strict-plugin": "^2.4.4",
"unplugin-icons": "^0.19.3",
"unplugin-vue-components": "^0.27.4",
"vite": "^5.4.14",
@@ -4312,33 +4311,6 @@
"integrity": "sha512-PJvH288AWQhKs2v9zyfYdPzlPqf5bXbGMmhmUIY9x4dAUGIWgomO771oBQNwJnMQSnUIXhKu6sgzpBRXTlvb8Q==",
"license": "MIT"
},
"node_modules/bl": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
"integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
"dev": true,
"license": "MIT",
"dependencies": {
"buffer": "^5.5.0",
"inherits": "^2.0.4",
"readable-stream": "^3.4.0"
}
},
"node_modules/bl/node_modules/readable-stream": {
"version": "3.6.2",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
"integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
"dev": true,
"license": "MIT",
"dependencies": {
"inherits": "^2.0.3",
"string_decoder": "^1.1.1",
"util-deprecate": "^1.0.1"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
@@ -4465,31 +4437,6 @@
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
}
},
"node_modules/buffer": {
"version": "5.7.1",
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
"integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "MIT",
"dependencies": {
"base64-js": "^1.3.1",
"ieee754": "^1.1.13"
}
},
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
@@ -4722,16 +4669,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/clone": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.8"
}
},
"node_modules/code-excerpt": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-4.0.0.tgz",
@@ -5232,19 +5169,6 @@
"node": ">=0.10.0"
}
},
"node_modules/defaults": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
"integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
"dev": true,
"license": "MIT",
"dependencies": {
"clone": "^1.0.2"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-data-property": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
@@ -5493,16 +5417,6 @@
"integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==",
"dev": true
},
"node_modules/end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"once": "^1.4.0"
}
},
"node_modules/entities": {
"version": "4.5.0",
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
@@ -6425,15 +6339,6 @@
"node": ">=10"
}
},
"node_modules/get-caller-file": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
"integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
"dev": true,
"engines": {
"node": "6.* || 8.* || >= 10.*"
}
},
"node_modules/get-east-asian-width": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz",
@@ -6779,27 +6684,6 @@
"node": ">=4"
}
},
"node_modules/ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true,
"funding": [
{
"type": "github",
"url": "https://github.com/sponsors/feross"
},
{
"type": "patreon",
"url": "https://www.patreon.com/feross"
},
{
"type": "consulting",
"url": "https://feross.org/support"
}
],
"license": "BSD-3-Clause"
},
"node_modules/ignore": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
@@ -7246,16 +7130,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-interactive": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
"integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/is-lower-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz",
@@ -7322,31 +7196,6 @@
"optional": true,
"peer": true
},
"node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"dev": true,
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-unicode-supported": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
"integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-upper-case": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-2.0.2.tgz",
@@ -8373,99 +8222,6 @@
"dev": true,
"license": "MIT"
},
"node_modules/log-symbols": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
"integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^4.1.0",
"is-unicode-supported": "^0.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/log-symbols/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/log-symbols/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/log-symbols/node_modules/color-convert": {
"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,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/log-symbols/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,
"license": "MIT"
},
"node_modules/log-symbols/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/log-symbols/node_modules/supports-color": {
"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,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/log-update": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz",
@@ -9800,18 +9556,6 @@
"node": ">=0.10.0"
}
},
"node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dev": true,
"dependencies": {
"path-key": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/nth-check": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -9861,15 +9605,6 @@
"node": ">= 0.4"
}
},
"node_modules/once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
"dev": true,
"dependencies": {
"wrappy": "1"
}
},
"node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -9947,133 +9682,6 @@
"node": ">= 0.8.0"
}
},
"node_modules/ora": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
"integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"bl": "^4.1.0",
"chalk": "^4.1.0",
"cli-cursor": "^3.1.0",
"cli-spinners": "^2.5.0",
"is-interactive": "^1.0.0",
"is-unicode-supported": "^0.1.0",
"log-symbols": "^4.1.0",
"strip-ansi": "^6.0.0",
"wcwidth": "^1.0.1"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/ora/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/ora/node_modules/chalk": {
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
},
"node_modules/ora/node_modules/cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
"integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
"dev": true,
"license": "MIT",
"dependencies": {
"restore-cursor": "^3.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ora/node_modules/color-convert": {
"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,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/ora/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,
"license": "MIT"
},
"node_modules/ora/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/ora/node_modules/restore-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
"integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"onetime": "^5.1.0",
"signal-exit": "^3.0.2"
},
"engines": {
"node": ">=8"
}
},
"node_modules/ora/node_modules/supports-color": {
"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,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/orderedmap": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
@@ -10938,17 +10546,6 @@
"optional": true,
"peer": true
},
"node_modules/pump": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
"integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
"dev": true,
"license": "MIT",
"dependencies": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"node_modules/punycode": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
@@ -11417,15 +11014,6 @@
"url": "https://opencollective.com/unified"
}
},
"node_modules/require-directory": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
"integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/require-from-string": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
@@ -11927,15 +11515,6 @@
"node": ">=0.10.0"
}
},
"node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"dev": true,
"engines": {
"node": ">=6"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -12441,264 +12020,6 @@
}
}
},
"node_modules/typescript-strict-plugin": {
"version": "2.4.4",
"resolved": "https://registry.npmjs.org/typescript-strict-plugin/-/typescript-strict-plugin-2.4.4.tgz",
"integrity": "sha512-OXcWHQk+pW9gqEL/Mb1eTgj/Yiqk1oHBERr9v4VInPOYN++p+cXejmQK/h/VlUPGD++FXQ8pgiqVMyEtxU4T6A==",
"dev": true,
"license": "MIT",
"dependencies": {
"chalk": "^3.0.0",
"execa": "^4.0.0",
"minimatch": "^9.0.3",
"ora": "^5.4.1",
"yargs": "^16.2.0"
},
"bin": {
"tsc-strict": "dist/cli/tsc-strict/index.js",
"update-strict-comments": "dist/cli/update-strict-comments/index.js"
}
},
"node_modules/typescript-strict-plugin/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/chalk/ansi-styles?sponsor=1"
}
},
"node_modules/typescript-strict-plugin/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,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/typescript-strict-plugin/node_modules/chalk": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
"integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/typescript-strict-plugin/node_modules/cliui": {
"version": "7.0.4",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
"integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^4.2.0",
"strip-ansi": "^6.0.0",
"wrap-ansi": "^7.0.0"
}
},
"node_modules/typescript-strict-plugin/node_modules/color-convert": {
"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,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
},
"engines": {
"node": ">=7.0.0"
}
},
"node_modules/typescript-strict-plugin/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,
"license": "MIT"
},
"node_modules/typescript-strict-plugin/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,
"license": "MIT"
},
"node_modules/typescript-strict-plugin/node_modules/execa": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
"dev": true,
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.0",
"get-stream": "^5.0.0",
"human-signals": "^1.1.1",
"is-stream": "^2.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.0",
"onetime": "^5.1.0",
"signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/typescript-strict-plugin/node_modules/get-stream": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true,
"license": "MIT",
"dependencies": {
"pump": "^3.0.0"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typescript-strict-plugin/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/typescript-strict-plugin/node_modules/human-signals": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=8.12.0"
}
},
"node_modules/typescript-strict-plugin/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/typescript-strict-plugin/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,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/typescript-strict-plugin/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,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
"is-fullwidth-code-point": "^3.0.0",
"strip-ansi": "^6.0.1"
},
"engines": {
"node": ">=8"
}
},
"node_modules/typescript-strict-plugin/node_modules/supports-color": {
"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,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/typescript-strict-plugin/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,
"license": "MIT",
"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/typescript-strict-plugin/node_modules/yargs": {
"version": "16.2.0",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
"integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
"dev": true,
"license": "MIT",
"dependencies": {
"cliui": "^7.0.2",
"escalade": "^3.1.1",
"get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
"string-width": "^4.2.0",
"y18n": "^5.0.5",
"yargs-parser": "^20.2.2"
},
"engines": {
"node": ">=10"
}
},
"node_modules/typescript-strict-plugin/node_modules/yargs-parser": {
"version": "20.2.9",
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
"integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=10"
}
},
"node_modules/uc.micro": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
@@ -13683,16 +13004,6 @@
"node": ">=14"
}
},
"node_modules/wcwidth": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
"dev": true,
"license": "MIT",
"dependencies": {
"defaults": "^1.0.3"
}
},
"node_modules/web-streams-polyfill": {
"version": "4.0.0-beta.3",
"resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
@@ -14010,12 +13321,6 @@
"url": "https://github.com/chalk/strip-ansi?sponsor=1"
}
},
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
"dev": true
},
"node_modules/ws": {
"version": "8.18.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz",
@@ -14067,15 +13372,6 @@
"optional": true,
"peer": true
},
"node_modules/y18n": {
"version": "5.0.8",
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
"integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
"dev": true,
"engines": {
"node": ">=10"
}
},
"node_modules/yaml": {
"version": "2.4.5",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz",

View File

@@ -13,7 +13,7 @@
"build": "npm run typecheck && vite build",
"build:types": "vite build --config vite.types.config.mts && node scripts/prepare-types.js",
"zipdist": "node scripts/zipdist.js",
"typecheck": "vue-tsc --noEmit && tsc --noEmit && tsc-strict",
"typecheck": "vue-tsc --noEmit && tsc --noEmit",
"format": "prettier --write './**/*.{js,ts,tsx,vue,mts}'",
"format:check": "prettier --check './**/*.{js,ts,tsx,vue,mts}'",
"test:browser": "npx playwright test",
@@ -58,7 +58,6 @@
"tsx": "^4.15.6",
"typescript": "^5.4.5",
"typescript-eslint": "^8.0.0",
"typescript-strict-plugin": "^2.4.4",
"unplugin-icons": "^0.19.3",
"unplugin-vue-components": "^0.27.4",
"vite": "^5.4.14",

View File

@@ -40,6 +40,7 @@ const showContextMenu = (event: MouseEvent) => {
}
onMounted(() => {
// @ts-expect-error fixme ts strict error
window['__COMFYUI_FRONTEND_VERSION__'] = config.app_version
console.log('ComfyUI Front-end version:', config.app_version)

View File

@@ -55,6 +55,7 @@ const classArray = computed(() => {
} else if (typeof props.class === 'string') {
return props.class.split(' ')
} else if (typeof props.class === 'object') {
// @ts-expect-error fixme ts strict error
return Object.keys(props.class).filter((key) => props.class[key])
}
return []

View File

@@ -98,12 +98,14 @@ const defaultIcon = iconOptions.find(
(option) => option.value === nodeBookmarkStore.defaultBookmarkIcon
)
// @ts-expect-error fixme ts strict error
const selectedIcon = ref<{ name: string; value: string }>(defaultIcon)
const finalColor = ref(
props.initialColor || nodeBookmarkStore.defaultBookmarkColor
)
const resetCustomization = () => {
// @ts-expect-error fixme ts strict error
selectedIcon.value =
iconOptions.find((option) => option.value === props.initialIcon) ||
defaultIcon

View File

@@ -101,13 +101,16 @@ const fileSize = computed(() =>
download.fileSize.value ? formatSize(download.fileSize.value) : '?'
)
const electronDownloadStore = useElectronDownloadStore()
// @ts-expect-error fixme ts strict error
const [savePath, filename] = props.label.split('/')
electronDownloadStore.$subscribe((_, { downloads }) => {
const download = downloads.find((download) => props.url === download.url)
if (download) {
// @ts-expect-error fixme ts strict error
downloadProgress.value = Number((download.progress * 100).toFixed(1))
// @ts-expect-error fixme ts strict error
status.value = download.status
}
})

View File

@@ -170,18 +170,21 @@ const deleteCommand = async (node: RenderedTreeExplorerNode) => {
await node.handleDelete?.()
emit('nodeDelete', node)
}
// @ts-expect-error fixme ts strict error
const menuItems = computed<MenuItem[]>(() =>
[
getAddFolderMenuItem(menuTargetNode.value),
{
label: t('g.rename'),
icon: 'pi pi-file-edit',
// @ts-expect-error fixme ts strict error
command: () => renameCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleRename !== undefined
},
{
label: t('g.delete'),
icon: 'pi pi-trash',
// @ts-expect-error fixme ts strict error
command: () => deleteCommand(menuTargetNode.value),
visible: menuTargetNode.value?.handleDelete !== undefined,
isAsync: true // The delete command can be async
@@ -189,6 +192,7 @@ const menuItems = computed<MenuItem[]>(() =>
...extraMenuItems.value
].map((menuItem) => ({
...menuItem,
// @ts-expect-error fixme ts strict error
command: wrapCommandWithErrorHandler(menuItem.command, {
isAsync: menuItem.isAsync ?? false
})
@@ -226,6 +230,7 @@ defineExpose({
* @param targetNodeKey - The key of the node where the folder will be added under
*/
addFolderCommand: (targetNodeKey: string) => {
// @ts-expect-error fixme ts strict error
addFolderCommand(findNodeByKey(renderedRoot.value, targetNodeKey))
}
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { mount } from '@vue/test-utils'
import PrimeVue from 'primevue/config'
import InputText from 'primevue/inputtext'
@@ -14,6 +13,7 @@ describe('EditableText', () => {
app.use(PrimeVue)
})
// @ts-expect-error fixme ts strict error
const mountComponent = (props, options = {}) => {
return mount(EditableText, {
global: {
@@ -65,6 +65,7 @@ describe('EditableText', () => {
})
await wrapper.findComponent(InputText).trigger('blur')
expect(wrapper.emitted('edit')).toBeTruthy()
// @ts-expect-error fixme ts strict error
expect(wrapper.emitted('edit')[0]).toEqual(['Test Text'])
})
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { createTestingPinia } from '@pinia/testing'
import { mount } from '@vue/test-utils'
import Badge from 'primevue/badge'
@@ -59,6 +58,7 @@ describe('TreeExplorerTreeNode', () => {
expect(wrapper.findComponent(EditableText).props('modelValue')).toBe(
'Test Node'
)
// @ts-expect-error fixme ts strict error
expect(wrapper.findComponent(Badge).props()['value'].toString()).toBe('3')
})

View File

@@ -157,7 +157,9 @@ const categories = computed<SettingTreeNode[]>(() =>
].map((node) => ({
...node,
translatedLabel: t(
// @ts-expect-error fixme ts strict error
`settingsCategories.${normalizeI18nKey(node.label)}`,
// @ts-expect-error fixme ts strict error
node.label
)
}))
@@ -175,12 +177,16 @@ onMounted(() => {
})
const sortedGroups = (category: SettingTreeNode): ISettingGroup[] => {
return [...(category.children ?? [])]
.sort((a, b) => a.label.localeCompare(b.label))
.map((group) => ({
label: group.label,
settings: flattenTree<SettingParams>(group)
}))
// @ts-expect-error fixme ts strict error
return (
[...(category.children ?? [])]
// @ts-expect-error fixme ts strict error
.sort((a, b) => a.label.localeCompare(b.label))
.map((group) => ({
label: group.label,
settings: flattenTree<SettingParams>(group)
}))
)
}
const searchQuery = ref<string>('')

View File

@@ -4,7 +4,7 @@
@submit="submit"
:resolver="zodResolver(issueReportSchema)"
>
<Panel :pt="$attrs.pt">
<Panel :pt="$attrs.pt as any">
<template #header>
<div class="flex items-center gap-2">
<span class="font-bold">{{ title }}</span>

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { Form } from '@primevue/forms'
import { mount } from '@vue/test-utils'
import Checkbox from 'primevue/checkbox'
@@ -95,12 +94,15 @@ vi.mock('@primevue/forms', () => ({
},
methods: {
onSubmit() {
// @ts-expect-error fixme ts strict error
this.$emit('submit', {
valid: true,
// @ts-expect-error fixme ts strict error
values: this.formValues
})
},
updateFieldValue(name: string, value: any) {
// @ts-expect-error fixme ts strict error
this.formValues[name] = value
}
}
@@ -116,13 +118,17 @@ vi.mock('@primevue/forms', () => ({
}
},
methods: {
// @ts-expect-error fixme ts strict error
updateValue(value) {
// @ts-expect-error fixme ts strict error
this.modelValue = value
// @ts-expect-error fixme ts strict error
let parent = this.$parent
while (parent && parent.$options.name !== 'Form') {
parent = parent.$parent
}
if (parent) {
// @ts-expect-error fixme ts strict error
parent.updateFieldValue(this.name, value)
}
}
@@ -163,6 +169,7 @@ describe('ReportIssuePanel', () => {
for (const field of DEFAULT_FIELDS) {
const checkbox = checkboxes.find(
// @ts-expect-error fixme ts strict error
(checkbox) => checkbox.props('value') === field
)
expect(checkbox).toBeDefined()
@@ -218,12 +225,11 @@ describe('ReportIssuePanel', () => {
})
// Filter out the contact preferences checkboxes
const fieldCheckboxes = wrapper
.findAllComponents(Checkbox)
.filter(
(checkbox) =>
!['followUp', 'notifyOnResolution'].includes(checkbox.props('value'))
)
const fieldCheckboxes = wrapper.findAllComponents(Checkbox).filter(
// @ts-expect-error fixme ts strict error
(checkbox) =>
!['followUp', 'notifyOnResolution'].includes(checkbox.props('value'))
)
expect(fieldCheckboxes.length).toBe(1)
expect(fieldCheckboxes.at(0)?.props('value')).toBe('Settings')
})
@@ -235,6 +241,7 @@ describe('ReportIssuePanel', () => {
})
const customCheckbox = wrapper
.findAllComponents(Checkbox)
// @ts-expect-error fixme ts strict error
.find((checkbox) => checkbox.props('value') === 'CustomField')
expect(customCheckbox).toBeDefined()
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { mount } from '@vue/test-utils'
import { createPinia } from 'pinia'
import PrimeVue from 'primevue/config'

View File

@@ -126,6 +126,7 @@ watch(
for (const n of comfyApp.graph.nodes) {
if (!n.widgets) continue
for (const w of n.widgets) {
// @ts-expect-error fixme ts strict error
if (w[IS_CONTROL_WIDGET]) {
updateControlWidgetLabel(w)
if (w.linkedWidgets) {
@@ -170,6 +171,7 @@ const loadCustomNodesI18n = async () => {
const comfyAppReady = ref(false)
const workflowPersistence = useWorkflowPersistence()
// @ts-expect-error fixme ts strict error
useCanvasDrop(canvasRef)
useLitegraphSettings()
@@ -190,12 +192,15 @@ onMounted(async () => {
CORE_SETTINGS.forEach((setting) => {
settingStore.addSetting(setting)
})
// @ts-expect-error fixme ts strict error
await comfyApp.setup(canvasRef.value)
canvasStore.canvas = comfyApp.canvas
canvasStore.canvas.render_canvas_border = false
workspaceStore.spinner = false
// @ts-expect-error fixme ts strict error
window['app'] = comfyApp
// @ts-expect-error fixme ts strict error
window['graph'] = comfyApp.graph
comfyAppReady.value = true

View File

@@ -146,6 +146,7 @@ const getCategoryIcon = (category: string) => {
camera: 'pi pi-camera',
light: 'pi pi-sun'
}
// @ts-expect-error fixme ts strict error
return `${icons[category]} text-white text-lg`
}

View File

@@ -95,6 +95,7 @@ watch(
if (load3d.value) {
const rawLoad3d = toRaw(load3d.value)
// @ts-expect-error fixme ts strict error
rawLoad3d.setEdgeThreshold(newValue)
}
}
@@ -132,6 +133,7 @@ const handleEvents = (action: 'add' | 'remove') => {
onMounted(() => {
load3d.value = useLoad3dService().registerLoad3d(
node.value as LGraphNode,
// @ts-expect-error fixme ts strict error
container.value,
props.type
)

View File

@@ -169,6 +169,7 @@ watch(
watch(
() => props.edgeThreshold,
(newValue) => {
// @ts-expect-error fixme ts strict error
edgeThreshold.value = newValue
}
)

View File

@@ -94,6 +94,7 @@ const addNode = (nodeDef: ComfyNodeDefImpl) => {
const eventDetail = triggerEvent.value?.detail
if (eventDetail && eventDetail.subType === 'empty-release') {
// @ts-expect-error fixme ts strict error
eventDetail.linkReleaseContext.links.forEach((link: ConnectingLink) => {
ConnectingLinkImpl.createFromPlainObject(link).connectTo(node)
})
@@ -121,6 +122,7 @@ const showSearchBox = (e: LiteGraphCanvasEvent) => {
showNewSearchBox(e)
}
} else {
// @ts-expect-error fixme ts strict error
canvasStore.canvas.showSearchBox(detail.originalEvent)
}
}
@@ -137,7 +139,9 @@ const showNewSearchBox = (e: LiteGraphCanvasEvent) => {
const filter = nodeDefStore.nodeSearchService.getFilterById(
firstLink.releaseSlotType
)
// @ts-expect-error fixme ts strict error
const dataType = firstLink.type.toString()
// @ts-expect-error fixme ts strict error
addFilter([filter, dataType])
}
@@ -180,6 +184,7 @@ const showContextMenu = (e: LiteGraphCanvasEvent) => {
slotTo: firstLink.input,
afterRerouteId: firstLink.afterRerouteId
}
// @ts-expect-error fixme ts strict error
canvasStore.canvas.showConnectionMenu({
...connectionOptions,
...commonOptions

View File

@@ -116,11 +116,13 @@ const renderedRoot = computed<TreeExplorerNode<ModelOrFolder>>(() => {
return {
key: node.key,
// @ts-expect-error fixme ts strict error
label: model
? nameFormat === 'title'
? model.title
: model.simplified_file_name
: node.label,
// @ts-expect-error fixme ts strict error
leaf: node.leaf,
data: node.data,
getIcon() {
@@ -134,6 +136,7 @@ const renderedRoot = computed<TreeExplorerNode<ModelOrFolder>>(() => {
}
return 'pi pi-folder'
},
// @ts-expect-error fixme ts strict error
getBadgeText() {
// Return null to apply default badge text
// Return empty string to hide badge
@@ -146,13 +149,16 @@ const renderedRoot = computed<TreeExplorerNode<ModelOrFolder>>(() => {
draggable: node.leaf,
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
const provider = modelToNodeStore.getNodeProvider(model.directory)
if (provider) {
const node = useLitegraphService().addNodeOnGraph(provider.nodeDef)
// @ts-expect-error fixme ts strict error
const widget = node.widgets.find(
(widget) => widget.name === provider.key
)
if (widget) {
// @ts-expect-error fixme ts strict error
widget.value = model.file_name
}
}

View File

@@ -114,8 +114,10 @@ const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
return {
key: node.key,
label: node.leaf ? node.data.display_name : node.label,
// @ts-expect-error fixme ts strict error
leaf: node.leaf,
data: node.data,
// @ts-expect-error fixme ts strict error
getIcon() {
if (this.leaf) {
return 'pi pi-circle-fill'
@@ -132,6 +134,7 @@ const renderedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(() => {
},
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
useLitegraphService().addNodeOnGraph(this.data)
} else {
toggleNodeOnEvent(e, this)
@@ -173,6 +176,7 @@ const handleSearch = (query: string) => {
)
nextTick(() => {
// @ts-expect-error fixme ts strict error
expandNode(filteredRoot.value)
})
}
@@ -189,6 +193,7 @@ const onAddFilter = (filterAndValue: FilterAndValue) => {
handleSearch(searchQuery.value)
}
// @ts-expect-error fixme ts strict error
const onRemoveFilter = (filterAndValue) => {
const index = filters.value.findIndex((f) => f === filterAndValue)
if (index !== -1) {

View File

@@ -267,7 +267,9 @@ const renderTreeNode = (
return {
key: node.key,
// @ts-expect-error fixme ts strict error
label: node.label,
// @ts-expect-error fixme ts strict error
leaf: node.leaf,
data: node.data,
children,

View File

@@ -131,6 +131,7 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
return {
key: node.key,
label: node.leaf ? node.data.display_name : node.label,
// @ts-expect-error fixme ts strict error
leaf: node.leaf,
data: node.data,
getIcon() {
@@ -161,15 +162,19 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
handleDrop(data: TreeExplorerDragAndDropData<ComfyNodeDefImpl>) {
const nodeDefToAdd = data.data.data
// Remove bookmark if the source is the top level bookmarked node.
// @ts-expect-error fixme ts strict error
if (nodeBookmarkStore.isBookmarked(nodeDefToAdd)) {
// @ts-expect-error fixme ts strict error
nodeBookmarkStore.toggleBookmark(nodeDefToAdd)
}
const folderNodeDef = node.data as ComfyNodeDefImpl
// @ts-expect-error fixme ts strict error
const nodePath = folderNodeDef.category + '/' + nodeDefToAdd.name
nodeBookmarkStore.addBookmark(nodePath)
},
handleClick(e: MouseEvent) {
if (this.leaf) {
// @ts-expect-error fixme ts strict error
useLitegraphService().addNodeOnGraph(this.data)
} else {
toggleNodeOnEvent(e, node)
@@ -185,6 +190,7 @@ const renderedBookmarkedRoot = computed<TreeExplorerNode<ComfyNodeDefImpl>>(
}
},
handleDelete() {
// @ts-expect-error fixme ts strict error
nodeBookmarkStore.deleteBookmarkFolder(this.data)
}
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import {
ContextMenu,
DragAndScale,
@@ -15,13 +14,22 @@ import {
* Assign all properties of LiteGraph to window to make it backward compatible.
*/
export const useGlobalLitegraph = () => {
// @ts-expect-error fixme ts strict error
window['LiteGraph'] = LiteGraph
// @ts-expect-error fixme ts strict error
window['LGraph'] = LGraph
// @ts-expect-error fixme ts strict error
window['LLink'] = LLink
// @ts-expect-error fixme ts strict error
window['LGraphNode'] = LGraphNode
// @ts-expect-error fixme ts strict error
window['LGraphGroup'] = LGraphGroup
// @ts-expect-error fixme ts strict error
window['DragAndScale'] = DragAndScale
// @ts-expect-error fixme ts strict error
window['LGraphCanvas'] = LGraphCanvas
// @ts-expect-error fixme ts strict error
window['ContextMenu'] = ContextMenu
// @ts-expect-error fixme ts strict error
window['LGraphBadge'] = LGraphBadge
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { LGraphNode, type NodeId } from '@comfyorg/litegraph/dist/LGraphNode'
@@ -40,9 +39,11 @@ const Workflow = {
Registered: 1,
InWorkflow: 2
},
// @ts-expect-error fixme ts strict error
isInUseGroupNode(name) {
const id = `${PREFIX}${SEPARATOR}${name}`
// Check if lready registered/in use in this workflow
// @ts-expect-error fixme ts strict error
if (app.graph.extra?.groupNodes?.[name]) {
if (app.graph.nodes.find((n) => n.type === id)) {
return Workflow.InUse.InWorkflow
@@ -57,12 +58,14 @@ const Workflow = {
if (!extra) app.graph.extra = extra = {}
let groupNodes = extra.groupNodes
if (!groupNodes) extra.groupNodes = groupNodes = {}
// @ts-expect-error fixme ts strict error
groupNodes[name] = data
}
}
class GroupNodeBuilder {
nodes: LGraphNode[]
// @ts-expect-error fixme ts strict error
nodeData: GroupNodeWorkflowData
constructor(nodes: LGraphNode[]) {
@@ -121,15 +124,18 @@ class GroupNodeBuilder {
}
getNodeData() {
// @ts-expect-error fixme ts strict error
const storeLinkTypes = (config) => {
// Store link types for dynamically typed nodes e.g. reroutes
for (const link of config.links) {
const origin = app.graph.getNodeById(link[4])
// @ts-expect-error fixme ts strict error
const type = origin.outputs[link[1]].type
link.push(type)
}
}
// @ts-expect-error fixme ts strict error
const storeExternalLinks = (config) => {
// Store any external links to the group in the config so when rebuilding we add extra slots
config.external = []
@@ -160,6 +166,7 @@ class GroupNodeBuilder {
// Use the built in copyToClipboard function to generate the node data we need
try {
// @ts-expect-error fixme ts strict error
const serialised = serialise(this.nodes, app.canvas.graph)
const config = JSON.parse(serialised)
@@ -186,12 +193,18 @@ export class GroupNodeConfig {
primitiveToWidget: {}
nodeInputs: {}
outputVisibility: any[]
// @ts-expect-error fixme ts strict error
nodeDef: ComfyNodeDef
// @ts-expect-error fixme ts strict error
inputs: any[]
// @ts-expect-error fixme ts strict error
linksFrom: {}
// @ts-expect-error fixme ts strict error
linksTo: {}
// @ts-expect-error fixme ts strict error
externalFrom: {}
// @ts-expect-error fixme ts strict error
constructor(name, nodeData) {
this.name = name
this.nodeData = nodeData
@@ -222,6 +235,7 @@ export class GroupNodeConfig {
category: 'group nodes' + (SEPARATOR + source),
input: { required: {} },
description: `Group node combining ${this.nodeData.nodes
// @ts-expect-error fixme ts strict error
.map((n) => n.type)
.join(', ')}`,
python_module: 'custom_nodes.' + this.name,
@@ -239,8 +253,10 @@ export class GroupNodeConfig {
}
for (const p of this.#convertedToProcess) {
// @ts-expect-error fixme ts strict error
p()
}
// @ts-expect-error fixme ts strict error
this.#convertedToProcess = null
await app.registerNodeDef(`${PREFIX}${SEPARATOR}` + this.name, this.nodeDef)
useNodeDefStore().addNodeDef(this.nodeDef)
@@ -258,31 +274,43 @@ export class GroupNodeConfig {
// Skip links outside the copy config
if (sourceNodeId == null) continue
// @ts-expect-error fixme ts strict error
if (!this.linksFrom[sourceNodeId]) {
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId] = {}
}
// @ts-expect-error fixme ts strict error
if (!this.linksFrom[sourceNodeId][sourceNodeSlot]) {
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId][sourceNodeSlot] = []
}
// @ts-expect-error fixme ts strict error
this.linksFrom[sourceNodeId][sourceNodeSlot].push(l)
// @ts-expect-error fixme ts strict error
if (!this.linksTo[targetNodeId]) {
// @ts-expect-error fixme ts strict error
this.linksTo[targetNodeId] = {}
}
// @ts-expect-error fixme ts strict error
this.linksTo[targetNodeId][targetNodeSlot] = l
}
if (this.nodeData.external) {
for (const ext of this.nodeData.external) {
// @ts-expect-error fixme ts strict error
if (!this.externalFrom[ext[0]]) {
// @ts-expect-error fixme ts strict error
this.externalFrom[ext[0]] = { [ext[1]]: ext[2] }
} else {
// @ts-expect-error fixme ts strict error
this.externalFrom[ext[0]][ext[1]] = ext[2]
}
}
}
}
// @ts-expect-error fixme ts strict error
processNode(node, seenInputs, seenOutputs) {
const def = this.getNodeDef(node)
if (!def) return
@@ -293,10 +321,13 @@ export class GroupNodeConfig {
if (def.output?.length) this.processNodeOutputs(node, seenOutputs, def)
}
// @ts-expect-error fixme ts strict error
getNodeDef(node) {
// @ts-expect-error fixme ts strict error
const def = globalDefs[node.type]
if (def) return def
// @ts-expect-error fixme ts strict error
const linksFrom = this.linksFrom[node.index]
if (node.type === 'PrimitiveNode') {
// Skip as its not linked
@@ -307,12 +338,14 @@ export class GroupNodeConfig {
// Use the array items
const source = node.outputs[0].widget.name
const fromTypeName = this.nodeData.nodes[linksFrom['0'][0][2]].type
// @ts-expect-error fixme ts strict error
const fromType = globalDefs[fromTypeName]
const input =
fromType.input.required[source] ?? fromType.input.optional[source]
type = input[0]
}
// @ts-expect-error fixme ts strict error
const def = (this.primitiveDefs[node.index] = {
input: {
required: {
@@ -325,7 +358,9 @@ export class GroupNodeConfig {
})
return def
} else if (node.type === 'Reroute') {
// @ts-expect-error fixme ts strict error
const linksTo = this.linksTo[node.index]
// @ts-expect-error fixme ts strict error
if (linksTo && linksFrom && !this.externalFrom[node.index]?.[0]) {
// Being used internally
return null
@@ -341,6 +376,7 @@ export class GroupNodeConfig {
rerouteType = input.type
}
if (input.widget) {
// @ts-expect-error fixme ts strict error
const targetDef = globalDefs[node.type]
const targetWidget =
targetDef.input.required[input.widget.name] ??
@@ -373,6 +409,7 @@ export class GroupNodeConfig {
}
if (rerouteType === '*') {
// Check for an external link
// @ts-expect-error fixme ts strict error
const t = this.externalFrom[node.index]?.[0]
if (t) {
rerouteType = t
@@ -402,10 +439,12 @@ export class GroupNodeConfig {
)
}
// @ts-expect-error fixme ts strict error
getInputConfig(node, inputName, seenInputs, config, extra?) {
const customConfig = this.nodeData.config?.[node.index]?.input?.[inputName]
let name =
customConfig?.name ??
// @ts-expect-error fixme ts strict error
node.inputs?.find((inp) => inp.name === inputName)?.label ??
inputName
let key = name
@@ -427,6 +466,7 @@ export class GroupNodeConfig {
if (config[0] === 'IMAGEUPLOAD') {
if (!extra) extra = {}
extra.widget =
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index]?.[config[1]?.widget ?? 'image'] ??
'image'
}
@@ -438,19 +478,23 @@ export class GroupNodeConfig {
return { name, config, customConfig }
}
// @ts-expect-error fixme ts strict error
processWidgetInputs(inputs, node, inputNames, seenInputs) {
const slots = []
const converted = new Map()
// @ts-expect-error fixme ts strict error
const widgetMap = (this.oldToNewWidgetMap[node.index] = {})
for (const inputName of inputNames) {
if (useWidgetStore().inputIsWidget(inputs[inputName])) {
const convertedIndex = node.inputs?.findIndex(
// @ts-expect-error fixme ts strict error
(inp) => inp.name === inputName && inp.widget?.name === inputName
)
if (convertedIndex > -1) {
// This widget has been converted to a widget
// We need to store this in the correct position so link ids line up
converted.set(convertedIndex, inputName)
// @ts-expect-error fixme ts strict error
widgetMap[inputName] = null
} else {
// Normal widget
@@ -460,8 +504,11 @@ export class GroupNodeConfig {
seenInputs,
inputs[inputName]
)
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
// @ts-expect-error fixme ts strict error
widgetMap[inputName] = name
// @ts-expect-error fixme ts strict error
this.newToOldWidgetMap[name] = { node, inputName }
}
} else {
@@ -472,11 +519,13 @@ export class GroupNodeConfig {
return { converted, slots }
}
// @ts-expect-error fixme ts strict error
checkPrimitiveConnection(link, inputName, inputs) {
const sourceNode = this.nodeData.nodes[link[0]]
if (sourceNode.type === 'PrimitiveNode') {
// Merge link configurations
const [sourceNodeId, _, targetNodeId, __] = link
// @ts-expect-error fixme ts strict error
const primitiveDef = this.primitiveDefs[sourceNodeId]
const targetWidget = inputs[inputName]
const primitiveConfig = primitiveDef.input.required.value
@@ -494,13 +543,16 @@ export class GroupNodeConfig {
? { ...inputs[inputName][1] }
: {}
// @ts-expect-error fixme ts strict error
let name = this.oldToNewWidgetMap[sourceNodeId]['value']
name = name.substr(0, name.length - 6)
primitiveConfig[1].control_after_generate = true
primitiveConfig[1].control_prefix = name
// @ts-expect-error fixme ts strict error
let toPrimitive = this.widgetToPrimitive[targetNodeId]
if (!toPrimitive) {
// @ts-expect-error fixme ts strict error
toPrimitive = this.widgetToPrimitive[targetNodeId] = {}
}
if (toPrimitive[inputName]) {
@@ -508,15 +560,19 @@ export class GroupNodeConfig {
}
toPrimitive[inputName] = sourceNodeId
// @ts-expect-error fixme ts strict error
let toWidget = this.primitiveToWidget[sourceNodeId]
if (!toWidget) {
// @ts-expect-error fixme ts strict error
toWidget = this.primitiveToWidget[sourceNodeId] = []
}
toWidget.push({ nodeId: targetNodeId, inputName })
}
}
// @ts-expect-error fixme ts strict error
processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs) {
// @ts-expect-error fixme ts strict error
this.nodeInputs[node.index] = {}
for (let i = 0; i < slots.length; i++) {
const inputName = slots[i]
@@ -533,21 +589,30 @@ export class GroupNodeConfig {
inputs[inputName]
)
// @ts-expect-error fixme ts strict error
this.nodeInputs[node.index][inputName] = name
if (customConfig?.visible === false) continue
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
inputMap[i] = this.inputCount++
}
}
processConvertedWidgets(
// @ts-expect-error fixme ts strict error
inputs,
// @ts-expect-error fixme ts strict error
node,
// @ts-expect-error fixme ts strict error
slots,
// @ts-expect-error fixme ts strict error
converted,
// @ts-expect-error fixme ts strict error
linksTo,
// @ts-expect-error fixme ts strict error
inputMap,
// @ts-expect-error fixme ts strict error
seenInputs
) {
// Add converted widgets sorted into their index order (ordered as they were converted) so link ids match up
@@ -576,12 +641,17 @@ export class GroupNodeConfig {
}
)
// @ts-expect-error fixme ts strict error
this.nodeDef.input.required[name] = config
// @ts-expect-error fixme ts strict error
this.newToOldWidgetMap[name] = { node, inputName }
// @ts-expect-error fixme ts strict error
if (!this.oldToNewWidgetMap[node.index]) {
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index] = {}
}
// @ts-expect-error fixme ts strict error
this.oldToNewWidgetMap[node.index][inputName] = name
inputMap[slots.length + i] = this.inputCount++
@@ -589,7 +659,9 @@ export class GroupNodeConfig {
}
#convertedToProcess = []
// @ts-expect-error fixme ts strict error
processNodeInputs(node, seenInputs, inputs) {
// @ts-expect-error fixme ts strict error
const inputMapping = []
const inputNames = Object.keys(inputs)
@@ -601,11 +673,14 @@ export class GroupNodeConfig {
inputNames,
seenInputs
)
// @ts-expect-error fixme ts strict error
const linksTo = this.linksTo[node.index] ?? {}
// @ts-expect-error fixme ts strict error
const inputMap = (this.oldToNewInputMap[node.index] = {})
this.processInputSlots(inputs, node, slots, linksTo, inputMap, seenInputs)
// Converted inputs have to be processed after all other nodes as they'll be at the end of the list
// @ts-expect-error fixme ts strict error
this.#convertedToProcess.push(() =>
this.processConvertedWidgets(
inputs,
@@ -618,17 +693,22 @@ export class GroupNodeConfig {
)
)
// @ts-expect-error fixme ts strict error
return inputMapping
}
// @ts-expect-error fixme ts strict error
processNodeOutputs(node, seenOutputs, def) {
// @ts-expect-error fixme ts strict error
const oldToNew = (this.oldToNewOutputMap[node.index] = {})
// Add outputs
for (let outputId = 0; outputId < def.output.length; outputId++) {
// @ts-expect-error fixme ts strict error
const linksFrom = this.linksFrom[node.index]
// If this output is linked internally we flag it to hide
const hasLink =
// @ts-expect-error fixme ts strict error
linksFrom?.[outputId] && !this.externalFrom[node.index]?.[outputId]
const customConfig =
this.nodeData.config?.[node.index]?.output?.[outputId]
@@ -638,17 +718,22 @@ export class GroupNodeConfig {
continue
}
// @ts-expect-error fixme ts strict error
oldToNew[outputId] = this.nodeDef.output.length
// @ts-expect-error fixme ts strict error
this.newToOldOutputMap[this.nodeDef.output.length] = {
node,
slot: outputId
}
// @ts-expect-error fixme ts strict error
this.nodeDef.output.push(def.output[outputId])
// @ts-expect-error fixme ts strict error
this.nodeDef.output_is_list.push(def.output_is_list[outputId])
let label = customConfig?.name
if (!label) {
label = def.output_name?.[outputId] ?? def.output[outputId]
// @ts-expect-error fixme ts strict error
const output = node.outputs.find((o) => o.name === label)
if (output?.label) {
label = output.label
@@ -665,10 +750,12 @@ export class GroupNodeConfig {
}
seenOutputs[name] = 1
// @ts-expect-error fixme ts strict error
this.nodeDef.output_name.push(name)
}
}
// @ts-expect-error fixme ts strict error
static async registerFromWorkflow(groupNodes, missingNodeTypes) {
for (const g in groupNodes) {
const groupData = groupNodes[g]
@@ -686,6 +773,7 @@ export class GroupNodeConfig {
type: `${PREFIX}${SEPARATOR}` + g,
action: {
text: 'Remove from workflow',
// @ts-expect-error fixme ts strict error
callback: (e) => {
delete groupNodes[g]
e.target.textContent = 'Removed'
@@ -733,6 +821,7 @@ export class GroupNodeHandler {
}
innerNode.index = innerNodeIndex
// @ts-expect-error fixme ts strict error
innerNode.getInputNode = (slot) => {
// Check if this input is internal or external
const externalSlot =
@@ -752,17 +841,17 @@ export class GroupNodeHandler {
return inputNode
}
// @ts-expect-error fixme ts strict error
innerNode.getInputLink = (slot) => {
const externalSlot =
this.groupData.oldToNewInputMap[innerNode.index]?.[slot]
if (externalSlot != null) {
// The inner node is connected via the group node inputs
const linkId = this.node.inputs[externalSlot].link
// @ts-expect-error fixme ts strict error
let link = app.graph.links[linkId]
// Use the outer link, but update the target to the inner node
// @ts-expect-error
// TODO: Fix this
link = {
...link,
target_id: innerNode.id,
@@ -812,10 +901,14 @@ export class GroupNodeHandler {
this.node.getInnerNodes = () => {
if (!this.innerNodes) {
// @ts-expect-error fixme ts strict error
this.node.setInnerNodes(
// @ts-expect-error fixme ts strict error
this.groupData.nodeData.nodes.map((n, i) => {
const innerNode = LiteGraph.createNode(n.type)
// @ts-expect-error fixme ts strict error
innerNode.configure(n)
// @ts-expect-error fixme ts strict error
innerNode.id = `${this.node.id}:${i}`
return innerNode
})
@@ -827,36 +920,50 @@ export class GroupNodeHandler {
return this.innerNodes
}
// @ts-expect-error fixme ts strict error
this.node.recreate = async () => {
const id = this.node.id
const sz = this.node.size
// @ts-expect-error fixme ts strict error
const nodes = this.node.convertToNodes()
// @ts-expect-error fixme ts strict error
const groupNode = LiteGraph.createNode(this.node.type)
// @ts-expect-error fixme ts strict error
groupNode.id = id
// Reuse the existing nodes for this instance
// @ts-expect-error fixme ts strict error
groupNode.setInnerNodes(nodes)
// @ts-expect-error fixme ts strict error
groupNode[GROUP].populateWidgets()
// @ts-expect-error fixme ts strict error
app.graph.add(groupNode)
// @ts-expect-error fixme ts strict error
groupNode.setSize([
// @ts-expect-error fixme ts strict error
Math.max(groupNode.size[0], sz[0]),
// @ts-expect-error fixme ts strict error
Math.max(groupNode.size[1], sz[1])
])
// Remove all converted nodes and relink them
const builder = new GroupNodeBuilder(nodes)
const nodeData = builder.getNodeData()
// @ts-expect-error fixme ts strict error
groupNode[GROUP].groupData.nodeData.links = nodeData.links
// @ts-expect-error fixme ts strict error
groupNode[GROUP].replaceNodes(nodes)
return groupNode
}
// @ts-expect-error fixme ts strict error
this.node.convertToNodes = () => {
const addInnerNodes = () => {
// Clone the node data so we dont mutate it for other nodes
const c = { ...this.groupData.nodeData }
c.nodes = [...c.nodes]
// @ts-expect-error fixme ts strict error
const innerNodes = this.node.getInnerNodes()
let ids = []
for (let i = 0; i < c.nodes.length; i++) {
@@ -864,6 +971,7 @@ export class GroupNodeHandler {
// Use existing IDs if they are set on the inner nodes
// @ts-expect-error id can be string or number
if (id == null || isNaN(id)) {
// @ts-expect-error fixme ts strict error
id = undefined
} else {
ids.push(id)
@@ -886,15 +994,21 @@ export class GroupNodeHandler {
const innerNode = innerNodes[i]
newNodes.push(newNode)
// @ts-expect-error fixme ts strict error
if (left == null || newNode.pos[0] < left) {
// @ts-expect-error fixme ts strict error
left = newNode.pos[0]
}
// @ts-expect-error fixme ts strict error
if (top == null || newNode.pos[1] < top) {
// @ts-expect-error fixme ts strict error
top = newNode.pos[1]
}
// @ts-expect-error fixme ts strict error
if (!newNode.widgets) continue
// @ts-expect-error fixme ts strict error
const map = this.groupData.oldToNewWidgetMap[innerNode.index]
if (map) {
const widgets = Object.keys(map)
@@ -903,6 +1017,7 @@ export class GroupNodeHandler {
const newName = map[oldName]
if (!newName) continue
// @ts-expect-error fixme ts strict error
const widgetIndex = this.node.widgets.findIndex(
(w) => w.name === newName
)
@@ -910,20 +1025,28 @@ export class GroupNodeHandler {
// Populate the main and any linked widgets
if (innerNode.type === 'PrimitiveNode') {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < newNode.widgets.length; i++) {
// @ts-expect-error fixme ts strict error
newNode.widgets[i].value =
// @ts-expect-error fixme ts strict error
this.node.widgets[widgetIndex + i].value
}
} else {
// @ts-expect-error fixme ts strict error
const outerWidget = this.node.widgets[widgetIndex]
// @ts-expect-error fixme ts strict error
const newWidget = newNode.widgets.find(
(w) => w.name === oldName
)
if (!newWidget) continue
newWidget.value = outerWidget.value
// @ts-expect-error fixme ts strict error
for (let w = 0; w < outerWidget.linkedWidgets?.length; w++) {
// @ts-expect-error fixme ts strict error
newWidget.linkedWidgets[w].value =
// @ts-expect-error fixme ts strict error
outerWidget.linkedWidgets[w].value
}
}
@@ -933,13 +1056,16 @@ export class GroupNodeHandler {
// Shift each node
for (const newNode of newNodes) {
// @ts-expect-error fixme ts strict error
newNode.pos[0] -= left - x
// @ts-expect-error fixme ts strict error
newNode.pos[1] -= top - y
}
return { newNodes, selectedIds }
}
// @ts-expect-error fixme ts strict error
const reconnectInputs = (selectedIds) => {
for (const innerNodeIndex in this.groupData.oldToNewInputMap) {
const id = selectedIds[innerNodeIndex]
@@ -954,11 +1080,13 @@ export class GroupNodeHandler {
if (!link) continue
// connect this node output to the input of another node
const originNode = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
originNode.connect(link.origin_slot, newNode, +innerInputId)
}
}
}
// @ts-expect-error fixme ts strict error
const reconnectOutputs = (selectedIds) => {
for (
let groupOutputId = 0;
@@ -973,6 +1101,7 @@ export class GroupNodeHandler {
const link = app.graph.links[l]
const targetNode = app.graph.getNodeById(link.target_id)
const newNode = app.graph.getNodeById(selectedIds[slot.node.index])
// @ts-expect-error fixme ts strict error
newNode.connect(slot.slot, targetNode, link.target_slot)
}
}
@@ -995,8 +1124,10 @@ export class GroupNodeHandler {
const getExtraMenuOptions = this.node.getExtraMenuOptions
// @ts-expect-error Should pass patched return value getExtraMenuOptions
this.node.getExtraMenuOptions = function (_, options) {
// @ts-expect-error fixme ts strict error
getExtraMenuOptions?.apply(this, arguments)
// @ts-expect-error fixme ts strict error
let optionIndex = options.findIndex((o) => o.content === 'Outputs')
if (optionIndex === -1) optionIndex = options.length
else optionIndex++
@@ -1008,11 +1139,13 @@ export class GroupNodeHandler {
content: 'Convert to nodes',
// @ts-expect-error
callback: () => {
// @ts-expect-error fixme ts strict error
return this.convertToNodes()
}
},
{
content: 'Manage Group Node',
// @ts-expect-error fixme ts strict error
callback: () => manageGroupNodes(this.type)
}
)
@@ -1021,6 +1154,7 @@ export class GroupNodeHandler {
// Draw custom collapse icon to identity this as a group
const onDrawTitleBox = this.node.onDrawTitleBox
this.node.onDrawTitleBox = function (ctx, height) {
// @ts-expect-error fixme ts strict error
onDrawTitleBox?.apply(this, arguments)
const fill = ctx.fillStyle
@@ -1044,11 +1178,14 @@ export class GroupNodeHandler {
const onDrawForeground = node.onDrawForeground
const groupData = this.groupData.nodeData
node.onDrawForeground = function (ctx) {
// @ts-expect-error fixme ts strict error
onDrawForeground?.apply?.(this, arguments)
if (
// @ts-expect-error fixme ts strict error
+app.runningNodeId === this.id &&
this.runningInternalNodeId !== null
) {
// @ts-expect-error fixme ts strict error
const n = groupData.nodes[this.runningInternalNodeId]
if (!n) return
const message = `Running ${n.title || n.type} (${this.runningInternalNodeId}/${groupData.nodes.length})`
@@ -1075,7 +1212,9 @@ export class GroupNodeHandler {
// Flag this node as needing to be reset
const onExecutionStart = this.node.onExecutionStart
this.node.onExecutionStart = function () {
// @ts-expect-error fixme ts strict error
this.resetExecution = true
// @ts-expect-error fixme ts strict error
return onExecutionStart?.apply(this, arguments)
}
@@ -1094,6 +1233,7 @@ export class GroupNodeHandler {
const widgetName = self.groupData.oldToNewWidgetMap[n][w]
const widget = this.widgets.find((w) => w.name === widgetName)
if (widget) {
// @ts-expect-error fixme ts strict error
widget.type = 'hidden'
widget.computeSize = () => [0, -4]
}
@@ -1101,21 +1241,27 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
return onNodeCreated?.apply(this, arguments)
}
// @ts-expect-error fixme ts strict error
function handleEvent(type, getId, getEvent) {
// @ts-expect-error fixme ts strict error
const handler = ({ detail }) => {
const id = getId(detail)
if (!id) return
const node = app.graph.getNodeById(id)
if (node) return
// @ts-expect-error fixme ts strict error
const innerNodeIndex = this.innerNodes?.findIndex((n) => n.id == id)
if (innerNodeIndex > -1) {
// @ts-expect-error fixme ts strict error
this.node.runningInternalNodeId = innerNodeIndex
api.dispatchCustomEvent(
type,
// @ts-expect-error fixme ts strict error
getEvent(detail, `${this.node.id}`, this.node)
)
}
@@ -1127,14 +1273,18 @@ export class GroupNodeHandler {
const executing = handleEvent.call(
this,
'executing',
// @ts-expect-error fixme ts strict error
(d) => d,
// @ts-expect-error fixme ts strict error
(_, id) => id
)
const executed = handleEvent.call(
this,
'executed',
// @ts-expect-error fixme ts strict error
(d) => d?.display_node || d?.node,
// @ts-expect-error fixme ts strict error
(d, id, node) => ({
...d,
node: id,
@@ -1145,6 +1295,7 @@ export class GroupNodeHandler {
const onRemoved = node.onRemoved
this.node.onRemoved = function () {
// @ts-expect-error fixme ts strict error
onRemoved?.apply(this, arguments)
api.removeEventListener('executing', executing)
api.removeEventListener('executed', executed)
@@ -1153,6 +1304,7 @@ export class GroupNodeHandler {
this.node.refreshComboInNode = (defs) => {
// Update combo widget options
for (const widgetName in this.groupData.newToOldWidgetMap) {
// @ts-expect-error fixme ts strict error
const widget = this.node.widgets.find((w) => w.name === widgetName)
if (widget?.type === 'combo') {
const old = this.groupData.newToOldWidgetMap[widgetName]
@@ -1169,7 +1321,9 @@ export class GroupNodeHandler {
// @ts-expect-error Widget values
!widget.options.values.includes(widget.value)
) {
// @ts-expect-error fixme ts strict error
widget.value = widget.options.values[0]
// @ts-expect-error fixme ts strict error
widget.callback(widget.value)
}
}
@@ -1179,6 +1333,7 @@ export class GroupNodeHandler {
updateInnerWidgets() {
for (const newWidgetName in this.groupData.newToOldWidgetMap) {
// @ts-expect-error fixme ts strict error
const newWidget = this.node.widgets.find((w) => w.name === newWidgetName)
if (!newWidget) continue
@@ -1191,6 +1346,7 @@ export class GroupNodeHandler {
const primitiveLinked = this.groupData.primitiveToWidget[old.node.index]
for (const linked of primitiveLinked ?? []) {
const node = this.innerNodes[linked.nodeId]
// @ts-expect-error fixme ts strict error
const widget = node.widgets.find((w) => w.name === linked.inputName)
if (widget) {
@@ -1206,6 +1362,7 @@ export class GroupNodeHandler {
const input = node.inputs[targetSlot]
if (input.widget) {
const widget = node.widgets?.find(
// @ts-expect-error fixme ts strict error
(w) => w.name === input.widget.name
)
if (widget) {
@@ -1216,6 +1373,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
const widget = innerNode.widgets?.find((w) => w.name === old.inputName)
if (widget) {
widget.value = newValue
@@ -1223,12 +1381,14 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
populatePrimitive(_node, nodeId, oldName) {
// Converted widget, populate primitive if linked
const primitiveId = this.groupData.widgetToPrimitive[nodeId]?.[oldName]
if (primitiveId == null) return
const targetWidgetName =
this.groupData.oldToNewWidgetMap[primitiveId]['value']
// @ts-expect-error fixme ts strict error
const targetWidgetIndex = this.node.widgets.findIndex(
(w) => w.name === targetWidgetName
)
@@ -1237,6 +1397,7 @@ export class GroupNodeHandler {
let len = primitiveNode.widgets.length
if (
len - 1 !==
// @ts-expect-error fixme ts strict error
this.node.widgets[targetWidgetIndex].linkedWidgets?.length
) {
// Fallback handling for if some reason the primitive has a different number of widgets
@@ -1244,6 +1405,7 @@ export class GroupNodeHandler {
len = 1
}
for (let i = 0; i < len; i++) {
// @ts-expect-error fixme ts strict error
this.node.widgets[targetWidgetIndex + i].value =
primitiveNode.widgets[i].value
}
@@ -1251,6 +1413,7 @@ export class GroupNodeHandler {
return true
}
// @ts-expect-error fixme ts strict error
populateReroute(node, nodeId, map) {
if (node.type !== 'Reroute') return
@@ -1267,6 +1430,7 @@ export class GroupNodeHandler {
if (v == null) return
const widgetName = Object.values(map)[0]
// @ts-expect-error fixme ts strict error
const widget = this.node.widgets.find((w) => w.name === widgetName)
if (widget) {
widget.value = v
@@ -1306,6 +1470,7 @@ export class GroupNodeHandler {
) {
// Find the inner widget and shift by the number of linked widgets as they will have been removed too
const innerWidget = this.innerNodes[nodeId].widgets?.find(
// @ts-expect-error fixme ts strict error
(w) => w.name === oldName
)
linkedShift += innerWidget?.linkedWidgets?.length ?? 0
@@ -1316,6 +1481,7 @@ export class GroupNodeHandler {
// Populate the main and any linked widget
mainWidget.value = node.widgets_values[i + linkedShift]
// @ts-expect-error fixme ts strict error
for (let w = 0; w < mainWidget.linkedWidgets?.length; w++) {
this.node.widgets[widgetIndex + w + 1].value =
node.widgets_values[i + ++linkedShift]
@@ -1324,6 +1490,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
replaceNodes(nodes) {
let top
let left
@@ -1345,6 +1512,7 @@ export class GroupNodeHandler {
this.node.pos = [left, top]
}
// @ts-expect-error fixme ts strict error
linkOutputs(originalNode, nodeId) {
if (!originalNode.outputs) return
@@ -1360,6 +1528,7 @@ export class GroupNodeHandler {
const newSlot =
this.groupData.oldToNewOutputMap[nodeId]?.[link.origin_slot]
if (newSlot != null) {
// @ts-expect-error fixme ts strict error
this.node.connect(newSlot, targetNode, link.target_slot)
}
}
@@ -1380,6 +1549,7 @@ export class GroupNodeHandler {
}
}
// @ts-expect-error fixme ts strict error
static getGroupData(node) {
return (node.nodeData ?? node.constructor?.nodeData)?.[GROUP]
}
@@ -1402,17 +1572,22 @@ export class GroupNodeHandler {
const groupNode = LiteGraph.createNode(`${PREFIX}${SEPARATOR}${name}`)
// Reuse the existing nodes for this instance
// @ts-expect-error fixme ts strict error
groupNode.setInnerNodes(builder.nodes)
// @ts-expect-error fixme ts strict error
groupNode[GROUP].populateWidgets()
// @ts-expect-error fixme ts strict error
app.graph.add(groupNode)
// Remove all converted nodes and relink them
// @ts-expect-error fixme ts strict error
groupNode[GROUP].replaceNodes(builder.nodes)
return groupNode
}
}
function addConvertToGroupOptions() {
// @ts-expect-error fixme ts strict error
function addConvertOption(options, index) {
const selected = Object.values(app.canvas.selected_nodes ?? {})
const disabled =
@@ -1425,6 +1600,7 @@ function addConvertToGroupOptions() {
})
}
// @ts-expect-error fixme ts strict error
function addManageOption(options, index) {
const groups = app.graph.extra?.groupNodes
const disabled = !groups || !Object.keys(groups).length
@@ -1438,6 +1614,7 @@ function addConvertToGroupOptions() {
// Add to canvas
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
// @ts-expect-error fixme ts strict error
const options = getCanvasMenuOptions.apply(this, arguments)
const index =
options.findIndex((o) => o?.content === 'Add Group') + 1 || options.length
@@ -1449,6 +1626,7 @@ function addConvertToGroupOptions() {
// Add to nodes
const getNodeMenuOptions = LGraphCanvas.prototype.getNodeMenuOptions
LGraphCanvas.prototype.getNodeMenuOptions = function (node) {
// @ts-expect-error fixme ts strict error
const options = getNodeMenuOptions.apply(this, arguments)
if (!GroupNodeHandler.isGroupNode(node)) {
const index =
@@ -1505,6 +1683,7 @@ function manageGroupNodes(type?: string) {
}
const id = 'Comfy.GroupNode'
// @ts-expect-error fixme ts strict error
let globalDefs
const ext: ComfyExtension = {
name: id,
@@ -1567,16 +1746,21 @@ const ext: ComfyExtension = {
},
nodeCreated(node) {
if (GroupNodeHandler.isGroupNode(node)) {
// @ts-expect-error fixme ts strict error
node[GROUP] = new GroupNodeHandler(node)
// Ensure group nodes pasted from other workflows are stored
// @ts-expect-error fixme ts strict error
if (node.title && node[GROUP]?.groupData?.nodeData) {
// @ts-expect-error fixme ts strict error
Workflow.storeGroupNode(node.title, node[GROUP].groupData.nodeData)
}
}
},
// @ts-expect-error fixme ts strict error
async refreshComboInNodes(defs) {
// Re-register group nodes so new ones are created with the correct options
// @ts-expect-error fixme ts strict error
Object.assign(globalDefs, defs)
const nodes = app.graph.extra?.groupNodes
if (nodes) {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import {
type LGraphNode,
type LGraphNodeConstructor,
@@ -17,6 +16,7 @@ const ORDER: symbol = Symbol()
const PREFIX = 'workflow'
const SEPARATOR = '>'
// @ts-expect-error fixme ts strict error
function merge(target, source) {
if (typeof target === 'object' && typeof source === 'object') {
for (const key in source) {
@@ -35,6 +35,7 @@ function merge(target, source) {
}
export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
// @ts-expect-error fixme ts strict error
tabs: Record<
'Inputs' | 'Outputs' | 'Widgets',
{ tab: HTMLAnchorElement; page: HTMLElement }
@@ -52,22 +53,30 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
>
>
> = {}
// @ts-expect-error fixme ts strict error
nodeItems: any[]
app: ComfyApp
// @ts-expect-error fixme ts strict error
groupNodeType: LGraphNodeConstructor<LGraphNode>
groupNodeDef: any
groupData: any
// @ts-expect-error fixme ts strict error
innerNodesList: HTMLUListElement
// @ts-expect-error fixme ts strict error
widgetsPage: HTMLElement
// @ts-expect-error fixme ts strict error
inputsPage: HTMLElement
// @ts-expect-error fixme ts strict error
outputsPage: HTMLElement
draggable: any
get selectedNodeInnerIndex() {
// @ts-expect-error fixme ts strict error
return +this.nodeItems[this.selectedNodeIndex].dataset.nodeindex
}
// @ts-expect-error fixme ts strict error
constructor(app) {
super()
this.app = app
@@ -76,14 +85,18 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
}) as HTMLDialogElement
}
// @ts-expect-error fixme ts strict error
changeTab(tab) {
this.tabs[this.selectedTab].tab.classList.remove('active')
this.tabs[this.selectedTab].page.classList.remove('active')
// @ts-expect-error fixme ts strict error
this.tabs[tab].tab.classList.add('active')
// @ts-expect-error fixme ts strict error
this.tabs[tab].page.classList.add('active')
this.selectedTab = tab
}
// @ts-expect-error fixme ts strict error
changeNode(index, force?) {
if (!force && this.selectedNodeIndex === index) return
@@ -114,11 +127,13 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.groupData = GroupNodeHandler.getGroupData(this.groupNodeType)
}
// @ts-expect-error fixme ts strict error
changeGroup(group, reset = true) {
this.selectedGroup = group
this.getGroupData()
const nodes = this.groupData.nodeData.nodes
// @ts-expect-error fixme ts strict error
this.nodeItems = nodes.map((n, i) =>
$el(
'li.draggable-item',
@@ -154,6 +169,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.changeNode(0)
} else {
const items = this.draggable.getAllItems()
// @ts-expect-error fixme ts strict error
let index = items.findIndex((item) => item.classList.contains('selected'))
if (index === -1) index = this.selectedNodeIndex
this.changeNode(index, true)
@@ -164,6 +180,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
this.draggable = new DraggableList(this.innerNodesList, 'li')
this.draggable.addEventListener(
'dragend',
// @ts-expect-error fixme ts strict error
({ detail: { oldPosition, newPosition } }) => {
if (oldPosition === newPosition) return
ordered.splice(newPosition, 0, ordered.splice(oldPosition, 1)[0])
@@ -186,6 +203,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
value: any
}) {
const { nodeIndex, section, prop, value } = props
// @ts-expect-error fixme ts strict error
const groupMod = (this.modifications[this.selectedGroup] ??= {})
const nodesMod = (groupMod.nodes ??= {})
const nodeMod = (nodesMod[nodeIndex ?? this.selectedNodeInnerIndex] ??= {})
@@ -198,10 +216,12 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
}
}
// @ts-expect-error fixme ts strict error
getEditElement(section, prop, value, placeholder, checked, checkable = true) {
if (value === placeholder) value = ''
const mods =
// @ts-expect-error fixme ts strict error
this.modifications[this.selectedGroup]?.nodes?.[
this.selectedNodeInnerIndex
]?.[section]?.[prop]
@@ -219,6 +239,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
value,
placeholder,
type: 'text',
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.storeModification({
section,
@@ -232,6 +253,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
type: 'checkbox',
checked,
disabled: !checkable,
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.storeModification({
section,
@@ -248,6 +270,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const widgets =
this.groupData.oldToNewWidgetMap[this.selectedNodeInnerIndex]
const items = Object.keys(widgets ?? {})
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.input
this.widgetsPage.replaceChildren(
@@ -267,9 +290,11 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
buildInputsPage() {
const inputs = this.groupData.nodeInputs[this.selectedNodeInnerIndex]
const items = Object.keys(inputs ?? {})
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.input
this.inputsPage.replaceChildren(
// @ts-expect-error fixme ts strict error
...items
.map((oldName) => {
let value = inputs[oldName]
@@ -299,12 +324,14 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const groupOutputs =
this.groupData.oldToNewOutputMap[this.selectedNodeInnerIndex]
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[this.selectedGroup]
const config = type.config?.[this.selectedNodeInnerIndex]?.output
const node = this.groupData.nodeData.nodes[this.selectedNodeInnerIndex]
const checkable = node.type !== 'PrimitiveNode'
this.outputsPage.replaceChildren(
...outputs
// @ts-expect-error fixme ts strict error
.map((type, slot) => {
const groupOutputIndex = groupOutputs?.[slot]
const oldName = innerNodeDef.output_name?.[slot] ?? type
@@ -327,6 +354,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
return !!outputs.length
}
// @ts-expect-error fixme ts strict error
show(type?) {
const groupNodes = Object.keys(app.graph.extra?.groupNodes ?? {}).sort(
(a, b) => a.localeCompare(b)
@@ -348,7 +376,9 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
['Inputs', this.inputsPage],
['Widgets', this.widgetsPage],
['Outputs', this.outputsPage]
// @ts-expect-error fixme ts strict error
].reduce((p, [name, page]: [string, HTMLElement]) => {
// @ts-expect-error fixme ts strict error
p[name] = {
tab: $el('a', {
onclick: () => {
@@ -367,6 +397,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
$el(
'select',
{
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.changeGroup(e.target.value)
}
@@ -409,6 +440,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
`Are you sure you want to remove the node: "${this.selectedGroup}"`
)
) {
// @ts-expect-error fixme ts strict error
delete app.graph.extra.groupNodes[this.selectedGroup]
LiteGraph.unregisterNodeType(
`${PREFIX}${SEPARATOR}` + this.selectedGroup
@@ -427,12 +459,14 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
let recreateNodes = []
const types = {}
for (const g in this.modifications) {
// @ts-expect-error fixme ts strict error
const type = app.graph.extra.groupNodes[g]
let config = (type.config ??= {})
let nodeMods = this.modifications[g]?.nodes
if (nodeMods) {
const keys = Object.keys(nodeMods)
// @ts-expect-error fixme ts strict error
if (nodeMods[keys[0]][ORDER]) {
// If any node is reordered, they will all need sequencing
const orderedNodes = []
@@ -440,8 +474,10 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
const orderedConfig = {}
for (const n of keys) {
// @ts-expect-error fixme ts strict error
const order = nodeMods[n][ORDER].order
orderedNodes[order] = type.nodes[+n]
// @ts-expect-error fixme ts strict error
orderedMods[order] = nodeMods[n]
orderedNodes[order].index = order
}
@@ -462,6 +498,7 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
// Rewrite modifications
for (const id of keys) {
if (config[id]) {
// @ts-expect-error fixme ts strict error
orderedConfig[type.nodes[id].index] = config[id]
}
delete config[id]
@@ -475,16 +512,20 @@ export class ManageGroupDialog extends ComfyDialog<HTMLDialogElement> {
merge(config, nodeMods)
}
// @ts-expect-error fixme ts strict error
types[g] = type
if (!nodesByType) {
nodesByType = app.graph.nodes.reduce((p, n) => {
// @ts-expect-error fixme ts strict error
p[n.type] ??= []
// @ts-expect-error fixme ts strict error
p[n.type].push(n)
return p
}, {})
}
// @ts-expect-error fixme ts strict error
const nodes = nodesByType[`${PREFIX}${SEPARATOR}` + g]
if (nodes) recreateNodes.push(...nodes)
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphGroup } from '@comfyorg/litegraph'
import { LGraphCanvas } from '@comfyorg/litegraph'
import type { LGraphNode } from '@comfyorg/litegraph'
@@ -26,7 +25,9 @@ app.registerExtension({
LGraphCanvas.prototype.getCanvasMenuOptions = function (
this: LGraphCanvas
) {
// @ts-expect-error fixme ts strict error
const options = orig.apply(this, arguments)
// @ts-expect-error fixme ts strict error
const group = this.graph.getGroupOnPos(
this.graph_mouse[0],
this.graph_mouse[1]
@@ -38,7 +39,9 @@ app.registerExtension({
callback: () => {
const group = new LGraphGroup()
addNodesToGroup(group, this.selectedItems)
// @ts-expect-error fixme ts strict error
this.graph.add(group)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -56,6 +59,7 @@ app.registerExtension({
disabled: !this.selectedItems?.size,
callback: () => {
addNodesToGroup(group, this.selectedItems)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -65,6 +69,7 @@ app.registerExtension({
return options
} else {
// Add a separator between the default options and the group options
// @ts-expect-error fixme ts strict error
options.push(null)
}
@@ -85,6 +90,7 @@ app.registerExtension({
'Comfy.GroupSelectedNodes.Padding'
)
group.resizeTo(group.children, padding)
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -93,6 +99,7 @@ app.registerExtension({
content: 'Select Nodes',
callback: () => {
this.selectNodes(nodesInGroup)
// @ts-expect-error fixme ts strict error
this.graph.change()
this.canvas.focus()
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { api } from '../../scripts/api'
import { app } from '../../scripts/app'
import { ComfyApp } from '../../scripts/app'
@@ -6,6 +5,7 @@ import { $el, ComfyDialog } from '../../scripts/ui'
import { ClipspaceDialog } from './clipspace'
// Helper function to convert a data URL to a Blob object
// @ts-expect-error fixme ts strict error
function dataURLToBlob(dataURL) {
const parts = dataURL.split(';base64,')
const contentType = parts[0].split(':')[1]
@@ -18,6 +18,7 @@ function dataURLToBlob(dataURL) {
return new Blob([arrayBuffer], { type: contentType })
}
// @ts-expect-error fixme ts strict error
function loadImage(imagePath) {
return new Promise((resolve) => {
const image = new Image()
@@ -30,6 +31,7 @@ function loadImage(imagePath) {
})
}
// @ts-expect-error fixme ts strict error
async function uploadMask(filepath, formData) {
await api
.fetchApi('/upload/mask', {
@@ -40,7 +42,9 @@ async function uploadMask(filepath, formData) {
console.error('Error:', error)
})
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']] = new Image()
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src = api.apiURL(
'/view?' +
new URLSearchParams(filepath).toString() +
@@ -48,12 +52,15 @@ async function uploadMask(filepath, formData) {
app.getRandParam()
)
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.images)
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.images[ComfyApp.clipspace['selectedIndex']] = filepath
ClipspaceDialog.invalidatePreview()
}
// @ts-expect-error fixme ts strict error
function prepare_mask(image, maskCanvas, maskCtx, maskColor) {
// paste mask data into alpha channel
maskCtx.drawImage(image, 0, 0, maskCanvas.width, maskCanvas.height)
@@ -94,32 +101,55 @@ export class MaskEditorDialogOld extends ComfyDialog {
static mousedown_x: number | null = null
static mousedown_y: number | null = null
// @ts-expect-error fixme ts strict error
brush: HTMLDivElement
maskCtx: any
// @ts-expect-error fixme ts strict error
maskCanvas: HTMLCanvasElement
// @ts-expect-error fixme ts strict error
brush_size_slider: HTMLDivElement
// @ts-expect-error fixme ts strict error
brush_opacity_slider: HTMLDivElement
// @ts-expect-error fixme ts strict error
colorButton: HTMLButtonElement
// @ts-expect-error fixme ts strict error
saveButton: HTMLButtonElement
// @ts-expect-error fixme ts strict error
zoom_ratio: number
// @ts-expect-error fixme ts strict error
pan_x: number
// @ts-expect-error fixme ts strict error
pan_y: number
// @ts-expect-error fixme ts strict error
imgCanvas: HTMLCanvasElement
// @ts-expect-error fixme ts strict error
last_display_style: string
// @ts-expect-error fixme ts strict error
is_visible: boolean
// @ts-expect-error fixme ts strict error
image: HTMLImageElement
// @ts-expect-error fixme ts strict error
handler_registered: boolean
// @ts-expect-error fixme ts strict error
brush_slider_input: HTMLInputElement
// @ts-expect-error fixme ts strict error
cursorX: number
// @ts-expect-error fixme ts strict error
cursorY: number
// @ts-expect-error fixme ts strict error
mousedown_pan_x: number
// @ts-expect-error fixme ts strict error
mousedown_pan_y: number
// @ts-expect-error fixme ts strict error
last_pressure: number
// @ts-expect-error fixme ts strict error
pointer_type: PointerType
// @ts-expect-error fixme ts strict error
brush_pointer_type_select: HTMLDivElement
static getInstance() {
if (!MaskEditorDialogOld.instance) {
// @ts-expect-error fixme ts strict error
MaskEditorDialogOld.instance = new MaskEditorDialogOld()
}
@@ -139,6 +169,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return []
}
// @ts-expect-error fixme ts strict error
createButton(name, callback): HTMLButtonElement {
var button = document.createElement('button')
button.style.pointerEvents = 'auto'
@@ -147,6 +178,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createLeftButton(name, callback) {
var button = this.createButton(name, callback)
button.style.cssFloat = 'left'
@@ -154,6 +186,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createRightButton(name, callback) {
var button = this.createButton(name, callback)
button.style.cssFloat = 'right'
@@ -161,6 +194,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return button
}
// @ts-expect-error fixme ts strict error
createLeftSlider(self, name, callback): HTMLDivElement {
const divElement = document.createElement('div')
divElement.id = 'maskeditor-slider'
@@ -195,6 +229,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return divElement
}
// @ts-expect-error fixme ts strict error
createOpacitySlider(self, name, callback): HTMLDivElement {
const divElement = document.createElement('div')
divElement.id = 'maskeditor-opacity-slider'
@@ -339,6 +374,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.brush_size_slider = this.createLeftSlider(
self,
'Thickness',
// @ts-expect-error fixme ts strict error
(event) => {
self.brush_size = event.target.value
self.updateBrushPreview(self)
@@ -348,6 +384,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.brush_opacity_slider = this.createOpacitySlider(
self,
'Opacity',
// @ts-expect-error fixme ts strict error
(event) => {
self.brush_opacity = event.target.value
if (self.brush_color_mode !== 'negative') {
@@ -482,6 +519,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
return this.element.style.display == 'block'
}
// @ts-expect-error fixme ts strict error
invalidateCanvas(orig_image, mask_image) {
this.imgCanvas.width = orig_image.width
this.imgCanvas.height = orig_image.height
@@ -494,10 +532,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
willReadFrequently: true
})
// @ts-expect-error fixme ts strict error
imgCtx.drawImage(orig_image, 0, 0, orig_image.width, orig_image.height)
prepare_mask(mask_image, this.maskCanvas, maskCtx, this.getMaskColor())
}
// @ts-expect-error fixme ts strict error
async setImages(imgCanvas) {
let self = this
@@ -510,6 +550,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
// image load
const alpha_url = new URL(
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src
)
alpha_url.searchParams.delete('channel')
@@ -519,6 +560,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
// original image load
const rgb_url = new URL(
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace.imgs[ComfyApp.clipspace['selectedIndex']].src
)
rgb_url.searchParams.delete('channel')
@@ -591,10 +633,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
this.imgCanvas.style.top = top
}
// @ts-expect-error fixme ts strict error
setEventHandler(maskCanvas) {
const self = this
if (!this.handler_registered) {
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('contextmenu', (event) => {
event.preventDefault()
})
@@ -615,12 +659,15 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
})
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('pointerdown', (event) =>
this.handlePointerDown(self, event)
)
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('pointermove', (event) =>
this.draw_move(self, event)
)
// @ts-expect-error fixme ts strict error
maskCanvas.addEventListener('touchmove', (event) =>
this.draw_move(self, event)
)
@@ -726,30 +773,40 @@ export class MaskEditorDialogOld extends ComfyDialog {
lasty = -1
lasttime = 0
// @ts-expect-error fixme ts strict error
static handleKeyDown(event) {
const self = MaskEditorDialogOld.instance
if (event.key === ']') {
// @ts-expect-error fixme ts strict error
self.brush_size = Math.min(self.brush_size + 2, 100)
// @ts-expect-error fixme ts strict error
self.brush_slider_input.value = self.brush_size
} else if (event.key === '[') {
// @ts-expect-error fixme ts strict error
self.brush_size = Math.max(self.brush_size - 2, 1)
// @ts-expect-error fixme ts strict error
self.brush_slider_input.value = self.brush_size
} else if (event.key === 'Enter') {
// @ts-expect-error fixme ts strict error
self.save()
}
// @ts-expect-error fixme ts strict error
self.updateBrushPreview(self)
}
// @ts-expect-error fixme ts strict error
static handlePointerUp(event) {
event.preventDefault()
this.mousedown_x = null
this.mousedown_y = null
// @ts-expect-error fixme ts strict error
MaskEditorDialogOld.instance.drawing_mode = false
}
// @ts-expect-error fixme ts strict error
updateBrushPreview(self) {
const brush = self.brush
@@ -762,6 +819,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
brush.style.top = centerY - self.brush_size * this.zoom_ratio + 'px'
}
// @ts-expect-error fixme ts strict error
handleWheelEvent(_, event) {
event.preventDefault()
@@ -785,6 +843,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
pointMoveEvent(self, event) {
this.cursorX = event.pageX
this.cursorY = event.pageY
@@ -814,10 +873,12 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
pan_move(self, event) {
if (event.buttons == 1) {
if (MaskEditorDialogOld.mousedown_x) {
let deltaX = MaskEditorDialogOld.mousedown_x - event.clientX
// @ts-expect-error fixme ts strict error
let deltaY = MaskEditorDialogOld.mousedown_y - event.clientY
self.pan_x = this.mousedown_pan_x - deltaX
@@ -828,6 +889,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
draw_move(self, event) {
if (event.ctrlKey || event.shiftKey) {
return
@@ -922,6 +984,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
} else if (
window.TouchEvent &&
event instanceof TouchEvent &&
// @ts-expect-error fixme ts strict error
diff < 20
) {
brush_size *= this.last_pressure
@@ -929,6 +992,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
brush_size = this.brush_size
}
// @ts-expect-error fixme ts strict error
if (diff > 20 && !this.drawing_mode)
// cannot tracking drawing_mode for touch event
requestAnimationFrame(() => {
@@ -961,6 +1025,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
handlePointerDown(self, event) {
if (event.ctrlKey) {
if (event.buttons == 1) {
@@ -1010,6 +1075,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
init_shape(self, compositionOperation) {
self.maskCtx.beginPath()
if (compositionOperation == CompositionOperation.SourceOver) {
@@ -1021,6 +1087,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
draw_shape(self, x, y, brush_size) {
if (self.pointer_type === PointerType.Rect) {
self.maskCtx.rect(
@@ -1043,7 +1110,9 @@ export class MaskEditorDialogOld extends ComfyDialog {
backupCanvas.width = this.image.width
backupCanvas.height = this.image.height
// @ts-expect-error fixme ts strict error
backupCtx.clearRect(0, 0, backupCanvas.width, backupCanvas.height)
// @ts-expect-error fixme ts strict error
backupCtx.drawImage(
this.maskCanvas,
0,
@@ -1057,6 +1126,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
)
// paste mask data into alpha channel
// @ts-expect-error fixme ts strict error
const backupData = backupCtx.getImageData(
0,
0,
@@ -1074,7 +1144,9 @@ export class MaskEditorDialogOld extends ComfyDialog {
backupData.data[i + 2] = 0
}
// @ts-expect-error fixme ts strict error
backupCtx.globalCompositeOperation = CompositionOperation.SourceOver
// @ts-expect-error fixme ts strict error
backupCtx.putImageData(backupData, 0, 0)
const formData = new FormData()
@@ -1086,13 +1158,17 @@ export class MaskEditorDialogOld extends ComfyDialog {
type: 'input'
}
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.images) ComfyApp.clipspace.images[0] = item
// @ts-expect-error fixme ts strict error
if (ComfyApp.clipspace.widgets) {
// @ts-expect-error fixme ts strict error
const index = ComfyApp.clipspace.widgets.findIndex(
(obj) => obj.name === 'image'
)
// @ts-expect-error fixme ts strict error
if (index >= 0) ComfyApp.clipspace.widgets[index].value = item
}
@@ -1104,6 +1180,7 @@ export class MaskEditorDialogOld extends ComfyDialog {
type Ref = { filename: string; subfolder?: string; type?: string }
const original_ref: Ref = {
// @ts-expect-error fixme ts strict error
filename: original_url.searchParams.get('filename')
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas } from '@comfyorg/litegraph'
import { t } from '@/i18n'
@@ -32,6 +31,7 @@ const id = 'Comfy.NodeTemplates'
const file = 'comfy.templates.json'
class ManageTemplates extends ComfyDialog {
// @ts-expect-error fixme ts strict error
templates: any[]
draggedEl: HTMLElement | null
saveVisualCue: number | null
@@ -65,6 +65,7 @@ class ManageTemplates extends ComfyDialog {
const btns = super.createButtons()
btns[0].textContent = 'Close'
btns[0].onclick = () => {
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
this.close()
}
@@ -106,11 +107,13 @@ class ManageTemplates extends ComfyDialog {
await api.storeUserData(file, templates, { stringify: false })
} catch (error) {
console.error(error)
// @ts-expect-error fixme ts strict error
useToastStore().addAlert(error.message)
}
}
async importAll() {
// @ts-expect-error fixme ts strict error
for (const file of this.importInput.files) {
if (file.type === 'application/json' || file.name.endsWith('.json')) {
const reader = new FileReader()
@@ -129,6 +132,7 @@ class ManageTemplates extends ComfyDialog {
}
}
// @ts-expect-error fixme ts strict error
this.importInput.value = null
this.close()
@@ -163,6 +167,7 @@ class ManageTemplates extends ComfyDialog {
'div',
{},
this.templates.flatMap((t, i) => {
// @ts-expect-error fixme ts strict error
let nameInput
return [
$el(
@@ -177,6 +182,7 @@ class ManageTemplates extends ComfyDialog {
gap: '5px',
backgroundColor: 'var(--comfy-menu-bg)'
},
// @ts-expect-error fixme ts strict error
ondragstart: (e) => {
this.draggedEl = e.currentTarget
e.currentTarget.style.opacity = '0.6'
@@ -184,6 +190,7 @@ class ManageTemplates extends ComfyDialog {
e.dataTransfer.effectAllowed = 'move'
e.dataTransfer.setDragImage(this.emptyImg, 0, 0)
},
// @ts-expect-error fixme ts strict error
ondragend: (e) => {
e.target.style.opacity = '1'
e.currentTarget.style.border = '1px dashed transparent'
@@ -192,7 +199,9 @@ class ManageTemplates extends ComfyDialog {
// rearrange the elements
this.element
.querySelectorAll('.templateManagerRow')
// @ts-expect-error fixme ts strict error
.forEach((el: HTMLElement, i) => {
// @ts-expect-error fixme ts strict error
var prev_i = Number.parseInt(el.dataset.id)
if (el == this.draggedEl && prev_i != i) {
@@ -206,6 +215,7 @@ class ManageTemplates extends ComfyDialog {
})
this.store()
},
// @ts-expect-error fixme ts strict error
ondragover: (e) => {
e.preventDefault()
if (e.currentTarget == this.draggedEl) return
@@ -232,6 +242,7 @@ class ManageTemplates extends ComfyDialog {
style: {
cursor: 'grab'
},
// @ts-expect-error fixme ts strict error
onmousedown: (e) => {
// enable dragging only from the label
if (e.target.localName == 'label')
@@ -246,7 +257,9 @@ class ManageTemplates extends ComfyDialog {
transitionProperty: 'background-color',
transitionDuration: '0s'
},
// @ts-expect-error fixme ts strict error
onchange: (e) => {
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
var el = e.target
var row = el.parentNode.parentNode
@@ -262,8 +275,10 @@ class ManageTemplates extends ComfyDialog {
el.style.backgroundColor = 'var(--comfy-input-bg)'
}, 15)
},
// @ts-expect-error fixme ts strict error
onkeypress: (e) => {
var el = e.target
// @ts-expect-error fixme ts strict error
clearTimeout(this.saveVisualCue)
el.style.transitionDuration = '0s'
el.style.backgroundColor = 'var(--comfy-input-bg)'
@@ -287,6 +302,7 @@ class ManageTemplates extends ComfyDialog {
const url = URL.createObjectURL(blob)
const a = $el('a', {
href: url,
// @ts-expect-error fixme ts strict error
download: (nameInput.value || t.name) + '.json',
style: { display: 'none' },
parent: document.body
@@ -305,6 +321,7 @@ class ManageTemplates extends ComfyDialog {
color: 'red',
fontWeight: 'normal'
},
// @ts-expect-error fixme ts strict error
onclick: (e) => {
const item = e.target.parentNode.parentNode
item.parentNode.removeChild(item)
@@ -315,6 +332,7 @@ class ManageTemplates extends ComfyDialog {
setTimeout(function () {
that.element
.querySelectorAll('.templateManagerRow')
// @ts-expect-error fixme ts strict error
.forEach((el: HTMLElement, i) => {
el.dataset.id = i.toString()
})
@@ -336,22 +354,27 @@ app.registerExtension({
setup() {
const manage = new ManageTemplates()
// @ts-expect-error fixme ts strict error
const clipboardAction = async (cb) => {
// We use the clipboard functions but dont want to overwrite the current user clipboard
// Restore it after we've run our callback
const old = localStorage.getItem('litegrapheditor_clipboard')
await cb()
// @ts-expect-error fixme ts strict error
localStorage.setItem('litegrapheditor_clipboard', old)
}
const orig = LGraphCanvas.prototype.getCanvasMenuOptions
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
// @ts-expect-error fixme ts strict error
const options = orig.apply(this, arguments)
// @ts-expect-error fixme ts strict error
options.push(null)
options.push({
content: `Save Selected as Template`,
disabled: !Object.keys(app.canvas.selected_nodes || {}).length,
// @ts-expect-error fixme ts strict error
callback: async () => {
const name = await useDialogService().prompt({
title: t('nodeTemplates.saveAsTemplate'),
@@ -363,6 +386,7 @@ app.registerExtension({
clipboardAction(() => {
app.canvas.copyToClipboard()
let data = localStorage.getItem('litegrapheditor_clipboard')
// @ts-expect-error fixme ts strict error
data = JSON.parse(data)
const nodeIds = Object.keys(app.canvas.selected_nodes)
for (let i = 0; i < nodeIds.length; i++) {
@@ -414,6 +438,7 @@ app.registerExtension({
}
})
// @ts-expect-error fixme ts strict error
subItems.push(null, {
content: 'Manage',
callback: () => manage.show()

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { LGraphNode } from '@comfyorg/litegraph'
@@ -21,6 +20,7 @@ app.registerExtension({
isVirtualNode: boolean
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = { text: '' }
@@ -59,6 +59,7 @@ app.registerExtension({
groupcolor = LGraphCanvas.node_colors.yellow.groupcolor
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = { text: '' }

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import type { IContextMenuValue } from '@comfyorg/litegraph'
import { LGraphCanvas, LGraphNode, LiteGraph } from '@comfyorg/litegraph'
@@ -19,6 +18,7 @@ app.registerExtension({
static defaultVisibility = false
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
if (!this.properties) {
this.properties = {}
@@ -31,6 +31,7 @@ app.registerExtension({
this.onAfterGraphConfigured = function () {
requestAnimationFrame(() => {
// @ts-expect-error fixme ts strict error
this.onConnectionsChange(LiteGraph.INPUT, null, true, null)
})
}
@@ -42,19 +43,23 @@ app.registerExtension({
if (connected && type === LiteGraph.OUTPUT) {
// Ignore wildcard nodes as these will be updated to real types
const types = new Set(
// @ts-expect-error fixme ts strict error
this.outputs[0].links
.map((l) => app.graph.links[l].type)
.filter((t) => t !== '*')
)
if (types.size > 1) {
const linksToDisconnect = []
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.outputs[0].links.length - 1; i++) {
// @ts-expect-error fixme ts strict error
const linkId = this.outputs[0].links[i]
const link = app.graph.links[linkId]
linksToDisconnect.push(link)
}
for (const link of linksToDisconnect) {
const node = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
node.disconnectInput(link.target_slot)
}
}
@@ -72,6 +77,7 @@ app.registerExtension({
const link = app.graph.links[linkId]
if (!link) return
const node = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
const type = node.constructor.type
if (type === 'Reroute') {
if (node === this) {
@@ -85,6 +91,7 @@ app.registerExtension({
} else {
// We've found the end
inputNode = currentNode
// @ts-expect-error fixme ts strict error
inputType = node.outputs[link.origin_slot]?.type ?? null
break
}
@@ -99,8 +106,10 @@ app.registerExtension({
const nodes: LGraphNode[] = [this]
let outputType = null
while (nodes.length) {
// @ts-expect-error fixme ts strict error
currentNode = nodes.pop()
const outputs =
// @ts-expect-error fixme ts strict error
(currentNode.outputs ? currentNode.outputs[0].links : []) || []
if (outputs.length) {
for (const linkId of outputs) {
@@ -110,25 +119,33 @@ app.registerExtension({
if (!link) continue
const node = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const type = node.constructor.type
if (type === 'Reroute') {
// Follow reroute nodes
// @ts-expect-error fixme ts strict error
nodes.push(node)
updateNodes.push(node)
} else {
// We've found an output
const nodeOutType =
// @ts-expect-error fixme ts strict error
node.inputs &&
// @ts-expect-error fixme ts strict error
node.inputs[link?.target_slot] &&
// @ts-expect-error fixme ts strict error
node.inputs[link.target_slot].type
? node.inputs[link.target_slot].type
? // @ts-expect-error fixme ts strict error
node.inputs[link.target_slot].type
: null
if (
inputType &&
// @ts-expect-error fixme ts strict error
!LiteGraph.isValidConnection(inputType, nodeOutType)
) {
// The output doesnt match our input so disconnect it
// @ts-expect-error fixme ts strict error
node.disconnectInput(link.target_slot)
} else {
outputType = nodeOutType
@@ -149,13 +166,18 @@ app.registerExtension({
for (const node of updateNodes) {
// If we dont have an input type we are always wildcard but we'll show the output type
// This lets you change the output link to a different type and all nodes will update
// @ts-expect-error fixme ts strict error
node.outputs[0].type = inputType || '*'
// @ts-expect-error fixme ts strict error
node.__outputType = displayType
// @ts-expect-error fixme ts strict error
node.outputs[0].name = node.properties.showOutputText
? displayType
: ''
// @ts-expect-error fixme ts strict error
node.setSize(node.computeSize())
// @ts-expect-error fixme ts strict error
for (const l of node.outputs[0].links || []) {
const link = app.graph.links[l]
if (link) {
@@ -163,6 +185,7 @@ app.registerExtension({
if (app.configuringGraph) continue
const targetNode = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const targetInput = targetNode.inputs?.[link.target_slot]
if (targetInput?.widget) {
const config = getWidgetConfig(targetInput)
@@ -185,17 +208,21 @@ app.registerExtension({
for (const node of updateNodes) {
if (widgetConfig && outputType) {
// @ts-expect-error fixme ts strict error
node.inputs[0].widget = { name: 'value' }
// @ts-expect-error fixme ts strict error
setWidgetConfig(node.inputs[0], [
widgetType ?? displayType,
widgetConfig
])
} else {
// @ts-expect-error fixme ts strict error
setWidgetConfig(node.inputs[0], null)
}
}
if (inputNode) {
// @ts-expect-error fixme ts strict error
const link = app.graph.links[inputNode.inputs[0].link]
if (link) {
link.color = color
@@ -205,8 +232,11 @@ app.registerExtension({
this.clone = function () {
const cloned = RerouteNode.prototype.clone.apply(this)
// @ts-expect-error fixme ts strict error
cloned.removeOutput(0)
// @ts-expect-error fixme ts strict error
cloned.addOutput(this.properties.showOutputText ? '*' : '', '*')
// @ts-expect-error fixme ts strict error
cloned.setSize(cloned.computeSize())
return cloned
}
@@ -215,6 +245,7 @@ app.registerExtension({
this.isVirtualNode = true
}
// @ts-expect-error fixme ts strict error
getExtraMenuOptions(_, options): IContextMenuValue[] {
options.unshift(
{
@@ -258,6 +289,7 @@ app.registerExtension({
]
}
// @ts-expect-error fixme ts strict error
static setDefaultTextVisibility(visible) {
RerouteNode.defaultVisibility = visible
if (visible) {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { applyTextReplacements } from '@/utils/searchAndReplace'
import { app } from '../../scripts/app'
@@ -17,11 +16,15 @@ app.registerExtension({
// When the SaveImage node is created we want to override the serialization of the output name widget to run our S&R
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated
? onNodeCreated.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
onNodeCreated.apply(this, arguments)
: undefined
// @ts-expect-error fixme ts strict error
const widget = this.widgets.find((w) => w.name === 'filename_prefix')
// @ts-expect-error fixme ts strict error
widget.serializeValue = () => {
// @ts-expect-error fixme ts strict error
return applyTextReplacements(app.graph.nodes, widget.value)
}
@@ -32,7 +35,8 @@ app.registerExtension({
const onNodeCreated = nodeType.prototype.onNodeCreated
nodeType.prototype.onNodeCreated = function () {
const r = onNodeCreated
? onNodeCreated.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
onNodeCreated.apply(this, arguments)
: undefined
if (!this.properties || !('Node name for S&R' in this.properties)) {

View File

@@ -1,18 +1,23 @@
// @ts-strict-ignore
import { LGraphCanvas, LiteGraph } from '@comfyorg/litegraph'
import { app } from '../../scripts/app'
// @ts-expect-error fixme ts strict error
let touchZooming
let touchCount = 0
app.registerExtension({
name: 'Comfy.SimpleTouchSupport',
setup() {
// @ts-expect-error fixme ts strict error
let touchDist
// @ts-expect-error fixme ts strict error
let touchTime
// @ts-expect-error fixme ts strict error
let lastTouch
// @ts-expect-error fixme ts strict error
let lastScale
// @ts-expect-error fixme ts strict error
function getMultiTouchPos(e) {
return Math.hypot(
e.touches[0].clientX - e.touches[1].clientX,
@@ -20,6 +25,7 @@ app.registerExtension({
)
}
// @ts-expect-error fixme ts strict error
function getMultiTouchCenter(e) {
return {
clientX: (e.touches[0].clientX + e.touches[1].clientX) / 2,
@@ -27,6 +33,7 @@ app.registerExtension({
}
}
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener(
'touchstart',
(e: TouchEvent) => {
@@ -52,10 +59,12 @@ app.registerExtension({
true
)
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener('touchend', (e: TouchEvent) => {
touchCount--
if (e.touches?.length !== 1) touchZooming = false
// @ts-expect-error fixme ts strict error
if (touchTime && !e.touches?.length) {
if (new Date().getTime() - touchTime > 600) {
if (e.target === app.canvasEl) {
@@ -73,10 +82,12 @@ app.registerExtension({
}
})
// @ts-expect-error fixme ts strict error
app.canvasEl.parentElement.addEventListener(
'touchmove',
(e) => {
touchTime = null
// @ts-expect-error fixme ts strict error
if (e.touches?.length === 2 && lastTouch && !e.ctrlKey && !e.shiftKey) {
e.preventDefault() // Prevent browser from zooming when two textareas are touched
app.canvas.pointer.isDown = false
@@ -89,6 +100,7 @@ app.registerExtension({
const center = getMultiTouchCenter(e)
// @ts-expect-error fixme ts strict error
let scale = (lastScale * newTouchDist) / touchDist
const newX = (center.clientX - lastTouch.clientX) / scale
@@ -112,6 +124,7 @@ app.registerExtension({
const newScale = app.canvas.ds.scale
// @ts-expect-error fixme ts strict error
const convertScaleToOffset = (scale) => [
center.clientX / scale - app.canvas.ds.offset[0],
center.clientY / scale - app.canvas.ds.offset[1]
@@ -135,17 +148,21 @@ app.registerExtension({
const processMouseDown = LGraphCanvas.prototype.processMouseDown
LGraphCanvas.prototype.processMouseDown = function () {
// @ts-expect-error fixme ts strict error
if (touchZooming || touchCount) {
return
}
app.canvas.pointer.isDown = false // Prevent context menu from opening on second tap
// @ts-expect-error fixme ts strict error
return processMouseDown.apply(this, arguments)
}
const processMouseMove = LGraphCanvas.prototype.processMouseMove
LGraphCanvas.prototype.processMouseMove = function () {
// @ts-expect-error fixme ts strict error
if (touchZooming || touchCount > 1) {
return
}
// @ts-expect-error fixme ts strict error
return processMouseMove.apply(this, arguments)
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import type { IWidget, LGraphNode } from '@comfyorg/litegraph'
import type { IStringWidget } from '@comfyorg/litegraph/dist/types/widgets'
@@ -64,7 +63,9 @@ async function uploadFile(
let path = data.name
if (data.subfolder) path = data.subfolder + '/' + path
// @ts-expect-error fixme ts strict error
if (!audioWidget.options.values.includes(path)) {
// @ts-expect-error fixme ts strict error
audioWidget.options.values.push(path)
}
@@ -78,6 +79,7 @@ async function uploadFile(
useToastStore().addAlert(resp.status + ' - ' + resp.statusText)
}
} catch (error) {
// @ts-expect-error fixme ts strict error
useToastStore().addAlert(error)
}
}
@@ -89,9 +91,11 @@ app.registerExtension({
async beforeRegisterNodeDef(nodeType, nodeData) {
if (
['LoadAudio', 'SaveAudio', 'PreviewAudio'].includes(
// @ts-expect-error fixme ts strict error
nodeType.prototype.comfyClass
)
) {
// @ts-expect-error fixme ts strict error
nodeData.input.required.audioUI = ['AUDIO_UI', {}]
}
},
@@ -115,6 +119,7 @@ app.registerExtension({
// Populate the audio widget UI on node execution.
const onExecuted = node.onExecuted
node.onExecuted = function (message: any) {
// @ts-expect-error fixme ts strict error
onExecuted?.apply(this, arguments)
const audios = message.audio
if (!audios) return
@@ -133,6 +138,7 @@ app.registerExtension({
for (const [nodeId, output] of Object.entries(nodeOutputs)) {
const node = app.graph.getNodeById(nodeId)
if ('audio' in output) {
// @ts-expect-error fixme ts strict error
const audioUIWidget = node.widgets.find(
(w) => w.name === 'audioUI'
) as unknown as DOMWidget<HTMLAudioElement, string>
@@ -157,9 +163,11 @@ app.registerExtension({
return {
AUDIOUPLOAD(node, inputName: string) {
// The widget that allows user to select file.
// @ts-expect-error fixme ts strict error
const audioWidget = node.widgets.find(
(w: IWidget) => w.name === 'audio'
) as IStringWidget
// @ts-expect-error fixme ts strict error
const audioUIWidget = node.widgets.find(
(w: IWidget) => w.name === 'audioUI'
) as unknown as DOMWidget<HTMLAudioElement, string>
@@ -178,6 +186,7 @@ app.registerExtension({
// Load saved audio file widget values if restoring from workflow
const onGraphConfigured = node.onGraphConfigured
node.onGraphConfigured = function () {
// @ts-expect-error fixme ts strict error
onGraphConfigured?.apply(this, arguments)
if (audioWidget.value) {
onAudioWidgetUpdate()

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { t } from '@/i18n'
import { useToastStore } from '@/stores/toastStore'
@@ -12,7 +11,9 @@ app.registerExtension({
getCustomWidgets() {
return {
WEBCAM(node, inputName) {
// @ts-expect-error fixme ts strict error
let res
// @ts-expect-error fixme ts strict error
node[WEBCAM_READY] = new Promise((resolve) => (res = resolve))
const container = document.createElement('div')
@@ -30,7 +31,9 @@ app.registerExtension({
})
container.replaceChildren(video)
// @ts-expect-error fixme ts strict error
setTimeout(() => res(video), 500) // Fallback as loadedmetadata doesnt fire sometimes?
// @ts-expect-error fixme ts strict error
video.addEventListener('loadedmetadata', () => res(video), false)
video.srcObject = stream
video.play()
@@ -44,10 +47,12 @@ app.registerExtension({
if (window.isSecureContext) {
label.textContent =
'Unable to load webcam, please ensure access is granted:\n' +
// @ts-expect-error fixme ts strict error
error.message
} else {
label.textContent =
'Unable to load webcam. A secure context is required, if you are not accessing ComfyUI on localhost (127.0.0.1) you will have to enable TLS (https)\n\n' +
// @ts-expect-error fixme ts strict error
error.message
}
@@ -64,10 +69,15 @@ app.registerExtension({
nodeCreated(node) {
if ((node.type, node.constructor.comfyClass !== 'WebcamCapture')) return
// @ts-expect-error fixme ts strict error
let video
// @ts-expect-error fixme ts strict error
const camera = node.widgets.find((w) => w.name === 'image')
// @ts-expect-error fixme ts strict error
const w = node.widgets.find((w) => w.name === 'width')
// @ts-expect-error fixme ts strict error
const h = node.widgets.find((w) => w.name === 'height')
// @ts-expect-error fixme ts strict error
const captureOnQueue = node.widgets.find(
(w) => w.name === 'capture_on_queue'
)
@@ -101,7 +111,9 @@ app.registerExtension({
btn.disabled = true
btn.serializeValue = () => undefined
// @ts-expect-error fixme ts strict error
camera.serializeValue = async () => {
// @ts-expect-error fixme ts strict error
if (captureOnQueue.value) {
capture()
} else if (!node.imgs?.length) {
@@ -111,6 +123,7 @@ app.registerExtension({
}
// Upload image to temp storage
// @ts-expect-error fixme ts strict error
const blob = await new Promise<Blob>((r) => canvas.toBlob(r))
const name = `${+new Date()}.png`
const file = new File([blob], name)
@@ -130,11 +143,15 @@ app.registerExtension({
return `webcam/${name} [temp]`
}
// @ts-expect-error fixme ts strict error
node[WEBCAM_READY].then((v) => {
video = v
// If width isnt specified then use video output resolution
// @ts-expect-error fixme ts strict error
if (!w.value) {
// @ts-expect-error fixme ts strict error
w.value = video.videoWidth || 640
// @ts-expect-error fixme ts strict error
h.value = video.videoHeight || 480
}
btn.disabled = false

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LGraphNode, LiteGraph } from '@comfyorg/litegraph'
import type {
IFoundSlot,
@@ -35,10 +34,13 @@ const GET_CONFIG = Symbol()
const replacePropertyName = 'Run widget replace on values'
export class PrimitiveNode extends LGraphNode {
// @ts-expect-error fixme ts strict error
controlValues: any[]
// @ts-expect-error fixme ts strict error
lastType: string
static category: string
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
this.addOutput('connect to widget input', '*')
this.serialize_widgets = true
@@ -63,11 +65,14 @@ export class PrimitiveNode extends LGraphNode {
// For each output link copy our value over the original widget value
for (const linkInfo of links) {
// @ts-expect-error fixme ts strict error
const node = this.graph.getNodeById(linkInfo.target_id)
// @ts-expect-error fixme ts strict error
const input = node.inputs[linkInfo.target_slot]
let widget: IWidget | undefined
const widgetName = (input.widget as { name: string }).name
if (widgetName) {
// @ts-expect-error fixme ts strict error
widget = node.widgets.find((w) => w.name === widgetName)
}
@@ -77,6 +82,7 @@ export class PrimitiveNode extends LGraphNode {
widget.callback(
widget.value,
app.canvas,
// @ts-expect-error fixme ts strict error
node,
app.canvas.graph_mouse,
{} as CanvasMouseEvent
@@ -91,7 +97,9 @@ export class PrimitiveNode extends LGraphNode {
if (widget?.type === 'combo') {
widget.options.values = this.outputs[0].widget[GET_CONFIG]()[0]
// @ts-expect-error fixme ts strict error
if (!widget.options.values.includes(widget.value as string)) {
// @ts-expect-error fixme ts strict error
widget.value = widget.options.values[0]
;(widget.callback as Function)(widget.value)
}
@@ -106,6 +114,7 @@ export class PrimitiveNode extends LGraphNode {
// Populate widget values from config data
if (this.widgets) {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.widgets_values.length; i++) {
const w = this.widgets[i]
if (w) {
@@ -141,6 +150,7 @@ export class PrimitiveNode extends LGraphNode {
}
}
// @ts-expect-error fixme ts strict error
onConnectOutput(
slot: number,
_type: string,
@@ -171,9 +181,11 @@ export class PrimitiveNode extends LGraphNode {
return
}
const linkId = this.outputs[0].links[0]
// @ts-expect-error fixme ts strict error
const link = this.graph.links[linkId]
if (!link) return
// @ts-expect-error fixme ts strict error
const theirNode = this.graph.getNodeById(link.target_id)
if (!theirNode || !theirNode.inputs) return
@@ -188,6 +200,7 @@ export class PrimitiveNode extends LGraphNode {
widget = input.widget
}
// @ts-expect-error fixme ts strict error
const config = widget[GET_CONFIG]?.()
if (!config) return
@@ -198,9 +211,11 @@ export class PrimitiveNode extends LGraphNode {
this.outputs[0].widget = widget
this.#createWidget(
// @ts-expect-error fixme ts strict error
widget[CONFIG] ?? config,
theirNode,
widget.name,
// @ts-expect-error fixme ts strict error
recreating
)
}
@@ -221,6 +236,7 @@ export class PrimitiveNode extends LGraphNode {
const [oldWidth, oldHeight] = this.size
let widget: IWidget | undefined
if (type in ComfyWidgets) {
// @ts-expect-error fixme ts strict error
widget = (ComfyWidgets[type](this, 'value', inputData, app) || {}).widget
} else {
// @ts-expect-error InputSpec is not typed correctly
@@ -243,6 +259,7 @@ export class PrimitiveNode extends LGraphNode {
control_value = 'fixed'
}
addValueControlWidgets(
// @ts-expect-error fixme ts strict error
this,
widget,
control_value as string,
@@ -250,6 +267,7 @@ export class PrimitiveNode extends LGraphNode {
inputData
)
let filter = this.widgets_values?.[2]
// @ts-expect-error fixme ts strict error
if (filter && this.widgets.length === 3) {
// @ts-expect-error change widget type from string to unknown
this.widgets[2].value = filter
@@ -259,10 +277,13 @@ export class PrimitiveNode extends LGraphNode {
// Restore any saved control values
const controlValues = this.controlValues
if (
// @ts-expect-error fixme ts strict error
this.lastType === this.widgets[0].type &&
// @ts-expect-error fixme ts strict error
controlValues?.length === this.widgets.length - 1
) {
for (let i = 0; i < controlValues.length; i++) {
// @ts-expect-error fixme ts strict error
this.widgets[i + 1].value = controlValues[i]
}
}
@@ -272,6 +293,7 @@ export class PrimitiveNode extends LGraphNode {
const callback = widget.callback
const self = this
widget.callback = function () {
// @ts-expect-error fixme ts strict error
const r = callback ? callback.apply(this, arguments) : undefined
self.applyToGraph()
return r
@@ -295,6 +317,7 @@ export class PrimitiveNode extends LGraphNode {
requestAnimationFrame(() => {
if (this.onResize) {
// @ts-expect-error fixme ts strict error
this.onResize(this.size)
}
})
@@ -306,7 +329,9 @@ export class PrimitiveNode extends LGraphNode {
this.#removeWidgets()
this.#onFirstConnection(true)
if (values?.length) {
// @ts-expect-error fixme ts strict error
for (let i = 0; i < this.widgets?.length; i++)
// @ts-expect-error fixme ts strict error
this.widgets[i].value = values[i]
}
return this.widgets?.[0]
@@ -322,8 +347,10 @@ export class PrimitiveNode extends LGraphNode {
delete output.widget[CONFIG]
}
// @ts-expect-error fixme ts strict error
if (links?.length < 2 && hasConfig) {
// Copy the widget options from the source
// @ts-expect-error fixme ts strict error
if (links.length) {
this.recreateWidget()
}
@@ -335,11 +362,13 @@ export class PrimitiveNode extends LGraphNode {
const isNumber = config1[0] === 'INT' || config1[0] === 'FLOAT'
if (!isNumber) return
// @ts-expect-error fixme ts strict error
for (const linkId of links) {
const link = app.graph.links[linkId]
if (!link) continue // Can be null when removing a node
const theirNode = app.graph.getNodeById(link.target_id)
// @ts-expect-error fixme ts strict error
const theirInput = theirNode.inputs[link.target_slot]
// Call is valid connection so it can merge the configs when validating
@@ -370,6 +399,7 @@ export class PrimitiveNode extends LGraphNode {
#isValidConnection(input: INodeInputSlot, forceUpdate?: boolean) {
// Only allow connections where the configs match
const output = this.outputs[0]
// @ts-expect-error fixme ts strict error
const config2 = input.widget[GET_CONFIG]()
return !!mergeIfValid.call(
this,
@@ -397,7 +427,9 @@ export class PrimitiveNode extends LGraphNode {
this.controlValues.push(this.widgets[i].value)
}
setTimeout(() => {
// @ts-expect-error fixme ts strict error
delete this.lastType
// @ts-expect-error fixme ts strict error
delete this.controlValues
}, 15)
this.widgets.length = 0
@@ -420,6 +452,7 @@ export function getWidgetConfig(slot: INodeInputSlot | INodeOutputSlot) {
}
function getConfig(widgetName: string) {
// @ts-expect-error fixme ts strict error
const { nodeData } = this.constructor
return (
nodeData?.input?.required?.[widgetName] ??
@@ -513,7 +546,9 @@ export function convertToInput(
...(inputIsOptional ? { shape: LiteGraph.SlotShape.HollowCircle } : {})
})
// @ts-expect-error fixme ts strict error
for (const widget of node.widgets) {
// @ts-expect-error fixme ts strict error
widget.last_y += LiteGraph.NODE_SLOT_HEIGHT
}
@@ -530,7 +565,9 @@ function convertToWidget(node: LGraphNode, widget: IWidget) {
const [oldWidth, oldHeight] = node.size
node.removeInput(node.inputs.findIndex((i) => i.widget?.name === widget.name))
// @ts-expect-error fixme ts strict error
for (const widget of node.widgets) {
// @ts-expect-error fixme ts strict error
widget.last_y -= LiteGraph.NODE_SLOT_HEIGHT
}
@@ -562,9 +599,11 @@ export function setWidgetConfig(
}
if ('link' in slot) {
// @ts-expect-error fixme ts strict error
const link = app.graph.links[slot.link]
if (link) {
const originNode = app.graph.getNodeById(link.origin_id)
// @ts-expect-error fixme ts strict error
if (isPrimitiveNode(originNode)) {
if (config) {
originNode.recreateWidget()
@@ -588,6 +627,7 @@ export function mergeIfValid(
config1 = getWidgetConfig(output)
}
// @ts-expect-error fixme ts strict error
const customSpec = mergeInputSpec(config1, config2)
if (customSpec || forceUpdate) {
@@ -595,17 +635,24 @@ export function mergeIfValid(
output.widget[CONFIG] = customSpec
}
// @ts-expect-error fixme ts strict error
const widget = recreateWidget?.call(this)
// When deleting a node this can be null
if (widget) {
// @ts-expect-error fixme ts strict error
const min = widget.options.min
// @ts-expect-error fixme ts strict error
const max = widget.options.max
// @ts-expect-error fixme ts strict error
if (min != null && widget.value < min) widget.value = min
// @ts-expect-error fixme ts strict error
if (max != null && widget.value > max) widget.value = max
// @ts-expect-error fixme ts strict error
widget.callback(widget.value)
}
}
// @ts-expect-error fixme ts strict error
return { customConfig: customSpec[1] }
}
@@ -622,6 +669,7 @@ app.registerExtension({
setup() {
app.canvas.getWidgetLinkType = function (widget, node) {
const nodeDefStore = useNodeDefStore()
// @ts-expect-error fixme ts strict error
const nodeDef = nodeDefStore.nodeDefsByName[node.type]
const input = nodeDef.inputs[widget.name]
return input?.type
@@ -675,6 +723,7 @@ app.registerExtension({
) {
if (!slot.input || !slot.input.widget) return []
// @ts-expect-error fixme ts strict error
const widget = this.widgets.find((w) => w.name === slot.input.widget.name)
if (!widget) return []
return [
@@ -685,13 +734,15 @@ app.registerExtension({
]
}
// @ts-expect-error fixme ts strict error
nodeType.prototype.getExtraMenuOptions = function (
this: LGraphNode,
_,
options
) {
const r = origGetExtraMenuOptions
? origGetExtraMenuOptions.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origGetExtraMenuOptions.apply(this, arguments)
: undefined
const getPointerCanvasPos = () => {
@@ -700,6 +751,7 @@ app.registerExtension({
}
if (this.widgets) {
// @ts-expect-error fixme ts strict error
const { canvasX, canvasY } = getPointerCanvasPos()
const widget = this.getWidgetOnPos(canvasX, canvasY)
// @ts-expect-error custom widget type
@@ -748,10 +800,12 @@ app.registerExtension({
options.push({
content: 'Convert Widget to Input',
submenu: {
// @ts-expect-error fixme ts strict error
options: toInput
}
})
} else {
// @ts-expect-error fixme ts strict error
options.push(...toInput, null)
}
}
@@ -778,8 +832,11 @@ app.registerExtension({
for (const input of this.inputs) {
if (input.widget) {
// @ts-expect-error fixme ts strict error
if (!input.widget[GET_CONFIG]) {
// @ts-expect-error fixme ts strict error
input.widget[GET_CONFIG] = () =>
// @ts-expect-error fixme ts strict error
getConfig.call(this, input.widget.name)
}
@@ -791,6 +848,7 @@ app.registerExtension({
// If we are an old converted combo then replace the input type and the stored link data
input.type = 'COMBO'
// @ts-expect-error fixme ts strict error
const link = app.graph.links[input.link]
if (link) {
link.type = input.type
@@ -800,6 +858,7 @@ app.registerExtension({
delete input.widget.config
}
// @ts-expect-error fixme ts strict error
const w = this.widgets.find((w) => w.name === input.widget.name)
if (w) {
hideWidget(this, w)
@@ -833,14 +892,19 @@ app.registerExtension({
const origOnConfigure = nodeType.prototype.onConfigure
nodeType.prototype.onConfigure = function (this: LGraphNode) {
const r = origOnConfigure
? origOnConfigure.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origOnConfigure.apply(this, arguments)
: undefined
if (!app.configuringGraph && this.inputs) {
// On copy + paste of nodes, ensure that widget configs are set up
for (const input of this.inputs) {
// @ts-expect-error fixme ts strict error
if (input.widget && !input.widget[GET_CONFIG]) {
// @ts-expect-error fixme ts strict error
input.widget[GET_CONFIG] = () =>
// @ts-expect-error fixme ts strict error
getConfig.call(this, input.widget.name)
// @ts-expect-error fixme ts strict error
const w = this.widgets.find((w) => w.name === input.widget.name)
if (w) {
hideWidget(this, w)
@@ -868,7 +932,8 @@ app.registerExtension({
slot: number
) {
const r = origOnInputDblClick
? origOnInputDblClick.apply(this, arguments)
? // @ts-expect-error fixme ts strict error
origOnInputDblClick.apply(this, arguments)
: undefined
const input = this.inputs[slot]
@@ -876,6 +941,7 @@ app.registerExtension({
// Not a widget input or already handled input
if (
!(input.type in ComfyWidgets) &&
// @ts-expect-error fixme ts strict error
!(input.widget?.[GET_CONFIG]?.()?.[0] instanceof Array)
) {
return r //also Not a ComfyWidgets input or combo (do nothing)
@@ -884,10 +950,12 @@ app.registerExtension({
// Create a primitive node
const node = LiteGraph.createNode('PrimitiveNode')
// @ts-expect-error fixme ts strict error
app.graph.add(node)
// Calculate a position that wont directly overlap another node
const pos: [number, number] = [
// @ts-expect-error fixme ts strict error
this.pos[0] - node.size[0] - 30,
this.pos[1]
]
@@ -895,8 +963,11 @@ app.registerExtension({
pos[1] += LiteGraph.NODE_TITLE_HEIGHT
}
// @ts-expect-error fixme ts strict error
node.pos = pos
// @ts-expect-error fixme ts strict error
node.connect(0, this, slot)
// @ts-expect-error fixme ts strict error
node.title = input.name
return r
@@ -905,6 +976,7 @@ app.registerExtension({
registerCustomNodes() {
LiteGraph.registerNodeType(
'PrimitiveNode',
// @ts-expect-error fixme ts strict error
Object.assign(PrimitiveNode, {
title: 'Primitive'
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import '@comfyorg/litegraph/style.css'
import { definePreset } from '@primevue/themes'
import Aura from '@primevue/themes/aura'
@@ -19,6 +18,7 @@ import { i18n } from './i18n'
const ComfyUIPreset = definePreset(Aura, {
semantic: {
// @ts-expect-error fixme ts strict error
primary: Aura['primitive'].blue
}
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import {
LGraph,
LGraphCanvas,
@@ -62,6 +61,7 @@ import { type ComfyWidgetConstructor, ComfyWidgets } from './widgets'
export const ANIM_PREVIEW_WIDGET = '$$comfy_animation_preview'
// @ts-expect-error fixme ts strict error
function sanitizeNodeName(string) {
let entityMap = {
'&': '',
@@ -73,6 +73,7 @@ function sanitizeNodeName(string) {
'=': ''
}
return String(string).replace(/[&<>"'`=]/g, function fromEntityMap(s) {
// @ts-expect-error fixme ts strict error
return entityMap[s]
})
}
@@ -110,17 +111,27 @@ export class ComfyApp {
vueAppReady: boolean
api: ComfyApi
ui: ComfyUI
// @ts-expect-error fixme ts strict error
extensionManager: ExtensionManager
// @ts-expect-error fixme ts strict error
_nodeOutputs: Record<string, any>
nodePreviewImages: Record<string, string[]>
// @ts-expect-error fixme ts strict error
graph: LGraph
// @ts-expect-error fixme ts strict error
canvas: LGraphCanvas
// @ts-expect-error fixme ts strict error
dragOverNode: LGraphNode | null
// @ts-expect-error fixme ts strict error
canvasEl: HTMLCanvasElement
// @ts-expect-error fixme ts strict error
lastNodeErrors: any[] | null
/** @type {ExecutionErrorWsMessage} */
// @ts-expect-error fixme ts strict error
lastExecutionError: { node_id?: NodeId } | null
// @ts-expect-error fixme ts strict error
configuringGraph: boolean
// @ts-expect-error fixme ts strict error
ctx: CanvasRenderingContext2D
bodyTop: HTMLElement
bodyLeft: HTMLElement
@@ -258,9 +269,11 @@ export class ComfyApp {
ComfyApp.clipspace_return_node = null
}
// @ts-expect-error fixme ts strict error
static copyToClipspace(node) {
var widgets = null
if (node.widgets) {
// @ts-expect-error fixme ts strict error
widgets = node.widgets.map(({ type, name, value }) => ({
type,
name,
@@ -361,6 +374,7 @@ export class ComfyApp {
}
if (ComfyApp.clipspace.widgets) {
ComfyApp.clipspace.widgets.forEach(({ type, name, value }) => {
// @ts-expect-error fixme ts strict error
const prop = Object.values(node.widgets).find(
(obj) => obj.type === type && obj.name === name
)
@@ -378,6 +392,7 @@ export class ComfyApp {
resultItem.filename +
(resultItem.type ? ` [${resultItem.type}]` : '')
} else {
// @ts-expect-error fixme ts strict error
prop.value = value
prop.callback?.(value)
}
@@ -394,6 +409,7 @@ export class ComfyApp {
const serialize = LGraph.prototype.serialize
const self = this
LGraph.prototype.serialize = function () {
// @ts-expect-error fixme ts strict error
const workflow = serialize.apply(this, arguments)
// Store the drag & scale info in the serialized workflow if the setting is enabled
@@ -432,17 +448,22 @@ export class ComfyApp {
}
// Dragging from Chrome->Firefox there is a file but its a bmp, so ignore that
if (
// @ts-expect-error fixme ts strict error
event.dataTransfer.files.length &&
// @ts-expect-error fixme ts strict error
event.dataTransfer.files[0].type !== 'image/bmp'
) {
// @ts-expect-error fixme ts strict error
await this.handleFile(event.dataTransfer.files[0])
} else {
// Try loading the first URI in the transfer list
const validTypes = ['text/uri-list', 'text/x-moz-url']
// @ts-expect-error fixme ts strict error
const match = [...event.dataTransfer.types].find((t) =>
validTypes.find((v) => t === v)
)
if (match) {
// @ts-expect-error fixme ts strict error
const uri = event.dataTransfer.getData(match)?.split('\n')?.[0]
if (uri) {
await this.handleFile(await (await fetch(uri)).blob())
@@ -533,6 +554,7 @@ export class ComfyApp {
}
// Fall through to Litegraph defaults
// @ts-expect-error fixme ts strict error
return origProcessKey.apply(this, arguments)
}
}
@@ -550,12 +572,15 @@ export class ComfyApp {
_fgcolor,
bgcolor
) {
// @ts-expect-error fixme ts strict error
const res = origDrawNodeShape.apply(this, arguments)
// @ts-expect-error fixme ts strict error
const nodeErrors = self.lastNodeErrors?.[node.id]
let color = null
let lineWidth = 1
// @ts-expect-error fixme ts strict error
if (node.id === +self.runningNodeId) {
color = '#0f0'
} else if (self.dragOverNode && node.id === self.dragOverNode.id) {
@@ -565,6 +590,7 @@ export class ComfyApp {
lineWidth = 2
} else if (
self.lastExecutionError &&
// @ts-expect-error fixme ts strict error
+self.lastExecutionError.node_id === node.id
) {
color = '#f0f'
@@ -587,6 +613,7 @@ export class ComfyApp {
})
}
// @ts-expect-error fixme ts strict error
if (self.progress && node.id === +self.runningNodeId) {
ctx.fillStyle = 'green'
ctx.fillRect(
@@ -659,6 +686,7 @@ export class ComfyApp {
node.bgcolor = adjustColor(bgColor, adjustments)
// @ts-expect-error fixme ts strict error
const res = origDrawNode.apply(this, arguments)
this.editor_alpha = editor_alpha
@@ -683,7 +711,9 @@ export class ComfyApp {
api.addEventListener('executing', () => {
this.graph.setDirtyCanvas(true, false)
// @ts-expect-error fixme ts strict error
this.revokePreviews(this.runningNodeId)
// @ts-expect-error fixme ts strict error
delete this.nodePreviewImages[this.runningNodeId]
})
@@ -741,6 +771,7 @@ export class ComfyApp {
LGraph.prototype.configure = function () {
app.configuringGraph = true
try {
// @ts-expect-error fixme ts strict error
return configure.apply(this, arguments)
} finally {
app.configuringGraph = false
@@ -757,6 +788,7 @@ export class ComfyApp {
node.onGraphConfigured?.()
}
// @ts-expect-error fixme ts strict error
const r = onConfigure?.apply(this, arguments)
// Fire after onConfigure, used by primitives to generate widget using input nodes config
@@ -772,10 +804,15 @@ export class ComfyApp {
* Set up the app on the page
*/
async setup(canvasEl: HTMLCanvasElement) {
// @ts-expect-error fixme ts strict error
this.bodyTop = document.getElementById('comfyui-body-top')
// @ts-expect-error fixme ts strict error
this.bodyLeft = document.getElementById('comfyui-body-left')
// @ts-expect-error fixme ts strict error
this.bodyRight = document.getElementById('comfyui-body-right')
// @ts-expect-error fixme ts strict error
this.bodyBottom = document.getElementById('comfyui-body-bottom')
// @ts-expect-error fixme ts strict error
this.canvasContainer = document.getElementById('graph-canvas-container')
this.canvasEl = canvasEl
@@ -798,6 +835,7 @@ export class ComfyApp {
this.canvas.state = reactive(this.canvas.state)
this.canvas.ds.state = reactive(this.canvas.ds.state)
// @ts-expect-error fixme ts strict error
this.ctx = canvasEl.getContext('2d')
LiteGraph.alt_drag_do_clone_nodes = true
@@ -831,6 +869,7 @@ export class ComfyApp {
const { width, height } = this.canvasEl.getBoundingClientRect()
this.canvasEl.width = Math.round(width * scale)
this.canvasEl.height = Math.round(height * scale)
// @ts-expect-error fixme ts strict error
this.canvasEl.getContext('2d').scale(scale, scale)
this.canvas?.draw(true, true)
}
@@ -840,6 +879,7 @@ export class ComfyApp {
) {
// Frontend only nodes registered by custom nodes.
// Example: https://github.com/rgthree/rgthree-comfy/blob/dd534e5384be8cf0c0fa35865afe2126ba75ac55/src_web/comfyui/fast_groups_bypasser.ts#L10
// @ts-expect-error fixme ts strict error
const rawDefs: Record<string, ComfyNodeDefV1> = Object.fromEntries(
Object.entries(LiteGraph.registered_node_types).map(([name, node]) => [
name,
@@ -880,6 +920,7 @@ export class ComfyApp {
`nodeDefs.${def.name}.display_name`,
def.display_name ?? def.name
),
// @ts-expect-error fixme ts strict error
description: def.description
? st(`nodeDefs.${def.name}.description`, def.description)
: undefined,
@@ -906,6 +947,7 @@ export class ComfyApp {
await this.registerNodesFromDefs(defs)
await useExtensionService().invokeExtensionsAsync('registerCustomNodes')
if (this.vueAppReady) {
// @ts-expect-error fixme ts strict error
this.updateVueAppNodeDefs(defs)
}
}
@@ -923,6 +965,7 @@ export class ComfyApp {
}
}
// @ts-expect-error fixme ts strict error
loadTemplateData(templateData) {
if (!templateData?.templates) {
return
@@ -955,14 +998,17 @@ export class ComfyApp {
nodeBottom = node.pos[1] + node.size[1]
// @ts-expect-error fixme ts strict error
if (maxY === false || nodeBottom > maxY) {
maxY = nodeBottom
}
}
// @ts-expect-error fixme ts strict error
app.canvas.graph_mouse[1] = maxY + 50
}
// @ts-expect-error fixme ts strict error
localStorage.setItem('litegrapheditor_clipboard', old)
}
@@ -972,6 +1018,7 @@ export class ComfyApp {
}
}
// @ts-expect-error fixme ts strict error
#showMissingModelsError(missingModels, paths) {
if (useSettingStore().get('Comfy.Workflow.ShowMissingModelsWarning')) {
useDialogService().showMissingModelsWarning({
@@ -1092,7 +1139,9 @@ export class ComfyApp {
let errorHint = []
// Try extracting filename to see if it was caused by an extension script
const filename =
// @ts-expect-error fixme ts strict error
error.fileName ||
// @ts-expect-error fixme ts strict error
(error.stack || '').match(/(\/extensions\/.*\.js)/)?.[1]
const pos = (filename || '').indexOf('/extensions/')
if (pos > -1) {
@@ -1118,6 +1167,7 @@ export class ComfyApp {
}),
$el('pre', {
style: { padding: '5px', backgroundColor: 'rgba(255,0,0,0.2)' },
// @ts-expect-error fixme ts strict error
textContent: error.toString()
}),
$el('pre', {
@@ -1129,6 +1179,7 @@ export class ComfyApp {
overflow: 'auto',
backgroundColor: 'rgba(0,0,0,0.2)'
},
// @ts-expect-error fixme ts strict error
textContent: error.stack || 'No stacktrace available'
}),
...errorHint
@@ -1174,9 +1225,12 @@ export class ComfyApp {
if (reset_invalid_values) {
if (widget.type == 'combo') {
if (
// @ts-expect-error fixme ts strict error
!widget.options.values.includes(widget.value as string) &&
// @ts-expect-error fixme ts strict error
widget.options.values.length > 0
) {
// @ts-expect-error fixme ts strict error
widget.value = widget.options.values[0]
}
}
@@ -1225,6 +1279,7 @@ export class ComfyApp {
})
}
// @ts-expect-error fixme ts strict error
#formatPromptError(error) {
if (error == null) {
return '(unknown error)'
@@ -1251,10 +1306,12 @@ export class ComfyApp {
}
async queuePrompt(number: number, batchCount: number = 1): Promise<boolean> {
// @ts-expect-error fixme ts strict error
this.#queueItems.push({ number, batchCount })
// Only have one action process the items so each one gets a unique seed correctly
if (this.#processingQueue) {
// @ts-expect-error fixme ts strict error
return
}
@@ -1263,6 +1320,7 @@ export class ComfyApp {
try {
while (this.#queueItems.length) {
// @ts-expect-error fixme ts strict error
;({ number, batchCount } = this.#queueItems.pop())
for (let i = 0; i < batchCount; i++) {
@@ -1273,12 +1331,15 @@ export class ComfyApp {
const p = await this.graphToPrompt()
try {
const res = await api.queuePrompt(number, p)
// @ts-expect-error fixme ts strict error
this.lastNodeErrors = res.node_errors
// @ts-expect-error fixme ts strict error
if (this.lastNodeErrors.length > 0) {
this.canvas.draw(true, true)
} else {
try {
useExecutionStore().storePrompt({
// @ts-expect-error fixme ts strict error
id: res.prompt_id,
nodes: Object.keys(p.output),
workflow: useWorkspaceStore().workflow
@@ -1289,7 +1350,9 @@ export class ComfyApp {
} catch (error) {
const formattedError = this.#formatPromptError(error)
this.ui.dialog.show(formattedError)
// @ts-expect-error fixme ts strict error
if (error.response) {
// @ts-expect-error fixme ts strict error
this.lastNodeErrors = error.response.node_errors
this.canvas.draw(true, true)
}
@@ -1299,6 +1362,7 @@ export class ComfyApp {
// Allow widgets to run callbacks after a prompt has been queued
// e.g. random seed after every gen
executeWidgetsCallback(
// @ts-expect-error fixme ts strict error
p.workflow.nodes.map((n) => this.graph.getNodeById(n.id)),
'afterQueued'
)
@@ -1313,6 +1377,7 @@ export class ComfyApp {
return !this.lastNodeErrors
}
// @ts-expect-error fixme ts strict error
showErrorOnFileLoad(file) {
this.ui.dialog.show(
$el('div', [
@@ -1325,7 +1390,9 @@ export class ComfyApp {
* Loads workflow data from the specified file
* @param {File} file
*/
// @ts-expect-error fixme ts strict error
async handleFile(file) {
// @ts-expect-error fixme ts strict error
const removeExt = (f) => {
if (!f) return f
const p = f.lastIndexOf('.')
@@ -1437,11 +1504,13 @@ export class ComfyApp {
}
}
// @ts-expect-error fixme ts strict error
isApiJson(data) {
// @ts-expect-error
return Object.values(data).every((v) => v.class_type)
}
// @ts-expect-error fixme ts strict error
loadApiJson(apiData, fileName: string) {
useWorkflowService().beforeLoadNewGraph()
@@ -1462,8 +1531,11 @@ export class ComfyApp {
for (const id of ids) {
const data = apiData[id]
const node = LiteGraph.createNode(data.class_type)
// @ts-expect-error fixme ts strict error
node.id = isNaN(+id) ? id : +id
// @ts-expect-error fixme ts strict error
node.title = data._meta?.title ?? node.title
// @ts-expect-error fixme ts strict error
app.graph.add(node)
}
@@ -1475,21 +1547,26 @@ export class ComfyApp {
if (value instanceof Array) {
const [fromId, fromSlot] = value
const fromNode = app.graph.getNodeById(fromId)
// @ts-expect-error fixme ts strict error
let toSlot = node.inputs?.findIndex((inp) => inp.name === input)
if (toSlot == null || toSlot === -1) {
try {
// Target has no matching input, most likely a converted widget
// @ts-expect-error fixme ts strict error
const widget = node.widgets?.find((w) => w.name === input)
// @ts-expect-error
if (widget && node.convertWidgetToInput?.(widget)) {
// @ts-expect-error fixme ts strict error
toSlot = node.inputs?.length - 1
}
} catch (error) {}
}
if (toSlot != null || toSlot !== -1) {
// @ts-expect-error fixme ts strict error
fromNode.connect(fromSlot, node, toSlot)
}
} else {
// @ts-expect-error fixme ts strict error
const widget = node.widgets?.find((w) => w.name === input)
if (widget) {
widget.value = value
@@ -1508,21 +1585,26 @@ export class ComfyApp {
if (value instanceof Array) {
const [fromId, fromSlot] = value
const fromNode = app.graph.getNodeById(fromId)
// @ts-expect-error fixme ts strict error
let toSlot = node.inputs?.findIndex((inp) => inp.name === input)
if (toSlot == null || toSlot === -1) {
try {
// Target has no matching input, most likely a converted widget
// @ts-expect-error fixme ts strict error
const widget = node.widgets?.find((w) => w.name === input)
// @ts-expect-error
if (widget && node.convertWidgetToInput?.(widget)) {
// @ts-expect-error fixme ts strict error
toSlot = node.inputs?.length - 1
}
} catch (error) {}
}
if (toSlot != null || toSlot !== -1) {
// @ts-expect-error fixme ts strict error
fromNode.connect(fromSlot, node, toSlot)
}
} else {
// @ts-expect-error fixme ts strict error
const widget = node.widgets?.find((w) => w.name === input)
if (widget) {
widget.value = value
@@ -1565,19 +1647,19 @@ export class ComfyApp {
this.registerNodeDef(nodeId, defs[nodeId])
}
for (const node of this.graph.nodes) {
// @ts-expect-error fixme ts strict error
const def = defs[node.type]
// Allow primitive nodes to handle refresh
node.refreshComboInNode?.(defs)
if (!def?.input) continue
// @ts-expect-error fixme ts strict error
for (const widget of node.widgets) {
if (widget.type === 'combo') {
if (def['input'].required?.[widget.name] !== undefined) {
// @ts-expect-error InputSpec is not typed correctly
widget.options.values = def['input'].required[widget.name][0]
} else if (def['input'].optional?.[widget.name] !== undefined) {
// @ts-expect-error InputSpec is not typed correctly
widget.options.values = def['input'].optional[widget.name][0]
}
}
@@ -1590,6 +1672,7 @@ export class ComfyApp {
)
if (this.vueAppReady) {
// @ts-expect-error fixme ts strict error
this.updateVueAppNodeDefs(defs)
useToastStore().remove(requestToastMessage)
useToastStore().add({
@@ -1628,6 +1711,7 @@ export class ComfyApp {
const rect = this.canvasContainer.getBoundingClientRect()
const containerOffsets = [rect.left, rect.top]
return _.zip(pos, this.canvas.ds.offset, containerOffsets).map(
// @ts-expect-error fixme ts strict error
([p, o1, o2]) => (p - o2) / this.canvas.ds.scale - o1
) as Vector2
}
@@ -1636,6 +1720,7 @@ export class ComfyApp {
const rect = this.canvasContainer.getBoundingClientRect()
const containerOffsets = [rect.left, rect.top]
return _.zip(pos, this.canvas.ds.offset, containerOffsets).map(
// @ts-expect-error fixme ts strict error
([p, o1, o2]) => (p + o1) * this.canvas.ds.scale + o2
) as Vector2
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
export function getFromFlacBuffer(buffer: ArrayBuffer): Record<string, string> {
const dataView = new DataView(buffer)
@@ -6,6 +5,7 @@ export function getFromFlacBuffer(buffer: ArrayBuffer): Record<string, string> {
const signature = String.fromCharCode(...new Uint8Array(buffer, 0, 4))
if (signature !== 'fLaC') {
console.error('Not a valid FLAC file')
// @ts-expect-error fixme ts strict error
return
}
@@ -29,6 +29,7 @@ export function getFromFlacBuffer(buffer: ArrayBuffer): Record<string, string> {
if (isLastBlock) break
}
// @ts-expect-error fixme ts strict error
return vorbisComment
}
@@ -36,6 +37,7 @@ export function getFromFlacFile(file: File): Promise<Record<string, string>> {
return new Promise((r) => {
const reader = new FileReader()
reader.onload = function (event) {
// @ts-expect-error fixme ts strict error
const arrayBuffer = event.target.result as ArrayBuffer
r(getFromFlacBuffer(arrayBuffer))
}
@@ -64,6 +66,7 @@ function parseVorbisComment(dataView: DataView): Record<string, string> {
const ind = comment.indexOf('=')
const key = comment.substring(0, ind)
// @ts-expect-error fixme ts strict error
comments[key] = comment.substring(ind + 1)
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
export function getFromPngBuffer(buffer: ArrayBuffer) {
// Get the PNG data as a Uint8Array
const pngData = new Uint8Array(buffer)
@@ -46,6 +45,7 @@ export function getFromPngFile(file: File) {
return new Promise<Record<string, string>>((r) => {
const reader = new FileReader()
reader.onload = (event) => {
// @ts-expect-error fixme ts strict error
r(getFromPngBuffer(event.target.result as ArrayBuffer))
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { LiteGraph } from '@comfyorg/litegraph'
import { api } from './api'
@@ -14,11 +13,13 @@ export function getFlacMetadata(file: File): Promise<Record<string, string>> {
return getFromFlacFile(file)
}
// @ts-expect-error fixme ts strict error
function parseExifData(exifData) {
// Check for the correct TIFF header (0x4949 for little-endian or 0x4D4D for big-endian)
const isLittleEndian = String.fromCharCode(...exifData.slice(0, 2)) === 'II'
// Function to read 16-bit and 32-bit integers from binary data
// @ts-expect-error fixme ts strict error
function readInt(offset, isLittleEndian, length) {
let arr = exifData.slice(offset, offset + length)
if (length === 2) {
@@ -37,10 +38,12 @@ function parseExifData(exifData) {
// Read the offset to the first IFD (Image File Directory)
const ifdOffset = readInt(4, isLittleEndian, 4)
// @ts-expect-error fixme ts strict error
function parseIFD(offset) {
const numEntries = readInt(offset, isLittleEndian, 2)
const result = {}
// @ts-expect-error fixme ts strict error
for (let i = 0; i < numEntries; i++) {
const entryOffset = offset + 2 + i * 12
const tag = readInt(entryOffset, isLittleEndian, 2)
@@ -53,10 +56,12 @@ function parseExifData(exifData) {
if (type === 2) {
// ASCII string
value = new TextDecoder('utf-8').decode(
// @ts-expect-error fixme ts strict error
exifData.subarray(valueOffset, valueOffset + numValues - 1)
)
}
// @ts-expect-error fixme ts strict error
result[tag] = value
}
@@ -68,10 +73,12 @@ function parseExifData(exifData) {
return ifdData
}
// @ts-expect-error fixme ts strict error
export function getWebpMetadata(file) {
return new Promise<Record<string, string>>((r) => {
const reader = new FileReader()
reader.onload = (event) => {
// @ts-expect-error fixme ts strict error
const webp = new Uint8Array(event.target.result as ArrayBuffer)
const dataView = new DataView(webp.buffer)
@@ -105,9 +112,11 @@ export function getWebpMetadata(file) {
webp.slice(offset + 8, offset + 8 + chunk_length)
)
for (var key in data) {
// @ts-expect-error fixme ts strict error
const value = data[key] as string
if (typeof value === 'string') {
const index = value.indexOf(':')
// @ts-expect-error fixme ts strict error
txt_chunks[value.slice(0, index)] = value.slice(index + 1)
}
}
@@ -124,10 +133,12 @@ export function getWebpMetadata(file) {
})
}
// @ts-expect-error fixme ts strict error
export function getLatentMetadata(file) {
return new Promise((r) => {
const reader = new FileReader()
reader.onload = (event) => {
// @ts-expect-error fixme ts strict error
const safetensorsData = new Uint8Array(event.target.result as ArrayBuffer)
const dataView = new DataView(safetensorsData.buffer)
let header_size = dataView.getUint32(0, true)
@@ -145,6 +156,7 @@ export function getLatentMetadata(file) {
})
}
// @ts-expect-error fixme ts strict error
export async function importA1111(graph, parameters) {
const p = parameters.lastIndexOf('\nSteps:')
if (p > -1) {
@@ -155,6 +167,7 @@ export async function importA1111(graph, parameters) {
.match(
new RegExp('\\s*([^:]+:\\s*([^"\\{].*?|".*?"|\\{.*?\\}))\\s*(,|$)', 'g')
)
// @ts-expect-error fixme ts strict error
.reduce((p, n) => {
const s = n.split(':')
if (s[1].endsWith(',')) {
@@ -176,18 +189,24 @@ export async function importA1111(graph, parameters) {
const imageNode = LiteGraph.createNode('EmptyLatentImage')
const vaeNode = LiteGraph.createNode('VAEDecode')
const saveNode = LiteGraph.createNode('SaveImage')
// @ts-expect-error fixme ts strict error
let hrSamplerNode = null
let hrSteps = null
// @ts-expect-error fixme ts strict error
const ceil64 = (v) => Math.ceil(v / 64) * 64
// @ts-expect-error fixme ts strict error
const getWidget = (node, name) => {
// @ts-expect-error fixme ts strict error
return node.widgets.find((w) => w.name === name)
}
// @ts-expect-error fixme ts strict error
const setWidgetValue = (node, name, value, isOptionPrefix?) => {
const w = getWidget(node, name)
if (isOptionPrefix) {
// @ts-expect-error fixme ts strict error
const o = w.options.values.find((w) => w.startsWith(value))
if (o) {
w.value = o
@@ -200,8 +219,11 @@ export async function importA1111(graph, parameters) {
}
}
// @ts-expect-error fixme ts strict error
const createLoraNodes = (clipNode, text, prevClip, prevModel) => {
// @ts-expect-error fixme ts strict error
const loras = []
// @ts-expect-error fixme ts strict error
text = text.replace(/<lora:([^:]+:[^>]+)>/g, function (m, c) {
const s = c.split(':')
const weight = parseFloat(s[1])
@@ -213,6 +235,7 @@ export async function importA1111(graph, parameters) {
return ''
})
// @ts-expect-error fixme ts strict error
for (const l of loras) {
const loraNode = LiteGraph.createNode('LoraLoader')
graph.add(loraNode)
@@ -227,6 +250,7 @@ export async function importA1111(graph, parameters) {
prevClip.node.connect(1, clipNode, 0)
prevModel.node.connect(0, samplerNode, 0)
// @ts-expect-error fixme ts strict error
if (hrSamplerNode) {
prevModel.node.connect(0, hrSamplerNode, 0)
}
@@ -234,6 +258,7 @@ export async function importA1111(graph, parameters) {
return { text, prevModel, prevClip }
}
// @ts-expect-error fixme ts strict error
const replaceEmbeddings = (text) => {
if (!embeddings.length) return text
return text.replaceAll(
@@ -249,6 +274,7 @@ export async function importA1111(graph, parameters) {
)
}
// @ts-expect-error fixme ts strict error
const popOpt = (name) => {
const v = opts[name]
delete opts[name]
@@ -265,28 +291,42 @@ export async function importA1111(graph, parameters) {
graph.add(vaeNode)
graph.add(saveNode)
// @ts-expect-error fixme ts strict error
ckptNode.connect(1, clipSkipNode, 0)
// @ts-expect-error fixme ts strict error
clipSkipNode.connect(0, positiveNode, 0)
// @ts-expect-error fixme ts strict error
clipSkipNode.connect(0, negativeNode, 0)
// @ts-expect-error fixme ts strict error
ckptNode.connect(0, samplerNode, 0)
// @ts-expect-error fixme ts strict error
positiveNode.connect(0, samplerNode, 1)
// @ts-expect-error fixme ts strict error
negativeNode.connect(0, samplerNode, 2)
// @ts-expect-error fixme ts strict error
imageNode.connect(0, samplerNode, 3)
// @ts-expect-error fixme ts strict error
vaeNode.connect(0, saveNode, 0)
// @ts-expect-error fixme ts strict error
samplerNode.connect(0, vaeNode, 0)
// @ts-expect-error fixme ts strict error
ckptNode.connect(2, vaeNode, 1)
const handlers = {
// @ts-expect-error fixme ts strict error
model(v) {
setWidgetValue(ckptNode, 'ckpt_name', v, true)
},
vae() {},
// @ts-expect-error fixme ts strict error
'cfg scale'(v) {
setWidgetValue(samplerNode, 'cfg', +v)
},
// @ts-expect-error fixme ts strict error
'clip skip'(v) {
setWidgetValue(clipSkipNode, 'stop_at_clip_layer', -v)
},
// @ts-expect-error fixme ts strict error
sampler(v) {
let name = v.toLowerCase().replace('++', 'pp').replaceAll(' ', '_')
if (name.includes('karras')) {
@@ -297,12 +337,14 @@ export async function importA1111(graph, parameters) {
}
const w = getWidget(samplerNode, 'sampler_name')
const o = w.options.values.find(
// @ts-expect-error fixme ts strict error
(w) => w === name || w === 'sample_' + name
)
if (o) {
setWidgetValue(samplerNode, 'sampler_name', o)
}
},
// @ts-expect-error fixme ts strict error
size(v) {
const wxh = v.split('x')
const w = ceil64(+wxh[0])
@@ -332,6 +374,7 @@ export async function importA1111(graph, parameters) {
if (hrMethod.startsWith('Latent')) {
latentNode = upscaleNode = LiteGraph.createNode('LatentUpscale')
graph.add(upscaleNode)
// @ts-expect-error fixme ts strict error
samplerNode.connect(0, upscaleNode, 0)
switch (hrMethod) {
@@ -343,7 +386,9 @@ export async function importA1111(graph, parameters) {
} else {
const decode = LiteGraph.createNode('VAEDecodeTiled')
graph.add(decode)
// @ts-expect-error fixme ts strict error
samplerNode.connect(0, decode, 0)
// @ts-expect-error fixme ts strict error
ckptNode.connect(2, decode, 1)
const upscaleLoaderNode =
@@ -355,17 +400,22 @@ export async function importA1111(graph, parameters) {
'ImageUpscaleWithModel'
)
graph.add(modelUpscaleNode)
// @ts-expect-error fixme ts strict error
decode.connect(0, modelUpscaleNode, 1)
// @ts-expect-error fixme ts strict error
upscaleLoaderNode.connect(0, modelUpscaleNode, 0)
upscaleNode = LiteGraph.createNode('ImageScale')
graph.add(upscaleNode)
// @ts-expect-error fixme ts strict error
modelUpscaleNode.connect(0, upscaleNode, 0)
const vaeEncodeNode = (latentNode =
LiteGraph.createNode('VAEEncodeTiled'))
graph.add(vaeEncodeNode)
// @ts-expect-error fixme ts strict error
upscaleNode.connect(0, vaeEncodeNode, 0)
// @ts-expect-error fixme ts strict error
ckptNode.connect(2, vaeEncodeNode, 1)
}
@@ -374,16 +424,23 @@ export async function importA1111(graph, parameters) {
hrSamplerNode = LiteGraph.createNode('KSampler')
graph.add(hrSamplerNode)
// @ts-expect-error fixme ts strict error
ckptNode.connect(0, hrSamplerNode, 0)
// @ts-expect-error fixme ts strict error
positiveNode.connect(0, hrSamplerNode, 1)
// @ts-expect-error fixme ts strict error
negativeNode.connect(0, hrSamplerNode, 2)
// @ts-expect-error fixme ts strict error
latentNode.connect(0, hrSamplerNode, 3)
// @ts-expect-error fixme ts strict error
hrSamplerNode.connect(0, vaeNode, 0)
}
},
// @ts-expect-error fixme ts strict error
steps(v) {
setWidgetValue(samplerNode, 'steps', +v)
},
// @ts-expect-error fixme ts strict error
seed(v) {
setWidgetValue(samplerNode, 'seed', +v)
}
@@ -391,6 +448,7 @@ export async function importA1111(graph, parameters) {
for (const opt in opts) {
if (opt in handlers) {
// @ts-expect-error fixme ts strict error
handlers[opt](popOpt(opt))
}
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { type StatusWsMessageStatus, TaskItem } from '@/schemas/apiSchema'
import { useDialogService } from '@/services/dialogService'
import { useLitegraphService } from '@/services/litegraphService'
@@ -92,6 +91,7 @@ export function $el<TTag extends string>(
return element as ElementType<TTag>
}
// @ts-expect-error fixme ts strict error
function dragElement(dragEl): () => void {
var posDiffX = 0,
posDiffY = 0,
@@ -148,6 +148,7 @@ function dragElement(dragEl): () => void {
dragEl.style.top = newPosY + 'px'
dragEl.style.bottom = 'unset'
// @ts-expect-error fixme ts strict error
if (savePos) {
localStorage.setItem(
'Comfy.MenuPosition',
@@ -170,10 +171,12 @@ function dragElement(dragEl): () => void {
}
}
// @ts-expect-error fixme ts strict error
let savePos = undefined
restorePos()
savePos = true
// @ts-expect-error fixme ts strict error
function dragMouseDown(e) {
e = e || window.event
e.preventDefault()
@@ -185,6 +188,7 @@ function dragElement(dragEl): () => void {
document.onmousemove = elementDrag
}
// @ts-expect-error fixme ts strict error
function elementDrag(e) {
e = e || window.event
e.preventDefault()
@@ -229,6 +233,7 @@ class ComfyList {
element: HTMLDivElement
button?: HTMLButtonElement
// @ts-expect-error fixme ts strict error
constructor(text, type?, reverse?) {
this.#text = text
this.#type = type || text.toLowerCase()
@@ -249,6 +254,7 @@ class ComfyList {
textContent: section
}),
$el('div.comfy-list-items', [
// @ts-expect-error fixme ts strict error
...(this.#reverse ? items[section].reverse() : items[section]).map(
(item: TaskItem) => {
// Allow items to specify a custom remove action (e.g. for interrupt current prompt)
@@ -264,6 +270,7 @@ class ComfyList {
textContent: 'Load',
onclick: async () => {
await app.loadGraphData(
// @ts-expect-error fixme ts strict error
item.prompt[3].extra_pnginfo.workflow,
true,
false
@@ -310,6 +317,7 @@ class ComfyList {
async show() {
this.element.style.display = 'block'
// @ts-expect-error fixme ts strict error
this.button.textContent = 'Close'
await this.load()
@@ -317,6 +325,7 @@ class ComfyList {
hide() {
this.element.style.display = 'none'
// @ts-expect-error fixme ts strict error
this.button.textContent = 'View ' + this.#text
}
@@ -339,14 +348,22 @@ export class ComfyUI {
lastQueueSize: number
queue: ComfyList
history: ComfyList
// @ts-expect-error fixme ts strict error
autoQueueMode: string
// @ts-expect-error fixme ts strict error
graphHasChanged: boolean
// @ts-expect-error fixme ts strict error
autoQueueEnabled: boolean
// @ts-expect-error fixme ts strict error
menuContainer: HTMLDivElement
// @ts-expect-error fixme ts strict error
queueSize: Element
// @ts-expect-error fixme ts strict error
restoreMenuPosition: () => void
// @ts-expect-error fixme ts strict error
loadFile: () => void
// @ts-expect-error fixme ts strict error
constructor(app) {
this.app = app
this.dialog = new ComfyDialog()
@@ -373,6 +390,7 @@ export class ComfyUI {
style: { display: 'none' },
parent: document.body,
onchange: async () => {
// @ts-expect-error fixme ts strict error
await app.handleFile(fileInput.files[0])
fileInput.value = ''
}
@@ -394,6 +412,7 @@ export class ComfyUI {
}
],
{
// @ts-expect-error fixme ts strict error
onChange: (value) => {
this.autoQueueMode = value.item.value
}
@@ -456,7 +475,9 @@ export class ComfyUI {
$el('label', { innerHTML: 'Extra options' }, [
$el('input', {
type: 'checkbox',
// @ts-expect-error fixme ts strict error
onchange: (i) => {
// @ts-expect-error fixme ts strict error
document.getElementById('extraOptions').style.display = i
.srcElement.checked
? 'block'
@@ -492,6 +513,7 @@ export class ComfyUI {
value: this.batchCount,
min: '1',
style: { width: '35%', marginLeft: '0.4em' },
// @ts-expect-error fixme ts strict error
oninput: (i) => {
this.batchCount = i.target.value
/* Even though an <input> element with a type of range logically represents a number (since
@@ -511,6 +533,7 @@ export class ComfyUI {
min: '1',
max: '100',
value: this.batchCount,
// @ts-expect-error fixme ts strict error
oninput: (i) => {
this.batchCount = i.srcElement.value
// Note
@@ -532,6 +555,7 @@ export class ComfyUI {
type: 'checkbox',
checked: false,
title: 'Automatically queue prompt when the queue size hits 0',
// @ts-expect-error fixme ts strict error
onchange: (e) => {
this.autoQueueEnabled = e.target.checked
autoQueueModeEl.style.display = this.autoQueueEnabled

View File

@@ -1,13 +1,14 @@
// @ts-strict-ignore
import { $el } from '../../ui'
import { ComfyDialog } from '../dialog'
export class ComfyAsyncDialog extends ComfyDialog<HTMLDialogElement> {
// @ts-expect-error fixme ts strict error
#resolve: (value: any) => void
constructor(actions?: Array<string | { value?: any; text: string }>) {
super(
'dialog.comfy-dialog.comfyui-dialog',
// @ts-expect-error fixme ts strict error
actions?.map((opt) => {
if (typeof opt === 'string') {
opt = { text: opt }

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { Settings } from '@/schemas/apiSchema'
import type { ComfyApp } from '@/scripts/app'
@@ -27,6 +26,7 @@ export class ComfyButton implements ComfyComponent<HTMLElement> {
isOver = false
iconElement = $el('i.mdi')
contentElement = $el('span')
// @ts-expect-error fixme ts strict error
popup: ComfyPopup
element: HTMLElement
overIcon: string
@@ -70,18 +70,22 @@ export class ComfyButton implements ComfyComponent<HTMLElement> {
[this.iconElement, this.contentElement]
)
// @ts-expect-error fixme ts strict error
this.icon = prop(
this,
'icon',
icon,
toggleElement(this.iconElement, { onShow: this.updateIcon })
)
// @ts-expect-error fixme ts strict error
this.overIcon = prop(this, 'overIcon', overIcon, () => {
if (this.isOver) {
this.updateIcon()
}
})
// @ts-expect-error fixme ts strict error
this.iconSize = prop(this, 'iconSize', iconSize, this.updateIcon)
// @ts-expect-error fixme ts strict error
this.content = prop(
this,
'content',
@@ -97,6 +101,7 @@ export class ComfyButton implements ComfyComponent<HTMLElement> {
})
)
// @ts-expect-error fixme ts strict error
this.tooltip = prop(this, 'tooltip', tooltip, (v) => {
if (v) {
this.element.title = v
@@ -113,6 +118,7 @@ export class ComfyButton implements ComfyComponent<HTMLElement> {
this.updateClasses()
;(this.element as HTMLButtonElement).disabled = !this.enabled
})
// @ts-expect-error fixme ts strict error
this.action = prop(this, 'action', action)
this.element.addEventListener('click', (e) => {
if (this.popup) {
@@ -127,9 +133,11 @@ export class ComfyButton implements ComfyComponent<HTMLElement> {
if (visibilitySetting?.id) {
const settingUpdated = () => {
this.hidden =
// @ts-expect-error fixme ts strict error
app.ui.settings.getSettingValue(visibilitySetting.id) !==
visibilitySetting.showValue
}
// @ts-expect-error fixme ts strict error
app.ui.settings.addEventListener(
visibilitySetting.id + '.change',
settingUpdated

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { $el } from '../../ui'
import { prop } from '../../utils'
import { ComfyButton } from './button'
@@ -33,6 +32,7 @@ export class ComfyButtonGroup {
}
update() {
// @ts-expect-error fixme ts strict error
this.element.replaceChildren(...this.buttons.map((b) => b['element'] ?? b))
}
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { $el } from '../../ui'
import { prop } from '../../utils'
import { ClassList, applyClasses } from '../utils'
@@ -90,6 +89,7 @@ export class ComfyPopup extends EventTarget {
this.dispatchEvent(new CustomEvent('change'))
}
// @ts-expect-error fixme ts strict error
#escHandler = (e) => {
if (e.key === 'Escape') {
this.open = false
@@ -98,6 +98,7 @@ export class ComfyPopup extends EventTarget {
}
}
// @ts-expect-error fixme ts strict error
#clickHandler = (e) => {
/** @type {any} */
const target = e.target

View File

@@ -1,10 +1,10 @@
// @ts-strict-ignore
import { $el } from '../ui'
export class ComfyDialog<
T extends HTMLElement = HTMLElement
> extends EventTarget {
element: T
// @ts-expect-error fixme ts strict error
textElement: HTMLElement
#buttons: HTMLButtonElement[] | null
@@ -35,6 +35,7 @@ export class ComfyDialog<
this.element.style.display = 'none'
}
// @ts-expect-error fixme ts strict error
show(html) {
if (typeof html === 'string') {
this.textElement.innerHTML = html

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
/*
Original implementation:
https://github.com/TahaSh/drag-to-reorder
@@ -45,9 +44,13 @@ $el('style', {
export class DraggableList extends EventTarget {
listContainer
// @ts-expect-error fixme ts strict error
draggableItem
// @ts-expect-error fixme ts strict error
pointerStartX
// @ts-expect-error fixme ts strict error
pointerStartY
// @ts-expect-error fixme ts strict error
scrollYMax
itemsGap = 0
items = []
@@ -56,6 +59,7 @@ export class DraggableList extends EventTarget {
off = []
offDrag = []
// @ts-expect-error fixme ts strict error
constructor(element, itemSelector) {
super()
this.listContainer = element
@@ -63,9 +67,13 @@ export class DraggableList extends EventTarget {
if (!this.listContainer) return
// @ts-expect-error fixme ts strict error
this.off.push(this.on(this.listContainer, 'mousedown', this.dragStart))
// @ts-expect-error fixme ts strict error
this.off.push(this.on(this.listContainer, 'touchstart', this.dragStart))
// @ts-expect-error fixme ts strict error
this.off.push(this.on(document, 'mouseup', this.dragEnd))
// @ts-expect-error fixme ts strict error
this.off.push(this.on(document, 'touchend', this.dragEnd))
}
@@ -75,6 +83,7 @@ export class DraggableList extends EventTarget {
this.listContainer.querySelectorAll(this.itemSelector)
)
this.items.forEach((element) => {
// @ts-expect-error fixme ts strict error
element.classList.add('is-idle')
})
}
@@ -83,24 +92,29 @@ export class DraggableList extends EventTarget {
getIdleItems() {
return this.getAllItems().filter((item) =>
// @ts-expect-error fixme ts strict error
item.classList.contains('is-idle')
)
}
// @ts-expect-error fixme ts strict error
isItemAbove(item) {
return item.hasAttribute('data-is-above')
}
// @ts-expect-error fixme ts strict error
isItemToggled(item) {
return item.hasAttribute('data-is-toggled')
}
// @ts-expect-error fixme ts strict error
on(source, event, listener, options?) {
listener = listener.bind(this)
source.addEventListener(event, listener, options)
return () => source.removeEventListener(event, listener)
}
// @ts-expect-error fixme ts strict error
dragStart(e) {
if (e.target.classList.contains(this.handleClass)) {
this.draggableItem = e.target.closest(this.itemSelector)
@@ -117,8 +131,10 @@ export class DraggableList extends EventTarget {
this.initDraggableItem()
this.initItemsState()
// @ts-expect-error fixme ts strict error
this.offDrag.push(this.on(document, 'mousemove', this.drag))
this.offDrag.push(
// @ts-expect-error fixme ts strict error
this.on(document, 'touchmove', this.drag, { passive: false })
)
@@ -126,6 +142,7 @@ export class DraggableList extends EventTarget {
new CustomEvent('dragstart', {
detail: {
element: this.draggableItem,
// @ts-expect-error fixme ts strict error
position: this.getAllItems().indexOf(this.draggableItem)
}
})
@@ -141,7 +158,9 @@ export class DraggableList extends EventTarget {
const item1 = this.getIdleItems()[0]
const item2 = this.getIdleItems()[1]
// @ts-expect-error fixme ts strict error
const item1Rect = item1.getBoundingClientRect()
// @ts-expect-error fixme ts strict error
const item2Rect = item2.getBoundingClientRect()
this.itemsGap = Math.abs(item1Rect.bottom - item2Rect.top)
@@ -149,7 +168,9 @@ export class DraggableList extends EventTarget {
initItemsState() {
this.getIdleItems().forEach((item, i) => {
// @ts-expect-error fixme ts strict error
if (this.getAllItems().indexOf(this.draggableItem) > i) {
// @ts-expect-error fixme ts strict error
item.dataset.isAbove = ''
}
})
@@ -160,6 +181,7 @@ export class DraggableList extends EventTarget {
this.draggableItem.classList.add('is-draggable')
}
// @ts-expect-error fixme ts strict error
drag(e) {
if (!this.draggableItem) return
@@ -193,18 +215,23 @@ export class DraggableList extends EventTarget {
// Update state
this.getIdleItems().forEach((item) => {
// @ts-expect-error fixme ts strict error
const itemRect = item.getBoundingClientRect()
const itemY = itemRect.top + itemRect.height / 2
if (this.isItemAbove(item)) {
if (draggableItemY <= itemY) {
// @ts-expect-error fixme ts strict error
item.dataset.isToggled = ''
} else {
// @ts-expect-error fixme ts strict error
delete item.dataset.isToggled
}
} else {
if (draggableItemY >= itemY) {
// @ts-expect-error fixme ts strict error
item.dataset.isToggled = ''
} else {
// @ts-expect-error fixme ts strict error
delete item.dataset.isToggled
}
}
@@ -214,8 +241,10 @@ export class DraggableList extends EventTarget {
this.getIdleItems().forEach((item) => {
if (this.isItemToggled(item)) {
const direction = this.isItemAbove(item) ? 1 : -1
// @ts-expect-error fixme ts strict error
item.style.transform = `translateY(${direction * (draggableItemRect.height + this.itemsGap)}px)`
} else {
// @ts-expect-error fixme ts strict error
item.style.transform = ''
}
})
@@ -256,6 +285,7 @@ export class DraggableList extends EventTarget {
this.listContainer.appendChild(item)
})
// @ts-expect-error fixme ts strict error
this.items = reorderedItems
this.dispatchEvent(
@@ -275,6 +305,7 @@ export class DraggableList extends EventTarget {
this.unsetDraggableItem()
this.unsetItemState()
// @ts-expect-error fixme ts strict error
this.offDrag.forEach((f) => f())
this.offDrag = []
}
@@ -288,13 +319,17 @@ export class DraggableList extends EventTarget {
unsetItemState() {
this.getIdleItems().forEach((item) => {
// @ts-expect-error fixme ts strict error
delete item.dataset.isAbove
// @ts-expect-error fixme ts strict error
delete item.dataset.isToggled
// @ts-expect-error fixme ts strict error
item.style.transform = ''
})
}
dispose() {
// @ts-expect-error fixme ts strict error
this.off.forEach((f) => f())
}
}

View File

@@ -1,10 +1,12 @@
// @ts-strict-ignore
import { app } from '../app'
import { $el } from '../ui'
export function calculateImageGrid(
// @ts-expect-error fixme ts strict error
imgs,
// @ts-expect-error fixme ts strict error
dw,
// @ts-expect-error fixme ts strict error
dh
): {
cellWidth: number
@@ -42,11 +44,14 @@ export function calculateImageGrid(
}
}
// @ts-expect-error fixme ts strict error
return { cellWidth, cellHeight, cols, rows, shiftX }
}
// @ts-expect-error fixme ts strict error
export function createImageHost(node) {
const el = $el('div.comfy-img-preview')
// @ts-expect-error fixme ts strict error
let currentImgs
let first = true
@@ -54,6 +59,7 @@ export function createImageHost(node) {
let w = null
let h = null
// @ts-expect-error fixme ts strict error
if (currentImgs) {
let elH = el.clientHeight
if (first) {
@@ -73,17 +79,24 @@ export function createImageHost(node) {
nw - 20,
elH
))
// @ts-expect-error fixme ts strict error
w += 'px'
// @ts-expect-error fixme ts strict error
h += 'px'
// @ts-expect-error fixme ts strict error
el.style.setProperty('--comfy-img-preview-width', w)
// @ts-expect-error fixme ts strict error
el.style.setProperty('--comfy-img-preview-height', h)
}
}
return {
el,
// @ts-expect-error fixme ts strict error
updateImages(imgs) {
// @ts-expect-error fixme ts strict error
if (imgs !== currentImgs) {
// @ts-expect-error fixme ts strict error
if (currentImgs == null) {
requestAnimationFrame(() => {
updateSize()
@@ -109,6 +122,7 @@ export function createImageHost(node) {
if (!over) return
// Set the overIndex so Open Image etc work
// @ts-expect-error fixme ts strict error
const idx = currentImgs.indexOf(over)
node.overIndex = idx
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { $el } from '../ui'
/**
@@ -11,24 +10,33 @@ import { $el } from '../ui'
* @param { Object } [opts]
* @param { (e: { item: ToggleSwitchItem, prev?: ToggleSwitchItem }) => void } [opts.onChange]
*/
// @ts-expect-error fixme ts strict error
export function toggleSwitch(name, items, e?) {
const onChange = e?.onChange
// @ts-expect-error fixme ts strict error
let selectedIndex
// @ts-expect-error fixme ts strict error
let elements
// @ts-expect-error fixme ts strict error
function updateSelected(index) {
// @ts-expect-error fixme ts strict error
if (selectedIndex != null) {
// @ts-expect-error fixme ts strict error
elements[selectedIndex].classList.remove('comfy-toggle-selected')
}
onChange?.({
item: items[index],
// @ts-expect-error fixme ts strict error
prev: selectedIndex == null ? undefined : items[selectedIndex]
})
selectedIndex = index
// @ts-expect-error fixme ts strict error
elements[selectedIndex].classList.add('comfy-toggle-selected')
}
// @ts-expect-error fixme ts strict error
elements = items.map((item, i) => {
if (typeof item === 'string') item = { text: item }
if (!item.value) item.value = item.text

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
export type ClassList = string | string[] | Record<string, boolean>
export function applyClasses(
@@ -34,11 +33,13 @@ export function toggleElement(
onShow
}: {
onHide?: (el: HTMLElement) => void
// @ts-expect-error fixme ts strict error
onShow?: (el: HTMLElement, value) => void
} = {}
) {
let placeholder: HTMLElement | Comment
let hidden: boolean
// @ts-expect-error fixme ts strict error
return (value) => {
if (value) {
if (hidden) {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { applyTextReplacements as _applyTextReplacements } from '@/utils/searchAndReplace'
import { api } from './api'
@@ -90,12 +89,15 @@ export function prop<T>(
name: string
) => void
): T {
// @ts-expect-error fixme ts strict error
let currentValue
Object.defineProperty(target, name, {
get() {
// @ts-expect-error fixme ts strict error
return currentValue
},
set(newValue) {
// @ts-expect-error fixme ts strict error
const prevValue = currentValue
currentValue = newValue
onChanged?.(currentValue, prevValue, target, name)

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import {
type IContextMenuValue,
type INodeInputSlot,
@@ -46,6 +45,7 @@ export const useLitegraphService = () => {
static category?: string
constructor(title?: string) {
// @ts-expect-error fixme ts strict error
super(title)
const nodeMinSize = { width: 1, height: 1 }
@@ -158,7 +158,9 @@ export const useLitegraphService = () => {
}
for (const field of ['inputs', 'outputs']) {
const slots = data[field] ?? []
// @ts-expect-error fixme ts strict error
data[field] = slots.map((slot, i) =>
// @ts-expect-error fixme ts strict error
merge(this[field][i] ?? {}, slot)
)
}
@@ -204,6 +206,7 @@ export const useLitegraphService = () => {
const url = new URL(img.src)
url.searchParams.delete('preview')
// @ts-expect-error fixme ts strict error
const writeImage = async (blob) => {
await navigator.clipboard.write([
new ClipboardItem({
@@ -225,13 +228,17 @@ export const useLitegraphService = () => {
height: img.naturalHeight
}) as HTMLCanvasElement
const ctx = canvas.getContext('2d')
// @ts-expect-error fixme ts strict error
let image
if (typeof window.createImageBitmap === 'undefined') {
image = new Image()
const p = new Promise((resolve, reject) => {
// @ts-expect-error fixme ts strict error
image.onload = resolve
// @ts-expect-error fixme ts strict error
image.onerror = reject
}).finally(() => {
// @ts-expect-error fixme ts strict error
URL.revokeObjectURL(image.src)
})
image.src = URL.createObjectURL(blob)
@@ -240,10 +247,13 @@ export const useLitegraphService = () => {
image = await createImageBitmap(blob)
}
try {
// @ts-expect-error fixme ts strict error
ctx.drawImage(image, 0, 0)
canvas.toBlob(writeImage, 'image/png')
} finally {
// @ts-expect-error fixme ts strict error
if (typeof image.close === 'function') {
// @ts-expect-error fixme ts strict error
image.close()
}
}
@@ -254,6 +264,7 @@ export const useLitegraphService = () => {
}
} catch (error) {
toastStore.addAlert(
// @ts-expect-error fixme ts strict error
'Error copying image: ' + (error.message ?? error)
)
}
@@ -293,6 +304,7 @@ export const useLitegraphService = () => {
a.href = url.toString()
a.setAttribute(
'download',
// @ts-expect-error fixme ts strict error
new URLSearchParams(url.search).get('filename')
)
document.body.append(a)
@@ -314,6 +326,7 @@ export const useLitegraphService = () => {
for (const item of app.canvas.selectedItems) {
if (item instanceof LGraphNode) item.mode = mode
}
// @ts-expect-error fixme ts strict error
this.graph.change()
}
})
@@ -341,7 +354,9 @@ export const useLitegraphService = () => {
content: 'Open in MaskEditor',
callback: () => {
ComfyApp.copyToClipspace(this)
// @ts-expect-error fixme ts strict error
ComfyApp.clipspace_return_node = this
// @ts-expect-error fixme ts strict error
ComfyApp.open_maskeditor()
}
})
@@ -390,6 +405,7 @@ export const useLitegraphService = () => {
const isAnimatedWebp =
this.animatedImages &&
// @ts-expect-error fixme ts strict error
output.images.some((img) => img.filename?.includes('webp'))
const isVideo =
(this.animatedImages && !isAnimatedWebp) || isVideoNode(this)
@@ -425,6 +441,7 @@ export const useLitegraphService = () => {
const origNodeOnKeyDown = node.prototype.onKeyDown
node.prototype.onKeyDown = function (e) {
// @ts-expect-error fixme ts strict error
if (origNodeOnKeyDown && origNodeOnKeyDown.apply(this, e) === false) {
return false
}
@@ -437,13 +454,18 @@ export const useLitegraphService = () => {
if (e.key === 'ArrowLeft' || e.key === 'ArrowRight') {
if (e.key === 'ArrowLeft') {
// @ts-expect-error fixme ts strict error
this.imageIndex -= 1
} else if (e.key === 'ArrowRight') {
// @ts-expect-error fixme ts strict error
this.imageIndex += 1
}
// @ts-expect-error fixme ts strict error
this.imageIndex %= this.imgs.length
// @ts-expect-error fixme ts strict error
if (this.imageIndex < 0) {
// @ts-expect-error fixme ts strict error
this.imageIndex = this.imgs.length + this.imageIndex
}
handled = true
@@ -472,7 +494,9 @@ export const useLitegraphService = () => {
options
)
// @ts-expect-error fixme ts strict error
app.graph.add(node)
// @ts-expect-error fixme ts strict error
return node
}

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import Fuse, { FuseSearchOptions, IFuseOptions } from 'fuse.js'
import _ from 'lodash'
@@ -23,6 +22,7 @@ export class FuseSearch<T> {
advancedScoring: boolean = false
) {
this.data = data
// @ts-expect-error fixme ts strict error
this.keys = (options.keys ?? []) as string[]
this.advancedScoring = advancedScoring
const index =
@@ -44,6 +44,7 @@ export class FuseSearch<T> {
const aux = fuseResult
.map((x) => ({
item: x.item,
// @ts-expect-error fixme ts strict error
scores: this.calcAuxScores(query.toLocaleLowerCase(), x.item, x.score)
}))
.sort((a, b) => this.compareAux(a.scores, b.scores))
@@ -54,6 +55,7 @@ export class FuseSearch<T> {
public calcAuxScores(query: string, entry: T, score: number): SearchAuxScore {
let values: string[] = []
if (!this.keys.length) values = [entry as string]
// @ts-expect-error fixme ts strict error
else values = this.keys.map((x) => entry[x])
const scores = values.map((x) => this.calcAuxSingle(query, x, score))
let result = scores.sort(this.compareAux)[0]
@@ -62,7 +64,9 @@ export class FuseSearch<T> {
x.toLocaleLowerCase().includes('deprecated')
)
result[0] += deprecated && result[0] != 0 ? 5 : 0
// @ts-expect-error fixme ts strict error
if (entry['postProcessSearchScores']) {
// @ts-expect-error fixme ts strict error
result = entry['postProcessSearchScores'](result) as SearchAuxScore
}
return result
@@ -155,8 +159,10 @@ export class NodeFilter<FilterOptionT = string> {
}
public getAllNodeOptions(nodeDefs: ComfyNodeDefImpl[]): FilterOptionT[] {
// @ts-expect-error fixme ts strict error
return [
...new Set(
// @ts-expect-error fixme ts strict error
nodeDefs.reduce((acc, nodeDef) => {
return [...acc, ...this.getNodeOptions(nodeDef)]
}, [])

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import type { LGraph, LGraphCanvas, LGraphNode } from '@comfyorg/litegraph'
import { LiteGraph } from '@comfyorg/litegraph'
@@ -32,6 +31,7 @@ export function serialise(nodes: LGraphNode[], graph: LGraph): string {
continue
}
// @ts-expect-error fixme ts strict error
serialisable.nodes.push(cloned.serialize())
if (!node.inputs?.length) continue
@@ -46,6 +46,7 @@ export function serialise(nodes: LGraphNode[], graph: LGraph): string {
if (!outNode) continue
// Special format for old Litegraph copy & paste only
// @ts-expect-error fixme ts strict error
serialisable.links.push([
outNode._relative_id,
link.origin_slot,
@@ -70,6 +71,7 @@ export function deserialiseAndCreate(data: string, canvas: LGraphCanvas): void {
const { graph, graph_mouse } = canvas
canvas.emitBeforeChange()
try {
// @ts-expect-error fixme ts strict error
graph.beforeChange()
const deserialised = JSON.parse(data)
@@ -99,6 +101,7 @@ export function deserialiseAndCreate(data: string, canvas: LGraphCanvas): void {
node.pos[0] += graph_mouse[0] - topLeft[0]
node.pos[1] += graph_mouse[1] - topLeft[1]
// @ts-expect-error fixme ts strict error
graph.add(node, true)
nodes.push(node)
}
@@ -115,6 +118,7 @@ export function deserialiseAndCreate(data: string, canvas: LGraphCanvas): void {
canvas.selectNodes(nodes)
// @ts-expect-error fixme ts strict error
graph.afterChange()
} finally {
canvas.emitAfterChange()

View File

@@ -176,6 +176,7 @@ const install = () => {
pythonMirror: pythonMirror.value,
pypiMirror: pypiMirror.value,
torchMirror: torchMirror.value,
// @ts-expect-error fixme ts strict error
device: device.value
}
electron.installComfyUI(options)

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it } from 'vitest'
import {
@@ -41,6 +40,7 @@ describe('validateNodeDef', () => {
(inputSpec, expected) => {
it(`should accept input spec format: ${JSON.stringify(inputSpec)}`, async () => {
expect(
// @ts-expect-error fixme ts strict error
validateComfyNodeDef({
...EXAMPLE_NODE_DEF,
input: {

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it, vi } from 'vitest'
import { adjustColor } from '@/utils/colorUtil'
@@ -107,7 +106,9 @@ describe('colorUtil - adjustColor', () => {
})
it('returns the original value for null or undefined inputs', () => {
// @ts-expect-error fixme ts strict error
expect(adjustColor(null, { opacity: targetOpacity })).toBe(null)
// @ts-expect-error fixme ts strict error
expect(adjustColor(undefined, { opacity: targetOpacity })).toBe(undefined)
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import fs from 'fs'
import { describe, expect, it } from 'vitest'
@@ -68,10 +67,12 @@ describe('parseComfyWorkflow', () => {
// Should automatically transform the legacy format object to array.
workflow.nodes[0].pos = { '0': 3, '1': 4 }
let validatedWorkflow = await validateComfyWorkflow(workflow)
// @ts-expect-error fixme ts strict error
expect(validatedWorkflow.nodes[0].pos).toEqual([3, 4])
workflow.nodes[0].pos = { 0: 3, 1: 4 }
validatedWorkflow = await validateComfyWorkflow(workflow)
// @ts-expect-error fixme ts strict error
expect(validatedWorkflow.nodes[0].pos).toEqual([3, 4])
// Should accept the legacy bugged format object.
@@ -89,6 +90,7 @@ describe('parseComfyWorkflow', () => {
'9': 0
}
validatedWorkflow = await validateComfyWorkflow(workflow)
// @ts-expect-error fixme ts strict error
expect(validatedWorkflow.nodes[0].pos).toEqual([600, 340])
})
@@ -107,6 +109,7 @@ describe('parseComfyWorkflow', () => {
// dynamic widgets display.
workflow.nodes[0].widgets_values = { foo: 'bar' }
const validatedWorkflow = await validateComfyWorkflow(workflow)
// @ts-expect-error fixme ts strict error
expect(validatedWorkflow.nodes[0].widgets_values).toEqual({ foo: 'bar' })
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it } from 'vitest'
import { transformNodeDefV1ToV2 } from '@/schemas/nodeDef/migration'
@@ -223,6 +222,7 @@ describe('NodeDef Migration', () => {
const result = transformNodeDefV1ToV2(nodeDef)
// @ts-expect-error fixme ts strict error
expect(result.hidden).toEqual(plainObject.hidden)
expect(result.hidden?.someHiddenValue).toBe(42)
expect(result.hidden?.anotherHiddenValue).toEqual({ nested: 'object' })

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it } from 'vitest'
import { ComfyNodeDef } from '@/schemas/nodeDefSchema'
@@ -66,8 +65,10 @@ describe('nodeSearchService', () => {
it('searches with input filter', () => {
const service = new NodeSearchService(EXAMPLE_NODE_DEFS)
const inputFilter = service.getFilterById('input')
// @ts-expect-error fixme ts strict error
expect(service.searchNode('L', [[inputFilter, 'LATENT']])).toHaveLength(1)
// Wildcard should match all.
// @ts-expect-error fixme ts strict error
expect(service.searchNode('L', [[inputFilter, '*']])).toHaveLength(2)
expect(service.searchNode('L')).toHaveLength(2)
})

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it } from 'vitest'
import { TaskItemImpl } from '@/stores/queueStore'
@@ -7,6 +6,7 @@ describe('TaskItemImpl', () => {
it('should remove animated property from outputs during construction', () => {
const taskItem = new TaskItemImpl(
'History',
// @ts-expect-error fixme ts strict error
[0, 'prompt-id', {}, {}, []],
{ status_str: 'success', messages: [] },
{
@@ -22,12 +22,14 @@ describe('TaskItemImpl', () => {
// Verify other output properties remain intact
expect(taskItem.outputs['node-1'].images).toBeDefined()
// @ts-expect-error fixme ts strict error
expect(taskItem.outputs['node-1'].images[0].filename).toBe('test.png')
})
it('should handle outputs without animated property', () => {
const taskItem = new TaskItemImpl(
'History',
// @ts-expect-error fixme ts strict error
[0, 'prompt-id', {}, {}, []],
{ status_str: 'success', messages: [] },
{
@@ -39,12 +41,14 @@ describe('TaskItemImpl', () => {
// Verify outputs are preserved when no animated property exists
expect(taskItem.outputs['node-1'].images).toBeDefined()
// @ts-expect-error fixme ts strict error
expect(taskItem.outputs['node-1'].images[0].filename).toBe('test.png')
})
it('should recognize webm video from core', () => {
const taskItem = new TaskItemImpl(
'History',
// @ts-expect-error fixme ts strict error
[0, 'prompt-id', {}, {}, []],
{ status_str: 'success', messages: [] },
{
@@ -67,6 +71,7 @@ describe('TaskItemImpl', () => {
it('should recognize webm video from VHS', () => {
const taskItem = new TaskItemImpl(
'History',
// @ts-expect-error fixme ts strict error
[0, 'prompt-id', {}, {}, []],
{ status_str: 'success', messages: [] },
{

View File

@@ -1,4 +1,3 @@
// @ts-strict-ignore
import { describe, expect, it } from 'vitest'
import type {
@@ -22,7 +21,9 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('INT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].min).toBe(5)
// @ts-expect-error fixme ts strict error
expect(result?.[1].max).toBe(10)
})
@@ -43,7 +44,9 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('FLOAT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].min).toBe(5.5)
// @ts-expect-error fixme ts strict error
expect(result?.[1].max).toBe(10.5)
})
@@ -55,7 +58,9 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('FLOAT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].min).toBe(0.5)
// @ts-expect-error fixme ts strict error
expect(result?.[1].max).toBe(15.5)
})
@@ -67,6 +72,7 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('INT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].step).toBe(6) // LCM of 2 and 3 is 6
})
@@ -78,6 +84,7 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('INT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].step).toBe(4) // LCM of 1 and 4 is 4
})
@@ -89,6 +96,7 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('FLOAT')
// @ts-expect-error fixme ts strict error
expect(result?.[1].step).toBe(0.5)
})
})
@@ -103,6 +111,7 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('COMBO')
// @ts-expect-error fixme ts strict error
expect(result?.[1].options).toEqual(['B', 'C'])
})
@@ -137,9 +146,13 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('COMBO')
// @ts-expect-error fixme ts strict error
expect(result?.[1].options).toEqual(['B', 'C'])
// @ts-expect-error fixme ts strict error
expect(result?.[1].default).toBe('B')
// @ts-expect-error fixme ts strict error
expect(result?.[1].tooltip).toBe('Select an option')
// @ts-expect-error fixme ts strict error
expect(result?.[1].multiline).toBe(true)
})
@@ -151,6 +164,7 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('COMBO')
// @ts-expect-error fixme ts strict error
expect(result?.[1].options).toEqual(['C', 'D'])
})
})
@@ -188,8 +202,11 @@ describe('nodeDefUtil', () => {
expect(result).not.toBeNull()
expect(result?.[0]).toBe('STRING')
// @ts-expect-error fixme ts strict error
expect(result?.[1].default).toBe('value2')
// @ts-expect-error fixme ts strict error
expect(result?.[1].tooltip).toBe('Tooltip 2')
// @ts-expect-error fixme ts strict error
expect(result?.[1].step).toBe(1)
})

View File

@@ -14,7 +14,7 @@
"resolveJsonModule": true,
/* Linting */
"strict": false,
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
@@ -29,12 +29,6 @@
"typeRoots": ["src/types", "node_modules/@types"],
"outDir": "./dist",
"rootDir": "./",
"plugins": [
{
"name": "typescript-strict-plugin"
}
]
},
"include": [
"src/**/*",