mirror of https://github.com/node-red/node-red.git
commit
afaede32dd
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -33,6 +33,17 @@ Nodes
|
|||
|
||||
- Add ability to use pfx or p12 file for TLS connection settings option (#4907) @dceejay
|
||||
|
||||
#### 4.1.6: Maintenance Release
|
||||
|
||||
- Allow palette.theme to be set via theme plugin and include icons (#5500) @knolleary
|
||||
- Ensure config sidebar tooltip handles html content (#5501) @knolleary
|
||||
- Allow node-red integrator access to available updates (#5499) @Steve-Mcl
|
||||
- Add frontend pre and post debug message hooks (#5495) @Steve-Mcl
|
||||
- Fix: allow middle-click panning over links and ports (#5496) @lklivingstone
|
||||
- Support ctrl key to select configuration nodes (#5486) @kazuhitoyokoi
|
||||
- Add § as shortcut meta-key (#5482) @gorenje
|
||||
- Update dependencies (#5502) @knolleary
|
||||
|
||||
#### 4.1.5: Maintenance Release
|
||||
|
||||
- chore: bump tar to 7.5.7 (#5472) @bryopsida
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@
|
|||
"version": "5.0.0-beta.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"acorn": "8.15.0",
|
||||
"acorn-walk": "8.3.4",
|
||||
"ajv": "8.17.1",
|
||||
"@node-rs/bcrypt": "^1.10.7",
|
||||
"acorn": "8.16.0",
|
||||
"acorn-walk": "8.3.5",
|
||||
"ajv": "8.18.0",
|
||||
"async-mutex": "0.5.0",
|
||||
"basic-auth": "2.0.1",
|
||||
"bcryptjs": "3.0.2",
|
||||
"bcryptjs": "3.0.3",
|
||||
"body-parser": "1.20.4",
|
||||
"chalk": "^4.1.2",
|
||||
"cheerio": "1.0.0-rc.10",
|
||||
|
|
@ -45,7 +46,7 @@
|
|||
"mime": "3.0.0",
|
||||
"moment": "2.30.1",
|
||||
"moment-timezone": "0.5.48",
|
||||
"mqtt": "5.11.0",
|
||||
"mqtt": "5.15.0",
|
||||
"multer": "2.0.2",
|
||||
"mustache": "4.2.0",
|
||||
"node-red-admin": "^4.1.3",
|
||||
|
|
@ -57,9 +58,9 @@
|
|||
"passport-http-bearer": "1.0.1",
|
||||
"passport-oauth2-client-password": "0.1.2",
|
||||
"raw-body": "3.0.0",
|
||||
"rfdc": "^1.3.1",
|
||||
"semver": "7.7.1",
|
||||
"tar": "7.5.7",
|
||||
"rfdc": "1.4.1",
|
||||
"semver": "7.7.4",
|
||||
"tar": "7.5.9",
|
||||
"tough-cookie": "5.1.2",
|
||||
"uglify-js": "3.19.3",
|
||||
"uuid": "9.0.1",
|
||||
|
|
@ -91,11 +92,11 @@
|
|||
"jquery-i18next": "1.2.1",
|
||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||
"marked": "4.3.0",
|
||||
"mermaid": "11.9.0",
|
||||
"mermaid": "11.12.3",
|
||||
"minami": "1.2.3",
|
||||
"mocha": "9.2.2",
|
||||
"node-red-node-test-helper": "^0.3.3",
|
||||
"nodemon": "3.1.9",
|
||||
"nodemon": "3.1.14",
|
||||
"proxy": "^1.0.2",
|
||||
"sass": "1.62.1",
|
||||
"should": "13.2.3",
|
||||
|
|
@ -107,7 +108,7 @@
|
|||
"node": ">=18.5"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@node-rs/bcrypt": "1.10.7"
|
||||
"@node-rs/bcrypt": "^1.10.7"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/install-pkg": {
|
||||
|
|
@ -124,16 +125,6 @@
|
|||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@antfu/utils": {
|
||||
"version": "8.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@antfu/utils/-/utils-8.1.1.tgz",
|
||||
"integrity": "sha512-Mex9nXf9vR6AhcXmMrlz/HVgYYZpVGJ6YlPgwl7UnaFpnshXs6EK/oa5Gpf3CzENMjkvEx2tQtntGnb7UtSTOQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/code-frame": {
|
||||
"version": "7.27.1",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
|
||||
|
|
@ -213,9 +204,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@babel/runtime": {
|
||||
"version": "7.28.4",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz",
|
||||
"integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==",
|
||||
"version": "7.28.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.6.tgz",
|
||||
"integrity": "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
|
|
@ -302,60 +293,46 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@chevrotain/cst-dts-gen": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.0.3.tgz",
|
||||
"integrity": "sha512-BvIKpRLeS/8UbfxXxgC33xOumsacaeCKAjAeLyOn7Pcp95HiRbrpl14S+9vaZLolnbssPIUuiUd8IvgkRyt6NQ==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/cst-dts-gen/-/cst-dts-gen-11.1.1.tgz",
|
||||
"integrity": "sha512-fRHyv6/f542qQqiRGalrfJl/evD39mAvbJLCekPazhiextEatq1Jx1K/i9gSd5NNO0ds03ek0Cbo/4uVKmOBcw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/gast": "11.0.3",
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
"@chevrotain/gast": "11.1.1",
|
||||
"@chevrotain/types": "11.1.1",
|
||||
"lodash-es": "4.17.23"
|
||||
}
|
||||
},
|
||||
"node_modules/@chevrotain/cst-dts-gen/node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@chevrotain/gast": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.0.3.tgz",
|
||||
"integrity": "sha512-+qNfcoNk70PyS/uxmj3li5NiECO+2YKZZQMbmjTqRI3Qchu8Hig/Q9vgkHpI3alNjr7M+a2St5pw5w5F6NL5/Q==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/gast/-/gast-11.1.1.tgz",
|
||||
"integrity": "sha512-Ko/5vPEYy1vn5CbCjjvnSO4U7GgxyGm+dfUZZJIWTlQFkXkyym0jFYrWEU10hyCjrA7rQtiHtBr0EaZqvHFZvg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
"@chevrotain/types": "11.1.1",
|
||||
"lodash-es": "4.17.23"
|
||||
}
|
||||
},
|
||||
"node_modules/@chevrotain/gast/node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@chevrotain/regexp-to-ast": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.0.3.tgz",
|
||||
"integrity": "sha512-1fMHaBZxLFvWI067AVbGJav1eRY7N8DDvYCTwGBiE/ytKBgP8azTdgyrKyWZ9Mfh09eHWb5PgTSO8wi7U824RA==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/regexp-to-ast/-/regexp-to-ast-11.1.1.tgz",
|
||||
"integrity": "sha512-ctRw1OKSXkOrR8VTvOxrQ5USEc4sNrfwXHa1NuTcR7wre4YbjPcKw+82C2uylg/TEwFRgwLmbhlln4qkmDyteg==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chevrotain/types": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.0.3.tgz",
|
||||
"integrity": "sha512-gsiM3G8b58kZC2HaWR50gu6Y1440cHiJ+i3JUvcp/35JchYejb2+5MVeJK0iKThYpAa/P2PYFV4hoi44HD+aHQ==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/types/-/types-11.1.1.tgz",
|
||||
"integrity": "sha512-wb2ToxG8LkgPYnKe9FH8oGn3TMCBdnwiuNC5l5y+CtlaVRbCytU0kbVsk6CGrqTL4ZN4ksJa0TXOYbxpbthtqw==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
"node_modules/@chevrotain/utils": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.0.3.tgz",
|
||||
"integrity": "sha512-YslZMgtJUyuMbZ+aKvfF3x1f5liK4mWNxghFRv7jqRR9C3R3fAOGTTKvxXDa2Y1s9zSbcpuO0cAxDYsc9SrXoQ==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@chevrotain/utils/-/utils-11.1.1.tgz",
|
||||
"integrity": "sha512-71eTYMzYXYSFPrbg/ZwftSaSDld7UYlS8OQa3lNnn9jzNtpFbaReRRyghzqS7rI3CDaorqpPJJcXGHK+FE1TVQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0"
|
||||
},
|
||||
|
|
@ -398,47 +375,17 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@iconify/utils": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-2.3.0.tgz",
|
||||
"integrity": "sha512-GmQ78prtwYW6EtzXRU1rY+KwOKfz32PD7iJh6Iyqw68GiKuoZ2A6pRtzWONz5VQJbp50mEjXh/7NkumtrAgRKA==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@iconify/utils/-/utils-3.1.0.tgz",
|
||||
"integrity": "sha512-Zlzem1ZXhI1iHeeERabLNzBHdOa4VhQbqAcOQaMKuTuyZCpwKbC2R4Dd0Zo3g9EAc+Y4fiarO8HIHRAth7+skw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@antfu/install-pkg": "^1.0.0",
|
||||
"@antfu/utils": "^8.1.0",
|
||||
"@antfu/install-pkg": "^1.1.0",
|
||||
"@iconify/types": "^2.0.0",
|
||||
"debug": "^4.4.0",
|
||||
"globals": "^15.14.0",
|
||||
"kolorist": "^1.8.0",
|
||||
"local-pkg": "^1.0.0",
|
||||
"mlly": "^1.7.4"
|
||||
"mlly": "^1.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/utils/node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"ms": "^2.1.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"supports-color": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@iconify/utils/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@isaacs/fs-minipass": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz",
|
||||
|
|
@ -504,13 +451,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@mermaid-js/parser": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-0.6.3.tgz",
|
||||
"integrity": "sha512-lnjOhe7zyHjc+If7yT4zoedx2vo4sHaTmtkl1+or8BRTnCtDmcTpAjpzDSfCZrshM5bCoz0GyidzadJAH1xobA==",
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@mermaid-js/parser/-/parser-1.0.0.tgz",
|
||||
"integrity": "sha512-vvK0Hi/VWndxoh03Mmz6wa1KDriSPjS2XMZL/1l19HFwygiObEEoEwSDxOqyLzzAI6J2PU3261JjTMTO7x+BPw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"langium": "3.3.1"
|
||||
"langium": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@napi-rs/wasm-runtime": {
|
||||
|
|
@ -860,6 +807,23 @@
|
|||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/@prantlf/jsonlint/node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
"fast-uri": "^3.0.1",
|
||||
"json-schema-traverse": "^1.0.0",
|
||||
"require-from-string": "^2.0.2"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/epoberezkin"
|
||||
}
|
||||
},
|
||||
"node_modules/@sindresorhus/is": {
|
||||
"version": "5.6.0",
|
||||
"resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.6.0.tgz",
|
||||
|
|
@ -1329,9 +1293,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.15.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
||||
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
||||
"version": "8.16.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
|
||||
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
|
|
@ -1341,9 +1305,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/acorn-walk": {
|
||||
"version": "8.3.4",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz",
|
||||
"integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==",
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.5.tgz",
|
||||
"integrity": "sha512-HEHNfbars9v4pgpW6SO1KSPkfoS0xVOM/9UzkJltjlsHZmJasxg8aXkuZa7SMf8vKGIBhpUsPluQSqhJFCqebw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"acorn": "^8.11.0"
|
||||
|
|
@ -1398,9 +1362,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
|
|
@ -1839,9 +1803,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/bcryptjs": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
|
||||
"integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.3.tgz",
|
||||
"integrity": "sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==",
|
||||
"license": "BSD-3-Clause",
|
||||
"bin": {
|
||||
"bcrypt": "bin/bcrypt"
|
||||
|
|
@ -2016,6 +1980,18 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/broker-factory": {
|
||||
"version": "3.1.13",
|
||||
"resolved": "https://registry.npmjs.org/broker-factory/-/broker-factory-3.1.13.tgz",
|
||||
"integrity": "sha512-H2VALe31mEtO/SRcNp4cUU5BAm1biwhc/JaF77AigUuni/1YT0FLCJfbUxwIEs9y6Kssjk2fmXgf+Y9ALvmKlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"fast-unique-numbers": "^9.0.26",
|
||||
"tslib": "^2.8.1",
|
||||
"worker-factory": "^7.0.48"
|
||||
}
|
||||
},
|
||||
"node_modules/browser-stdout": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
||||
|
|
@ -2267,18 +2243,18 @@
|
|||
}
|
||||
},
|
||||
"node_modules/chevrotain": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.0.3.tgz",
|
||||
"integrity": "sha512-ci2iJH6LeIkvP9eJW6gpueU8cnZhv85ELY8w8WiFtNjMHA5ad6pQLaJo9mEly/9qUyCpvqX8/POVUTf18/HFdw==",
|
||||
"version": "11.1.1",
|
||||
"resolved": "https://registry.npmjs.org/chevrotain/-/chevrotain-11.1.1.tgz",
|
||||
"integrity": "sha512-f0yv5CPKaFxfsPTBzX7vGuim4oIC1/gcS7LUGdBSwl2dU6+FON6LVUksdOo1qJjoUvXNn45urgh8C+0a24pACQ==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@chevrotain/cst-dts-gen": "11.0.3",
|
||||
"@chevrotain/gast": "11.0.3",
|
||||
"@chevrotain/regexp-to-ast": "11.0.3",
|
||||
"@chevrotain/types": "11.0.3",
|
||||
"@chevrotain/utils": "11.0.3",
|
||||
"lodash-es": "4.17.21"
|
||||
"@chevrotain/cst-dts-gen": "11.1.1",
|
||||
"@chevrotain/gast": "11.1.1",
|
||||
"@chevrotain/regexp-to-ast": "11.1.1",
|
||||
"@chevrotain/types": "11.1.1",
|
||||
"@chevrotain/utils": "11.1.1",
|
||||
"lodash-es": "4.17.23"
|
||||
}
|
||||
},
|
||||
"node_modules/chevrotain-allstar": {
|
||||
|
|
@ -2294,13 +2270,6 @@
|
|||
"chevrotain": "^11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/chevrotain/node_modules/lodash-es": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz",
|
||||
"integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||
|
|
@ -2624,9 +2593,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/confbox": {
|
||||
"version": "0.2.2",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.2.2.tgz",
|
||||
"integrity": "sha512-1NB+BKqhtNipMsov4xI/NnhCKp9XG9NamYp5PVm9klAT0fsrNPjaFICsCFhNhwZJKNh7zB/3q8qXz0E9oaMNtQ==",
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
@ -3184,9 +3153,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/d3-format": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
|
||||
"integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.2.tgz",
|
||||
"integrity": "sha512-AJDdYOdnyRDV5b6ArilzCPPwc1ejkHcoyFarqlPqT7zRYjhavcT3uSrqcMvsgh2CgoPbK3RCwyHaVyxYcP2Arg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
|
|
@ -3442,9 +3411,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/dagre-d3-es": {
|
||||
"version": "7.0.11",
|
||||
"resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.11.tgz",
|
||||
"integrity": "sha512-tvlJLyQf834SylNKax8Wkzco/1ias1OPw8DcUMDE7oUIoSEW25riQVuiu/0OWEFqT0cxHT3Pa9/D82Jr47IONw==",
|
||||
"version": "7.0.13",
|
||||
"resolved": "https://registry.npmjs.org/dagre-d3-es/-/dagre-d3-es-7.0.13.tgz",
|
||||
"integrity": "sha512-efEhnxpSuwpYOKRm/L5KbqoZmNNukHa/Flty4Wp62JRvgH2ojwVgPgdYyr4twpieZnyRDdIH7PY2mopX26+j2Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -4125,13 +4094,6 @@
|
|||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/exsolve": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz",
|
||||
"integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
|
|
@ -4170,16 +4132,16 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-unique-numbers": {
|
||||
"version": "8.0.13",
|
||||
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-8.0.13.tgz",
|
||||
"integrity": "sha512-7OnTFAVPefgw2eBJ1xj2PGGR9FwYzSUso9decayHgCDX4sJkHLdcsYTytTg+tYv+wKF3U8gJuSBz2jJpQV4u/g==",
|
||||
"version": "9.0.26",
|
||||
"resolved": "https://registry.npmjs.org/fast-unique-numbers/-/fast-unique-numbers-9.0.26.tgz",
|
||||
"integrity": "sha512-3Mtq8p1zQinjGyWfKeuBunbuFoixG72AUkk4VvzbX4ykCW9Q4FzRaNyIlfQhUjnKw2ARVP+/CKnoyr6wfHftig==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.23.8",
|
||||
"tslib": "^2.6.2"
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"tslib": "^2.8.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.1.0"
|
||||
"node": ">=18.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-uri": {
|
||||
|
|
@ -4777,19 +4739,6 @@
|
|||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "15.15.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-15.15.0.tgz",
|
||||
"integrity": "sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/globule": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/globule/-/globule-1.3.4.tgz",
|
||||
|
|
@ -6399,9 +6348,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/jsdoc-api/node_modules/markdown-it": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"version": "14.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.1.tgz",
|
||||
"integrity": "sha512-BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
|
|
@ -6772,28 +6721,22 @@
|
|||
"graceful-fs": "^4.1.9"
|
||||
}
|
||||
},
|
||||
"node_modules/kolorist": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/kolorist/-/kolorist-1.8.0.tgz",
|
||||
"integrity": "sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/langium": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/langium/-/langium-3.3.1.tgz",
|
||||
"integrity": "sha512-QJv/h939gDpvT+9SiLVlY7tZC3xB2qK57v0J04Sh9wpMb6MP1q8gB21L3WIo8T5P1MSMg3Ep14L7KkDCFG3y4w==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/langium/-/langium-4.2.1.tgz",
|
||||
"integrity": "sha512-zu9QWmjpzJcomzdJQAHgDVhLGq5bLosVak1KVa40NzQHXfqr4eAHupvnPOVXEoLkg6Ocefvf/93d//SB7du4YQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chevrotain": "~11.0.3",
|
||||
"chevrotain-allstar": "~0.3.0",
|
||||
"chevrotain": "~11.1.1",
|
||||
"chevrotain-allstar": "~0.3.1",
|
||||
"vscode-languageserver": "~9.0.1",
|
||||
"vscode-languageserver-textdocument": "~1.0.11",
|
||||
"vscode-uri": "~3.0.8"
|
||||
"vscode-uri": "~3.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
"node": ">=20.10.0",
|
||||
"npm": ">=10.2.3"
|
||||
}
|
||||
},
|
||||
"node_modules/layout-base": {
|
||||
|
|
@ -6952,24 +6895,6 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/local-pkg": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz",
|
||||
"integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"mlly": "^1.7.4",
|
||||
"pkg-types": "^2.3.0",
|
||||
"quansync": "^0.2.11"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/locate-path": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
|
||||
|
|
@ -6987,16 +6912,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
|
||||
"integrity": "sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash-es": {
|
||||
"version": "4.17.22",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.22.tgz",
|
||||
"integrity": "sha512-XEawp1t0gxSi9x01glktRZ5HDy0HXqrM0x5pXQM98EaI0NxO6jVM7omDOxsuEo5UIASAnm2bRp1Jt/e0a2XU8Q==",
|
||||
"version": "4.17.23",
|
||||
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.23.tgz",
|
||||
"integrity": "sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
@ -7327,28 +7252,28 @@
|
|||
}
|
||||
},
|
||||
"node_modules/mermaid": {
|
||||
"version": "11.9.0",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.9.0.tgz",
|
||||
"integrity": "sha512-YdPXn9slEwO0omQfQIsW6vS84weVQftIyyTGAZCwM//MGhPzL1+l6vO6bkf0wnP4tHigH1alZ5Ooy3HXI2gOag==",
|
||||
"version": "11.12.3",
|
||||
"resolved": "https://registry.npmjs.org/mermaid/-/mermaid-11.12.3.tgz",
|
||||
"integrity": "sha512-wN5ZSgJQIC+CHJut9xaKWsknLxaFBwCPwPkGTSUYrTiHORWvpT8RxGk849HPnpUAQ+/9BPRqYb80jTpearrHzQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@braintree/sanitize-url": "^7.0.4",
|
||||
"@iconify/utils": "^2.1.33",
|
||||
"@mermaid-js/parser": "^0.6.2",
|
||||
"@braintree/sanitize-url": "^7.1.1",
|
||||
"@iconify/utils": "^3.0.1",
|
||||
"@mermaid-js/parser": "^1.0.0",
|
||||
"@types/d3": "^7.4.3",
|
||||
"cytoscape": "^3.29.3",
|
||||
"cytoscape-cose-bilkent": "^4.1.0",
|
||||
"cytoscape-fcose": "^2.2.0",
|
||||
"d3": "^7.9.0",
|
||||
"d3-sankey": "^0.12.3",
|
||||
"dagre-d3-es": "7.0.11",
|
||||
"dayjs": "^1.11.13",
|
||||
"dagre-d3-es": "7.0.13",
|
||||
"dayjs": "^1.11.18",
|
||||
"dompurify": "^3.2.5",
|
||||
"katex": "^0.16.22",
|
||||
"khroma": "^2.1.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"marked": "^16.0.0",
|
||||
"lodash-es": "^4.17.23",
|
||||
"marked": "^16.2.1",
|
||||
"roughjs": "^4.6.6",
|
||||
"stylis": "^4.3.6",
|
||||
"ts-dedent": "^2.2.0",
|
||||
|
|
@ -7532,25 +7457,6 @@
|
|||
"ufo": "^1.6.1"
|
||||
}
|
||||
},
|
||||
"node_modules/mlly/node_modules/confbox": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/confbox/-/confbox-0.1.8.tgz",
|
||||
"integrity": "sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/mlly/node_modules/pkg-types": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.1.8",
|
||||
"mlly": "^1.7.4",
|
||||
"pathe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha": {
|
||||
"version": "9.2.2",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-9.2.2.tgz",
|
||||
|
|
@ -7666,9 +7572,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/glob/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -7749,28 +7655,27 @@
|
|||
}
|
||||
},
|
||||
"node_modules/mqtt": {
|
||||
"version": "5.11.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.11.0.tgz",
|
||||
"integrity": "sha512-VDqfADTNvohwcY02NgxPb7OojIeDrNQ1q62r/DcM+bnIWY8LBi3nMTvdEaFEp6Bu4ejBIpHjJVthUEgnvGLemA==",
|
||||
"version": "5.15.0",
|
||||
"resolved": "https://registry.npmjs.org/mqtt/-/mqtt-5.15.0.tgz",
|
||||
"integrity": "sha512-KC+wAssYk83Qu5bT8YDzDYgUJxPhbLeVsDvpY2QvL28PnXYJzC2WkKruyMUgBAZaQ7h9lo9k2g4neRNUUxzgMw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^4.0.18",
|
||||
"@types/ws": "^8.5.14",
|
||||
"@types/readable-stream": "^4.0.21",
|
||||
"@types/ws": "^8.18.1",
|
||||
"commist": "^3.2.0",
|
||||
"concat-stream": "^2.0.0",
|
||||
"debug": "^4.4.0",
|
||||
"debug": "^4.4.1",
|
||||
"help-me": "^5.0.0",
|
||||
"lru-cache": "^10.4.3",
|
||||
"minimist": "^1.2.8",
|
||||
"mqtt-packet": "^9.0.2",
|
||||
"number-allocator": "^1.0.14",
|
||||
"readable-stream": "^4.7.0",
|
||||
"reinterval": "^1.1.0",
|
||||
"rfdc": "^1.4.1",
|
||||
"socks": "^2.8.3",
|
||||
"socks": "^2.8.6",
|
||||
"split2": "^4.2.0",
|
||||
"worker-timers": "^7.1.8",
|
||||
"ws": "^8.18.0"
|
||||
"worker-timers": "^8.0.23",
|
||||
"ws": "^8.18.3"
|
||||
},
|
||||
"bin": {
|
||||
"mqtt": "build/bin/mqtt.js",
|
||||
|
|
@ -8077,6 +7982,15 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/node-red-admin/node_modules/bcryptjs": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-3.0.2.tgz",
|
||||
"integrity": "sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog==",
|
||||
"license": "BSD-3-Clause",
|
||||
"bin": {
|
||||
"bcrypt": "bin/bcrypt"
|
||||
}
|
||||
},
|
||||
"node_modules/node-red-node-test-helper": {
|
||||
"version": "0.3.5",
|
||||
"resolved": "https://registry.npmjs.org/node-red-node-test-helper/-/node-red-node-test-helper-0.3.5.tgz",
|
||||
|
|
@ -8226,16 +8140,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/nodemon": {
|
||||
"version": "3.1.9",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.9.tgz",
|
||||
"integrity": "sha512-hdr1oIb2p6ZSxu3PB2JWWYS7ZQ0qvaZsc3hK8DR8f02kRzc8rjYmxAIvdz+aYC+8F2IjNaB7HMcSDg8nQpJxyg==",
|
||||
"version": "3.1.14",
|
||||
"resolved": "https://registry.npmjs.org/nodemon/-/nodemon-3.1.14.tgz",
|
||||
"integrity": "sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"chokidar": "^3.5.2",
|
||||
"debug": "^4",
|
||||
"ignore-by-default": "^1.0.1",
|
||||
"minimatch": "^3.1.2",
|
||||
"minimatch": "^10.2.1",
|
||||
"pstree.remy": "^1.1.8",
|
||||
"semver": "^7.5.3",
|
||||
"simple-update-notifier": "^2.0.0",
|
||||
|
|
@ -8254,6 +8168,29 @@
|
|||
"url": "https://opencollective.com/nodemon"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/balanced-match": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
|
||||
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/brace-expansion": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.3.tgz",
|
||||
"integrity": "sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20 || >=22"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/debug": {
|
||||
"version": "4.4.3",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
|
||||
|
|
@ -8283,16 +8220,19 @@
|
|||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "10.2.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.3.tgz",
|
||||
"integrity": "sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
"brace-expansion": "^5.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
"node": "18 || 20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/nodemon/node_modules/ms": {
|
||||
|
|
@ -9348,15 +9288,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/pkg-types": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz",
|
||||
"integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==",
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-1.3.1.tgz",
|
||||
"integrity": "sha512-/Jm5M4RvtBFVkKWRu2BLUTNP8/M2a+UwuAX+ae4770q1qVGtfjG+WTCupoZixokjmHiry8uI+dlY8KXYV5HVVQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"confbox": "^0.2.2",
|
||||
"exsolve": "^1.0.7",
|
||||
"pathe": "^2.0.3"
|
||||
"confbox": "^0.1.8",
|
||||
"mlly": "^1.7.4",
|
||||
"pathe": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/points-on-curve": {
|
||||
|
|
@ -9511,9 +9451,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.14.1",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz",
|
||||
"integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==",
|
||||
"version": "6.14.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz",
|
||||
"integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.1.0"
|
||||
|
|
@ -9525,23 +9465,6 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/quansync": {
|
||||
"version": "0.2.11",
|
||||
"resolved": "https://registry.npmjs.org/quansync/-/quansync-0.2.11.tgz",
|
||||
"integrity": "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/sxzz"
|
||||
}
|
||||
],
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
|
|
@ -9785,9 +9708,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/readdir-glob/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
|
||||
"version": "5.1.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz",
|
||||
"integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
@ -9883,12 +9806,6 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/reinterval": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/reinterval/-/reinterval-1.1.0.tgz",
|
||||
"integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/release-zalgo": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz",
|
||||
|
|
@ -10129,9 +10046,9 @@
|
|||
"license": "BlueOak-1.0.0"
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.7.1",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
|
||||
"integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
|
||||
"version": "7.7.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
|
||||
"integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
|
||||
"license": "ISC",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
|
|
@ -11012,9 +10929,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"node_modules/tar": {
|
||||
"version": "7.5.7",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.7.tgz",
|
||||
"integrity": "sha512-fov56fJiRuThVFXD6o6/Q354S7pnWMJIVlDBYijsTNx6jKSE4pvrDTs6lUnmGvNyfJwFQQwWy3owKz1ucIhveQ==",
|
||||
"version": "7.5.9",
|
||||
"resolved": "https://registry.npmjs.org/tar/-/tar-7.5.9.tgz",
|
||||
"integrity": "sha512-BTLcK0xsDh2+PUe9F6c2TlRp4zOOBMTkoQHQIWSIzI0R7KG46uEwq4OPk2W7bZcprBMsuaeFsqwYr7pjh6CuHg==",
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/fs-minipass": "^4.0.0",
|
||||
|
|
@ -11357,9 +11274,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ufo": {
|
||||
"version": "1.6.2",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.2.tgz",
|
||||
"integrity": "sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==",
|
||||
"version": "1.6.3",
|
||||
"resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.3.tgz",
|
||||
"integrity": "sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
@ -11572,9 +11489,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/vscode-uri": {
|
||||
"version": "3.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.0.8.tgz",
|
||||
"integrity": "sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==",
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
|
|
@ -11685,38 +11602,51 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/worker-timers": {
|
||||
"version": "7.1.8",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-7.1.8.tgz",
|
||||
"integrity": "sha512-R54psRKYVLuzff7c1OTFcq/4Hue5Vlz4bFtNEIarpSiCYhpifHU3aIQI29S84o1j87ePCYqbmEJPqwBTf+3sfw==",
|
||||
"node_modules/worker-factory": {
|
||||
"version": "7.0.48",
|
||||
"resolved": "https://registry.npmjs.org/worker-factory/-/worker-factory-7.0.48.tgz",
|
||||
"integrity": "sha512-CGmBy3tJvpBPjUvb0t4PrpKubUsfkI1Ohg0/GGFU2RvA9j/tiVYwKU8O7yu7gH06YtzbeJLzdUR29lmZKn5pag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.5",
|
||||
"tslib": "^2.6.2",
|
||||
"worker-timers-broker": "^6.1.8",
|
||||
"worker-timers-worker": "^7.0.71"
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"fast-unique-numbers": "^9.0.26",
|
||||
"tslib": "^2.8.1"
|
||||
}
|
||||
},
|
||||
"node_modules/worker-timers": {
|
||||
"version": "8.0.30",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers/-/worker-timers-8.0.30.tgz",
|
||||
"integrity": "sha512-8P7YoMHWN0Tz7mg+9oEhuZdjBIn2z6gfjlJqFcHiDd9no/oLnMGCARCDkV1LR3ccQus62ZdtIp7t3aTKrMLHOg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"tslib": "^2.8.1",
|
||||
"worker-timers-broker": "^8.0.15",
|
||||
"worker-timers-worker": "^9.0.13"
|
||||
}
|
||||
},
|
||||
"node_modules/worker-timers-broker": {
|
||||
"version": "6.1.8",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-6.1.8.tgz",
|
||||
"integrity": "sha512-FUCJu9jlK3A8WqLTKXM9E6kAmI/dR1vAJ8dHYLMisLNB/n3GuaFIjJ7pn16ZcD1zCOf7P6H62lWIEBi+yz/zQQ==",
|
||||
"version": "8.0.15",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers-broker/-/worker-timers-broker-8.0.15.tgz",
|
||||
"integrity": "sha512-Te+EiVUMzG5TtHdmaBZvBrZSFNauym6ImDaCAnzQUxvjnw+oGjMT2idmAOgDy30vOZMLejd0bcsc90Axu6XPWA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.5",
|
||||
"fast-unique-numbers": "^8.0.13",
|
||||
"tslib": "^2.6.2",
|
||||
"worker-timers-worker": "^7.0.71"
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"broker-factory": "^3.1.13",
|
||||
"fast-unique-numbers": "^9.0.26",
|
||||
"tslib": "^2.8.1",
|
||||
"worker-timers-worker": "^9.0.13"
|
||||
}
|
||||
},
|
||||
"node_modules/worker-timers-worker": {
|
||||
"version": "7.0.71",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-7.0.71.tgz",
|
||||
"integrity": "sha512-ks/5YKwZsto1c2vmljroppOKCivB/ma97g9y77MAAz2TBBjPPgpoOiS1qYQKIgvGTr2QYPT3XhJWIB6Rj2MVPQ==",
|
||||
"version": "9.0.13",
|
||||
"resolved": "https://registry.npmjs.org/worker-timers-worker/-/worker-timers-worker-9.0.13.tgz",
|
||||
"integrity": "sha512-qjn18szGb1kjcmh2traAdki1eiIS5ikFo+L90nfMOvSRpuDw1hAcR1nzkP2+Hkdqz5thIRnfuWx7QSpsEUsA6Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.24.5",
|
||||
"tslib": "^2.6.2"
|
||||
"@babel/runtime": "^7.28.6",
|
||||
"tslib": "^2.8.1",
|
||||
"worker-factory": "^7.0.48"
|
||||
}
|
||||
},
|
||||
"node_modules/workerpool": {
|
||||
|
|
@ -11969,9 +11899,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/zip-stream/node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
|
|
|
|||
20
package.json
20
package.json
|
|
@ -26,12 +26,12 @@
|
|||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"acorn": "8.15.0",
|
||||
"acorn-walk": "8.3.4",
|
||||
"ajv": "8.17.1",
|
||||
"acorn": "8.16.0",
|
||||
"acorn-walk": "8.3.5",
|
||||
"ajv": "8.18.0",
|
||||
"async-mutex": "0.5.0",
|
||||
"basic-auth": "2.0.1",
|
||||
"bcryptjs": "3.0.2",
|
||||
"bcryptjs": "3.0.3",
|
||||
"body-parser": "1.20.4",
|
||||
"chalk": "^4.1.2",
|
||||
"cheerio": "1.0.0-rc.10",
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
"mime": "3.0.0",
|
||||
"moment": "2.30.1",
|
||||
"moment-timezone": "0.5.48",
|
||||
"mqtt": "5.11.0",
|
||||
"mqtt": "5.15.0",
|
||||
"multer": "2.0.2",
|
||||
"mustache": "4.2.0",
|
||||
"node-red-admin": "^4.1.3",
|
||||
|
|
@ -74,9 +74,9 @@
|
|||
"passport-http-bearer": "1.0.1",
|
||||
"passport-oauth2-client-password": "0.1.2",
|
||||
"raw-body": "3.0.0",
|
||||
"rfdc": "^1.3.1",
|
||||
"semver": "7.7.1",
|
||||
"tar": "7.5.7",
|
||||
"rfdc": "1.4.1",
|
||||
"semver": "7.7.4",
|
||||
"tar": "7.5.9",
|
||||
"tough-cookie": "5.1.2",
|
||||
"uglify-js": "3.19.3",
|
||||
"uuid": "9.0.1",
|
||||
|
|
@ -111,11 +111,11 @@
|
|||
"jquery-i18next": "1.2.1",
|
||||
"jsdoc-nr-template": "github:node-red/jsdoc-nr-template",
|
||||
"marked": "4.3.0",
|
||||
"mermaid": "11.9.0",
|
||||
"mermaid": "11.12.3",
|
||||
"minami": "1.2.3",
|
||||
"mocha": "9.2.2",
|
||||
"node-red-node-test-helper": "^0.3.3",
|
||||
"nodemon": "3.1.9",
|
||||
"nodemon": "3.1.14",
|
||||
"proxy": "^1.0.2",
|
||||
"sass": "1.62.1",
|
||||
"should": "13.2.3",
|
||||
|
|
|
|||
|
|
@ -53,10 +53,10 @@ module.exports = {
|
|||
var opts = {
|
||||
user: req.user
|
||||
}
|
||||
runtimeAPI.settings.getRuntimeSettings(opts).then(function(result) {
|
||||
runtimeAPI.settings.getRuntimeSettings(opts).then(async function(result) {
|
||||
if (!settings.disableEditor) {
|
||||
result.editorTheme = result.editorTheme||{};
|
||||
var themeSettings = theme.settings();
|
||||
const themeSettings = await theme.settings();
|
||||
if (themeSettings) {
|
||||
// result.editorTheme may already exist with the palette
|
||||
// disabled. Need to merge that into the receive settings
|
||||
|
|
|
|||
|
|
@ -42,7 +42,13 @@ var defaultContext = {
|
|||
var settings;
|
||||
|
||||
var theme = null;
|
||||
/**
|
||||
* themeContext is an object passed to the mustache template to generate the editor index.html.
|
||||
*/
|
||||
var themeContext = clone(defaultContext);
|
||||
/**
|
||||
* themeSettings is an object passed to the editor client as the "editorTheme" property of the settings object
|
||||
*/
|
||||
var themeSettings = null;
|
||||
|
||||
var activeTheme = null;
|
||||
|
|
@ -91,6 +97,119 @@ function serveFilesFromTheme(themeValue, themeApp, directory, baseDirectory) {
|
|||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a theme is enabled and load its settings.
|
||||
* This is done lazily as it has to happen after the plugins have been loaded, but before the editor is served.
|
||||
*/
|
||||
async function loadThemePlugin () {
|
||||
if (activeTheme && !activeThemeInitialised) {
|
||||
const themePlugin = await runtimeAPI.plugins.getPlugin({
|
||||
id:activeTheme
|
||||
});
|
||||
if (themePlugin) {
|
||||
if (themePlugin.css) {
|
||||
const cssFiles = serveFilesFromTheme(
|
||||
themePlugin.css,
|
||||
themeApp,
|
||||
"/css/",
|
||||
themePlugin.path
|
||||
);
|
||||
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
|
||||
// Mutating `theme` is not ideal, but currently necessary as debug (packages/node_modules/@node-red/nodes/core/common/21-debug.js)
|
||||
// accesses RED.settings.editorTheme.page._.css directly to apply theme to the debug pop-out window.
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.css = cssFiles.concat(theme.page._.css || [])
|
||||
}
|
||||
if (themePlugin.scripts) {
|
||||
const scriptFiles = serveFilesFromTheme(
|
||||
themePlugin.scripts,
|
||||
themeApp,
|
||||
"/scripts/",
|
||||
themePlugin.path
|
||||
)
|
||||
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.scripts = scriptFiles.concat(theme.page._.scripts || [])
|
||||
}
|
||||
// check and load page settings from theme
|
||||
if (themePlugin.page) {
|
||||
if (themePlugin.page.favicon && !theme.page.favicon) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.page.favicon],
|
||||
themeApp,
|
||||
"/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext page favicon
|
||||
themeContext.page.favicon = result[0]
|
||||
}
|
||||
}
|
||||
if (themePlugin.page.tabicon && themePlugin.page.tabicon.icon && !theme.page.tabicon) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.page.tabicon.icon],
|
||||
themeApp,
|
||||
"/page/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext page tabicon
|
||||
themeContext.page.tabicon.icon = result[0]
|
||||
themeContext.page.tabicon.colour = themeContext.page.tabicon.colour || themeContext.page.tabicon.colour
|
||||
}
|
||||
}
|
||||
// if the plugin has a title AND the users settings.js does NOT
|
||||
if (themePlugin.page.title && !theme.page.title) {
|
||||
themeContext.page.title = themePlugin.page.title || themeContext.page.title
|
||||
}
|
||||
}
|
||||
// check and load header settings from theme
|
||||
if (themePlugin.header) {
|
||||
if (themePlugin.header.image && !theme.header.image) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.header.image],
|
||||
themeApp,
|
||||
"/header/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext header image
|
||||
themeContext.header.image = result[0]
|
||||
}
|
||||
}
|
||||
// if the plugin has a title AND the users settings.js does NOT have a title
|
||||
if (themePlugin.header.title && !theme.header.title) {
|
||||
themeContext.header.title = themePlugin.header.title || themeContext.header.title
|
||||
}
|
||||
// if the plugin has a header url AND the users settings.js does NOT
|
||||
if (themePlugin.header.url && !theme.header.url) {
|
||||
themeContext.header.url = themePlugin.header.url || themeContext.header.url
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(themePlugin.palette?.theme)) {
|
||||
themeSettings.palette = themeSettings.palette || {};
|
||||
themeSettings.palette.theme = themePlugin.palette.theme;
|
||||
// The theme is providing its own palette theme. It *might* include icons that need namespacing
|
||||
// to the theme plugin module.
|
||||
themePlugin.palette.theme.forEach(themeRule => {
|
||||
if (themeRule.icon && themeRule.icon.indexOf("/") === -1) {
|
||||
themeRule.icon = `${themePlugin.module}/${themeRule.icon}`;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// These settings are not exposed under `editorTheme`, so we don't have a merge strategy for them
|
||||
// If they're defined in the theme plugin, they replace any settings.js values.
|
||||
// But, this direct manipulation of `theme` is not ideal and relies on mutating a passed-in object
|
||||
theme.codeEditor = theme.codeEditor || {}
|
||||
theme.codeEditor.options = Object.assign({}, themePlugin.monacoOptions, theme.codeEditor.options);
|
||||
theme.mermaid = Object.assign({}, themePlugin.mermaid, theme.mermaid)
|
||||
}
|
||||
activeThemeInitialised = true;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
init: function(_settings, _runtimeAPI) {
|
||||
settings = _settings;
|
||||
|
|
@ -232,6 +351,7 @@ module.exports = {
|
|||
res.json(themeContext);
|
||||
})
|
||||
|
||||
// Copy the settings that need passing to the editor into themeSettings.
|
||||
if (theme.hasOwnProperty("menu")) {
|
||||
themeSettings.menu = theme.menu;
|
||||
}
|
||||
|
|
@ -263,104 +383,11 @@ module.exports = {
|
|||
return themeApp;
|
||||
},
|
||||
context: async function() {
|
||||
if (activeTheme && !activeThemeInitialised) {
|
||||
const themePlugin = await runtimeAPI.plugins.getPlugin({
|
||||
id:activeTheme
|
||||
});
|
||||
if (themePlugin) {
|
||||
if (themePlugin.css) {
|
||||
const cssFiles = serveFilesFromTheme(
|
||||
themePlugin.css,
|
||||
themeApp,
|
||||
"/css/",
|
||||
themePlugin.path
|
||||
);
|
||||
themeContext.page.css = cssFiles.concat(themeContext.page.css || [])
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.css = cssFiles.concat(theme.page._.css || [])
|
||||
}
|
||||
if (themePlugin.scripts) {
|
||||
const scriptFiles = serveFilesFromTheme(
|
||||
themePlugin.scripts,
|
||||
themeApp,
|
||||
"/scripts/",
|
||||
themePlugin.path
|
||||
)
|
||||
themeContext.page.scripts = scriptFiles.concat(themeContext.page.scripts || [])
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.scripts = scriptFiles.concat(theme.page._.scripts || [])
|
||||
}
|
||||
// check and load page settings from theme
|
||||
if (themePlugin.page) {
|
||||
if (themePlugin.page.favicon && !theme.page.favicon) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.page.favicon],
|
||||
themeApp,
|
||||
"/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext page favicon
|
||||
themeContext.page.favicon = result[0]
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.favicon = result[0]
|
||||
}
|
||||
}
|
||||
if (themePlugin.page.tabicon && themePlugin.page.tabicon.icon && !theme.page.tabicon) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.page.tabicon.icon],
|
||||
themeApp,
|
||||
"/page/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext page tabicon
|
||||
themeContext.page.tabicon.icon = result[0]
|
||||
themeContext.page.tabicon.colour = themeContext.page.tabicon.colour || themeContext.page.tabicon.colour
|
||||
theme.page = theme.page || {_:{}}
|
||||
theme.page._.tabicon = theme.page._.tabicon || {}
|
||||
theme.page._.tabicon.icon = themeContext.page.tabicon.icon
|
||||
theme.page._.tabicon.colour = themeContext.page.tabicon.colour
|
||||
}
|
||||
}
|
||||
// if the plugin has a title AND the users settings.js does NOT
|
||||
if (themePlugin.page.title && !theme.page.title) {
|
||||
themeContext.page.title = themePlugin.page.title || themeContext.page.title
|
||||
}
|
||||
}
|
||||
// check and load header settings from theme
|
||||
if (themePlugin.header) {
|
||||
if (themePlugin.header.image && !theme.header.image) {
|
||||
const result = serveFilesFromTheme(
|
||||
[themePlugin.header.image],
|
||||
themeApp,
|
||||
"/header/",
|
||||
themePlugin.path
|
||||
)
|
||||
if(result && result.length > 0) {
|
||||
// update themeContext header image
|
||||
themeContext.header.image = result[0]
|
||||
}
|
||||
}
|
||||
// if the plugin has a title AND the users settings.js does NOT have a title
|
||||
if (themePlugin.header.title && !theme.header.title) {
|
||||
themeContext.header.title = themePlugin.header.title || themeContext.header.title
|
||||
}
|
||||
// if the plugin has a header url AND the users settings.js does NOT
|
||||
if (themePlugin.header.url && !theme.header.url) {
|
||||
themeContext.header.url = themePlugin.header.url || themeContext.header.url
|
||||
}
|
||||
}
|
||||
theme.codeEditor = theme.codeEditor || {}
|
||||
theme.codeEditor.options = Object.assign({}, themePlugin.monacoOptions, theme.codeEditor.options);
|
||||
|
||||
theme.mermaid = Object.assign({}, themePlugin.mermaid, theme.mermaid)
|
||||
}
|
||||
activeThemeInitialised = true;
|
||||
}
|
||||
await loadThemePlugin();
|
||||
return themeContext;
|
||||
},
|
||||
settings: function() {
|
||||
settings: async function() {
|
||||
await loadThemePlugin();
|
||||
return themeSettings;
|
||||
},
|
||||
serveFile: function(baseUrl,file) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"dependencies": {
|
||||
"@node-red/util": "5.0.0-beta.2",
|
||||
"@node-red/editor-client": "5.0.0-beta.2",
|
||||
"bcryptjs": "3.0.2",
|
||||
"bcryptjs": "3.0.3",
|
||||
"body-parser": "1.20.4",
|
||||
"clone": "2.1.2",
|
||||
"cors": "2.8.5",
|
||||
|
|
|
|||
|
|
@ -1,135 +1,206 @@
|
|||
RED.hooks = (function() {
|
||||
RED.hooks = (function () {
|
||||
// At the time of writing this PR, VALID_HOOKS were not enforced. There may be a good reason for this
|
||||
// so the below flag has been added to permit this behaviour. If desired, this can be set to false to
|
||||
// enforce that only known hooks can be added/triggered.
|
||||
const knownHooksOnly = false
|
||||
|
||||
var VALID_HOOKS = [
|
||||
const VALID_HOOKS = Object.freeze({
|
||||
viewRemoveNode: true,
|
||||
viewAddNode: true,
|
||||
viewRemovePort: true,
|
||||
viewAddPort: true,
|
||||
viewRedrawNode: true,
|
||||
debugPreProcessMessage: true,
|
||||
debugPostProcessMessage: true
|
||||
})
|
||||
|
||||
]
|
||||
/**
|
||||
* @typedef {keyof typeof VALID_HOOKS} HookId - A string literal type representing a hook identifier (sans label).
|
||||
*
|
||||
* @typedef {Object} HookItem - An item in the linked list of hooks for a given HookId
|
||||
* @property {function} cb - The callback function to be called when the hook is triggered
|
||||
* @property {HookItem|null} previousHook - The previous hook in the linked list
|
||||
* @property {HookItem|null} nextHook - The next hook in the linked list
|
||||
* @property {boolean} removed - Flag indicating if the hook has been removed
|
||||
*
|
||||
* @typedef {Record<HookId, HookItem|null>} Hooks - A mapping of HookIds to the head of their linked list of HookItems
|
||||
*/
|
||||
|
||||
var hooks = { }
|
||||
var labelledHooks = { }
|
||||
|
||||
/** @type {Hooks} - A mapping of HookIds to the head of their linked list of HookItems */
|
||||
let hooks = {}
|
||||
|
||||
/** @type {Record<string, Record<HookId, HookItem>>} - A mapping of labels to their hooks */
|
||||
let labelledHooks = {}
|
||||
|
||||
function add(hookId, callback) {
|
||||
var parts = hookId.split(".");
|
||||
var id = parts[0], label = parts[1];
|
||||
const { label, id } = parseLabelledHook(hookId)
|
||||
|
||||
// if (VALID_HOOKS.indexOf(id) === -1) {
|
||||
// throw new Error("Invalid hook '"+id+"'");
|
||||
// }
|
||||
if (label && labelledHooks[label] && labelledHooks[label][id]) {
|
||||
throw new Error("Hook "+hookId+" already registered")
|
||||
if (knownHooksOnly && !isKnownHook(id)) {
|
||||
throw new Error("Invalid hook '" + id + "'")
|
||||
}
|
||||
if (label && labelledHooks[label] && labelledHooks[label][id]) {
|
||||
throw new Error("Hook " + hookId + " already registered")
|
||||
}
|
||||
if (typeof callback !== "function") {
|
||||
throw new Error("Invalid hook '" + hookId + "'. Callback must be a function")
|
||||
}
|
||||
var hookItem = {cb:callback, previousHook: null, nextHook: null }
|
||||
|
||||
var tailItem = hooks[id];
|
||||
/** @type {HookItem} */
|
||||
const hookItem = { cb: callback, previousHook: null, nextHook: null }
|
||||
|
||||
let tailItem = hooks[id]
|
||||
if (tailItem === undefined) {
|
||||
hooks[id] = hookItem;
|
||||
hooks[id] = hookItem
|
||||
} else {
|
||||
while(tailItem.nextHook !== null) {
|
||||
while (tailItem.nextHook !== null) {
|
||||
tailItem = tailItem.nextHook
|
||||
}
|
||||
tailItem.nextHook = hookItem;
|
||||
hookItem.previousHook = tailItem;
|
||||
tailItem.nextHook = hookItem
|
||||
hookItem.previousHook = tailItem
|
||||
}
|
||||
|
||||
if (label) {
|
||||
labelledHooks[label] = labelledHooks[label]||{};
|
||||
labelledHooks[label][id] = hookItem;
|
||||
labelledHooks[label] = labelledHooks[label] || {}
|
||||
labelledHooks[label][id] = hookItem
|
||||
}
|
||||
}
|
||||
|
||||
function remove(hookId) {
|
||||
var parts = hookId.split(".");
|
||||
var id = parts[0], label = parts[1];
|
||||
if ( !label) {
|
||||
throw new Error("Cannot remove hook without label: "+hookId)
|
||||
const { label, id } = parseLabelledHook(hookId)
|
||||
if (!label) {
|
||||
throw new Error("Cannot remove hook without label: " + hookId)
|
||||
}
|
||||
if (labelledHooks[label]) {
|
||||
if (id === "*") {
|
||||
// Remove all hooks for this label
|
||||
var hookList = Object.keys(labelledHooks[label]);
|
||||
for (var i=0;i<hookList.length;i++) {
|
||||
removeHook(hookList[i],labelledHooks[label][hookList[i]])
|
||||
const hookList = Object.keys(labelledHooks[label])
|
||||
for (let i = 0; i < hookList.length; i++) {
|
||||
removeHook(hookList[i], labelledHooks[label][hookList[i]])
|
||||
}
|
||||
delete labelledHooks[label];
|
||||
delete labelledHooks[label]
|
||||
} else if (labelledHooks[label][id]) {
|
||||
removeHook(id,labelledHooks[label][id])
|
||||
delete labelledHooks[label][id];
|
||||
if (Object.keys(labelledHooks[label]).length === 0){
|
||||
delete labelledHooks[label];
|
||||
removeHook(id, labelledHooks[label][id])
|
||||
delete labelledHooks[label][id]
|
||||
if (Object.keys(labelledHooks[label]).length === 0) {
|
||||
delete labelledHooks[label]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removeHook(id,hookItem) {
|
||||
var previousHook = hookItem.previousHook;
|
||||
var nextHook = hookItem.nextHook;
|
||||
/**
|
||||
* Remove a hook from the linked list of hooks for a given id
|
||||
* @param {HookId} id
|
||||
* @param {HookItem} hookItem
|
||||
* @private
|
||||
*/
|
||||
function removeHook(id, hookItem) {
|
||||
let previousHook = hookItem.previousHook
|
||||
let nextHook = hookItem.nextHook
|
||||
|
||||
if (previousHook) {
|
||||
previousHook.nextHook = nextHook;
|
||||
previousHook.nextHook = nextHook
|
||||
} else {
|
||||
hooks[id] = nextHook;
|
||||
hooks[id] = nextHook
|
||||
}
|
||||
if (nextHook) {
|
||||
nextHook.previousHook = previousHook;
|
||||
nextHook.previousHook = previousHook
|
||||
}
|
||||
hookItem.removed = true;
|
||||
hookItem.removed = true
|
||||
if (!previousHook && !nextHook) {
|
||||
delete hooks[id];
|
||||
delete hooks[id]
|
||||
}
|
||||
}
|
||||
|
||||
function trigger(hookId, payload, done) {
|
||||
var hookItem = hooks[hookId];
|
||||
/**
|
||||
* Trigger a hook, calling all registered callbacks in sequence.
|
||||
* If any callback returns false, the flow is halted and no further hooks are called.
|
||||
* @param {HookId} id The id of the hook to trigger (should not include a label - e.g. "viewAddNode", not "viewAddNode.myLabel")
|
||||
* @param {*} payload The payload to be passed to each hook callback
|
||||
* @param {function(?Error=):void} [done] Optional callback. If not provided, a Promise will be returned.
|
||||
* @return {Promise|undefined} Returns a Promise if the done callback is not provided, otherwise undefined
|
||||
*/
|
||||
function trigger(id, payload, done) {
|
||||
let hookItem = hooks[id]
|
||||
if (!hookItem) {
|
||||
if (done) {
|
||||
done();
|
||||
done()
|
||||
return
|
||||
} else {
|
||||
return Promise.resolve()
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!done) {
|
||||
return new Promise((resolve, reject) => {
|
||||
invokeStack(hookItem, payload, function (err) {
|
||||
if (err !== undefined && err !== false) {
|
||||
if (!(err instanceof Error)) {
|
||||
err = new Error(err)
|
||||
}
|
||||
err.hook = id
|
||||
reject(err)
|
||||
} else {
|
||||
resolve(err)
|
||||
}
|
||||
})
|
||||
})
|
||||
} else {
|
||||
invokeStack(hookItem, payload, done)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
function invokeStack(hookItem, payload, done) {
|
||||
function callNextHook(err) {
|
||||
if (!hookItem || err) {
|
||||
if (done) { done(err) }
|
||||
return err;
|
||||
done(err)
|
||||
return
|
||||
}
|
||||
if (hookItem.removed) {
|
||||
hookItem = hookItem.nextHook;
|
||||
return callNextHook();
|
||||
hookItem = hookItem.nextHook
|
||||
callNextHook()
|
||||
return
|
||||
}
|
||||
var callback = hookItem.cb;
|
||||
const callback = hookItem.cb
|
||||
if (callback.length === 1) {
|
||||
try {
|
||||
let result = callback(payload);
|
||||
let result = callback(payload)
|
||||
if (result === false) {
|
||||
// Halting the flow
|
||||
if (done) { done(false) }
|
||||
return result;
|
||||
done(false)
|
||||
return
|
||||
}
|
||||
hookItem = hookItem.nextHook;
|
||||
return callNextHook();
|
||||
} catch(e) {
|
||||
console.warn(e);
|
||||
if (done) { done(e);}
|
||||
return e;
|
||||
if (result && typeof result.then === 'function') {
|
||||
result.then(handleResolve, callNextHook)
|
||||
return
|
||||
}
|
||||
hookItem = hookItem.nextHook
|
||||
callNextHook()
|
||||
} catch (e) {
|
||||
done(e)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
// There is a done callback
|
||||
try {
|
||||
callback(payload,function(result) {
|
||||
if (result === undefined) {
|
||||
hookItem = hookItem.nextHook;
|
||||
callNextHook();
|
||||
} else {
|
||||
if (done) { done(result)}
|
||||
}
|
||||
})
|
||||
} catch(e) {
|
||||
console.warn(e);
|
||||
if (done) { done(e) }
|
||||
return e;
|
||||
callback(payload, handleResolve)
|
||||
} catch (e) {
|
||||
done(e)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return callNextHook();
|
||||
function handleResolve(result) {
|
||||
if (result === undefined) {
|
||||
hookItem = hookItem.nextHook
|
||||
callNextHook()
|
||||
} else {
|
||||
done(result)
|
||||
}
|
||||
}
|
||||
callNextHook()
|
||||
}
|
||||
|
||||
function clear() {
|
||||
|
|
@ -137,20 +208,48 @@ RED.hooks = (function() {
|
|||
labelledHooks = {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a hook with the given id exists
|
||||
* @param {string} hookId The hook identifier, which may include a label (e.g. "viewAddNode.myLabel")
|
||||
* @returns {boolean}
|
||||
*/
|
||||
function has(hookId) {
|
||||
var parts = hookId.split(".");
|
||||
var id = parts[0], label = parts[1];
|
||||
const { label, id } = parseLabelledHook(hookId)
|
||||
if (label) {
|
||||
return !!(labelledHooks[label] && labelledHooks[label][id])
|
||||
}
|
||||
return !!hooks[id]
|
||||
}
|
||||
|
||||
return {
|
||||
has: has,
|
||||
clear: clear,
|
||||
add: add,
|
||||
remove: remove,
|
||||
trigger: trigger
|
||||
function isKnownHook(hookId) {
|
||||
const { id } = parseLabelledHook(hookId)
|
||||
return !!VALID_HOOKS[id]
|
||||
}
|
||||
})();
|
||||
|
||||
/**
|
||||
* Split a hook identifier into its id and label components.
|
||||
* @param {*} hookId A hook identifier, which may include a label (e.g. "viewAddNode.myLabel")
|
||||
* @returns {{label: string, id: HookId}}
|
||||
* @private
|
||||
*/
|
||||
function parseLabelledHook(hookId) {
|
||||
if (typeof hookId !== "string") {
|
||||
return { label: '', id: '' }
|
||||
}
|
||||
const parts = hookId.split(".")
|
||||
const id = parts[0]
|
||||
const label = parts[1]
|
||||
return { label, id }
|
||||
}
|
||||
|
||||
VALID_HOOKS['all'] = true // Special wildcard to allow hooks to indicate they should be triggered for all ids
|
||||
|
||||
return {
|
||||
has,
|
||||
clear,
|
||||
add,
|
||||
remove,
|
||||
trigger,
|
||||
isKnownHook
|
||||
}
|
||||
})()
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ RED.keyboard = (function() {
|
|||
"-":189,
|
||||
".":190,
|
||||
"/":191,
|
||||
"§":192, // <- top left key MacOS
|
||||
"\\":220,
|
||||
"'":222,
|
||||
"?":191, // <- QWERTY specific
|
||||
|
|
|
|||
|
|
@ -40,6 +40,12 @@ RED.palette.editor = (function() {
|
|||
// Install tab - search input
|
||||
let searchInput;
|
||||
|
||||
// Core and Package Updates
|
||||
/** @type {Array<{package: string, current: string, available: string}>} */
|
||||
const moduleUpdates = []
|
||||
const updateStatusState = { version: null, moduleCount: 0 }
|
||||
|
||||
|
||||
const SMALL_CATALOGUE_SIZE = 40
|
||||
|
||||
const typesInUse = {};
|
||||
|
|
@ -1825,8 +1831,6 @@ RED.palette.editor = (function() {
|
|||
|
||||
const updateStatusWidget = $('<button type="button" class="red-ui-footer-button red-ui-update-status"></button>');
|
||||
let updateStatusWidgetPopover;
|
||||
const updateStatusState = { moduleCount: 0 }
|
||||
let updateAvailable = [];
|
||||
|
||||
function addUpdateInfoToStatusBar() {
|
||||
updateStatusWidgetPopover = RED.popover.create({
|
||||
|
|
@ -1835,7 +1839,7 @@ RED.palette.editor = (function() {
|
|||
interactive: true,
|
||||
direction: "bottom",
|
||||
content: function () {
|
||||
const count = updateAvailable.length || 0;
|
||||
const count = moduleUpdates.length || 0
|
||||
const content = $('<div style="display: flex; flex-direction: column; gap: 5px;"></div>');
|
||||
if (updateStatusState.version) {
|
||||
$(`<a class='red-ui-button' href="https://github.com/node-red/node-red/releases/tag/${updateStatusState.version}" target="_blank">${RED._("telemetry.updateAvailableDesc", updateStatusState)}</a>`).appendTo(content)
|
||||
|
|
@ -1845,7 +1849,7 @@ RED.palette.editor = (function() {
|
|||
updateStatusWidgetPopover.close()
|
||||
RED.actions.invoke("core:manage-palette", {
|
||||
view: "nodes",
|
||||
filter: '"' + updateAvailable.join('", "') + '"'
|
||||
filter: '"' + moduleUpdates.map(u => u.package).join('", "') + '"'
|
||||
});
|
||||
}).appendTo(content)
|
||||
}
|
||||
|
|
@ -1867,7 +1871,7 @@ RED.palette.editor = (function() {
|
|||
function refreshUpdateStatus() {
|
||||
clearTimeout(pendingRefreshTimeout)
|
||||
pendingRefreshTimeout = setTimeout(() => {
|
||||
updateAvailable = [];
|
||||
moduleUpdates.length = 0
|
||||
for (const module of Object.keys(nodeEntries)) {
|
||||
if (loadedIndex.hasOwnProperty(module)) {
|
||||
const moduleInfo = nodeEntries[module].info;
|
||||
|
|
@ -1875,35 +1879,51 @@ RED.palette.editor = (function() {
|
|||
// Module updated
|
||||
continue;
|
||||
}
|
||||
const current = moduleInfo.version
|
||||
const latest = loadedIndex[module].version
|
||||
if (updateAllowed &&
|
||||
semVerCompare(loadedIndex[module].version, moduleInfo.version) > 0 &&
|
||||
semVerCompare(latest, current) > 0 &&
|
||||
RED.utils.checkModuleAllowed(module, null, updateAllowList, updateDenyList)
|
||||
) {
|
||||
updateAvailable.push(module);
|
||||
moduleUpdates.push({ package: module, current, latest })
|
||||
}
|
||||
}
|
||||
}
|
||||
updateStatusState.moduleCount = updateAvailable.length;
|
||||
updateStatusState.moduleCount = moduleUpdates.length
|
||||
updateStatus();
|
||||
}, 200)
|
||||
}
|
||||
|
||||
function updateStatus() {
|
||||
if (updateStatusState.moduleCount || updateStatusState.version) {
|
||||
const updates = RED.palette.editor.getAvailableUpdates()
|
||||
if (updates.count > 0) {
|
||||
updateStatusWidget.empty();
|
||||
let count = updateStatusState.moduleCount || 0;
|
||||
if (updateStatusState.version) {
|
||||
count ++
|
||||
}
|
||||
$(`<span><i class="fa fa-cube"></i> ${RED._("telemetry.updateAvailable", { count: count })}</span>`).appendTo(updateStatusWidget);
|
||||
$(`<span><i class="fa fa-cube"></i> ${RED._("telemetry.updateAvailable", { count: updates.count })}</span>`).appendTo(updateStatusWidget);
|
||||
RED.statusBar.show("red-ui-status-package-update");
|
||||
} else {
|
||||
RED.statusBar.hide("red-ui-status-package-update");
|
||||
}
|
||||
RED.events.emit("registry:updates-available", updates)
|
||||
}
|
||||
|
||||
function getAvailableUpdates () {
|
||||
const palette = [...moduleUpdates]
|
||||
let core = null
|
||||
let count = palette.length
|
||||
if (updateStatusState.version) {
|
||||
core = { current: RED.settings.version, latest: updateStatusState.version }
|
||||
count ++
|
||||
}
|
||||
return {
|
||||
count,
|
||||
core,
|
||||
palette
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
init: init,
|
||||
install: install
|
||||
init,
|
||||
install,
|
||||
getAvailableUpdates
|
||||
}
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ RED.sidebar.config = (function() {
|
|||
nodeDiv.addClass("red-ui-palette-node-config-invalid");
|
||||
RED.popover.tooltip(nodeDivAnnotations, function () {
|
||||
if (node.validationErrors && node.validationErrors.length > 0) {
|
||||
return RED._("editor.errors.invalidProperties") + "<br> - " + node.validationErrors.join("<br> - ");
|
||||
return $('<span>' + RED._("editor.errors.invalidProperties") + "<br> - " + node.validationErrors.join("<br> - ") + '</span>');
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -218,7 +218,7 @@ RED.sidebar.config = (function() {
|
|||
nodeDiv.on('click',function(e) {
|
||||
e.stopPropagation();
|
||||
RED.view.select(false);
|
||||
if (e.metaKey) {
|
||||
if (e.metaKey || e.ctrlKey) {
|
||||
$(this).toggleClass("selected");
|
||||
} else {
|
||||
$(content).find(".red-ui-palette-node").removeClass("selected");
|
||||
|
|
|
|||
|
|
@ -1110,20 +1110,36 @@ RED.utils = (function() {
|
|||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default icon for a given node based on its definition.
|
||||
* @param {*} def
|
||||
* @param {*} node
|
||||
* @returns
|
||||
*/
|
||||
function getDefaultNodeIcon(def,node) {
|
||||
def = def || {};
|
||||
var icon_url;
|
||||
if (node && node.type === "subflow") {
|
||||
icon_url = "node-red/subflow.svg";
|
||||
} else if (typeof def.icon === "function") {
|
||||
try {
|
||||
icon_url = def.icon.call(node);
|
||||
} catch(err) {
|
||||
console.log("Definition error: "+def.type+".icon",err);
|
||||
icon_url = "arrow-in.svg";
|
||||
}
|
||||
} else {
|
||||
icon_url = def.icon;
|
||||
let themeRule = nodeIconCache[def.type]
|
||||
if (themeRule === undefined) {
|
||||
// If undefined, we've not checked the theme yet
|
||||
nodeIconCache[def.type] = getThemeOverrideForNode(def, 'icon') || null;
|
||||
themeRule = nodeIconCache[def.type];
|
||||
}
|
||||
if (themeRule) {
|
||||
icon_url = themeRule.icon;
|
||||
} else if (typeof def.icon === "function") {
|
||||
try {
|
||||
icon_url = def.icon.call(node);
|
||||
} catch(err) {
|
||||
console.log("Definition error: "+def.type+".icon",err);
|
||||
icon_url = "arrow-in.svg";
|
||||
}
|
||||
} else {
|
||||
icon_url = def.icon;
|
||||
}
|
||||
}
|
||||
|
||||
var iconPath = separateIconPath(icon_url);
|
||||
|
|
@ -1249,48 +1265,60 @@ RED.utils = (function() {
|
|||
return label
|
||||
}
|
||||
|
||||
var nodeColorCache = {};
|
||||
let nodeColorCache = {};
|
||||
let nodeIconCache = {}
|
||||
function clearNodeColorCache() {
|
||||
nodeColorCache = {};
|
||||
}
|
||||
|
||||
function getNodeColor(type, def) {
|
||||
def = def || {};
|
||||
var result = def.color;
|
||||
var paletteTheme = RED.settings.theme('palette.theme') || [];
|
||||
/**
|
||||
* Checks if there is a theme override for the given node definition and property
|
||||
* @param {*} def node definition
|
||||
* @param {*} property either 'color' or 'icon'
|
||||
* @returns the theme override value if there is a match, otherwise null
|
||||
*/
|
||||
function getThemeOverrideForNode(def, property) {
|
||||
const paletteTheme = RED.settings.theme('palette.theme') || [];
|
||||
if (paletteTheme.length > 0) {
|
||||
if (!nodeColorCache.hasOwnProperty(type)) {
|
||||
nodeColorCache[type] = def.color;
|
||||
var l = paletteTheme.length;
|
||||
for (var i = 0; i < l; i++ ){
|
||||
var themeRule = paletteTheme[i];
|
||||
if (themeRule.hasOwnProperty('category')) {
|
||||
if (!themeRule.hasOwnProperty('_category')) {
|
||||
themeRule._category = new RegExp(themeRule.category);
|
||||
}
|
||||
if (!themeRule._category.test(def.category)) {
|
||||
continue;
|
||||
}
|
||||
for (let i = 0; i < paletteTheme.length; i++ ){
|
||||
const themeRule = paletteTheme[i];
|
||||
if (themeRule.hasOwnProperty('category')) {
|
||||
if (!themeRule.hasOwnProperty('_category')) {
|
||||
themeRule._category = new RegExp(themeRule.category);
|
||||
}
|
||||
if (themeRule.hasOwnProperty('type')) {
|
||||
if (!themeRule.hasOwnProperty('_type')) {
|
||||
themeRule._type = new RegExp(themeRule.type);
|
||||
}
|
||||
if (!themeRule._type.test(type)) {
|
||||
continue;
|
||||
}
|
||||
if (!themeRule._category.test(def.category)) {
|
||||
continue;
|
||||
}
|
||||
nodeColorCache[type] = themeRule.color || def.color;
|
||||
break;
|
||||
}
|
||||
if (themeRule.hasOwnProperty('type')) {
|
||||
if (!themeRule.hasOwnProperty('_type')) {
|
||||
themeRule._type = new RegExp(themeRule.type);
|
||||
}
|
||||
if (!themeRule._type.test(def.type)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// We have found a rule that matches - now see if it provides the requested property
|
||||
if (themeRule.hasOwnProperty(property)) {
|
||||
return themeRule;
|
||||
}
|
||||
}
|
||||
result = nodeColorCache[type];
|
||||
}
|
||||
if (result) {
|
||||
return result;
|
||||
} else {
|
||||
return "#ddd";
|
||||
return null;
|
||||
}
|
||||
|
||||
function getNodeColor(type, def) {
|
||||
def = def || {};
|
||||
if (!nodeColorCache.hasOwnProperty(type)) {
|
||||
const paletteTheme = RED.settings.theme('palette.theme') || [];
|
||||
if (paletteTheme.length > 0) {
|
||||
const themeRule = getThemeOverrideForNode(def, 'color');
|
||||
nodeColorCache[type] = themeRule?.color || def.color;
|
||||
} else {
|
||||
nodeColorCache[type] = def.color;
|
||||
}
|
||||
}
|
||||
return nodeColorCache[type] || "#ddd";
|
||||
}
|
||||
|
||||
function addSpinnerOverlay(container,contain) {
|
||||
|
|
|
|||
|
|
@ -4032,7 +4032,7 @@ RED.view = (function() {
|
|||
clearSuggestedFlow();
|
||||
RED.contextMenu.hide();
|
||||
evt = evt || d3.event;
|
||||
if (evt === 1) {
|
||||
if (evt.button !== 0) {
|
||||
return;
|
||||
}
|
||||
if (mouse_mode === RED.state.SELECTING_NODE) {
|
||||
|
|
@ -4897,7 +4897,7 @@ RED.view = (function() {
|
|||
d3.event.stopPropagation();
|
||||
return;
|
||||
}
|
||||
if (d3.event.button === 2) {
|
||||
if (d3.event.button !== 0) {
|
||||
return
|
||||
}
|
||||
mousedown_link = d;
|
||||
|
|
|
|||
|
|
@ -433,12 +433,28 @@ RED.debug = (function() {
|
|||
if (o) { stack.push(o); }
|
||||
if (!busy && (stack.length > 0)) {
|
||||
busy = true;
|
||||
processDebugMessage(stack.shift());
|
||||
setTimeout(function() {
|
||||
busy = false;
|
||||
handleDebugMessage();
|
||||
}, 15); // every 15mS = 66 times a second
|
||||
if (stack.length > numMessages) { stack = stack.splice(-numMessages); }
|
||||
const message = stack.shift()
|
||||
// call any preDebugLog hooks, allowing them to modify the message or block it from being displayed
|
||||
RED.hooks.trigger('debugPreProcessMessage', { message }).then(result => {
|
||||
if (result === false) {
|
||||
return false; // A hook returned false - halt processing of this message
|
||||
}
|
||||
return processDebugMessage(message);
|
||||
}).then(processArtifacts => {
|
||||
if (processArtifacts === false) {
|
||||
return false; // A hook returned false - halt processing of this message
|
||||
}
|
||||
const { message, element, payload } = processArtifacts || {};
|
||||
return RED.hooks.trigger('debugPostProcessMessage', { message, element, payload });
|
||||
}).catch(err => {
|
||||
console.error("Error in debug process message hooks", err);
|
||||
}).finally(() => {
|
||||
setTimeout(function() {
|
||||
busy = false;
|
||||
handleDebugMessage();
|
||||
}, 15); // every 15mS = 66 times a second
|
||||
if (stack.length > numMessages) { stack = stack.splice(-numMessages); }
|
||||
})
|
||||
}
|
||||
} else {
|
||||
debugPausedMessageCount++
|
||||
|
|
@ -564,10 +580,13 @@ RED.debug = (function() {
|
|||
sourceId: sourceNode && sourceNode.id,
|
||||
rootPath: path,
|
||||
nodeSelector: config.messageSourceClick,
|
||||
enablePinning: true
|
||||
enablePinning: true,
|
||||
tools: o.tools // permit preDebugLog hooks to add extra tools to the <debugMessage> element
|
||||
});
|
||||
// Do this in a separate step so the element functions aren't stripped
|
||||
debugMessage.appendTo(el);
|
||||
// add the meta row tools container, even if there are no tools, so that the postProcessDebugMessage hook can add tools
|
||||
const tools = $('<span class="red-ui-debug-msg-tools button-group"></span>').appendTo(metaRow)
|
||||
// NOTE: relying on function error to have a "type" that all other msgs don't
|
||||
if (o.hasOwnProperty("type") && (o.type === "function")) {
|
||||
var errorLvlType = 'error';
|
||||
|
|
@ -579,7 +598,6 @@ RED.debug = (function() {
|
|||
msg.addClass('red-ui-debug-msg-level-' + errorLvl);
|
||||
$('<span class="red-ui-debug-msg-topic">function : (' + errorLvlType + ')</span>').appendTo(metaRow);
|
||||
} else {
|
||||
var tools = $('<span class="red-ui-debug-msg-tools button-group"></span>').appendTo(metaRow);
|
||||
var filterMessage = $('<button class="red-ui-button red-ui-button-small"><i class="fa fa-caret-down"></i></button>').appendTo(tools);
|
||||
filterMessage.on("click", function(e) {
|
||||
e.preventDefault();
|
||||
|
|
@ -635,6 +653,14 @@ RED.debug = (function() {
|
|||
if (atBottom) {
|
||||
messageList.scrollTop(sbc.scrollHeight);
|
||||
}
|
||||
|
||||
// return artifacts to permit postProcessDebugMessage hooks to modify the message element, access the
|
||||
// processed payload or otherwise modify the message after it has been generated.
|
||||
return {
|
||||
message: o, // original debug message object, useful for any hook that might have tagged additional info onto it
|
||||
element: msg, // the top-level element for this debug message
|
||||
payload // the reconstructed debug message
|
||||
}
|
||||
}
|
||||
|
||||
function clearMessageList(clearFilter, filteredOnly) {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@
|
|||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"acorn": "8.15.0",
|
||||
"acorn-walk": "8.3.4",
|
||||
"ajv": "8.17.1",
|
||||
"acorn": "8.16.0",
|
||||
"acorn-walk": "8.3.5",
|
||||
"ajv": "8.18.0",
|
||||
"body-parser": "1.20.4",
|
||||
"cheerio": "1.0.0-rc.10",
|
||||
"content-type": "1.0.5",
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
"is-utf8": "0.2.1",
|
||||
"js-yaml": "4.1.1",
|
||||
"media-typer": "1.1.0",
|
||||
"mqtt": "5.11.0",
|
||||
"mqtt": "5.15.0",
|
||||
"multer": "2.0.2",
|
||||
"mustache": "4.2.0",
|
||||
"node-watch": "0.7.4",
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
"@node-red/util": "5.0.0-beta.2",
|
||||
"clone": "2.1.2",
|
||||
"fs-extra": "11.3.0",
|
||||
"semver": "7.7.1",
|
||||
"tar": "7.5.7",
|
||||
"semver": "7.7.4",
|
||||
"tar": "7.5.9",
|
||||
"uglify-js": "3.19.3"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
"fs-extra": "11.3.0",
|
||||
"got": "12.6.1",
|
||||
"json-stringify-safe": "5.0.1",
|
||||
"rfdc": "^1.3.1",
|
||||
"semver": "7.7.1"
|
||||
"rfdc": "1.4.1",
|
||||
"semver": "7.7.4"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@
|
|||
"@node-red/util": "5.0.0-beta.2",
|
||||
"@node-red/nodes": "5.0.0-beta.2",
|
||||
"basic-auth": "2.0.1",
|
||||
"bcryptjs": "3.0.2",
|
||||
"bcryptjs": "3.0.3",
|
||||
"cors": "2.8.5",
|
||||
"express": "4.22.1",
|
||||
"fs-extra": "11.3.0",
|
||||
"node-red-admin": "^4.1.3",
|
||||
"nopt": "5.0.0",
|
||||
"semver": "7.7.1"
|
||||
"semver": "7.7.4"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@node-rs/bcrypt": "1.10.7"
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ describe("api/editor/theme", function () {
|
|||
context.asset.should.have.a.property("main", "red/main.min.js");
|
||||
context.asset.should.have.a.property("vendorMonaco", "vendor/monaco/monaco-bootstrap.js");
|
||||
|
||||
should.not.exist(theme.settings());
|
||||
should.not.exist(await theme.settings());
|
||||
});
|
||||
|
||||
it("uses non-minified js files when in dev mode", async function () {
|
||||
|
|
@ -158,7 +158,7 @@ describe("api/editor/theme", function () {
|
|||
context.should.have.a.property("login");
|
||||
context.login.should.have.a.property("image", "theme/login/image");
|
||||
|
||||
var settings = theme.settings();
|
||||
var settings = await theme.settings();
|
||||
settings.should.have.a.property("deployButton");
|
||||
settings.deployButton.should.have.a.property("type", "simple");
|
||||
settings.deployButton.should.have.a.property("label", "Save");
|
||||
|
|
@ -199,7 +199,7 @@ describe("api/editor/theme", function () {
|
|||
|
||||
});
|
||||
|
||||
it("test explicit userMenu set to true in theme setting", function () {
|
||||
it("test explicit userMenu set to true in theme setting", async function () {
|
||||
theme.init({
|
||||
editorTheme: {
|
||||
userMenu: true,
|
||||
|
|
@ -208,7 +208,7 @@ describe("api/editor/theme", function () {
|
|||
|
||||
theme.app();
|
||||
|
||||
var settings = theme.settings();
|
||||
var settings = await theme.settings();
|
||||
settings.should.have.a.property("userMenu");
|
||||
settings.userMenu.should.be.eql(true);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue