Initial commit of ERP Plugin SDK
This commit is contained in:
commit
97e680f87c
|
|
@ -0,0 +1,3 @@
|
||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,491 @@
|
||||||
|
{
|
||||||
|
"name": "erp-plugin-sdk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 3,
|
||||||
|
"requires": true,
|
||||||
|
"packages": {
|
||||||
|
"": {
|
||||||
|
"name": "erp-plugin-sdk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@nestjs/common": "^11.1.23",
|
||||||
|
"@nestjs/core": "^11.1.23",
|
||||||
|
"@nestjs/microservices": "^11.1.23",
|
||||||
|
"@types/node": "^25.9.1",
|
||||||
|
"@types/react": "^19.2.15",
|
||||||
|
"reflect-metadata": "^0.2.2",
|
||||||
|
"rxjs": "^7.8.2",
|
||||||
|
"typescript": "^6.0.3",
|
||||||
|
"uuid": "^14.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@borewit/text-codec": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@lukeed/csprng": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@lukeed/csprng/-/csprng-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nestjs/common": {
|
||||||
|
"version": "11.1.23",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/common/-/common-11.1.23.tgz",
|
||||||
|
"integrity": "sha512-qKgEqwQXHIVu8TwiISmgbTrGHAFBsseP86KNolBZwAiHQryinJ5FPiDpp0ZJBBryY+WEMnsqaCa4TSxVuQEWug==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"file-type": "21.3.4",
|
||||||
|
"iterare": "1.2.1",
|
||||||
|
"load-esm": "1.0.3",
|
||||||
|
"tslib": "2.8.1",
|
||||||
|
"uid": "2.0.2"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/nest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"class-transformer": ">=0.4.1",
|
||||||
|
"class-validator": ">=0.13.2",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
||||||
|
"rxjs": "^7.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"class-transformer": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"class-validator": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nestjs/core": {
|
||||||
|
"version": "11.1.23",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/core/-/core-11.1.23.tgz",
|
||||||
|
"integrity": "sha512-Yd+mVFUilw4A6PzV7tyfiW+zrG2wmRXnFZVmNQA+fl1N0k6km4bhhNboxjLu//dzl+XiZI5AsOHHOTegzvOgNQ==",
|
||||||
|
"dev": true,
|
||||||
|
"hasInstallScript": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@nuxt/opencollective": "0.4.1",
|
||||||
|
"fast-safe-stringify": "2.1.1",
|
||||||
|
"iterare": "1.2.1",
|
||||||
|
"path-to-regexp": "8.4.2",
|
||||||
|
"tslib": "2.8.1",
|
||||||
|
"uid": "2.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/nest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@nestjs/common": "^11.0.0",
|
||||||
|
"@nestjs/microservices": "^11.0.0",
|
||||||
|
"@nestjs/platform-express": "^11.0.0",
|
||||||
|
"@nestjs/websockets": "^11.0.0",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
||||||
|
"rxjs": "^7.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@nestjs/microservices": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@nestjs/platform-express": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@nestjs/websockets": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nestjs/microservices": {
|
||||||
|
"version": "11.1.23",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nestjs/microservices/-/microservices-11.1.23.tgz",
|
||||||
|
"integrity": "sha512-iVPp3u274Xx6XAEbKPWDCzUHP6wlt7L7RXUIyIpf3caJ3ldFh/dG3uyHva1lgjHG+ukz+XCXafl1cx352TPW0w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"iterare": "1.2.1",
|
||||||
|
"tslib": "2.8.1"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/nest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@grpc/grpc-js": "*",
|
||||||
|
"@nestjs/common": "^11.0.0",
|
||||||
|
"@nestjs/core": "^11.0.0",
|
||||||
|
"@nestjs/websockets": "^11.0.0",
|
||||||
|
"amqp-connection-manager": "*",
|
||||||
|
"amqplib": "*",
|
||||||
|
"cache-manager": "*",
|
||||||
|
"ioredis": "*",
|
||||||
|
"kafkajs": "*",
|
||||||
|
"mqtt": "*",
|
||||||
|
"nats": "*",
|
||||||
|
"reflect-metadata": "^0.1.12 || ^0.2.0",
|
||||||
|
"rxjs": "^7.1.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@grpc/grpc-js": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@nestjs/websockets": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"amqp-connection-manager": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"amqplib": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"cache-manager": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"ioredis": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"kafkajs": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"mqtt": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"nats": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@nuxt/opencollective": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@nuxt/opencollective/-/opencollective-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-GXD3wy50qYbxCJ652bDrDzgMr3NFEkIS374+IgFQKkCvk9yiYcLvX2XDYr7UyQxf4wK0e+yqDYRubZ0DtOxnmQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"consola": "^3.2.3"
|
||||||
|
},
|
||||||
|
"bin": {
|
||||||
|
"opencollective": "bin/opencollective.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.10.0",
|
||||||
|
"npm": ">=5.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tokenizer/inflate": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.4.3",
|
||||||
|
"token-types": "^6.1.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@tokenizer/token": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/@types/node": {
|
||||||
|
"version": "25.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-25.9.1.tgz",
|
||||||
|
"integrity": "sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": ">=7.24.0 <7.24.7"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/react": {
|
||||||
|
"version": "19.2.15",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.15.tgz",
|
||||||
|
"integrity": "sha512-eRwcGNHve+E8qtEQSSRl6urh+rFop4v8gm6O8rGv25CodbvFdLjA1vVQ1KkiFE0w0UPOnb8tDiFKL5lp0rtY5Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"csstype": "^3.2.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/consola": {
|
||||||
|
"version": "3.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/consola/-/consola-3.4.2.tgz",
|
||||||
|
"integrity": "sha512-5IKcdX0nnYavi6G7TtOhwkYzyjfJlatbjMjuLSfE2kYT5pMDOilZ4OvMhi637CcDICTmz3wARPoyhqyX1Y+XvA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.18.0 || >=16.10.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/csstype": {
|
||||||
|
"version": "3.2.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz",
|
||||||
|
"integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"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/fast-safe-stringify": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz",
|
||||||
|
"integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/file-type": {
|
||||||
|
"version": "21.3.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/file-type/-/file-type-21.3.4.tgz",
|
||||||
|
"integrity": "sha512-Ievi/yy8DS3ygGvT47PjSfdFoX+2isQueoYP1cntFW1JLYAuS4GD7NUPGg4zv2iZfV52uDyk5w5Z0TdpRS6Q1g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@tokenizer/inflate": "^0.4.1",
|
||||||
|
"strtok3": "^10.3.4",
|
||||||
|
"token-types": "^6.1.1",
|
||||||
|
"uint8array-extras": "^1.4.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=20"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sindresorhus/file-type?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/ieee754": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "patreon",
|
||||||
|
"url": "https://www.patreon.com/feross"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "consulting",
|
||||||
|
"url": "https://feross.org/support"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "BSD-3-Clause"
|
||||||
|
},
|
||||||
|
"node_modules/iterare": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/iterare/-/iterare-1.2.1.tgz",
|
||||||
|
"integrity": "sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "ISC",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=6"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/load-esm": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/load-esm/-/load-esm-1.0.3.tgz",
|
||||||
|
"integrity": "sha512-v5xlu8eHD1+6r8EHTg6hfmO97LN8ugKtiXcy5e6oN72iD2r6u0RPfLl6fxM+7Wnh2ZRq15o0russMst44WauPA==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "buymeacoffee",
|
||||||
|
"url": "https://buymeacoffee.com/borewit"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=13.2.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"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/path-to-regexp": {
|
||||||
|
"version": "8.4.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
|
||||||
|
"integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/express"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/reflect-metadata": {
|
||||||
|
"version": "0.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz",
|
||||||
|
"integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0"
|
||||||
|
},
|
||||||
|
"node_modules/rxjs": {
|
||||||
|
"version": "7.8.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz",
|
||||||
|
"integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"tslib": "^2.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/strtok3": {
|
||||||
|
"version": "10.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.3.5.tgz",
|
||||||
|
"integrity": "sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@tokenizer/token": "^0.3.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/token-types": {
|
||||||
|
"version": "6.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/token-types/-/token-types-6.1.2.tgz",
|
||||||
|
"integrity": "sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@borewit/text-codec": "^0.2.1",
|
||||||
|
"@tokenizer/token": "^0.3.0",
|
||||||
|
"ieee754": "^1.2.1"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/Borewit"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/tslib": {
|
||||||
|
"version": "2.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
|
||||||
|
"integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "0BSD"
|
||||||
|
},
|
||||||
|
"node_modules/typescript": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"bin": {
|
||||||
|
"tsc": "bin/tsc",
|
||||||
|
"tsserver": "bin/tsserver"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14.17"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uid": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/uid/-/uid-2.0.2.tgz",
|
||||||
|
"integrity": "sha512-u3xV3X7uzvi5b1MncmZo3i2Aw222Zk1keqLA1YkHldREkAhAqi65wuPfe7lHx8H/Wzy+8CE7S7uS3jekIM5s8g==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@lukeed/csprng": "^1.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/uint8array-extras": {
|
||||||
|
"version": "1.5.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.5.0.tgz",
|
||||||
|
"integrity": "sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "7.24.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.24.6.tgz",
|
||||||
|
"integrity": "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==",
|
||||||
|
"dev": true,
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/uuid": {
|
||||||
|
"version": "14.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/uuid/-/uuid-14.0.0.tgz",
|
||||||
|
"integrity": "sha512-Qo+uWgilfSmAhXCMav1uYFynlQO7fMFiMVZsQqZRMIXp0O7rR7qjkj+cPvBHLgBqi960QCoo/PH2/6ZtVqKvrg==",
|
||||||
|
"dev": true,
|
||||||
|
"funding": [
|
||||||
|
"https://github.com/sponsors/broofa",
|
||||||
|
"https://github.com/sponsors/ctavan"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"uuid": "dist-node/bin/uuid"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"name": "erp-plugin-sdk",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"main": "dist/index.js",
|
||||||
|
"types": "dist/index.d.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://gitea.ss.3w.com.ua/erp/erp-plugin-sdk.git"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"description": "",
|
||||||
|
"devDependencies": {
|
||||||
|
"@nestjs/common": "^11.1.23",
|
||||||
|
"@nestjs/core": "^11.1.23",
|
||||||
|
"@nestjs/microservices": "^11.1.23",
|
||||||
|
"@types/node": "^25.9.1",
|
||||||
|
"@types/react": "^19.2.15",
|
||||||
|
"reflect-metadata": "^0.2.2",
|
||||||
|
"rxjs": "^7.8.2",
|
||||||
|
"typescript": "^6.0.3",
|
||||||
|
"uuid": "^14.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
import { Transport, MicroserviceOptions } from '@nestjs/microservices';
|
||||||
|
|
||||||
|
export const getRabbitMQOptions = (queueName: string, url?: string): MicroserviceOptions => {
|
||||||
|
return {
|
||||||
|
transport: Transport.RMQ,
|
||||||
|
options: {
|
||||||
|
urls: [url || process.env.RABBITMQ_URL || 'amqp://localhost:5672'],
|
||||||
|
queue: queueName,
|
||||||
|
queueOptions: {
|
||||||
|
durable: true, // Черга не зникає при перезавантаженні RabbitMQ
|
||||||
|
},
|
||||||
|
persistent: true, // Повідомлення зберігаються на диску
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,43 @@
|
||||||
|
import {
|
||||||
|
ExceptionFilter,
|
||||||
|
Catch,
|
||||||
|
ArgumentsHost,
|
||||||
|
HttpException,
|
||||||
|
HttpStatus,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
@Catch()
|
||||||
|
export class AllExceptionsFilter implements ExceptionFilter {
|
||||||
|
catch(exception: unknown, host: ArgumentsHost) {
|
||||||
|
const ctx = host.switchToHttp();
|
||||||
|
const response = ctx.getResponse();
|
||||||
|
const request = ctx.getRequest();
|
||||||
|
|
||||||
|
const status =
|
||||||
|
exception instanceof HttpException
|
||||||
|
? exception.getStatus()
|
||||||
|
: HttpStatus.INTERNAL_SERVER_ERROR;
|
||||||
|
|
||||||
|
const message =
|
||||||
|
exception instanceof HttpException
|
||||||
|
? exception.getResponse()
|
||||||
|
: 'Internal server error';
|
||||||
|
|
||||||
|
const serviceName = process.env.SERVICE_NAME || 'unknown-service';
|
||||||
|
|
||||||
|
response.status(status).json({
|
||||||
|
success: false,
|
||||||
|
error: {
|
||||||
|
code: `ERR_${status}`,
|
||||||
|
message: typeof message === 'string' ? message : (message as any).message || 'Error',
|
||||||
|
details: typeof message === 'object' ? message : null,
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
traceId: uuidv4(),
|
||||||
|
service: serviceName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { AsyncLocalStorage } from 'async_hooks';
|
||||||
|
|
||||||
|
export const requestContext = new AsyncLocalStorage<Map<string, string>>();
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RequestContextInterceptor implements NestInterceptor {
|
||||||
|
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
|
||||||
|
const request = context.switchToHttp().getRequest();
|
||||||
|
const store = new Map<string, string>();
|
||||||
|
|
||||||
|
// Зберігаємо токен авторизації, якщо він є
|
||||||
|
const authHeader = request.headers['authorization'];
|
||||||
|
if (authHeader) {
|
||||||
|
store.set('authorization', authHeader);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Зберігаємо IP та User-Agent
|
||||||
|
const ip = request.headers['x-forwarded-for'] || request.ip || request.socket?.remoteAddress;
|
||||||
|
if (ip) {
|
||||||
|
store.set('ip', ip);
|
||||||
|
}
|
||||||
|
const userAgent = request.headers['user-agent'];
|
||||||
|
if (userAgent) {
|
||||||
|
store.set('userAgent', userAgent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Observable(observer => {
|
||||||
|
requestContext.run(store, () => {
|
||||||
|
next.handle().subscribe(observer);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import {
|
||||||
|
Injectable,
|
||||||
|
NestInterceptor,
|
||||||
|
ExecutionContext,
|
||||||
|
CallHandler,
|
||||||
|
} from '@nestjs/common';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { map } from 'rxjs/operators';
|
||||||
|
import { ApiResponse } from '../interfaces/communication';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class TransformInterceptor<T> implements NestInterceptor<T, ApiResponse<T>> {
|
||||||
|
intercept(
|
||||||
|
context: ExecutionContext,
|
||||||
|
next: CallHandler,
|
||||||
|
): Observable<ApiResponse<T>> {
|
||||||
|
const serviceName = process.env.SERVICE_NAME || 'unknown-service';
|
||||||
|
|
||||||
|
return next.handle().pipe(
|
||||||
|
map((data) => ({
|
||||||
|
success: true,
|
||||||
|
data,
|
||||||
|
meta: {
|
||||||
|
timestamp: Date.now(),
|
||||||
|
traceId: uuidv4(),
|
||||||
|
service: serviceName,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
/**
|
||||||
|
* Стандартний конверт для всіх API відповідей (Синхронно)
|
||||||
|
*/
|
||||||
|
export interface ApiResponse<T = any> {
|
||||||
|
success: boolean;
|
||||||
|
data?: T;
|
||||||
|
error?: {
|
||||||
|
code: string;
|
||||||
|
message: string;
|
||||||
|
details?: any;
|
||||||
|
};
|
||||||
|
meta: {
|
||||||
|
timestamp: number;
|
||||||
|
traceId: string;
|
||||||
|
service: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Стандартний конверт для подій (Асинхронно)
|
||||||
|
*/
|
||||||
|
export interface SystemEvent<T = any> {
|
||||||
|
eventId: string;
|
||||||
|
pattern: string; // Наприклад: 'user.login', 'transaction.created'
|
||||||
|
payload: T;
|
||||||
|
source: string; // Назва сервісу-відправника
|
||||||
|
timestamp: number;
|
||||||
|
priority?: 'low' | 'medium' | 'high';
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { Injectable, Inject } from '@nestjs/common';
|
||||||
|
import { ClientProxy } from '@nestjs/microservices';
|
||||||
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
import { SystemEvent } from '../interfaces/communication';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CoreClientService {
|
||||||
|
constructor(
|
||||||
|
@Inject('CORE_SERVICE') private readonly client: ClientProxy,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Запитати у Ядра дані користувача (Синхронно через RabbitMQ RPC)
|
||||||
|
*/
|
||||||
|
async getUserInfo(userId: number) {
|
||||||
|
try {
|
||||||
|
return await firstValueFrom(
|
||||||
|
this.client.send({ cmd: 'get_user_info' }, { userId })
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Повідомити Ядро про подію в плагіні (Асинхронно)
|
||||||
|
*/
|
||||||
|
async notifyCore(pattern: string, payload: any) {
|
||||||
|
const event: SystemEvent = {
|
||||||
|
eventId: uuidv4(),
|
||||||
|
pattern,
|
||||||
|
payload,
|
||||||
|
source: process.env.SERVICE_NAME || 'plugin',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
this.client.emit(pattern, event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
import { Injectable, Inject, Logger } from '@nestjs/common';
|
||||||
|
import { ClientProxy } from '@nestjs/microservices';
|
||||||
|
import { firstValueFrom } from 'rxjs';
|
||||||
|
import { SystemEvent } from '../interfaces/communication';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import * as fs from 'fs';
|
||||||
|
import * as path from 'path';
|
||||||
|
import { requestContext } from '../interceptors/request-context.interceptor';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class CoreService {
|
||||||
|
private readonly logger = new Logger(CoreService.name);
|
||||||
|
private readonly serviceName = process.env.SERVICE_NAME || 'plugin';
|
||||||
|
private heartbeatInterval: any = null;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject('RABBITMQ_CLIENT') private readonly client: ClientProxy,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Спеціальний метод для виконання запитів до Ядра з автоматичним прокиданням авторизації
|
||||||
|
*/
|
||||||
|
async fetchCore(endpoint: string, options: RequestInit = {}) {
|
||||||
|
const coreUrl = process.env.CORE_BACKEND_URL || 'http://localhost:3001';
|
||||||
|
const store = requestContext.getStore();
|
||||||
|
const authHeader = store?.get('authorization');
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
...(authHeader ? { 'Authorization': authHeader } : {}),
|
||||||
|
...((options.headers as any) || {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
this.logger.log(`[CoreRequest] Sending request to ${endpoint} (Auth: ${!!authHeader})`);
|
||||||
|
|
||||||
|
const response = await fetch(`${coreUrl}${endpoint}`, {
|
||||||
|
...options,
|
||||||
|
headers,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
this.logger.error(`[CoreRequest] Request to ${endpoint} failed with status ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (решта методів register, emit, request залишаються без змін)
|
||||||
|
|
||||||
|
async register(): Promise<void> {
|
||||||
|
const coreUrl = process.env.CORE_BACKEND_URL || 'http://localhost:3001';
|
||||||
|
const possiblePaths = [
|
||||||
|
path.resolve(process.cwd(), '..', 'manifest.json'),
|
||||||
|
path.resolve(process.cwd(), 'manifest.json'),
|
||||||
|
];
|
||||||
|
|
||||||
|
let manifestPath = '';
|
||||||
|
for (const p of possiblePaths) {
|
||||||
|
if (fs.existsSync(p)) {
|
||||||
|
manifestPath = p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!manifestPath) return;
|
||||||
|
|
||||||
|
// Dynamically calculate the backendUrl
|
||||||
|
const port = process.env.PORT || '3002';
|
||||||
|
const serviceName = process.env.SERVICE_NAME || 'plugin';
|
||||||
|
const isDocker = coreUrl.includes('core-backend') || (!coreUrl.includes('localhost') && !coreUrl.includes('127.0.0.1'));
|
||||||
|
const backendUrl = process.env.PLUGIN_BACKEND_URL || (isDocker ? `http://${serviceName}:${port}` : `http://localhost:${port}`);
|
||||||
|
|
||||||
|
let registered = false;
|
||||||
|
while (!registered) {
|
||||||
|
try {
|
||||||
|
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
|
||||||
|
if (process.env.PUBLIC_URL) {
|
||||||
|
manifest.remoteEntry = `${process.env.PUBLIC_URL}/remoteEntry.js`;
|
||||||
|
}
|
||||||
|
manifest.backendUrl = backendUrl;
|
||||||
|
|
||||||
|
const response = await fetch(`${coreUrl}/api/plugins/register`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify(manifest),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
this.logger.log(`Plugin registered successfully!`);
|
||||||
|
registered = true;
|
||||||
|
this.startHeartbeatLoop(manifest.id, backendUrl);
|
||||||
|
} else {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private startHeartbeatLoop(pluginId: string, backendUrl: string) {
|
||||||
|
if (this.heartbeatInterval) {
|
||||||
|
clearInterval(this.heartbeatInterval);
|
||||||
|
}
|
||||||
|
this.heartbeatInterval = setInterval(async () => {
|
||||||
|
try {
|
||||||
|
const coreUrl = process.env.CORE_BACKEND_URL || 'http://localhost:3001';
|
||||||
|
this.logger.log(`[Heartbeat] Sending heartbeat for ${pluginId}`);
|
||||||
|
const response = await fetch(`${coreUrl}/api/plugins/heartbeat`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ id: pluginId, backendUrl }),
|
||||||
|
});
|
||||||
|
|
||||||
|
if (response.ok) {
|
||||||
|
const resBody = await response.json();
|
||||||
|
const data = resBody && resBody.data !== undefined ? resBody.data : resBody;
|
||||||
|
if (data && data.registered === false) {
|
||||||
|
this.logger.warn(`[Heartbeat] Core does not recognize plugin ${pluginId}. Re-registering.`);
|
||||||
|
this.register();
|
||||||
|
} else {
|
||||||
|
this.logger.log(`[Heartbeat] Heartbeat acknowledged by core.`);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.logger.error(`[Heartbeat] Failed to send heartbeat. Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
} catch (error: any) {
|
||||||
|
this.logger.error(`[Heartbeat] Error sending heartbeat:`, error.message || error);
|
||||||
|
}
|
||||||
|
}, 30 * 1000); // 30 seconds
|
||||||
|
}
|
||||||
|
|
||||||
|
async emit<T>(pattern: string, payload: T): Promise<void> {
|
||||||
|
const event: SystemEvent<T> = {
|
||||||
|
eventId: uuidv4(),
|
||||||
|
pattern,
|
||||||
|
payload,
|
||||||
|
source: this.serviceName,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
};
|
||||||
|
this.client.emit(pattern, event).subscribe({
|
||||||
|
error: (err) => this.logger.error(`Failed to emit event ${pattern}:`, err),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async auditLog(action: string, resource: string, details?: any): Promise<void> {
|
||||||
|
const store = requestContext.getStore();
|
||||||
|
const authHeader = store?.get('authorization');
|
||||||
|
const ipAddress = store?.get('ip');
|
||||||
|
const userAgent = store?.get('userAgent');
|
||||||
|
let userId: number | undefined;
|
||||||
|
|
||||||
|
if (authHeader && authHeader.startsWith('Bearer ')) {
|
||||||
|
try {
|
||||||
|
const token = authHeader.split(' ')[1];
|
||||||
|
const base64Url = token.split('.')[1];
|
||||||
|
const base64 = base64Url.replace(/-/g, '+').replace(/_/g, '/');
|
||||||
|
const jsonPayload = Buffer.from(base64, 'base64').toString();
|
||||||
|
const payload = JSON.parse(jsonPayload);
|
||||||
|
userId = payload.sub || payload.userId || payload.id;
|
||||||
|
} catch (e) {
|
||||||
|
this.logger.error('Failed to decode JWT for audit log', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.emit('system.audit.log', {
|
||||||
|
userId,
|
||||||
|
action,
|
||||||
|
resource,
|
||||||
|
details,
|
||||||
|
ipAddress,
|
||||||
|
userAgent,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async getGlobalData<T = string>(key: string): Promise<T | null> {
|
||||||
|
const response = await this.fetchCore(`/api/store/${key}`, {
|
||||||
|
headers: {
|
||||||
|
'x-plugin-id': this.serviceName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (response.success) {
|
||||||
|
if (response.data === null || response.data === undefined) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return JSON.parse(response.data) as T;
|
||||||
|
} catch (e) {
|
||||||
|
return response.data as unknown as T;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async setGlobalData(key: string, value: any): Promise<void> {
|
||||||
|
const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
|
||||||
|
await this.fetchCore(`/api/store/${key}`, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify({ value: stringValue }),
|
||||||
|
headers: {
|
||||||
|
'x-plugin-id': this.serviceName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteGlobalData(key: string): Promise<void> {
|
||||||
|
await this.fetchCore(`/api/store/${key}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: {
|
||||||
|
'x-plugin-id': this.serviceName,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
declare module 'host/UIKit' {
|
||||||
|
export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
|
||||||
|
variant?: 'primary' | 'secondary' | 'danger' | 'ghost';
|
||||||
|
size?: 'sm' | 'md' | 'lg';
|
||||||
|
}
|
||||||
|
export const Button: React.FC<ButtonProps>;
|
||||||
|
|
||||||
|
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {
|
||||||
|
label?: string;
|
||||||
|
icon?: React.ReactNode;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
export const Input: React.FC<InputProps>;
|
||||||
|
|
||||||
|
export interface CardProps {
|
||||||
|
title?: React.ReactNode;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
}
|
||||||
|
export const Card: React.FC<CardProps>;
|
||||||
|
|
||||||
|
export const Typography: {
|
||||||
|
H1: React.FC<React.HTMLAttributes<HTMLHeadingElement>>;
|
||||||
|
H2: React.FC<React.HTMLAttributes<HTMLHeadingElement>>;
|
||||||
|
H3: React.FC<React.HTMLAttributes<HTMLHeadingElement>>;
|
||||||
|
P: React.FC<React.HTMLAttributes<HTMLParagraphElement>>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference path="./frontend/uikit.d.ts" />
|
||||||
|
export * from './backend/services/core.service';
|
||||||
|
export * from './backend/services/core-client.service';
|
||||||
|
export * from './backend/interfaces/communication';
|
||||||
|
export * from './backend/filters/exception.filter';
|
||||||
|
export * from './backend/interceptors/request-context.interceptor';
|
||||||
|
export * from './backend/interceptors/transform.interceptor';
|
||||||
|
export * from './backend/config/rabbitmq.config';
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2021",
|
||||||
|
"module": "CommonJS",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src",
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"types": ["node", "react"],
|
||||||
|
"ignoreDeprecations": "6.0"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"]
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue