{"_id":"@apiaddicts/asyncapi-style-guide-spectral","_rev":"7-6f8e92228310ef8b22855eb981119e2e","name":"@apiaddicts/asyncapi-style-guide-spectral","dist-tags":{"latest":"1.1.0","beta":"1.1.0-beta.5"},"versions":{"1.0.0":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.0.0","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.0.0","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"15a2aff711a3f857a4dfe9d3c451b39e13bb54ff","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.0.0.tgz","fileCount":13,"integrity":"sha512-mZEr3W72px8OoZue0n9pkA6wcKv57bYTaRP+ew2RU4jXUO5D0ROA9Mpz2r2s+TlQcSonsoZoVQd0upNXp/7H9Q==","signatures":[{"sig":"MEYCIQCgeozOsOpMYTThJF2nOJvNwu/mpT1pPiR2PdgVhfhItAIhAIHxzmXN6X1ip2vWrIjH0Ags+Sgp3beCxb8hWgOF61kw","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":84156},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"a931c8249ed91293a08d30d5582a131d2263edc9","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"11.6.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"25.3.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.0.0_1778511654880_0.49730631913992496","host":"s3://npm-registry-packages-npm-production"}},"1.1.0-beta.1":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.1.0-beta.1","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0-beta.1","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"54fe501856d15b49e1437bf0d2d2da9bb0603970","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0-beta.1.tgz","fileCount":23,"integrity":"sha512-EAqom5JWUbyx5uWBvi5Fv7Xr+H87+9tr6cUsppKJ4N+j0O5Qt4PfaYHPG2OcRCnj2dcOwjp7ekkBB6oTb+9hew==","signatures":[{"sig":"MEQCIBDrqyXzaM/EbYICVjvInEWLGZAV314Q5G3kcB2RRjIXAiAXD2VLvJJYyrWIZ3j910hi1JLyTimnzqnwc8sA02JNMg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":107770},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"7ee285ef362523a6055b9ace42180ee1eb9fd0b8","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"11.6.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"25.3.0","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.1.0-beta.1_1787144119439_0.5683849297170904","host":"s3://npm-registry-packages-npm-production"}},"1.1.0-beta.2":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.1.0-beta.2","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0-beta.2","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"ee223f58505622c234ea719ed2f6f600d0648516","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0-beta.2.tgz","fileCount":28,"integrity":"sha512-ZMtly9ZZsK1Gf9+/m4GxHl4lpJYTivQ9EhBvcXJPd8g6LN1l7ZyLdbmFv9cGrGdbfRwUaH7EZwWVnVXana/2Cw==","signatures":[{"sig":"MEYCIQCDo3hGD6c6fXV7tDc205rqZRdSPLj33pEHBTPKXEIO+wIhAJ6Hyr+RbcOtc7SlohNLeo6XjppukqWjueFLK11kn8eO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":124018},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"eb3d112dd10e57dde7ff2ef3c33dd0f846145360","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"10.9.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"22.14.0","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.1.0-beta.2_1787692871254_0.3381090506208233","host":"s3://npm-registry-packages-npm-production"}},"1.1.0-beta.3":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.1.0-beta.3","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0-beta.3","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"5e282308c99ac67a55d0d27f45060630ff315365","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0-beta.3.tgz","fileCount":29,"integrity":"sha512-HjqqRfTWLeRNejbuVwoYA4eJ/ctdA+n7fxy4cK6MfO9TwyRKgQ1+4vas8/naBc3BTcrMkPIL2phLxy7cCZa4TA==","signatures":[{"sig":"MEQCIEZEbN2FdhqZ/gYz/k5olmZe8bwGcIP+S7mL3cWpakgdAiBguDU2SAnd32z8L3IxlAmKhg0Yjd3LKtmbGV27P4ppOA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":128409},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"948fc45d03b0d0ea7c9f0dc6a7853b34c1564633","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"10.8.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.1.0-beta.3_1788298643282_0.26029442305589523","host":"s3://npm-registry-packages-npm-production"}},"1.1.0-beta.4":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.1.0-beta.4","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0-beta.4","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"77b47766956f7b0052762f722ef7649babe7ec45","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0-beta.4.tgz","fileCount":29,"integrity":"sha512-WjisrehDqIPNe95EcBt6rsekf0oGjfTMkMNiB3DD0jwChpAhZFmFZe44PJrtc7yRJDHzgTERih0dBbe9aMAg1g==","signatures":[{"sig":"MEQCIFUljyKDfJYE5Y+TbqfY4xHKWwKRaOIQk+gjOAnZIDVmAiB9JAVM190khpgikAwM2EtbMAY/ZAHtwvgVd2Lk3LJU8w==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":130871},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"dab27c9f47254f9992e5e28d9f5fa57d8e271d46","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"10.8.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.1.0-beta.4_1788362059288_0.07615722213689424","host":"s3://npm-registry-packages-npm-production"}},"1.1.0-beta.5":{"name":"@apiaddicts/asyncapi-style-guide-spectral","version":"1.1.0-beta.5","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"author":{"name":"APIQuality"},"license":"GPL-3.0","_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0-beta.5","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"c464ae437242798bca1b69abb06b97e377a44497","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0-beta.5.tgz","fileCount":29,"integrity":"sha512-436Ba03m+LJcXgNWONjRsMts06QHP1b4w5pRbziE5qz5aN4yuZVK36cuEitXBGLzrDm9ChE1LhqwF4H6FVEURA==","signatures":[{"sig":"MEYCIQC17D+dnKOV25+QgsQBQczUBl0EdWl0TLVTqM81J94hlgIhAIoDXqdrmTx3T1f1VcbAMcLiWrhL7vLBnfVUuGyisGAy","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"sig":"MEUCIFpeeU7+CpD0AuQGxi4YIFbsA/Hu5sGjNZHGLsJyqIiWAiEAteFufv3/xIoakCj27qEJnJEQsHY4Bz3FTTPUefy9AEM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":131988},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","gitHead":"e3aeca67471d46adda67aa5c529461accda5bbe8","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"10.8.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"tmp":"tmp/asyncapi-style-guide-spectral_1.1.0-beta.5_1789741769586_0.585052684308998","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"_id":"@apiaddicts/asyncapi-style-guide-spectral@1.1.0","bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"dist":{"shasum":"3e81257dfd96dbebc4f989cd9b57a5a40e6c5cbb","tarball":"https://registry.npmjs.org/@apiaddicts/asyncapi-style-guide-spectral/-/asyncapi-style-guide-spectral-1.1.0.tgz","fileCount":29,"integrity":"sha512-HPSvwqR5G8Sn14Lb3ZurSxhasJxhLajj3wf+W+QzdCmkbVeXpCbe4nVSSmZ/OKhG+u2ERq9jG28OGZODoD7zPg==","signatures":[{"sig":"MEUCIQCSwkSNGtayRegH2R2iByjiHVO9OOIpTjVRxkjXPWCYVQIgezwxISZpJrnSb+kntdvoMw6kHgoDdcT1Gr+xAdZmvZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC1JHDvC9yssHvsTEYYFxoYRacbI8cJ5xpHxfkJa8yQ5wIgM7+uXXzM1WaLG2EHiBapjq5zZWU/hCCyBIDKTGejEek="}],"unpackedSize":131981},"jest":{"collectCoverage":true,"coverageReporters":["lcov","json-summary"],"coverageThreshold":{"./functions/*.js":{"statements":0}},"collectCoverageFrom":["functions/*.js"]},"main":"asa-spectral.yaml","name":"@apiaddicts/asyncapi-style-guide-spectral","author":{"name":"APIQuality"},"gitHead":"9257d9f1e46da438109cf83c9fc9865ae586f9fa","license":"GPL-3.0","scripts":{"test":"jest --coverage --detectOpenHandles --no-cache --forceExit","make-badges":"coverage-badges","lint:example":"spectral lint -r asa-spectral.yaml test/fixtures/valid-asyncapi2.yaml"},"version":"1.1.0","_npmUser":{"name":"apiaddict","email":"devrel@apiaddicts.org"},"homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"_npmVersion":"10.8.2","description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","directories":{},"maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.7.0","@types/jest":"^29.5.14","coverage-badges-cli":"^2.2.0","@stoplight/spectral-core":"^1.19.5","@stoplight/spectral-rulesets":"^1.20.2","@stoplight/spectral-functions":"^1.9.0","@stoplight/spectral-ruleset-migrator":"^1.10.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/asyncapi-style-guide-spectral_1.1.0_1789963608081_0.8946597886275964"}}},"time":{"created":"2026-05-11T15:00:54.757Z","modified":"2026-09-21T04:06:48.324Z","1.0.0":"2026-05-11T15:00:55.086Z","1.1.0-beta.1":"2026-08-19T12:55:19.583Z","1.1.0-beta.2":"2026-08-25T21:21:11.392Z","1.1.0-beta.3":"2026-09-01T21:37:23.398Z","1.1.0-beta.4":"2026-09-02T15:14:19.423Z","1.1.0-beta.5":"2026-09-18T14:29:29.682Z","1.1.0":"2026-09-21T04:06:48.170Z"},"bugs":{"url":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/issues"},"author":{"name":"APIQuality"},"license":"GPL-3.0","homepage":"https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral#readme","keywords":["spectral","linter","asyncapi","asyncapi2","asyncapi3","apiaddicts","apiquality"],"repository":{"url":"git+https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git","type":"git"},"description":"Spectral ruleset for AsyncAPI definitions by APIAddicts / ApiQuality","maintainers":[{"name":"apiaddict","email":"devrel@apiaddicts.org"}],"readme":"# APIAddicts AsyncAPI Style Guide - Spectral Ruleset\r\n\r\n[![Node.js CI](https://github.com/apiaddicts/apquality-spectral/actions/workflows/node.js.yml/badge.svg)](https://github.com/apiaddicts/apquality-spectral/actions/workflows/node.js.yml) ![Coverage](./coverage/badges.svg)\r\n[![License: GPL-3.0](https://img.shields.io/badge/License-GPL%203.0-blue.svg)](LICENSE)\r\n\r\nSpectral rules for **AsyncAPI 2.x and 3.x** definitions, managed by [ApiQuality](https://apiquality.io) and provided to the [APIAddicts](https://apiaddicts.org) community.\r\n\r\nBased on the SonarQube rules from [sonarasyncapi-rules](https://github.com/apiaddicts/sonarasyncapi-rules) and following the same conventions as [apiaddicts-style-guide-spectral](https://github.com/apiaddicts/apiaddicts-style-guide-spectral) (OpenAPI).\r\n\r\n---\r\n\r\n## Quick Start\r\n\r\n### Prerequisites\r\n\r\n- Node.js 18+ (LTS recommended)\r\n- Spectral CLI: `npm install -g @stoplight/spectral-cli`\r\n\r\n### Installation\r\n\r\n```bash\r\n# Clone the repository\r\ngit clone https://github.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral.git\r\ncd apiaddicts-asyncapi-style-guide-spectral\r\nnpm install\r\n```\r\n\r\n### Usage\r\n\r\n#### Command Line\r\n\r\n```bash\r\n# Lint a local AsyncAPI file\r\nspectral lint -r asa-spectral.yaml your-asyncapi.yaml\r\n\r\n# Lint using remote ruleset\r\nspectral lint -r https://raw.githubusercontent.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/main/asa-spectral.yaml your-asyncapi.yaml\r\n```\r\n\r\n#### Spectral Config File\r\n\r\nCreate a `.spectral.yaml` in your project root:\r\n\r\n```yaml\r\nextends:\r\n  - https://raw.githubusercontent.com/apiaddicts/apiaddicts-asyncapi-style-guide-spectral/main/asa-spectral.yaml\r\n```\r\n\r\nThen run:\r\n\r\n```bash\r\nspectral lint your-asyncapi.yaml\r\n```\r\n\r\n#### VSCode Extension\r\n\r\n1. Install the [Spectral VSCode extension](https://marketplace.visualstudio.com/items?itemName=stoplight.spectral).\r\n2. Create a `.spectral.yaml` file as shown above.\r\n3. Open any AsyncAPI YAML/JSON file for real-time linting.\r\n\r\n---\r\n\r\n## Rules Reference\r\n\r\n### Security Rules\r\n\r\n| Rule | Severity | Description |\r\n|------|----------|-------------|\r\n| **AAR001** | `error` | A secure protocol (https, wss, amqps, etc.) is mandatory for all servers. |\r\n| **AAR008** | `error` | The `servers` section must be defined in the AsyncAPI document. |\r\n| **AAR018** | `warn` | Security schemes must be among allowed types and must be complete (all required fields). |\r\n| **AAR043** | `warn` | Each channel operation should define a security scheme. |\r\n| **AAR064** | `error` | In the Kafka context, each server protocol must be `kafka` or `kafka-ssl` (not `https`, `wss`, etc.). |\r\n\r\n### Operations Rules\r\n\r\n| Rule | Severity | Description |\r\n|------|----------|-------------|\r\n| **AAR009** | `error` | Each operation (publish/subscribe) must declare at least one tag. |\r\n| **AAR010** | `warn` | All tags should have a `description` field. |\r\n| **AAR040** | `warn` | Channel servers must reference servers defined in the root `servers` object. |\r\n| **AAR041** | `info` | Servers and channels should be defined in `components` for reusability. |\r\n| **AAR053** | `error` | Channel/topic name must follow the corporate naming pattern `<cod_poaps>.<classification>.<domain>.<origin>.<scope>[.<version>]`. |\r\n| **AAR054** | `error` | Channel/topic classification (2nd segment) must be `cdc`, `cmd` or `sys`. |\r\n| **AAR057** | `error` | At least one channel must be documented as an error topic following `<topicOriginal>.[<consumerGroup>.]error.<n>`. |\r\n| **AAR058** | `warn` | If a channel name contains `.retry.`, it must follow `<topicOriginal>.<consumerGroup>.retry.<n>`. |\r\n| **AAR061** | `warn` | Producing and consuming operations must share the same `x-scs-function-name` so the JAPI generator links them as one processor. |\r\n| **AAR062** | `error` | Each consuming operation (v2 `subscribe`, v3 `receive`) must declare a consumer group via `x-scs-group` or `bindings.kafka.groupId`. |\r\n\r\n### Format / Documentation Rules\r\n\r\n| Rule | Severity | Description |\r\n|------|----------|-------------|\r\n| **AAR011** | `warn` | License should be documented in `info.license`. |\r\n| **AAR012** | `warn` | Each operation must have a unique `operationId`. |\r\n| **AAR013** | `error` | No two operations may share the same `operationId`. |\r\n| **AAR015** | `warn` | The `info` object must contain a `contact` section. |\r\n| **AAR016** | `warn` | Contact must include `name`, `url`, and `email` fields. |\r\n| **AAR017** | `warn` | The `license` object must have a `url` field. |\r\n| **AAR019** | `warn` | The AsyncAPI document should define an `id` field. |\r\n| **AAR021** | `warn` | Each operation must have a `summary` field. |\r\n| **AAR022** | `warn` | Operation `description` must differ from its `summary`. |\r\n| **AAR029** | `warn` | Each channel and operation must have a `description`. |\r\n| **AAR032** | `warn` | Numeric properties must declare a value restriction (`minimum`, `maximum`, `format`, `enum` or `const`). |\r\n| **AAR033** | `warn` | String properties must declare a value restriction (`minLength`, `maxLength`, `pattern`, `enum`, `const` or `format`). |\r\n| **AAR034** | `warn` | Numeric types must specify a valid `format` (int32, int64, float, double). |\r\n| **AAR035** | `info` | Messages should have a `title` field. |\r\n| **AAR036** | `warn` | Descriptions must begin with a capital letter and end with a period. |\r\n| **AAR037** | `warn` | Bindings must specify a `bindingVersion`. |\r\n| **AAR042** | `info` | Messages should have a unique `messageId` identifier. |\r\n| **AAR050** | `error` | The `info.title` field must exist and not be empty. |\r\n| **AAR051** | `error` | Every operation's `operationId` must be present and follow camelCase naming convention. |\r\n| **AAR063** | `error` | The root `asyncapi` version must be one of the versions allowed by the organization (configurable via `allowedVersions`; default `2.6.0,3.0.0,3.1.0`). |\r\n\r\n### Schema Rules\r\n\r\n| Rule | Severity | Description |\r\n|------|----------|-------------|\r\n| **AAR024** | `error` | Every message must declare a `contentType` unless it is an Avro message (auto-detected via `schemaFormat`). |\r\n| **AAR026** | `info` | Message schemas should be defined in `components.messages` and referenced via `$ref`. |\r\n| **AAR031** | `warn` | Message examples must follow the declared payload and headers schemas. |\r\n| **AAR052** | `error` | The namespace of a named Avro schema (record, enum or fixed) is required and must follow the corporate pattern. |\r\n| **AAR055** | `warn` | The `x-payload-references` extension, wherever it appears, must have `subject`, `ref` and `referenceName` on every item. |\r\n| **AAR056** | `error` | When the payload uses Avro, `schemaFormat` must be exactly `application/vnd.apache.avro;version=1.9.0`. |\r\n| **AAR059** | `error` | The `name` field of every Avro record (including nested records) must be in CamelCase with an uppercase first letter. |\r\n| **AAR060** | `error` | A message's `contentType` (and the document-level `defaultContentType`) must match `application/*+avro`. |\r\n\r\n---\r\n\r\n## AsyncAPI Version Support\r\n\r\nAll rules support **AsyncAPI 2.x** by default. Rules that differ structurally for **AsyncAPI 3.x** have dedicated `-v3` variants that are automatically applied based on the document format. Key differences handled:\r\n\r\n- **AsyncAPI 2.x**: Operations are under `channels[*].publish` / `channels[*].subscribe`\r\n- **AsyncAPI 3.x**: Operations are under `operations[*]` (top-level)\r\n\r\n---\r\n\r\n## Custom Functions\r\n\r\nThe ruleset includes 24 custom Spectral functions for complex validation logic:\r\n\r\n| Function | Used by | Purpose |\r\n|----------|---------|---------|\r\n| `asa-check-security-schemes` | AAR018 | Validates security scheme types and completeness |\r\n| `asa-description-format` | AAR036 | Checks description starts uppercase, ends with period |\r\n| `asa-duplicate-operation-id` | AAR013 | Detects duplicate operationId values across channels |\r\n| `asa-operation-id-camel-case` | AAR051 | Checks operationId is present and follows camelCase |\r\n| `asa-message-content-type` | AAR024 | Validates each message declares a contentType unless it is Avro |\r\n| `asa-message-examples-validation` | AAR031 | Validates message examples against schemas |\r\n| `asa-numeric-parameter-integrity` | AAR032 | Checks numeric properties have constraints |\r\n| `asa-numeric-format` | AAR034 | Checks numeric properties declare a valid format |\r\n| `asa-string-parameter-integrity` | AAR033 | Checks string properties have constraints |\r\n| `asa-channel-servers-defined` | AAR040 | Validates channel server references exist |\r\n| `asa-binding-version` | AAR037 | Checks bindings have bindingVersion |\r\n| `asa-message-schemas-in-components` | AAR026 | Recommends $ref usage for message schemas |\r\n| `asa-avro-namespace-pattern` | AAR052 | Validates Avro namespace against the corporate pattern |\r\n| `asa-channel-naming-convention` | AAR053 | Validates channel/topic name against the corporate topic naming pattern |\r\n| `asa-classification-valid-values` | AAR054 | Validates that the channel/topic classification segment is cdc, cmd or sys |\r\n| `asa-x-payload-references-well-formed` | AAR055 | Validates that x-payload-references items each have subject, ref and referenceName |\r\n| `asa-avro-schema-format` | AAR056 | Validates that an Avro schemaFormat is exactly application/vnd.apache.avro;version=1.9.0 |\r\n| `asa-error-topic-documented` | AAR057 | Validates that at least one channel is documented as an error topic |\r\n| `asa-retry-topic-naming-convention` | AAR058 | Validates that retry channels follow the required retry-topic naming pattern |\r\n| `asa-avro-record-name-camel-case` | AAR059 | Validates that every Avro record's `name` (including nested records) is in CamelCase |\r\n| `asa-content-type-avro` | AAR060 | Validates that every message `contentType` and the `defaultContentType` match `application/*+avro` |\r\n| `asa-processor-function-name-paired` | AAR061 | Validates that producing and consuming operations share the same `x-scs-function-name` |\r\n| `asa-subscribe-group-required` | AAR062 | Validates that each consuming operation declares a consumer group |\r\n| `asa-asyncapi-version-allowed` | AAR063 | Validates that the root `asyncapi` version is one of the allowed versions |\r\n| `asa-kafka-protocol-required` | AAR064 | Validates that each server protocol is `kafka` or `kafka-ssl` |\r\n\r\n---\r\n\r\n## Project Structure\r\n\r\n```\r\napiaddicts-asyncapi-style-guide-spectral/\r\n├── .github/workflows/       # CI/CD configuration\r\n├── functions/               # Custom Spectral rule functions\r\n│   ├── asa-avro-namespace-pattern.js\r\n│   ├── asa-binding-version.js\r\n│   ├── asa-channel-naming-convention.js\r\n│   ├── asa-channel-servers-defined.js\r\n│   ├── asa-check-security-schemes.js\r\n│   ├── asa-description-format.js\r\n│   ├── asa-duplicate-operation-id.js\r\n│   ├── asa-message-examples-validation.js\r\n│   ├── asa-message-schemas-in-components.js\r\n│   ├── asa-numeric-parameter-integrity.js\r\n│   ├── asa-string-parameter-integrity.js\r\n│   ├── asa-content-type-avro.js\r\n│   ├── asa-avro-record-name-camel-case.js\r\n│   ├── asa-error-topic-documented.js\r\n│   ├── asa-avro-schema-format.js\r\n│   ├── asa-string-parameter-integrity.js\r\n│   ├── asa-classification-valid-values.js\r\n│   ├── asa-x-payload-references-well-formed.js\r\n│   └── asa-retry-topic-naming-convention.js\r\n├── test/\r\n│   ├── helpers/utils.js     # Test utilities\r\n│   ├── asyncapi2/           # AsyncAPI 2.x tests\r\n│   │   ├── security/        # Security rule tests\r\n│   │   ├── operations/      # Operations rule tests\r\n│   │   ├── format/          # Format/documentation tests\r\n│   │   └── schemas/         # Schema rule tests\r\n│   └── asyncapi3/           # AsyncAPI 3.x tests\r\n│       ├── operations/      # Operations rule tests\r\n│       ├── format/          # Format/documentation tests\r\n│       └── schemas/         # Schema rule tests\r\n├── asa-spectral.yaml        # Main Spectral ruleset\r\n├── package.json\r\n├── CONTRIBUTING.md\r\n└── README.md\r\n```\r\n\r\n---\r\n\r\n## Running Tests\r\n\r\n```bash\r\n# Run all tests with coverage\r\nnpm test\r\n\r\n# Run a specific test file\r\nnpx jest test/asyncapi2/security/aar001.test.js\r\n```\r\n\r\n---\r\n\r\n## Mapping to SonarQube Rules\r\n\r\nThis Spectral ruleset is a direct translation of the [sonarasyncapi-rules](https://github.com/apiaddicts/sonarasyncapi-rules) SonarQube plugin. The mapping is:\r\n\r\n| SonarQube Rule | Spectral Rule | SonarQube Type | SonarQube Severity |\r\n|----------------|---------------|----------------|-------------------|\r\n| AAR001 | `asa:AAR001` | VULNERABILITY | CRITICAL |\r\n| AAR008 | `asa:AAR008` | VULNERABILITY | CRITICAL |\r\n| AAR009 | `asa:AAR009` | BUG | BLOCKER |\r\n| AAR010 | `asa:AAR010` | BUG | MAJOR |\r\n| AAR011 | `asa:AAR011` | BUG | MAJOR |\r\n| AAR012 | `asa:AAR012` | BUG | MAJOR |\r\n| AAR013 | `asa:AAR013` | BUG | MAJOR |\r\n| AAR015 | `asa:AAR015` | BUG | MAJOR |\r\n| AAR016 | `asa:AAR016` | BUG | MAJOR |\r\n| AAR017 | `asa:AAR017` | BUG | MAJOR |\r\n| AAR018 | `asa:AAR018` | VULNERABILITY | MAJOR |\r\n| AAR019 | `asa:AAR019` | BUG | MAJOR |\r\n| AAR021 | `asa:AAR021` | BUG | MAJOR |\r\n| AAR022 | `asa:AAR022` | BUG | MAJOR |\r\n| AAR024 | `asa:AAR024` | BUG | MAJOR |\r\n| AAR026 | `asa:AAR026` | BUG | MAJOR |\r\n| AAR029 | `asa:AAR029` | BUG | MAJOR |\r\n| AAR031 | `asa:AAR031` | BUG | MAJOR |\r\n| AAR032 | `asa:AAR032` | BUG | MAJOR |\r\n| AAR033 | `asa:AAR033` | BUG | MAJOR |\r\n| AAR034 | `asa:AAR034` | BUG | MAJOR |\r\n| AAR035 | `asa:AAR035` | BUG | MAJOR |\r\n| AAR036 | `asa:AAR036` | BUG | MAJOR |\r\n| AAR037 | `asa:AAR037` | BUG | MAJOR |\r\n| AAR040 | `asa:AAR040` | BUG | MAJOR |\r\n| AAR041 | `asa:AAR041` | BUG | MAJOR |\r\n| AAR042 | `asa:AAR042` | BUG | MAJOR |\r\n| AAR043 | `asa:AAR043` | VULNERABILITY | MAJOR |\r\n| AAR050 | `asa:AAR050` | BUG | MAJOR |\r\n| AAR051 | `asa:AAR051` | BUG | MAJOR |\r\n| AAR052 | `asa:AAR052` | BUG | MAJOR |\r\n| AAR053 | `asa:AAR053` | BUG | MAJOR |\r\n| AAR054 | `asa:AAR054` | BUG | MAJOR |\r\n| AAR055 | `asa:AAR055` | BUG | MAJOR |\r\n| AAR056 | `asa:AAR056` | BUG | MAJOR |\r\n| AAR057 | `asa:AAR057` | BUG | MAJOR |\r\n| AAR058 | `asa:AAR058` | BUG | MINOR |\r\n| AAR059 | `asa:AAR059` | BUG | MAJOR |\r\n| AAR060 | `asa:AAR060` | BUG | MAJOR |\r\n| AAR061 | `asa:AAR061` | BUG | MINOR |\r\n| AAR062 | `asa:AAR062` | BUG | MAJOR |\r\n| AAR063 | `asa:AAR063` | BUG | MAJOR |\r\n| AAR064 | `asa:AAR064` | VULNERABILITY | CRITICAL |\r\n\r\n---\r\n\r\n## Related Projects\r\n\r\n- [apiaddicts-style-guide-spectral](https://github.com/apiaddicts/apiaddicts-style-guide-spectral) - Spectral rules for OpenAPI (OAR rules)\r\n- [sonarasyncapi-rules](https://github.com/apiaddicts/sonarasyncapi-rules) - SonarQube plugin for AsyncAPI (source rules)\r\n- [SonarAPI Rules](https://github.com/apiaddicts/sonarapi-rules) - SonarQube plugin for OpenAPI\r\n\r\n---\r\n\r\n## License\r\n\r\nThis project is licensed under the [GPL-3.0 License](LICENSE).\r\n\r\n---\r\n\r\n## Contributors\r\n\r\nManaged by [ApiQuality](https://apiquality.io) for the [APIAddicts](https://apiaddicts.org) community.\r\n\r\nContributions are welcome! See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.\r\n","readmeFilename":"README.md"}