{"_id":"@admandev/socketio-decorator","_rev":"20-a93d63f6b2cdf25a26ee1a4a11260927","name":"@admandev/socketio-decorator","dist-tags":{"latest":"1.4.1"},"versions":{"1.0.1":{"name":"@admandev/socketio-decorator","version":"1.0.1","author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.0.1","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"28e0af0c7ebae5565e6ec778a26cc68147d70097","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.0.1.tgz","fileCount":7,"integrity":"sha512-DVu1eA6BCOtW6L734JXx1aZVW/tI2Ohn1VqyLgA0bZ2aaSvTrsB7ml42295MXxoIJ9OGXYyB0Y/10mnxYJhwHA==","signatures":[{"sig":"MEUCIQCaXRkEOaahjJkeIa1FXxRZtXWBeGWbPT1gtcVzfmIemQIgCnBD0A6U2sNaePSACUhQKXjoDoDlUlOMx0YS90+R9GM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":47183},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"fd1cc73a5df26ac26a75a733bf980d89c6bcd25a","private":false,"scripts":{"dev":"tsup --sourcemap","lint":"eslint src","build":"tsup"},"typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git"},"_npmVersion":"10.2.4","description":"Decorators for socket.io","directories":{},"_nodeVersion":"20.11.1","typesVersions":{"*":{"*":["/*"]}},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.2.2","eslint":"8.36.0","typescript":"^5.5.3","eslint-plugin-jsdoc":"^48.8.3","@typescript-eslint/parser":"5.55.0","@typescript-eslint/eslint-plugin":"5.55.0"},"peerDependencies":{"socket.io":"^4.7.5"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.0.1_1722112491336_0.48533166738909794","host":"s3://npm-registry-packages"}},"1.0.2":{"name":"@admandev/socketio-decorator","version":"1.0.2","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.0.2","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"d2580c505daae2afee90d8fca00124bf462521a5","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.0.2.tgz","fileCount":7,"integrity":"sha512-RNiBatwT+RyNfZEWI0B14FbfdPu1xLIF9gbQRMRSpYOafkXyq6HkAb5vQEEM6WLvSJlM+7q9R7/SvVg9sDhKrw==","signatures":[{"sig":"MEUCIB57Ozx9HR1ROYiUMNgsuI1ffa3qYpRv/U8D63ncNFaWAiEA7ghjgd7i0AJ8scZBZjWYwlUpZSCas8I+zypDdWI/TX8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":52463},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"dd7066c821203022d6248b9059ed152790885707","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.7.0","description":"Decorators for socket.io","directories":{},"_nodeVersion":"20.15.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.7.5"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.0.2_1722180152387_0.6295516327165216","host":"s3://npm-registry-packages"}},"1.1.0":{"name":"@admandev/socketio-decorator","version":"1.1.0","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.1.0","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"6d9e19a1481a8093fb148fd0d494f9dd3f2a5058","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.1.0.tgz","fileCount":7,"integrity":"sha512-HyUIATmqSm3GPCevXT/wzufPnTILQ4QwWd+BU0H28T2eX5pyJxYgeNj3pXIbbPcLZJAKUgAsQRlq7gudiZo0Ig==","signatures":[{"sig":"MEUCIQCQ6kBBsjnK5lCUwIobhRqdGIfsScF6VrUoHud+zrhSTQIgMWX/uSi2lUIkC/LZtWAzp0UnaeLQPwnGKk9bZNF4gG0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62837},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"6691f23c10c248e4331bb4c01836c5d59ac6ac4b","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.7.0","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.15.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.7.5"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.1.0_1722533980467_0.1334544858233646","host":"s3://npm-registry-packages"}},"1.1.1":{"name":"@admandev/socketio-decorator","version":"1.1.1","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.1.1","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"b890079737a9c6ef3f8dd8d24d5a5c1610e401e7","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.1.1.tgz","fileCount":7,"integrity":"sha512-AVa2PuSHV2sMy6e8PCmfNWC6UImE39JCQqytjVMlUoc0gzAWBs0rJlxpzNEQkDOvx1oU4PQijiEb69xzHYLLqQ==","signatures":[{"sig":"MEQCIFOeEbMt9RbY71vagwpsFC4g69dvghMBdGJtM1SEpl4sAiACzTP40JJ3T4apgLV44mrQg6MInLBGplho/QQ/UOx3Ww==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":62863},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"0a316bc9525c9fc8029a27880dbb9f7955b95b6a","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.1","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.16.0","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.7.5"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.1.1_1722798999342_0.4220790229806759","host":"s3://npm-registry-packages"}},"1.1.2":{"name":"@admandev/socketio-decorator","version":"1.1.2","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.1.2","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"7375a309642ea90b72ec9c5d726a9819da07bfa5","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.1.2.tgz","fileCount":7,"integrity":"sha512-YN/GY2oUJz6SjbC89tQeA8A79JweZuVDdUwzGSd0o3QS2r43fi4+d7IghNR8MSG3sw0IHxtreOzAr4Mx97TGTQ==","signatures":[{"sig":"MEUCIHqk/9YOVlL2OzHXC2FEnktCvllBraZ6MN9mlPdnogGUAiEA0pWu/Sk+PgJumk+v+yOoe6MfZNzIpY/cot8pZjiyfvQ=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":63126},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"47a20275116a3f0b01145964f0e517b0faf85a6b","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.17.0","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.7.5"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.1.2_1725106121920_0.945429791742419","host":"s3://npm-registry-packages"}},"1.1.3":{"name":"@admandev/socketio-decorator","version":"1.1.3","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.1.3","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"d015e2e753f47467e98ade5401097ece61561743","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.1.3.tgz","fileCount":7,"integrity":"sha512-O+PR6ZOHtnLrM5knx6q5j1hanbGZ9KCfUsy4RsL5NaIKsKxZbYrRFKbkE2IT+iHBQx+JfUXYeqANoKr1qtgYEw==","signatures":[{"sig":"MEUCICPXC+NfrD1E9IBrB9oZvnx/w0A1EIQygwmP0TBrVgqmAiEA3WBodgtSEK6hvQo4f5ikM3mICUXCTklS2UvAP/CqugA=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":63280},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"376afc9af226d4050e1baa76eb0d4b48571f6869","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.17.0","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.7.5"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.1.3_1726318774824_0.8544332727681689","host":"s3://npm-registry-packages"}},"1.2.0":{"name":"@admandev/socketio-decorator","version":"1.2.0","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.2.0","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"154a7bf6065bf3df7fc284b12a7b002f07fac64f","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.2.0.tgz","fileCount":7,"integrity":"sha512-1aEhz1bDKt6348izdfVU+2t7Mj52L99xYamhlUFeTl7ZPOd58Nr/6NQT91x9VyTwTLnXYgBOarwsmREA7gBmtw==","signatures":[{"sig":"MEQCIA7ZZpO0Z9+EWgK68cMNm/3j6whowMBSVO/Yp9hIbpqOAiBETuaqyLgEX/OyHYYcjYt3OSXaplJJvNoNSCx3cQ/2SA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":88096},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"90c20c540bb8c9d3f2e9466828837d79b76b59b1","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.18.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.2.0_1733757779306_0.9022377444754452","host":"s3://npm-registry-packages-npm-production"}},"1.2.1":{"name":"@admandev/socketio-decorator","version":"1.2.1","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.2.1","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"8d5036afa5c16f75b45242765b4023bdb059397f","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.2.1.tgz","fileCount":7,"integrity":"sha512-fWD6pv1j+guPBa8/TG5wUtiVxNQ2S4mOL201OYgcE/d5fxXucAUQGEeE1v9scoMUAUQWtmEkqhoPr+PUFjNsPw==","signatures":[{"sig":"MEUCIQCOp3y5O+K8AqJlJ22156ums4S5Aq1ED1TV8Nyy2gG1rwIgLiWr9CWVawkAgPB8UtWLDVirBWN9aSuweIbZ8vkrpKo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":88768},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"31d9b13bd0a7ba81709d50c730989a96018c255b","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.2.4","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.11.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.2.1_1733759120662_0.8130536295190891","host":"s3://npm-registry-packages-npm-production"}},"1.2.2":{"name":"@admandev/socketio-decorator","version":"1.2.2","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.2.2","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"f6aef24c51eaf1a4e1a5649312526bece3612308","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.2.2.tgz","fileCount":7,"integrity":"sha512-swf/p2N6zAyzr/hXNk+C4RSR0gEVpEAjFuG6fyBwOv/UNlug3cYbfgVVjLusfN+fPpsc1JPZVxxSZylzvjln/g==","signatures":[{"sig":"MEQCIBpmgA+Ko87xHN8Lea47frlHOQuXKa8Mir7Jn+a26ORKAiAinuyV5kz4cKG0932amwDc3hbAm2Pe/QKiaN1fVpZrLA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84488},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"31d9b13bd0a7ba81709d50c730989a96018c255b","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.2.4","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.11.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.2.2_1733759623641_0.7440709219904265","host":"s3://npm-registry-packages-npm-production"}},"1.2.3":{"name":"@admandev/socketio-decorator","version":"1.2.3","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.2.3","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"beb98dca33d31c014269ac04eb78b21ae3d18e36","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.2.3.tgz","fileCount":7,"integrity":"sha512-mfbNaTXlKwhamMs1Eh10blpBvbU+uGCQJOpsazlbQaykL/uYES4OzRoykBIYMAZ1fsYSodjJVwNkdpTtYsksUg==","signatures":[{"sig":"MEUCIQC9TkbSiYJctT1u6dlPXKrw6E1QA77/93FGdDWN1+NPlwIgT+FDbcSJdbLZVNLX3FpW/PNwxBvgQ+3ZNV8jAYiY/ok=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":88770},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"31d9b13bd0a7ba81709d50c730989a96018c255b","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.2.4","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.11.1","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.2.3_1733760022285_0.32119812453576047","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@admandev/socketio-decorator","version":"1.3.0","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.3.0","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"102eefa5182ec97fa1b59a9b1637ff9b1aa5c708","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.3.0.tgz","fileCount":7,"integrity":"sha512-wjuRGnpRbh6ww3LXASKXKQlz/1mxkGTPT3kfrvis6bvVcVJViCgDYdd1g13EyREbs0pXQCM6Afj3Iv/hjxxLCg==","signatures":[{"sig":"MEUCIQD3AS9a/Ec5+BuNecbUncZwfpUEXcoOy/wTJ5UxaPug+QIgIRAgUAQza71LGA4H8YGLFNaTqrKNWFc1b8Z1H3AqD4c=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128596},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"dd139810eb19a7d280d6f82e5b1be03261b0e237","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.2","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.1","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.3.0_1749995714074_0.6485756694994282","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@admandev/socketio-decorator","version":"1.3.1","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.3.1","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"23910cb51035ff6919b805dcc12a7651f0d7859b","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.3.1.tgz","fileCount":7,"integrity":"sha512-+kuBQbRAi/dfP7m0xbf1F4Ja7OCK3gRb0+jDJXhMMUd7FIH661HePoJ7GouHPiG1iXq68mrP1f9t4B2xHfBVrw==","signatures":[{"sig":"MEMCIEzF7s4DgMjZvWg61T2aojw5XHaKyiDL8YFlwL7pstxlAh9Gf0lX9YyU+IG0Vkk+7f2cFzs3Oo5c7bARUuV+wqaF","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":141117},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"a5a3cbe629d70001ac87774f09cd966ed94d75dd","typings":"./index.d.ts","_npmUser":{"name":"admandev","actor":{"name":"admandev","type":"user","email":"adman.software@gmail.com"},"email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.2","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.3.1_1751226130695_0.9561943224468397","host":"s3://npm-registry-packages-npm-production"}},"1.3.2":{"name":"@admandev/socketio-decorator","version":"1.3.2","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.3.2","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"b0a81aa2ea15dc936755dfa188c5245adf20f2ed","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.3.2.tgz","fileCount":7,"integrity":"sha512-wXv7dTVS+UJNJWBzTjmB3n3KNLGVQHvz4r3iy2qm/zdaKU+xX677CSzAcfDI/btqhtZVA88Y3TfHDfHe89jrWg==","signatures":[{"sig":"MEUCIQDMyj+/lmnq8Bgih3oKRlyeLhFEWAi4TQgCryLc+O3P4gIgK5l2tmleyLXJZYsm57p8V3S8E/7ZaTSU0qTO8wkYVUI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":143375},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"671de95cee55ebce9da92d861eb5114618be074a","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.3","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.3.2_1752661566985_0.4118153532537001","host":"s3://npm-registry-packages-npm-production"}},"1.3.3":{"name":"@admandev/socketio-decorator","version":"1.3.3","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.3.3","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"ac5c841ee44dffa9be08db21acdfd388f8e68396","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.3.3.tgz","fileCount":7,"integrity":"sha512-QEzRUU3E7EIOHz3RuCK9KVsCbrwAkmiDyv5JEb5hmpIBV5k6BWTxfLyiLFMjAx9oMVwH9izCtTd/0nsYUoKFqw==","signatures":[{"sig":"MEUCIQDhb4cz89rlAODUwHCzQNPFuaC9QYb1BgpbPXX+Zx4O3wIgQlHV8eUJ5+lwYa3MCHpAjma2xlgQcjw8knz7SXCsN5o=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":149230},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"b051848a34d908dbbdfcdf89aab163594394f1ef","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.4","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.3.3_1757418754535_0.2847277629059817","host":"s3://npm-registry-packages-npm-production"}},"1.3.4":{"name":"@admandev/socketio-decorator","version":"1.3.4","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.3.4","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"aeedf778a24c25776f888af8c15b9d1d1de5a441","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.3.4.tgz","fileCount":7,"integrity":"sha512-0V5tKAOJtpWTot4PTUjqZsmXQCWZAWvnY1kAfCe/n/ORwHV6m9Bj+WvnnICw+R2PqYfENbFG7lviU7Mu0zdtpA==","signatures":[{"sig":"MEQCID2VPlKyojPuEZxFX/oWfP+B820IceKSdJoqqsdtYUc1AiAKqw95aA/jDUURTQ8QCVUj7pZIIFys8fqgtuttzEqPsg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":192434},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"380c84c6da8ee40704f59f111b3a93b7e0dd3af6","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.5","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.3.4_1759918032240_0.028608340400507526","host":"s3://npm-registry-packages-npm-production"}},"1.4.0":{"name":"@admandev/socketio-decorator","version":"1.4.0","keywords":["socket.io","decorator","typescript","nodejs"],"author":{"name":"Admandev"},"license":"MIT","_id":"@admandev/socketio-decorator@1.4.0","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"dist":{"shasum":"d97bc8b51cf80770b2f0ba3012384cae39c65774","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.4.0.tgz","fileCount":7,"integrity":"sha512-rYow/YGvTlu2Lbcm/Gv5qnnKpMu9KFmJjmMFhYafoix14Y9vcTnsNXXWzrkL5qPSKWJRWlXY7ymZRq2GRvhGfg==","signatures":[{"sig":"MEUCIQDqIr+2R4R5k1CHREnLTvI16Go+MH+MbVCBid+v1yqtFAIgVF8vVvd3JN4laVz4jBk4gCq3JN8Q5Fkin41C4gO3yD8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":283594},"main":"./index.js","module":"./index.mjs","exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"gitHead":"7423dd01bade3cc6a0833cea659251b5f18ea693","typings":"./index.d.ts","_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"repository":{"url":"git+https://github.com/AdmanDev/socketio-decorator.git","type":"git"},"_npmVersion":"10.8.2","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","directories":{},"_nodeVersion":"20.19.5","typesVersions":{"*":{"*":["./*"]}},"_hasShrinkwrap":false,"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-validator":"^0.14.2","reflect-metadata":"^0.2.2","class-transformer":"^0.5.1"},"_npmOperationalInternal":{"tmp":"tmp/socketio-decorator_1.4.0_1762345211975_0.4275455339275238","host":"s3://npm-registry-packages-npm-production"}},"1.4.1":{"name":"@admandev/socketio-decorator","version":"1.4.1","description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","typesVersions":{"*":{"*":["./*"]}},"exports":{".":{"types":"./index.d.ts","import":"./index.mjs","require":"./index.js"}},"main":"./index.js","module":"./index.mjs","typings":"./index.d.ts","author":{"name":"Admandev"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AdmanDev/socketio-decorator.git"},"keywords":["socket.io","decorator","typescript","nodejs"],"peerDependencies":{"socket.io":"^4.8.1"},"optionalDependencies":{"class-transformer":"^0.5.1","class-validator":"^0.14.3","reflect-metadata":"^0.2.2"},"_id":"@admandev/socketio-decorator@1.4.1","gitHead":"6797f9e51a2e008f413a27a2b1b916d439bc4276","bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"homepage":"https://github.com/AdmanDev/socketio-decorator#readme","_nodeVersion":"20.19.6","_npmVersion":"10.8.2","dist":{"integrity":"sha512-6ko7ZtPt/QclVGdpLb6ZiDEwGd/gOb9QLyrE8YtoGra8egG2w4XWE0mqFs8Kzm+POTgw+pIRh0BPy99kHi7YFQ==","shasum":"22a170e3ab6831726182c2d7a0b6d138cf28a0ca","tarball":"https://registry.npmjs.org/@admandev/socketio-decorator/-/socketio-decorator-1.4.1.tgz","fileCount":7,"unpackedSize":283594,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGbPl66kdpRSzfxQuxcpB9vC+JPKMLZt8+o14YbbkBeiAiAtsgMFOAJKThj3SupinVAdMvAsc50pVK0i0iXiv6dLag=="}]},"_npmUser":{"name":"admandev","email":"adman.software@gmail.com"},"directories":{},"maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/socketio-decorator_1.4.1_1765972156041_0.4539073755065306"},"_hasShrinkwrap":false}},"time":{"created":"2024-07-27T20:34:51.250Z","modified":"2025-12-17T11:49:16.429Z","1.0.0":"2024-07-27T20:27:48.281Z","1.0.1":"2024-07-27T20:34:51.495Z","1.0.2":"2024-07-28T15:22:32.594Z","1.1.0":"2024-08-01T17:39:40.646Z","1.1.1":"2024-08-04T19:16:39.482Z","1.1.2":"2024-08-31T12:08:42.130Z","1.1.3":"2024-09-14T12:59:34.971Z","1.2.0":"2024-12-09T15:22:59.463Z","1.2.1":"2024-12-09T15:45:20.857Z","1.2.2":"2024-12-09T15:53:43.817Z","1.2.3":"2024-12-09T16:00:22.442Z","1.3.0":"2025-06-15T13:55:14.248Z","1.3.1":"2025-06-29T19:42:10.893Z","1.3.2":"2025-07-16T10:26:07.149Z","1.3.3":"2025-09-09T11:52:34.710Z","1.3.4":"2025-10-08T10:07:12.463Z","1.4.0":"2025-11-05T12:20:12.189Z","1.4.1":"2025-12-17T11:49:16.207Z"},"bugs":{"url":"https://github.com/AdmanDev/socketio-decorator/issues"},"author":{"name":"Admandev"},"license":"MIT","homepage":"https://github.com/AdmanDev/socketio-decorator#readme","keywords":["socket.io","decorator","typescript","nodejs"],"repository":{"type":"git","url":"git+https://github.com/AdmanDev/socketio-decorator.git"},"description":"This library allows you to use Socket.io with TypeScript decorators, simplifying the integration and usage of Socket.io in a TypeScript environment.","maintainers":[{"name":"admandev","email":"adman.software@gmail.com"}],"readme":"\n# Socketio Decorator\n\nUse TypeScript decorators to simplify working with [Socket.IO](https://socket.io/) in your Node.js applications.\n\nThis library provides an elegant and declarative way to define Socket.IO event listeners, emitters, middlewares, and more — all using modern TypeScript decorators.\n\n## 📚 Table of Contents\n\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Decorators](#decorators)\n  - [Listening for Events](#listening-for-events)\n  - [Emitting Events](#emitting-events)\n  - [Room management decorators](#room-decorators)\n  - [Parameter injection](#parameter-injection-decorators)\n  - [Other decorators](#other-decorators)\n- [Middlewares](#middlewares)\n  - [Server Middleware](#server-middleware)\n  - [Socket Middleware](#socket-middleware)\n  - [Namespace middleware](#namespace-middleware)\n  - [Error handling middleware](#error-handling-middleware)\n- [Rate Limiting](#rate-limiting)\n- [Data validation](#data-validation)\n  - [Setup](#setup)\n  - [Disable validation for a specific handler](#disable-validation-for-a-specific-handler)\n- [Application Events Bus](#application-events)\n- [Hooks](#hooks)\n  - [UseIoServer hook](#useioserver-hook)\n  - [UseUserSocket hook](#useusersocket-hook)\n  - [UseAppEventBus hook](#useappeventbus-hook)\n  - [UseRoomStore hook](#useroomstore-hook)\n  - [UseRoom hook](#useroom-hook)\n- [Dependency Injection](#dependency-injection)\n\n## Installation\n\nTo get started, follow these steps:\n\n1. Install the package:\n\n    ```bash\n    npm install @admandev/socketio-decorator socket.io\n    ```\n\n    > [!NOTE]\n    > ℹ️ Peer dependencies like `reflect-metadata` and `class-validator` may also be required depending on your use case (see [Data Validation](#data-validation)).\n\n2. Update your `tsconfig.json` to enable decorators:\n\n    ```json\n    {\n        \"compilerOptions\": {\n            \"module\": \"Node16 (or more recent)\",\n            \"experimentalDecorators\": true,\n            \"emitDecoratorMetadata\": true\n        }\n    }\n    ```\n\n## Quick Start\n\n1. **Create a Socket Controller**\n\n    ```typescript\n    import { Data, ServerOn, SocketOn, SocketEmitter } from \"@admandev/socketio-decorator\"\n    import { Socket } from \"socket.io\"\n\n    export class SocketController {\n        @ServerOn(\"connection\")\n        public onConnection(@CurrentSocket() socket: Socket) {\n            console.log(\"Socket connected with socket id\", socket.id)\n        }\n\n        @SocketOn(\"message\")\n        public onMessage(@CurrentSocket() socket: Socket, @Data() data: any) {\n            console.log(\"Message received:\", data, \"from socket id:\", socket.id)\n        }\n\n        // Async / Await is supported\n        @SocketOn(\"hello\")\n        @SocketEmitter(\"hello-back\") // Emit returned data as response, automatically\n        public async onHello() {\n            await something()\n            return {\n                message: \"Hello you\"\n            }\n        }\n\n    }\n    ```\n\n2. **Set Up the Server**\n\n   In your `app.ts` file, set up the server and use the Controller:\n\n    ```typescript\n    import { useSocketIoDecorator } from \"@admandev/socketio-decorator\"\n    import express from \"express\"\n    import http from \"http\"\n    import { Server } from \"socket.io\"\n    import { SocketController } from \"./SocketController\"\n\n    const app = express()\n    const server = http.createServer(app)\n\n    const io = new Server(server)\n\n    useSocketIoDecorator({\n        ioserver: io,\n        controllers: [SocketController],\n    })\n\n    server.listen(3000, () => {\n        console.log(\"Server running on port 3000\")\n    })\n    ```\n\n    You can also auto import controllers from a directory:\n\n    ```typescript\n    useSocketIoDecorator({\n        controllers: [path.join(__dirname, \"/controllers/*.js\")],\n        ...\n    })\n    ```\n\n## Decorators\n\n### Listening for Events\n\nThe following decorators can be used to listen for events:\n\n| Decorator               | Description                                              | Equivalent in Basic Socket.io       |\n|-------------------------|----------------------------------------------------------|-------------------------------------|\n| `@ServerOn(event: string)`     | Listens for server events.            | `io.on(event, callback)`            |\n| `@SocketOn(event: string)`     | Listens for events emitted by the client.             | `socket.on(event, callback)`        |\n| `@SocketOnce(event: string)`   | Listens for events emitted by the client only once.    | `socket.once(event, callback)`      |\n| `@SocketOnAny()`               | Listens for any event emitted by the client.           | `socket.onAny(callback)`            |\n| `@SocketOnAnyOutgoing()`       | Listens for any outgoing event.  | `socket.onAnyOutgoing(callback)`    |\n\n#### Example\n\n---\n\n##### @SeverOn(event: string)\n\n**Equivalent in basic Socket.io:** `io.on(event, callback)`\n\nListens for server events.\n\n**Usage** :\n\n```typescript\n@ServerOn(\"connection\")\npublic onConnection(@CurrentSocket() socket: Socket) {\n    console.log(\"Socket connected with socket id\", socket.id)\n}\n```\n\n---\n\n##### @SocketOn(event: string)\n\n**Equivalent in basic Socket.io:** `socket.on(event, callback)`\n\nListens for events emitted by the client.\n\n**Usage** :\n\n```typescript\n@SocketOn(\"message\")\npublic onMessage(@Data() data: any) {\n    console.log(\"Message received:\", data)\n}\n```\n\n---\n\n##### @SocketOnce(event: string)\n\n**Equivalent in basic Socket.io:** `socket.once(event, callback)`\n\nListens for events emitted by the client only once.\n\n**Usage** :\n\n```typescript\n@SocketOnce(\"message\")\npublic onMessage(@Data() data: any) {\n    console.log(\"Message received:\", data)\n}\n```\n\n---\n\n##### @SocketOnAny()\n\n**Equivalent in basic Socket.io:** `socket.onAny(callback)`\n\nListens for any event emitted by the client.\n\n**Usage** :\n\n```typescript\n@SocketOnAny()\npublic onAnyEvent(@EventName() event: string, @Data() data: any) {\n    console.log(\"Any event received:\", event, data)\n}\n```\n\n---\n\n##### @SocketOnAnyOutgoing()\n\n**Equivalent in basic Socket.io:** `socket.onAnyOutgoing(callback)`\n\nListens for any outgoing event\n\n**Usage** :\n\n```typescript\n@SocketOnAnyOutgoing()\npublic onAnyOutgoingEvent(@EventName() event: string, @Data() data: any) {\n    console.log(\"Any outgoing event received:\", event, data)\n}\n```\n\n### Emitting Events\n\nThe following decorators can be used to emit events to the client:\n\n| Decorator               | Description                                             | Equivalent in Basic Socket.io        |\n|-------------------------|---------------------------------------------------------|--------------------------------------|\n| `@ServerEmitter(event?: string, to?: string)`  | Emits event to all clients.                        | `io.emit(event, data)`               |\n| `@SocketEmitter(event:? string)`  | Emits event to specific client.                  | `socket.emit(event, data)`           |\n\n#### How to use\n\n1. **Basic usage**\n\n    The return value of the method is sent as the data of the event.\n\n    ```typescript\n    @SocketOn(\"get-latest-message\")\n    @SocketEmitter(\"message\")\n    public sendMessage() {\n        return { message: \"Hello, world!\" }\n    }\n    ```\n\n    The above code will emit a `message` event with the following data as response to the client :\n\n    ```json\n        {\n            \"message\": \"Hello, world!\"\n        }\n    ```\n\n2. **Emitting options**\n\n    - You can also specify options for the emitted event by returning an `EmitterOption` object.\n\n        ```typescript\n        import { EmitterOption, SocketEmitter } from \"@admandev/socketio-decorator\"\n        import { Socket } from \"socket.io\"\n\n        @SocketOn(\"chat-message\")\n        @SocketEmitter() // No event name specified\n        public sendMessage(@CurrentSocket() socket: Socket): EmitterOptions {\n            const isAllowedToSend = isUserAllowedToSendMessage(socket)\n            return new EmitterOption({\n                to: \"room1\",\n                message: \"newMessage\", // Event name set here\n                data: { message: \"Hello, world!\" },\n                disableEmit: !isAllowedToSend,\n            })\n        }\n        ```\n\n        The above code will emit a `newMessage` event to the `room1` room. The event will only be emitted if the `isUserAllowedToSendMessage` function returns `true`.\n.\n\n    - If you return an array of `EmitterOption` objects, an event will be emitted for each `EmitterOption` items.\n\n        ```typescript\n        @SocketOn(\"multiple-events\")\n        @ServerEmitter()\n        onMultipleEvents(@CurrentSocket() socket: Socket) {\n            socket.join(\"multiple-events\")\n            const events: EmitterOption[] = [\n                new EmitterOption({\n                    to: socket.id,\n                    message: \"event-1\",\n                    data: {\n                        message: \"This is event 1\"\n                    }\n                }),\n                new EmitterOption({\n                    to: \"multiple-events\",\n                    message: \"event-2\",\n                    data: {\n                        message: \"This is events-2\"\n                    }\n                }),\n            ]\n\n            return events\n        }\n        ```\n\n        The above code will emit two events: `event-1` and `event-2`.\n        `event-1` will be emitted to the client with the `id` of the socket and `event-2` will be emitted to the `multiple-events` room.\n\n    **Emitter options**\n    The `EmitterOption` object has the following properties:\n\n    | Property | Type | Required | Description |\n    |----------|------|----------|-------------|\n    | `to`     | string | No (if the decorator provides this) | The target to emit the event to. |\n    | `message`| string | No (if the decorator provides this) | The event name to emit. |\n    | `data`   | any    | Yes | The data to emit. |\n    | `disableEmit` | boolean | No | If `true`, the event will not be emitted. |\n\n3. **Emitting falsy value**\n    If the method returns a falsy value (false, null undefined, 0, ...), the event will not be emitted.\n\n#### Examples\n\n---\n\n##### @ServerEmitter(event?: string, to?: string)\n\n**Equivalent in basic Socket.io:** `io.emit(event, data)` or `io.to(to).emit(event, data)`\n\nEmits events to all connected clients or to a specific room if the `to` parameter is provided.\n\n**Usages** :\n\n```typescript\n@ServerEmitter(\"newMessage\", \"room1\")\npublic sendMessage() {\n    return { message: \"Hello, world!\" }\n}\n```\n\n```typescript\n@ServerEmitter()\npublic sendMessage() {\n    return new EmitterOption({\n        to: \"room1\",\n        message: \"newMessage\",\n        data: { message: \"Hello, world!\" },\n    })\n}\n```\n\n---\n\n##### @SocketEmitter(event?: string)\n\n**Equivalent in basic Socket.io:** `socket.emit(event, data)`\n\nEmits event to the current client.\n\n> [!WARNING]\n> If the `event` parameter is not provided in decorator, it must be provided in the `EmitterOption` object.\n\n> [!WARNING]\n> This decorator must be used with a listener decorator (ServerOn or SocketOn) to work.\n\n**Usage** :\n\n```typescript\n@SocketOn(\"join-room\")\n@SocketEmitter(\"room-joined\")\npublic joinRoom(@CurrentSocket() socket: Socket) {\n    socket.join(\"myRoom\")\n    return {\n        info: `You have successfully joined room myRoom`,\n        roomId: \"myRoom\"\n    }\n}\n```\n\n```typescript\n@SocketOn(\"join-room\")\n@SocketEmitter()\npublic joinRoom(@CurrentSocket() socket: Socket) {\n    socket.join(\"myRoom\")\n    return new EmitterOption({\n        to: socket.id,\n        message: \"room-joined\",\n        data: {\n            info: `You have successfully joined room myRoom`,\n            roomId: \"myRoom\"\n        },\n    })\n}\n```\n\n### Room decorators\n\nThe following decorators can be used to manage socket.io rooms:\n\n| Decorator | Description | Equivalent in Basic Socket.io |\n|-----------|-------------|-------------------------------|\n| `@OnRoomCreated(roomName?: string)` | Listens for room creation events. | `namespace.adapter.on(\"create-room\", callback)` |\n| `@OnRoomDeleted(roomName?: string)` | Listens for room deletion events. | `namespace.adapter.on(\"delete-room\", callback)` |\n| `@OnRoomJoined(roomName?: string)` | Listens for room joined events. | `namespace.adapter.on(\"join-room\", callback)` |\n| `@OnRoomLeft(roomName?: string)` | Listens for room left events. | `namespace.adapter.on(\"leave-room\", callback)` |\n| `@SocketRoom(roomName?: string)` | Injects a specific room or all rooms the current socket is in. | / |\n\n> [!NOTE]\n> Socket ID room events are automatically filtered out and will not trigger the listener.\n\nTo learn more about room management, see [UseRoomStore hook](#useroomstore-hook) and [UseRoom hook](#useroom-hook).\n\n#### Room listeners setup\n\nClasses using these decorators **must be registered in the `useSocketIoDecorator` config:**\n\n```typescript\nclass ChatRoomEvents {\n    @OnRoomCreated()\n    public onRoomCreated(roomName: string) {\n        console.log(`Room ${roomName} has been created`)\n    }\n}\n\nuseSocketIoDecorator({\n    roomEventListeners: [ChatRoomEvents], // Or [path/to/directory/*.js]\n    ...\n})\n```\n\n#### Wildcard patterns\n\nAll room decorators support wildcard patterns using `*` to match dynamic room names. This allows you to listen for events on multiple rooms with a single handler.\n\n```typescript\nclass ChatRoomEvents {\n    // Listens to all chat rooms (chat-1, chat-2, chat-general, etc.)\n    @OnRoomCreated(\"chat-*\")\n    public onChatRoomCreated(roomName: string) {\n        console.log(`Chat room ${roomName} was created`)\n    }\n\n    // Listens to all notification rooms (user-notifications, admin-notifications, etc.)\n    @OnRoomJoined(\"*-notifications\")\n    public onNotificationRoomJoined(roomName: string, socket: Socket) {\n        console.log(`Socket ${socket.id} joined notification room ${roomName}`)\n    }\n\n    // Listens to all game lobbies (game-1-lobby, game-tournament-lobby, etc.)\n    @OnRoomLeft(\"game-*-lobby\")\n    public onGameLobbyLeft(roomName: string, socket: Socket) {\n        console.log(`Socket ${socket.id} left game lobby ${roomName}`)\n    }\n}\n```\n\n#### Namespace support\n\nAll room decorators support namespace. You can specify the namespace to listen for events on a specific namespace.\n\n```typescript\n// This will trigger only in the /my-namespace namespace\n@OnRoomCreated(\"lobby\", { namespace: \"/my-namespace\" })\npublic onLobbyRoomCreated(roomName: string) {\n    console.log(`Room ${roomName} has been created`)\n}\n```\n\n#### Examples\n\n---\n\n##### @OnRoomCreated(roomName?: string)\n\n**Equivalent in basic Socket.io:** `namespace.adapter.on(\"create-room\", callback)`\n\nListens for room creation events. If no room name is provided, the listener will be triggered for any room.\n\nThis decorator requires to be used on a handler with the signature:\n\n```typescript\n(roomName: string) => any\n```\n\n**Usage** :\n\n```typescript\n// Trigger only for the lobby room creation event\n@OnRoomCreated(\"lobby\")\npublic onLobbyRoomCreated(roomName: string) {\n    console.log(`Room ${roomName} has been created`)\n}\n```\n\n```typescript\n// Trigger for any room creation event\n@OnRoomCreated()\npublic onAnyRoomCreated(roomName: string) {\n    console.log(`Room ${roomName} has been created`)\n}\n```\n\n---\n\n##### @OnRoomDeleted(roomName?: string)\n\n**Equivalent in basic Socket.io:** `namespace.adapter.on(\"delete-room\", callback)`\n\nListens for room deletion events. If no room name is provided, the listener will be triggered for any room.\n\nThis decorator requires to be used on a handler with the signature:\n\n```typescript\n(roomName: string) => any\n```\n\n**Usage** :\n\n```typescript\n// Trigger only for the lobby room deletion event\n@OnRoomDeleted(\"lobby\")\npublic onLobbyRoomDeleted(roomName: string) {\n    console.log(`Room ${roomName} has been deleted`)\n}\n```\n\n```typescript\n// Trigger for any room deletion event\n@OnRoomDeleted()\npublic onAnyRoomDeleted(roomName: string) {\n    console.log(`Room ${roomName} has been deleted`)\n}\n```\n\n---\n\n##### @OnRoomJoined(roomName?: string)\n\n**Equivalent in basic Socket.io:** `namespace.adapter.on(\"join-room\", callback)`\n\nListens for specific room joined events. If no room name is provided, the listener will be triggered for any room.\n\nThis decorator requires to be used on a handler with the signature:\n\n```typescript\n(roomName: string, socket: Socket) => any\n```\n\n**Usage** :\n\n```typescript\n// Trigger only for the lobby room joined event\n@OnRoomJoined(\"lobby\")\npublic onLobbyRoomJoined(roomName: string, socket: Socket) {\n    console.log(`Socket ${socket.id} joined room ${roomName}`)\n}\n```\n\n```typescript\n// Trigger for any room joined event\n@OnRoomJoined()\npublic onAnyRoomJoined(roomName: string, socket: Socket) {\n    console.log(`Socket ${socket.id} joined room ${roomName}`)\n}\n```\n\n---\n\n##### @OnRoomLeft(roomName?: string)\n\n**Equivalent in basic Socket.io:** `namespace.adapter.on(\"leave-room\", callback)`\n\nListens for specific room left events. If no room name is provided, the listener will be triggered for any room.\n\nThis decorator requires to be used on a handler with the signature:\n\n```typescript\n(roomName: string, socket: Socket) => any\n```\n\n**Usage** :\n\n```typescript\n// Trigger only for the lobby room left event\n@OnRoomLeft(\"lobby\")\npublic onLobbyRoomLeft(roomName: string, socket: Socket) {\n    console.log(`Socket ${socket.id} left room ${roomName}`)\n}\n```\n\n```typescript\n// Trigger for any room left event\n@OnRoomLeft()\npublic onAnyRoomLeft(roomName: string, socket: Socket) {\n    console.log(`Socket ${socket.id} left room ${roomName}`)\n}\n```\n\n---\n\n##### @SocketRoom(roomName?: string)\n\nInjects a specific room or all rooms the current socket is in.\n\n**Usage** :\n\n1. **Inject all rooms the socket is in**\n\n   When used without a parameter, `@SocketRoom()` injects an array of all rooms the current socket is in.\n\n   ```typescript\n   @SocketOn(\"message\")\n   public onMessage(@SocketRoom() rooms: ChatRoom[]) {\n       console.log(`Socket is in ${rooms.length} rooms`)\n   }\n   ```\n\n2. **Inject a specific room**\n\n   When used with a room name parameter, `@SocketRoom(\"roomName\")` injects the specific room object if the socket is in that room, otherwise it injects `null`.\n\n   ```typescript\n   @SocketOn(\"message\")\n   public onMessage(@SocketRoom(\"roomName\") room: ChatRoom | null) {\n       if (room) {\n           console.log(\"Socket is in room:\", room.name)\n       } else {\n           console.log(\"Socket is not in the room\")\n       }\n   }\n   ```\n\n3. Handler with required room\n\n    If you want to ensure that the socket is in a specific room before handling the event, you can use the `required` option. If the socket is not in the specified room, an `SiodRequiredRoomError` will be thrown.\n\n    ```typescript\n    @SocketOn(\"message\")\n    public onMessage(@SocketRoom(\"roomName\", { required: true }) room: ChatRoom) {\n        console.log(\"For sure, socket is in the room:\", room.name)\n    }\n    ```\n\n### Parameter injection decorators\n\nThe following decorators can be used to inject parameters into the event handler methods:\n\n| Decorator | Description                                              |\n|-----------|----------------------------------------------------------|\n| `@CurrentSocket()` | Injects the current socket instance that is handling the message. |\n| `@Data(dataIndex?: number)` | Injects the data sent by the client                 |\n| `@EventName()` | Injects the name of the event message that triggered the handler. |\n| `@CurrentUser()` | Injects the current user object. |\n| `@SocketData(dataKey?: string)` | Injects socket data value (socket.data[dataKey]). |\n\n#### Examples\n\n---\n\n##### @CurrentSocket()\n\nInjects the current socket instance that is handling the message.\n\n**Usage** :\n\n```typescript\n@SocketOn(\"joinGame\")\npublic onJoinGame(@CurrentSocket() socket: Socket) {\n    socket.join(\"gameRoom\")\n}\n```\n\n---\n\n##### @Data(dataIndex?: number)\n\nInjects the data sent by the client.\n\n**Usage** :\n\n```typescript\n@SocketOn(\"message\")\npublic onMessage(@Data() data: MessageData) {\n    console.log(\"Message received:\", data.message)\n}\n```\n\nYou can also specify the index of the data in the socket message if you want to inject a specific part of the data:\n\n```typescript\n@SocketOn(\"chat-message\")\npublic onChatMessage(@Data(0) message: string, @Data(1) roomId: string) {\n    console.log(`Received message: \"${message}\" for room: ${roomId}`)\n}\n```\n\nThis is useful when the client sends multiple arguments:\n\n```typescript\n// Client side\nsocket.emit(\"chat-message\", \"Hello everyone!\", \"gaming-lobby\")\n```\n\n---\n\n##### @EventName()\n\nInjects the name of the event message that triggered the handler.\n\n**Usage** :\n\n```typescript\n@SocketOn(\"user-joined\")\n@SocketOn(\"user-left\")\npublic trackUserActivity(@EventName() event: string) {\n    const action = event === \"user-joined\" ? \"joined the chat\" : \"left the chat\" \n\n    console.log(`User ${action}`)\n}\n```\n\n---\n\n##### @CurrentUser()\n\nInjects the current user object into an event handler parameter.\n\n**Usage** :\n\n1. **Create the `currentUserProvider`**\n\n   In the `app.ts` file, create a function that returns the current user object:\n\n    ```typescript\n    useSocketIoDecorator({\n        ...,\n        currentUserProvider: async (socket: Socket) => {\n            const token = socket.handshake.auth.token\n            return await userServices.getUserByToken(token)\n        },\n    })\n    ```\n\n2. **Use the `CurrentUser` decoratoar**\n\n   In the event handler, use the `CurrentUser` decorator to get the current user object:\n\n    ```typescript\n    import { CurrentUser, SocketOn } from \"@admandev/socketio-decorator\"\n\n    @SocketOn(\"message\")\n    public onMessage(@CurrentUser() user: User) {\n        console.log(\"Message received from user:\", user.name)\n    }\n    ```\n\n---\n\n##### @SocketData(dataKey?: string)\n\n**Equivalent in basic Socket.io:** `socket.data[dataKey]`\n\nInjects a socket data attribute value into an event handler parameter. SocketData decorator allow you to store custom data on a per-socket basis, which persists for the lifetime of the socket connection.\n\n**Usage** :\n\n1. **Inject the entire SocketDataStore**\n\n   When used without a parameter, `@SocketData()` injects a `SocketDataStore` instance that provides methods to manage socket data attribute:\n\n    ```typescript\n    @SocketOn(\"save-user-preferences\")\n    public savePreferences(@SocketData() dataStore: SocketDataStore) {\n        // Store user preferences on this socket\n        dataStore.setData(\"theme\", \"dark\")\n        dataStore.setData(\"language\", \"fr\")\n        \n        console.log(\"Preferences saved for this socket\")\n    }\n\n    @SocketOn(\"get-user-preferences\")\n    @SocketEmitter(\"preferences\")\n    public getPreferences(@SocketData() dataStore: SocketDataStore) {\n        return {\n            theme: dataStore.getData(\"theme\"),\n            language: dataStore.getData(\"language\")\n        }\n    }\n    ```\n\n    **SocketDataStore API**\n\n    The `SocketDataStore` class provides the following methods:\n\n    | Method | Parameters | Returns | Description |\n    |--------|------------|---------|-------------|\n    | `getData(key)` | `key: string` | `any \\| null` | Retrieves the value of a socket data attribute. Returns `null` if the key doesn't exist. |\n    | `setData(key, value)` | `key: string, value: any` | `void` | Sets a socket data with the specified key and value. |\n    | `removeData(key)` | `key: string` | `void` | Removes a socket data attribute by key. |\n    | `hasData(key)` | `key: string` | `boolean` | Checks if a socket data exists for the specified key. |\n\n    **Type Safety with Generics**\n\n    You can type the `SocketDataStore` methods using generics by defining an interface that describes your socket data structure:\n\n    ```typescript\n    // Define your socket data type\n    interface MyStoreType {\n        userId: number\n        theme: 'light' | 'dark'\n        language: string\n    }\n\n    @SocketOn(\"example\")\n    public example(@SocketData() dataStore: SocketDataStore<MyStoreType>) {\n        // ❌ Type error - \"unknownKey\" is not a valid key of MyStoreType\n        dataStore.getData(\"unknownKey\")\n        \n        // ✅ Correct - \"userId\" is a valid key\n        dataStore.getData(\"userId\") // Returns: number | null\n        \n        // ❌ Type error - Argument of type 'string' is not assignable to parameter of type 'number'\n        dataStore.setData(\"userId\", \"not-a-number\")\n        \n        // ✅ Correct - proper type\n        dataStore.setData(\"userId\", 123) // ✅ Works correctly\n        dataStore.setData(\"theme\", \"dark\") // ✅ Only 'light' | 'dark' allowed\n        dataStore.setData(\"language\", \"en\") // ✅ String type as expected\n    }\n    ```\n\n    With typed `SocketDataStore<MyStoreType>`, you get:\n    - **Autocompletion**: IDE suggests only valid keys from your interface\n    - **Type checking**: Values must match the expected types\n    - **Compile-time errors**: Catch mistakes before runtime\n\n2. **Inject a specific data attribute value**\n\n   When used with a key parameter, `@SocketData(\"key\")` directly injects the value of that specific data attribute:\n\n    ```typescript\n    @SocketOn(\"update-theme\")\n    public updateTheme(@SocketData(\"theme\") currentTheme: string) {\n        console.log(\"Current theme:\", currentTheme) // Will be null if not set\n    }\n    ```\n\n    **Important notes**\n\n    - Socket data attributes are stored per socket connection and persist for the lifetime of that connection\n    - When a socket disconnects, all associated data attributes are automatically cleared\n    - This is built on top of Socket.IO's native `socket.data` property\n    - Data attributes are not shared between different socket connections, even for the same user\n\n### Other decorators\n\n| Decorator | Description                                              |\n|-------------------------|----------------------------------------------------------|\n| `@UseSocketMiddleware(...ISocketMiddleware[])` | Applies one or more socket middleware to the event handler or controller class. |\n| `@SocketNamespace(namespace: string)` | Defines a namespace for a socket controller |\n| `@MiddlewareOption(options: MiddlewareOptionType)` | Applies options to a middleware. |\n| `@Throttle(limit: number, timeWindowMs: number)` | Applies rate limiting to a controller or event handler. ( [See Rate Limiting](#rate-limiting)) |\n\n#### Examples\n\n---\n\n##### @UseSocketMiddleware(...ISocketMiddleware[])\n\nApplies one or more socket middlewares to the event handler or controller class.\n\n**Usage** :\n\nFirst create a [socket middleware](#socket-middleware) before choosing one of next steps.\n\n1. **Use it on an event handler method**:\n\n    ```typescript\n    @SocketOn(\"message\")\n    @UseSocketMiddleware(MyMiddleware1, MyMiddleware2)\n    public onMessage() {\n        console.log(\"Message received\")\n    }\n    ```\n\n    In this case, the `MyMiddleware1` and `MyMiddleware2` will be called before the `onMessage` event handler is executed.\n\n2. **Use it on a controller class**:\n\n    ```typescript\n    @UseSocketMiddleware(MyMiddleware)\n    export class MyController {\n        @SocketOn(\"event1\")\n        public onEvent1() {\n            console.log(\"Event 1 received\")\n        }\n\n        @SocketOn(\"event2\")\n        public onEvent2() {\n            console.log(\"Event 2 received\")\n        }\n    }\n    ```\n\n    In this case, the `MyMiddleware` will be applied to all event handlers in the `MyController` class.\n\n    > [!NOTE]\n    > This decorator is applied to socket listener handlers only (`@SocketOn`, `@SocketOnce`, `@SocketOnAny`, ...).\n    > It does not apply to server listeners (`@ServerOn`) or emitters.\n\n---\n\n##### @SocketNamespace(namespace: string)\n\n**Equivalent in basic Socket.io:** `io.of(namespace)`\n\nDefines a namespace for a socket controller. All socket events in this controller will be handled within this namespace. Learn more about [Socket.IO namespaces](https://socket.io/docs/v4/namespaces/).\n\n**Usage** :\n\n```typescript\n@SocketNamespace(\"/my-namespace\")\nexport class MyNamespaceController {\n    @SocketOn(\"message\")\n    public onMessage(@Data() data: MessageRequest) {\n        console.log(\"Message in my-namespace\", data.message)\n    }\n}\n```\n\n> [!WARNING]\n> The namespace must start with \"/\" or it will throw a `SiodDecoratorError`.\n\n---\n\n##### @MiddlewareOption(options: MiddlewareOptionType)\n\nApplies options to a middleware.\n\n**Middleware options**\n\n| Property | Type | Description |\n|----------|------|-------------|\n| [`namespace`](#namespace-middleware) | string | The namespace to which the middleware should be applied. |\n\n## Middlewares\n\nYou can use middlewares to execute code before  an event is handled. Middlewares can be used to perform tasks such as authentication or logging.\n\n### Server Middleware\n\nA Server Middleware is executed for each incoming connection.\n\n1. **Create a Middleware**\n\n    ```typescript\n    export class MyServerMiddleware implements IServerMiddleware {        \n        use(socket: Socket, next: (err?: unknown) => void) {\n            console.log(\"You can perform tasks here before the event is handled\")\n            next()\n        }\n    }\n    ```\n\n    The `use` method is called before any event is handled. You can perform any tasks here and call `next()` to proceed with the event handling.\n\n2. **Register the Middleware**\n\n   Update the `app.ts` file to register the middleware:\n\n    ```typescript\n    useSocketIoDecorator({\n        ...,\n        serverMiddlewares: [MyServerMiddleware], // Add the middleware here\n    })\n    ```\n\n### Socket Middleware\n\nA Socket Middleware is like Server Middleware but it is called for each incoming packet.\n\n1. **Create a Middleware**\n\n    ```typescript\n    import { ISocketMiddleware } from \"@admandev/socketio-decorator\"\n    import { Event, Socket } from \"socket.io\"\n\n    export class MySocketMiddleware implements ISocketMiddleware {\n        use(socket: Socket, [event, ...args]: Event, next: (err?: Error) => void): void {\n            console.log(`MySocketMiddleware triggered from ${event} event`)\n            next()\n        }\n    }\n    ```\n\n2. **Use the Middleware**\n\n    Now you can use the socket middleware in 2 ways:\n\n    - **Globally**: This will apply the middleware to all events in your application.\n    Update the `app.ts` file to register the middleware:\n\n        ```typescript\n        useSocketIoDecorator({\n            ...,\n            socketMiddlewares: [MySocketMiddleware], // Add the middleware here\n        })\n        ```\n\n    - **Per event**: You can also use the middleware for a specific event by using the [@UseSocketMiddleware decorator](#other-decorators).\n\n### Namespace middleware\n\nYou can scope a middleware to a specific namespace using the `@MiddlewareOption` decorator. This is particularly useful when using the `@SocketNamespace` decorator to organize your controllers by namespaces.\n\n```typescript\n@MiddlewareOption({ namespace: \"/orders\" })\nclass OrderMiddleware implements IServerMiddleware {\n    public use(socket: Socket, next: (err?: unknown) => void) {\n        // This middleware will only be executed for connections to the \"/orders\" namespace\n        console.log(\"New connection to /orders namespace\")\n        next()\n    }\n}\n```\n\nIn this example:\n\n- The `OrderMiddleware` will only be executed for connections to the \"/orders\" namespace\n- Other namespaces (or the default namespace) will not trigger this middleware\n- This works for both Server and Socket middlewares (globally only)\n\n### Error handling middleware\n\nYou can create a middleware to handle errors that occur during event handling and above middlewares.\n\n1. **Create an Error Middleware**\n\n    ```typescript\n    import { IErrorMiddleware } from \"@admandev/socketio-decorator\"\n    import { Socket } from \"socket.io\"\n\n    export class MyErrorMiddleware implements IErrorMiddleware{\n        handleError (error: any, socket?: Socket) {\n            // Handle the error here\n            console.log('Error middleware: ', error)\n        }\n    }\n    ```\n\n2. **Register the Middleware**\n\n    Update the `app.ts` file to register the middleware:\n\n     ```typescript\n     useSocketIoDecorator({\n          ...,\n          errorMiddleware: MyErrorMiddleware, // Add the unique error middleware here\n     })\n     ```\n\n## Rate Limiting\n\nYou can use rate limiting to control how many requests a client can make within a specific time window. This helps protect your application from abuse and ensures fair resource usage.\n\n### Global Rate Limiting\n\nTo enable rate limiting globally for all controllers:\n\n```typescript\nuseSocketIoDecorator({\n    ...,\n    throttleConfig: {\n        rateLimitConfig: {\n            limit: 100,        // Maximum number of requests\n            timeWindowMs: 60000 // Time window in milliseconds (1 minute)\n        },\n        // Optional: cleanup interval for expired throttle data (default: 1 hour)\n        cleanupIntervalMs: 3600000,\n        // Optional: custom storage implementation\n        store: InMemoryThrottleStorage // By default, uses in-memory storage\n        getUserIdentifier: (socket) => {\n            // Return any unique identifier for the user\n            return \"By default, it uses the socket id\"\n        }\n    }\n})\n```\n\n### Class-Level Rate Limiting\n\nApply rate limiting to all socket events in a controller:\n\n```typescript\n@Throttle(10, 60000) // Max 10 requests per minute\nclass UserController {\n    @SocketOn(\"update-profile\")\n    public updateProfile() { }\n\n    @SocketOn(\"change-settings\")\n    public changeSettings() { }\n\n    @SocketOn(\"upload-avatar\")\n    public uploadAvatar() { }\n}\n```\n\n### Method-Level Rate Limiting\n\nUse the `@Throttle` decorator to apply rate limiting to specific methods:\n\n```typescript\nclass ChatController {\n    @SocketOn(\"message\")\n    @Throttle(5, 1000) // Max 5 requests per second\n    public sendMessage(@Data() message: string) {\n        console.log(\"Message received:\", message)\n    }\n}\n```\n\n### Priority and Scope\n\nRate limiting follows a hierarchy where more specific configurations override broader ones:\n\n1. **Method-level** (Highest Priority): `@Throttle` decorator on individual methods\n2. **Class-level** (Medium Priority): `@Throttle` decorator on controller classes  \n3. **Global** (Lowest Priority): `throttleConfig` in `useSocketIoDecorator`\n\n```typescript\n// Global configuration (lowest priority)\nuseSocketIoDecorator({\n    throttleConfig: {\n        rateLimitConfig: { limit: 100, timeWindowMs: 60000 }\n    }\n})\n\n// Class-level configuration (medium priority)\n@Throttle(20, 60000) // Overrides global config for this controller\nclass ChatController {\n    \n    @SocketOn(\"message\")\n    public sendMessage() {\n        // Uses class-level: 20 requests per minute\n    }\n\n    @SocketOn(\"upload\")\n    @Throttle(5, 300000) // Method-level (highest priority)\n    public uploadFile() {\n        // Uses method-level: 5 requests per 5 minutes\n        // Overrides both class and global configs\n    }\n}\n```\n\n### Custom User Identification\n\nBy default, rate limiting uses the socket ID to identify clients. However, since socket IDs change when users reconnect, you might want to use a more persistent identifier (e.g., user ID, session ID). You can configure this through the `getUserIdentifier` option:\n\n```typescript\nuseSocketIoDecorator({\n    throttleConfig: {\n       ...,\n        // Custom user identification function\n        getUserIdentifier: (socket) => {\n            return \"Return any unique identifier for the user\"\n        }\n    }\n})\n```\n\nThe `getUserIdentifier` function:\n\n- Receives the socket instance as parameter\n- Should return a string or Promise\n\n### Error Handling\n\nRate limit errors are thrown as `SiodThrottleError`. Handle them using an [error middleware](#error-handling-middleware):\n\n```typescript\nclass ErrorMiddleware implements IErrorMiddleware {\n    handleError(error: unknown) {\n        if (error instanceof SiodThrottleError) {\n            console.error(\"Rate limit exceeded. Retry in:\", error.remainingTime, \"ms\")\n        }\n    }\n}\n```\n\n### Important Notes\n\n- Rate limits are applied per client ID\n- Each event has its own independent rate limit counter\n- Class-level rate limits can be overridden by method-level decorators\n- Global configuration applies to all controllers without explicit `@Throttle` decorators\n- Rate limit data is automatically cleaned up based on `cleanupIntervalMs`\n\n### Custom Storage Implementation\n\nBy default, rate limiting data is stored in memory using `InMemoryThrottleStorage`. However, you can implement your own storage solution (e.g., Redis, Database) by implementing the `IThrottleStorage` interface.\n\nExample implementation using Redis:\n\n```typescript\nclass RedisThrottleStorage implements IThrottleStorage {\n    private static readonly redis = new Redis(\"You url\")\n    private readonly prefix = \"throttle\"\n\n    // Get the throttle entry for a specific client and event\n    public async get(clientId: string, event: string): Promise<ThrottleEntry | undefined> {\n        try {\n            const key = this.getKey(clientId, event)\n            const data = await RedisThrottleStore.redis.get(key)\n\n            if (!data) {\n                return undefined\n            }\n\n            return JSON.parse(data) as ThrottleEntry\n        } catch (error) {\n            console.error(\"Redis get error:\", error)\n            return undefined\n        }\n    }\n\n    // Set / update the throttle entry for a specific client and event\n    public async set(clientId: string, event: string, entry: ThrottleEntry): Promise<void> {\n        try {\n            const key = this.getKey(clientId, event)\n            const ttl = Math.max(0, entry.resetTime - Date.now()) // in ms\n\n            // Save the entry with automatic expiration\n            if (ttl > 0) {\n                await RedisThrottleStore.redis.set(key, JSON.stringify(entry), \"PX\", ttl)\n            }\n        } catch (error) {\n            console.error(\"Redis set error:\", error)\n        }\n    }\n\n    // Cleanup method to remove expired entries\n    public async cleanup(): Promise<void> {\n        // Redis handles expiration automatically with TTL → nothing to do here.\n        // But we can flush if needed (optional)\n        // await this.redis.flushall()\n        return Promise.resolve()\n    }\n\n    private getKey(clientId: string, event: string): string {\n        return `${this.prefix}:${clientId}:${event}`\n    }\n}\n```\n\nThen configure it in your application:\n\n```typescript\nuseSocketIoDecorator({\n    ...,\n    throttleConfig: {\n        store: RedisThrottleStorage // Your custom storage class\n    }\n})\n```\n\n## Data validation\n\nYou can use the `class-validator` library to validate the data received from the client and be sure that required fields are present and have the correct type.\n\n### Setup\n\n1. **Install the following libraries**\n\n    ```bash\n    npm install class-validator class-transformer reflect-metadata\n    ```\n\n2. **Import the `reflect-metadata` library**\n  \n    Add the following line at the top of your `app.ts` file:\n\n    ```typescript\n    import \"reflect-metadata\"\n     ```\n\n3. **Be sure to enable the `emitDecoratorMetadata` option in your `tsconfig.json` file**\n\n    ```json\n    {\n        \"compilerOptions\": {\n            \"emitDecoratorMetadata\": true\n        }\n    }\n    ```\n\n4. **Enable the validation option in the `useSocketIoDecorator` config**\n\n    ```typescript\n    useSocketIoDecorator({\n        ...,\n        dataValidationEnabled: true\n    })\n    ```\n\n5. **Create and use a class with validation rules**\n\n    ```typescript\n    import { IsString } from \"class-validator\"\n\n    export class MessageData {\n        @IsString()\n        @IsNotEmpty()\n        message: string\n    }\n    ```\n\n    Use the class in the event handler:\n\n    ```typescript\n    @SocketOn(\"message\")\n    public onMessage(@Data() data: MessageData) {\n        console.log(\"Message received:\", data.message)\n    }\n    ```\n\n    If the data does not match the validation rules, an error will be thrown before the event handler is called.\n\n> [!WARNING]\n> We recommend using the [error handling middleware](#error-handling-middleware) to catch and handle validation errors.\n\n### Disable validation for a specific handler\n\nYou can disable validation for a specific handler by setting the `disableDataValidation` option to `true`:\n\n```typescript\n@SocketOn(\"message\", { disableDataValidation: true })\npublic onMessage(@Data() data: MessageData) {\n    ...\n}\n```\n\n#### Default enabled validation\n\nData validation works only on socket listeners (not server listeners or emitters).\n\nHere is the default value for the `disableDataValidation` option:\n\n- `@SocketOn` - `false`\n- `@SocketOnce` - `false`\n- `@SocketOnAny` - `true` - If you want to validate the data, you need to set the option to `false`\n- `@SocketOnAnyOutgoing` - `true` because it is not an incoming event from the client\n\n### Learn more about data validation\n\nFor more information on data validation, see the [class-validator documentation](https://github.com/typestack/class-validator).\n\n## Application Events\n\nApplication events provide an internal event bus for cross-service / class communication within your server. Unlike Socket.IO events that communicate over the network, application events are server-side only and enable decoupled communication between different parts of your application.\n\n### Why use Application Events?\n\nApplication events are particularly useful for:\n\n- **Cross-Service communication**: Enable different services to communicate without direct references (e.g., OrderController notifying InventoryService and NotificationService)\n\n- **Decoupled architecture**: Create loosely coupled components that can interact through events\n\n- **Event-driven actions**: Trigger application-wide actions when Socket.IO events occur (e.g., emit an app event after processing a socket message)\n\n### How It Works\n\nThe Application Events system uses two main decorators:\n\n| Decorator  | Description |\n|-----------|-------------|\n| `@AppOn(eventName: string)` | Registers a method as an application event listener |\n| `@AppEmit(eventName: string)` | Emits an application event when a method executes |\n\nWhen an event is emitted, all registered listeners for that event are called asynchronously with an `AppEventContext` object containing the event details.\n\n**How to use them?**\n\n#### `@AppOn(eventName: string)`\n\n**Description**: Registers a method as an application event listener\n\n**Method signature required**: `(context: AppEventContext) => unknown | Promise<unknown>`\n\n**Usage**:\n\n1. **Create a class with the event listener**\n\n    ```typescript\n    type OrderData = {\n        orderId: string\n        items: OrderItem[]\n        total: number\n        createdAt: Date\n    }\n\n    // App event listener that responds to order creation\n    class InventoryService {\n        @AppOn(\"order-created\")\n        public updateInventory(context: AppEventContext) {\n            const order = context.data as OrderData\n                    \n            // Inventory update logic\n        }\n    }\n\n    // Another listener for the same event\n    class NotificationService {\n        @AppOn(\"order-created\")\n        public notifyWarehouse(context: AppEventContext) {\n            const order = context.data as OrderData\n\n            // Available when the event is triggered from a socket handler\n            const socket = context.ioContext?.currentSocket\n            \n            // Warehouse notification logic\n        }\n    }\n    ```\n\n2. **Register them in the `useSocketIoDecorator` config**\n\n    ```typescript\n    useSocketIoDecorator({\n        ...,\n        appEventListeners: [InventoryService, NotificationService] // Or [path/to/directory/*.js]\n    })\n    ```\n\n**Key features**:\n\n- Multiple listeners can subscribe to the same event\n- Listeners execute independently and asynchronously\n- Method receives an `AppEventContext` object with event details\n\n---\n\n#### `@AppEmit(eventName: string)`\n\n**Description**: Emits an application event when the decorated method executes\n\n**Usage**:\n\n```typescript\n// Emits from a Socket.IO listener\nclass OrderController {\n    @SocketOn(\"create-order\")\n    @AppEmit(\"order-created\")\n    public createOrder(@Data() orderData: any) {\n        console.log(\"Creating order from socket event\")\n        \n        // Order creation logic\n        const order: OrderData = {\n            orderId: \"ORD-123\",\n            items: orderData.items,\n            total: orderData.total,\n            createdAt: new Date()\n        }\n        \n        // This return value becomes the data available in listeners context\n        return order\n    }\n}\n\n// Emits from a simple class method\nclass OrderService {\n    @AppEmit(\"order-created\")\n    public createOrder(orderData: any) {\n        console.log(\"Creating order from service\")\n        \n        // Order creation logic\n        const order = ...\n        \n        // This return value becomes the data available in listeners context\n        return order\n    }\n}\n```\n\nNote: No need to register the event emitters in the `useSocketIoDecorator` config.\n\n**Key features**:\n\n- Method's return value becomes the event data in listeners context\n- Can be combined with Socket.IO decorators\n- Can be used with any class method\n- Event is emitted to all registered listeners\n\n### AppEventContext Interface\n\nThe `AppEventContext` object passed to event listeners contains:\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `eventName` | `string` | The name of the application event that triggered the listener |\n| `data` | `unknown` | The data associated with the event (return value from `@AppEmit` method) |\n| `ioContext` | `object` (optional) | Socket.IO context when event is triggered from a socket handler |\n\n**`ioContext` properties** (when available):\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `currentSocket` | `Socket \\| null` | The current Socket.IO socket instance |\n| `eventName` | `string` | The original Socket.IO event name |\n| `eventData` | `unknown[]` | The original Socket.IO event arguments |\n\n### Use application event bus dynamically\n\nYou can also use the application event bus dynamically by using the `useAppEventBus` hook.\nSee [UseAppEventBus hook](#useappeventbus-hook)\n\n### Important Notes\n\n- **Server-side only**: Application Events are internal to your server and don't communicate over the network\n\n- **Asynchronous execution**: Listeners execute independently and asynchronously\n\n- **No execution order guarantee**: The order in which multiple listeners execute is not guaranteed\n\n- **Error isolation**: Errors in one listener don't affect the emitter or other listeners\n\n- **Error handling**: ErrorMiddleware is not applied to app event listeners - you must handle errors within your listener methods\n\n## Hooks\n\nHooks in Socketio Decorator are functions that provides some services.\n\n### UseAppEventBus hook\n\nThe `useAppEventBus` hook allows you to use the application event bus dynamically in your code.\n\nThis hook provides the `ApplicationEventBus` instance that you can use to listen and emit events without using the `@AppOn` and `@AppEmit` decorators.\n\n```typescript\nimport { useAppEventBus, ApplicationEventBus } from \"@admandev/socketio-decorator\"\n\nconst appEventBus: ApplicationEventBus = useAppEventBus()\n\nappEventBus.on({\n    eventName: \"new-message\",\n    targetClass: NotificationService,\n    methodName: \"sendMessage\"\n})\n\nappEventBus.emit({\n    eventName: \"new-message\",\n    data: \"Hello, world!\"\n})\n```\n\n#### `ApplicationEventBus` API\n\nThe `ApplicationEventBus` instance provides the following methods:\n\n| Method | Description |\n|--------|---------|\n| `on(listenerInfo: ListenerRegistration<TTarget>)` | Registers a listener for a specific event |\n| `emit(context: AppEventContext)` | Emits an event to all registered listeners |\n| `off(listenerInfo: ListenerRegistration<TTarget>)` | Removes a specific listener for an event |\n| `offAll(eventName: string)` | Removes all listeners for a specific event |\n| `removeAllListeners()` | Removes all listeners |\n\n**The `ListenerRegistration<TTarget>` type is defined as follows:**\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `eventName` | `string` | The name of the event to listen for |\n| `targetClass` | `ClassConstructorType<unknown>` | The target class constructor of the listener |\n| `methodName` | `string` | The name of the method to listen for in the target class |\n\n---\n\n### UseIoServer hook\n\nThe `useIoServer` is the simpliest hook that provides the `io` socketio server object.\n\n```typescript\nimport { useIoServer } from \"@admandev/socketio-decorator\"\nimport { Server } from \"socket.io\"\n\nconst io: Server = useIoServer()\n```\n\n---\n\n### UseUserSocket hook\n\nThe `useUserSocket` hook allows you to retrieve a specific connected socket instance based on a search argument (e.g., user ID).\n\n1. **Setup the `searchUserSocket` function**\n\n   In the `app.ts` file, provide a function that searches for a user socket based on an argument:\n\n    ```typescript\n    useSocketIoDecorator({\n        ...,\n        // Here we decide that the search argument is the user ID but you can use any other argument type\n        searchUserSocket: async (userId: string) => {\n            const allSockets = Array.from(io.sockets.sockets.values())\n            return allSockets.find(socket => socket.user.id === userId) || null\n        },\n    })\n    ```\n\n2. **Use the `useUserSocket` hook anywhere**\n\n    ```typescript\n    import { useUserSocket } from \"@admandev/socketio-decorator\"\n    import { Socket } from \"socket.io\"\n\n    const userSocket: Socket | null = await useUserSocket(userId)\n    ```\n\n---\n\n### UseRoomStore hook\n\nThe `useRoomStore` hook allows you to manage rooms dynamically in your code.\nIt provides the `RoomStore` instance that you can use to set or get room data.\n\n```typescript\nimport { useRoomStore } from \"@admandev/socketio-decorator\"\n\nconst roomStore: RoomStore<ChatRoom> = useRoomStore()\n\nroomStore.addRoom(\"myRoom\", {\n    id: \"myRoom\",\n    messages: [],\n    users: []\n})\n\nconst room = roomStore.getRoom(\"myRoom\")\n```\n\n#### `RoomStore` API\n\n| Method | Description |\n|--------|---------|\n| `addRoom(roomId: string, room: TRoom)` | Adds a room to the store |\n| `getRoom(roomId: string)` | Gets a room by its id |\n| `removeRoom(roomId: string)` | Removes a room from the store |\n| `clearAllRooms()` | Clears all rooms from the store |\n\n---\n\n#### Example of using `useRoomStore` with room event handlers\n\n```typescript\nclass ChatRoomEvents {\n    @OnRoomCreated(\"chat-*\")\n    public onChatRoomCreated(roomName: string) {\n        console.log(`Room ${roomName} has been created`)\n\n        const roomStore = useRoomStore<ChatRoom>()\n        roomStore.addRoom(roomName, {\n            id: roomName,\n            members: [],\n            users: [],\n        })\n    }\n\n    @OnRoomJoined(\"chat-*\")\n    public onChatRoomJoined(roomName: string, socket: Socket) {\n        console.log(`Socket ${socket.id} has joined room ${roomName}`)\n\n        const roomStore = useRoomStore<ChatRoom>()\n        const room = roomStore.getRoom(roomName)\n\n        const socketDataStore = new SocketDataStore<DataStoreSchema>(socket)\n        const member = socketDataStore.getData(\"member\")\n        \n        if (room && member) {\n            room.members.push(member)\n        }\n    }\n\n    @OnRoomLeft(\"chat-*\")\n    public onChatRoomLeft(roomName: string, socket: Socket) {\n        console.log(`Socket ${socket.id} has left room ${roomName}`)\n\n        const roomStore = useRoomStore<ChatRoom>()\n        const room = roomStore.getRoom(roomName)\n\n        if (room) {\n            const socketDataStore = new SocketDataStore<DataStoreSchema>(socket)\n            const leftMember = socketDataStore.getData(\"member\")\n\n            room.members = room.members.filter(member => member !== leftMember)\n        }\n    }\n\n    @OnRoomDeleted(\"chat-*\")\n    public onChatRoomDeleted(roomName: string) {\n        console.log(`Room ${roomName} has been deleted`)\n\n        const roomStore = useRoomStore<ChatRoom>()\n        roomStore.removeRoom(roomName)\n    }\n}\n```\n\n---\n\n### UseRoom hook\n\nThe `useRoom` hook provides utilities for working with a specific room, including accessing room data and utility functions.\n\n```typescript\nimport { useRoom } from \"@admandev/socketio-decorator\"\n\n// Get room data and utilities for a specific room\nconst { room, getClients, isEmpty, hasClientInRoom } = useRoom<ChatRoom>(\"myRoom\")\n```\n\n**Return value properties:**\n\n| Property | Type | Description |\n|----------|------|-------------|\n| `room` | `TRoom \\| null` | The room data object if it exists, null otherwise |\n| `getClients` | `() => string[]` | Returns an array of socket IDs for all clients in the room |\n| `isEmpty` | `() => boolean` | Returns true if the room has no clients |\n| `hasClientInRoom` | `(socketId: string) => boolean` | Checks if a specific client is in the room |\n\n> [!NOTE]\n> The utility functions are based on Socket.IO's room management (`io.sockets.adapter.rooms`) and may not reflect custom room data stored in `RoomStore`.\n\n## Dependency Injection\n\nSocketio Decorator supports dependency injection using a DI library. You can inject services into your controllers and middlewares.\n\nTo allow Socketio Decorator to work with your DI system, you need to provide the `Container` object to the `useSocketIoDecorator` options.\n\n```typescript\nimport { Container } from \"typedi\"\n\nuseSocketIoDecorator({\n    ...,\n    iocContainer: Container,\n})\n```\n\n> [!NOTE]\n> Your Container object must provide the `get` method to resolve dependencies.\n\n## 🧪 Example project\n\nCheck out the full example using Express:\n👉 [Example on GitHub](https://github.com/AdmanDev/socketio-decorator/tree/master/examples/nodeexample)\n\n## 🛠 Troubleshooting & Help\n\nIf you run into any issues or have suggestions, feel free to open an issue on GitHub:\n\n🔗 [Socket.io Decorator Issues](https://github.com/AdmanDev/socketio-decorator/issues)\n\nThank you for using Socketio Decorator\n","readmeFilename":"README.md"}