diff --git a/Dockerfile b/Dockerfile index 6f80b614..bdebf5eb 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # syntax = docker/dockerfile:1.3 -ARG NODE_VERSION=16 +ARG NODE_VERSION=20 diff --git a/README.EN.md b/README.EN.md index 94fed0f4..b38bbeb9 100644 --- a/README.EN.md +++ b/README.EN.md @@ -107,7 +107,7 @@ docker-compose up --build **Requirements:** -* nodejs >= 12 +* nodejs >= 20 * plantuml with shade plugin diff --git a/README.md b/README.md index d89b05c3..400a4d43 100644 --- a/README.md +++ b/README.md @@ -149,7 +149,7 @@ DocHub станет доступен по адресу [http://localhost:8080/ma Проект является VueJS SPA приложением. В качестве backend пользуется GitLab. -Для развёртывания потребуется стандартная сборка VueJS приложения средствами npm, версией не ниже 8.1.х (версия node 16.х.х). +Для развёртывания потребуется стандартная сборка VueJS приложения средствами npm, версией не ниже 8.1.х (версия node 20.х.х). ``` npm сi npm run build diff --git a/package-lock.json b/package-lock.json index e2890d77..6744de2e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -81,7 +81,7 @@ "yo": "4.3.0" }, "engines": { - "node": ">=16.0.0", + "node": ">=20.0.0", "npm": ">=8.1.0" } }, @@ -9792,6 +9792,21 @@ "type": "^1.0.1" } }, + "node_modules/d/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/d/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/d3": { "version": "7.8.4", "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.4.tgz", @@ -11040,20 +11055,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "hasInstallScript": true, - "dependencies": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -11070,6 +11071,21 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/es6-iterator/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-iterator/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/es6-symbol": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", @@ -11090,6 +11106,21 @@ "es6-symbol": "^3.1.1" } }, + "node_modules/es6-weak-map/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/es6-weak-map/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/escalade": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", @@ -11719,6 +11750,21 @@ "es5-ext": "~0.10.14" } }, + "node_modules/event-emitter/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/event-emitter/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/event-pubsub": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz", @@ -18090,6 +18136,21 @@ "es5-ext": "~0.10.2" } }, + "node_modules/lru-queue/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/lru-queue/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/macos-release": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.5.1.tgz", @@ -18462,6 +18523,21 @@ "timers-ext": "^0.1.7" } }, + "node_modules/memoizee/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/memoizee/node_modules/es5-ext/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/memory-fs": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", @@ -25949,6 +26025,21 @@ "next-tick": "1" } }, + "node_modules/timers-ext/node_modules/es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dependencies": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "node_modules/timers-ext/node_modules/next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + }, "node_modules/timm": { "version": "1.7.1", "resolved": "https://registry.npmjs.org/timm/-/timm-1.7.1.tgz", @@ -37791,8 +37882,25 @@ "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", "requires": { - "es5-ext": "^0.10.50", + "es5-ext": "0.10.53", "type": "^1.0.1" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "d3": { @@ -38743,16 +38851,6 @@ "is-symbol": "^1.0.2" } }, - "es5-ext": { - "version": "0.10.62", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.62.tgz", - "integrity": "sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==", - "requires": { - "es6-iterator": "^2.0.3", - "es6-symbol": "^3.1.3", - "next-tick": "^1.1.0" - } - }, "es6-error": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", @@ -38765,8 +38863,25 @@ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==", "requires": { "d": "1", - "es5-ext": "^0.10.35", + "es5-ext": "0.10.53", "es6-symbol": "^3.1.1" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "es6-symbol": { @@ -38784,9 +38899,26 @@ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==", "requires": { "d": "1", - "es5-ext": "^0.10.46", + "es5-ext": "0.10.53", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "escalade": { @@ -39234,7 +39366,24 @@ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "requires": { "d": "1", - "es5-ext": "~0.10.14" + "es5-ext": "0.10.53" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "event-pubsub": { @@ -44123,7 +44272,24 @@ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz", "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==", "requires": { - "es5-ext": "~0.10.2" + "es5-ext": "0.10.53" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "macos-release": { @@ -44431,13 +44597,32 @@ "integrity": "sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ==", "requires": { "d": "^1.0.1", - "es5-ext": "^0.10.53", + "es5-ext": "0.10.53", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + }, + "dependencies": { + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } + } + } } }, "memory-fs": { @@ -50206,8 +50391,25 @@ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz", "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==", "requires": { - "es5-ext": "~0.10.46", + "es5-ext": "0.10.53", "next-tick": "1" + }, + "dependencies": { + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha512-mc/caHeUcdjnC/boPWJefDr4KUIWQNv+tlnFnJd38QMou86QtxQzBJfxgGRzvx8jazYRqrVlaHarfO72uNxPOg==" + } } }, "timm": { diff --git a/package.json b/package.json index 80c11554..5c90adbf 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "@mdi/font": "5.9.55", "@mermaid-js/mermaid-mindmap": "9.3.0", "ajv": "8.12.0", - "ajv-i18n": "4.2.0", "ajv-formats": "2.1.1", + "ajv-i18n": "4.2.0", "axios": "0.21.4", "core-js": "3.26.1", "dateformat": "3.0.3", @@ -109,7 +109,7 @@ }, "engines": { "npm": ">=8.1.0", - "node": ">=16.0.0" + "node": ">=20.0.0" }, "ide": { "idea": { diff --git a/public/documentation/arch/aspects.yaml b/public/documentation/arch/aspects.yaml index 2e9c7964..694ae161 100755 --- a/public/documentation/arch/aspects.yaml +++ b/public/documentation/arch/aspects.yaml @@ -10,9 +10,6 @@ aspects: # Архитектурные аспекты dochub.git: title: Git location: DocHub/Git - dochub.git.test.pest.kwest: - title: Git - location: DocHub/Git dochub.git.client: title: Развитие репы location: DocHub/GitLab/Git-клиент diff --git a/public/documentation/arch/components/examples/root.yaml b/public/documentation/arch/components/examples/root.yaml index f95bb758..72d37cc6 100644 --- a/public/documentation/arch/components/examples/root.yaml +++ b/public/documentation/arch/components/examples/root.yaml @@ -5,6 +5,7 @@ components: dochub.examples: title: Примеры entity: component + expert: R.Piontik imports: - order.yaml - payment.yaml diff --git a/public/documentation/entities/interactions/entity.yaml b/public/documentation/entities/interactions/entity.yaml index 894e906a..99094306 100755 --- a/public/documentation/entities/interactions/entity.yaml +++ b/public/documentation/entities/interactions/entity.yaml @@ -331,6 +331,15 @@ interactions: value: Первый опыт components: + interactions: + title: Взаимодействия + entity: component + interactions.example: + title: Примеры взаимодействий + entity: component + interactions.example.dochub: + title: Примеры взаимодействий DocHub + entity: component interactions.example.dochub.customer: title: Клиент entity: actor @@ -340,3 +349,10 @@ components: interactions.example.habr.articles: title: Статьи entity: component + +contexts: + interactions: + title: Контекст для отображения объектов вовлеченных во взаимодействие + components: + - interactions + - interactions.** \ No newline at end of file diff --git a/public/metamodel/dochub/rules/validators.yaml b/public/metamodel/dochub/rules/validators.yaml index d01b0e60..27fb82b6 100644 --- a/public/metamodel/dochub/rules/validators.yaml +++ b/public/metamodel/dochub/rules/validators.yaml @@ -19,7 +19,7 @@ rules: "contextID": $CONTEXT_ID, "componentID": $ }; - )[$ and $not($substring(componentID, -2) = ".*") and $not($exists($lookup($MANIFEST.components, componentID)))] + )[$ and $not($exists($match(componentID,/(^\*)*\*(^\*)*/))) and $not($exists($lookup($MANIFEST.components, componentID)))] ).{ "uid": "$dh-mm-nfc-" & contextID & "-" & componentID, "correction": "Определите компонент или удалите ссылку на него в контексте", diff --git a/src/backend/controllers/core.mjs b/src/backend/controllers/core.mjs index 793c7ca4..b7de95a9 100644 --- a/src/backend/controllers/core.mjs +++ b/src/backend/controllers/core.mjs @@ -3,8 +3,9 @@ import storeManager from '../storage/manager.mjs'; import cache from '../storage/cache.mjs'; import queries from '../../global/jsonata/queries.mjs'; import helpers from './helpers.mjs'; -import pathTool from '../../global/manifest/tools/path.mjs'; -import md5 from 'md5'; +import compression from '../../global/compress/compress.mjs'; + +const compressor = compression(); // const LOG_TAG = 'controller-core'; @@ -12,7 +13,7 @@ export default (app) => { // Создает ответ на JSONata запрос и при необходимости кэширует ответ function makeJSONataQueryResponse(res, query, params, subject) { - cache.pullFromCache(JSON.stringify({query, params, subject}), async()=> { + cache.pullFromCache(JSON.stringify({ query, params, subject }), async() => { return await datasets(app).parseSource( app.storage.manifest, query, @@ -33,11 +34,11 @@ export default (app) => { } // Выполняет произвольные запросы - app.get('/core/storage/jsonata/:query', function(req, res) { + app.get('/core/storage/jsonata/:query', function (req, res) { if (!helpers.isServiceReady(app, res)) return; const request = parseRequest(req); - const query = (request.query.length === 36) && queries.QUERIES[request.query] + const query = (request.query.length === 36) && queries.QUERIES[request.query] ? `(${queries.makeQuery(queries.QUERIES[request.query], request.params)})` : request.query; @@ -46,18 +47,18 @@ export default (app) => { // Запрос на обновление манифеста app.put('/core/storage/reload', function(req, res) { - const reloadSecret = req.query.secret; - if(reloadSecret !== process.env.VUE_APP_DOCHUB_RELOAD_SECRET) { - res.status(403).json({ - error: `Error reload secret is not valid [${reloadSecret}]` - }); - return; - } else { - storeManager.reloadManifest() - .then((storage) => storeManager.applyManifest(app, storage)) - .then(cache.clearCache) - .then(() => res.json({ message: 'success' })); - } + const reloadSecret = req.query.secret; + if (reloadSecret !== process.env.VUE_APP_DOCHUB_RELOAD_SECRET) { + res.status(403).json({ + error: `Error reload secret is not valid [${reloadSecret}]` + }); + return; + } else { + storeManager.reloadManifest() + .then((storage) => storeManager.applyManifest(app, storage)) + .then(cache.clearCache) + .then(() => res.json({ message: 'success' })); + } }); // Выполняет произвольные запросы @@ -65,12 +66,18 @@ export default (app) => { if (!helpers.isServiceReady(app, res)) return; const request = parseRequest(req); - cache.pullFromCache(JSON.stringify({path: request.query, params: request.params}), async()=> { - if (request.query.startsWith('/')) + cache.pullFromCache(JSON.stringify({ path: request.query, params: request.params }), async () => { + if (request.query.startsWith('/')) return await datasets(app).releaseData(request.query, request.params); - else if (request.query.startsWith('{')) { + else { + let profile = null; + const params = request.params; + if (request.query.startsWith('{')) + profile = JSON.parse(request.query); + else + profile = JSON.parse(await compressor.decodeBase64(request.query)); + const ds = datasets(app); - const profile = JSON.parse(request.query); if (profile.$base) { const path = ds.pathResolver(profile.$base); if (!path) { @@ -79,20 +86,11 @@ export default (app) => { }); return; } - //todo: Нужно разобраться с первопричиной, почему передаётся объект целиком - if (profile.source?.startsWith('$backend/')) { - const hash = profile.source.slice(9); - profile.source = pathTool.get(app.storage.manifest, profile.$base).source; - if (hash !== md5(profile.source)) { - throw `Error: wrong source hash for release-data-profile: ${profile.$base}`; - } - } - return await ds.getData(path.context, profile, request.params, path.baseURI); + return await ds.getData(path.context, profile, params, path.baseURI); } else { - return await ds.getData(app.storage.manifest, profile, request.params); + return await ds.getData(app.storage.manifest, profile, params); } - } else - throw `Error query param [${request.query}]`; + } }, res); }); diff --git a/src/frontend/components/Docs/DocSwagger.vue b/src/frontend/components/Docs/DocSwagger.vue index 52d4d459..7a1b46ac 100644 --- a/src/frontend/components/Docs/DocSwagger.vue +++ b/src/frontend/components/Docs/DocSwagger.vue @@ -19,7 +19,7 @@ }, computed: { getClass() { - return this.inline ? 'inline' : 'not-inline'; + return this.inline ? 'sgr-inline' : 'sgr-not-inline'; } }, watch: { @@ -51,10 +51,14 @@ }; - diff --git a/src/frontend/consts.js b/src/frontend/consts.js index d20bb475..692c2db2 100644 --- a/src/frontend/consts.js +++ b/src/frontend/consts.js @@ -7,7 +7,7 @@ export default { MAIN_PAGE: '/main' }, plantuml: { - DEFAULT_SERVER: 'www.plantuml.com/plantuml/svg/' + DEFAULT_SERVER: 'seaf.su/seafplantuml/svg/' // 'www.plantuml.com/plantuml/svg/' }, transports: { HTTP: 'http', diff --git a/src/frontend/helpers/datasets.js b/src/frontend/helpers/datasets.js index 112aafeb..79b98a63 100644 --- a/src/frontend/helpers/datasets.js +++ b/src/frontend/helpers/datasets.js @@ -3,7 +3,14 @@ import query from '../manifest/query'; import datasetDriver from '@global/datasets/driver.mjs'; import pathTool from '@global/manifest/tools/path.mjs'; import env from '@front/helpers/env'; -import md5 from 'md5'; +import compress from '@global/compress/compress.mjs'; + +const compressor = compress({ + // eslint-disable-next-line no-undef + DecompressionStream, + // eslint-disable-next-line no-undef + CompressionStream +}); export default function() { return Object.assign({}, datasetDriver, @@ -37,9 +44,10 @@ export default function() { getDataOriginal: datasetDriver.getData, async getData(context, subject, params, baseURI) { if (env.isBackendMode()) { - //todo: Нужно разобраться с первопричиной, почему передаётся объект целиком - subject.source = `$backend/${md5(subject.source)}`; - const query = encodeURIComponent(JSON.stringify(subject)); + //todo: Нужно разобраться с первопричиной, почему передаётся объект целиком + // subject.source = `$backend/${md5(subject.source)}`; + // const query = encodeURIComponent(JSON.stringify(subject)); + const query = encodeURIComponent(await compressor.encodeBase64(JSON.stringify(subject))); const url = new URL(`backend://release-data-profile/${query}`); url.searchParams.set('params', JSON.stringify(params || null)); url.searchParams.set('baseuri', baseURI); diff --git a/src/global/compress/compress.mjs b/src/global/compress/compress.mjs new file mode 100644 index 00000000..cf421f60 --- /dev/null +++ b/src/global/compress/compress.mjs @@ -0,0 +1,50 @@ +const COMPRESS_METHOD = 'gzip'; //deflate + +export default function(driver) { + + const compressor = { + // eslint-disable-next-line no-undef + DecompressionStream: driver?.DecompressionStream || DecompressionStream, + // eslint-disable-next-line no-undef + CompressionStream: driver?.CompressionStream || CompressionStream + }; + + return { + // Упаковывает строку в COMPRESS_METHOD + encodeBin: async function(str) { + const byteArray = new TextEncoder().encode(str); + const cs = new compressor.CompressionStream(COMPRESS_METHOD); + const writer = cs.writable.getWriter(); + writer.write(byteArray); + writer.close(); + return new Response(cs.readable).arrayBuffer(); + }, + + // Упаковывает строку в COMPRESS_METHOD и кодирует в base64 + encodeBase64: async function(str) { + const bin = new Uint8Array(await this.encodeBin(str)); + const strOut = String.fromCodePoint(...bin); + const base64 = btoa(strOut); + console.info(`>>>>> InSize=${str.length} outSize=${encodeURIComponent(base64).length}`); + return base64; + }, + + // Распаковывает byteArray из COMPRESS_METHOD в строку + decodeBin: async function(byteArray) { + const cs = new compressor.DecompressionStream(COMPRESS_METHOD); + const writer = cs.writable.getWriter(); + writer.write(byteArray); + writer.close(); + return new TextDecoder().decode(await new Response(cs.readable).arrayBuffer()); + }, + + // Распаковывает строку из COMPRESS_METHOD и кодирует в base64 + decodeBase64: async function(base64) { + const str = atob(base64); + const bin = Uint8Array.from(Buffer.from(str, 'binary')); + const result = await this.decodeBin(bin); + return result; + } + }; +} +