{"_id":"@codenamemarkov/openapi-quality-scorer","name":"@codenamemarkov/openapi-quality-scorer","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@codenamemarkov/openapi-quality-scorer","version":"0.1.0","description":"Get a quality score (0-100) and letter grade (A-F) for your OpenAPI specification with actionable improvement recommendations","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc","dev":"tsc --watch","test":"vitest","test:run":"vitest run","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["openapi","swagger","api","linter","quality","documentation","validator","scoring","grade","api-quality","openapi-linter"],"author":{"name":"Marek V"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/MarkoVcode/openapi-quality-scorer.git"},"bugs":{"url":"https://github.com/MarkoVcode/openapi-quality-scorer/issues"},"homepage":"https://github.com/MarkoVcode/openapi-quality-scorer#readme","dependencies":{"yaml":"^2.6.1"},"devDependencies":{"@types/node":"^22.10.1","typescript":"^5.7.2","vitest":"^2.1.6"},"engines":{"node":">=18.0.0"},"_id":"@codenamemarkov/openapi-quality-scorer@0.1.0","gitHead":"945a191ffc35fe04cfc08ae08c0b8c9e8f6ce831","_nodeVersion":"22.21.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-4Eqe6A2mVqMXIEk7OMVCSU76TeA4UNu2J5ZOhniVtF5F9RWdl0HKnQ9en9IrM+nD8OAceGxB1GMAd0253IkX1w==","shasum":"f2d5a65e1fad58214b4fd2cf0f0aefee10af19f1","tarball":"https://registry.npmjs.org/@codenamemarkov/openapi-quality-scorer/-/openapi-quality-scorer-0.1.0.tgz","fileCount":59,"unpackedSize":174929,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQC2LFcXNUHyJ62yuDKuFso/w3thqjOlSJmpgEiRyzItAQIgKNNTQGv8n4A+8PLhgH3Ok0I1nJyMQilX/+wM6rkYTr8="}]},"_npmUser":{"name":"codenamemarkov","email":"marek.kaszewski@gmail.com"},"directories":{},"maintainers":[{"name":"codenamemarkov","email":"marek.kaszewski@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/openapi-quality-scorer_0.1.0_1764871973617_0.37896855378467076"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-04T18:12:53.558Z","0.1.0":"2025-12-04T18:12:53.764Z","modified":"2025-12-04T18:12:54.002Z"},"maintainers":[{"name":"codenamemarkov","email":"marek.kaszewski@gmail.com"}],"description":"Get a quality score (0-100) and letter grade (A-F) for your OpenAPI specification with actionable improvement recommendations","homepage":"https://github.com/MarkoVcode/openapi-quality-scorer#readme","keywords":["openapi","swagger","api","linter","quality","documentation","validator","scoring","grade","api-quality","openapi-linter"],"repository":{"type":"git","url":"git+https://github.com/MarkoVcode/openapi-quality-scorer.git"},"author":{"name":"Marek V"},"bugs":{"url":"https://github.com/MarkoVcode/openapi-quality-scorer/issues"},"license":"MIT","readme":"# @codenamemarkov/openapi-quality-scorer\n\n> Get a quality score (0-100) and letter grade (A-F) for your OpenAPI specification\n\n[![npm version](https://badge.fury.io/js/@codenamemarkov%2Fopenapi-quality-scorer.svg)](https://www.npmjs.com/package/@codenamemarkov/openapi-quality-scorer)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n\n## Why This Library?\n\nUnlike linters (Spectral, Redocly, etc.) that only report pass/fail rules, this library gives you a **quantifiable quality score** with **actionable improvement suggestions**.\n\n| Feature | Linters (Spectral, etc.) | This Library |\n|---------|--------------------------|--------------|\n| Numeric Score | :x: | :white_check_mark: 0-100 |\n| Letter Grade | :x: | :white_check_mark: A-F |\n| Category Breakdown | :x: | :white_check_mark: 5 weighted categories |\n| Prioritized Improvements | :x: | :white_check_mark: Impact-sorted |\n| Zero Config | :x: Needs ruleset | :white_check_mark: Works immediately |\n\n**Spectral says:** *\"You have 47 warnings\"*\n\n**This library says:** *\"Your API is 72/100 (Grade B). Fix these 3 things to improve by 15 points.\"*\n\n## Installation\n\n```bash\nnpm install @codenamemarkov/openapi-quality-scorer\n```\n\n## Quick Start\n\n```typescript\nimport { analyzeOpenAPISync } from '@codenamemarkov/openapi-quality-scorer'\n\nconst spec = {\n  openapi: '3.0.0',\n  info: { title: 'My API', version: '1.0.0' },\n  paths: { /* ... */ }\n}\n\nconst report = analyzeOpenAPISync(spec)\n\nconsole.log(report.score)    // 72\nconsole.log(report.grade)    // \"B\"\nconsole.log(report.summary)  // \"Good API specification with minor areas for improvement.\"\n```\n\n### Async Version (File/URL Support)\n\n```typescript\nimport { analyzeOpenAPI } from '@codenamemarkov/openapi-quality-scorer'\n\n// From file path\nconst report = await analyzeOpenAPI('./openapi.yaml')\n\n// From YAML/JSON string\nconst report = await analyzeOpenAPI(yamlString, { format: 'yaml' })\n```\n\n## Scoring Categories\n\nYour API is scored across 5 weighted categories:\n\n| Category | Weight | What It Measures |\n|----------|--------|------------------|\n| **Documentation** | 30% | Info descriptions, operation summaries, parameter docs |\n| **Completeness** | 25% | Response codes, error responses, request body schemas |\n| **Examples** | 20% | Request/response examples, parameter examples |\n| **Structure** | 15% | Organization, naming conventions, tags |\n| **Security** | 10% | Security schemes, applied security, OAuth scopes |\n\n## Output Structure\n\n```typescript\ninterface QualityReport {\n  score: number          // 0-100\n  grade: 'A' | 'B' | 'C' | 'D' | 'F'\n  summary: string        // Human-readable summary\n  categories: {\n    documentation: { score: number, weight: number, rulesPassed: number, rulesFailed: number }\n    completeness: { score: number, weight: number, rulesPassed: number, rulesFailed: number }\n    examples: { score: number, weight: number, rulesPassed: number, rulesFailed: number }\n    structure: { score: number, weight: number, rulesPassed: number, rulesFailed: number }\n    security: { score: number, weight: number, rulesPassed: number, rulesFailed: number }\n  }\n  improvements: Array<{\n    priority: 'high' | 'medium' | 'low'\n    category: string\n    rule: string\n    message: string\n    impact: number       // Points gained if fixed\n    locations?: string[] // Specific paths to fix\n  }>\n  rules: RuleResult[]    // Detailed per-rule results\n  metadata: {\n    specVersion: string\n    title: string\n    operationCount: number\n    schemaCount: number\n    analyzedAt: string\n  }\n}\n```\n\n## Example Output\n\n```json\n{\n  \"score\": 72,\n  \"grade\": \"B\",\n  \"summary\": \"Good API specification with minor areas for improvement. 2 high-priority improvements identified.\",\n  \"categories\": {\n    \"documentation\": { \"score\": 85, \"weight\": 30, \"rulesPassed\": 6, \"rulesFailed\": 2 },\n    \"completeness\": { \"score\": 70, \"weight\": 25, \"rulesPassed\": 3, \"rulesFailed\": 2 },\n    \"examples\": { \"score\": 50, \"weight\": 20, \"rulesPassed\": 1, \"rulesFailed\": 2 },\n    \"structure\": { \"score\": 90, \"weight\": 15, \"rulesPassed\": 4, \"rulesFailed\": 0 },\n    \"security\": { \"score\": 80, \"weight\": 10, \"rulesPassed\": 2, \"rulesFailed\": 1 }\n  },\n  \"improvements\": [\n    {\n      \"priority\": \"high\",\n      \"category\": \"documentation\",\n      \"rule\": \"parameter-description\",\n      \"message\": \"Add descriptions to all parameters (8 of 12 items need attention)\",\n      \"impact\": 5.2,\n      \"locations\": [\"GET /users/{id}\", \"POST /orders\", \"PUT /products/{sku}\"]\n    },\n    {\n      \"priority\": \"high\",\n      \"category\": \"examples\",\n      \"rule\": \"response-examples\",\n      \"message\": \"Add examples to response bodies\",\n      \"impact\": 4.0,\n      \"locations\": [\"GET /users\", \"POST /orders\"]\n    }\n  ]\n}\n```\n\n## Use Cases\n\n- **Quality Dashboards** - Track API quality metrics over time\n- **CI/CD Integration** - Fail builds if quality drops below threshold\n- **Gamification** - Encourage teams to improve their API scores\n- **Stakeholder Reporting** - Communicate quality in terms everyone understands\n- **API Reviews** - Quantify improvement during code reviews\n\n### CI/CD Example\n\n```typescript\nconst report = analyzeOpenAPISync(spec)\n\nif (report.score < 70) {\n  console.error(`API quality too low: ${report.score}/100 (${report.grade})`)\n  process.exit(1)\n}\n```\n\n## Configuration\n\nCustomize weights, thresholds, and disabled rules:\n\n```typescript\nconst report = analyzeOpenAPISync(spec, {\n  // Adjust category weights (must sum to 100)\n  weights: {\n    documentation: 40,  // Increase documentation importance\n    completeness: 25,\n    examples: 15,\n    structure: 10,\n    security: 10\n  },\n\n  // Customize grade thresholds\n  thresholds: {\n    A: 95,  // Stricter A grade\n    B: 80,\n    C: 65,\n    D: 50,\n    F: 0\n  },\n\n  // Disable specific rules\n  disabledRules: ['operation-description', 'tag-description']\n})\n```\n\n## API Reference\n\n### `analyzeOpenAPI(input, options?)` - Async\n\nAnalyzes an OpenAPI specification from a file path, URL, or string content.\n\n```typescript\n// File path\nconst report = await analyzeOpenAPI('./openapi.yaml')\n\n// String content\nconst report = await analyzeOpenAPI(yamlContent, { format: 'yaml' })\nconst report = await analyzeOpenAPI(jsonContent, { format: 'json' })\n```\n\n### `analyzeOpenAPISync(spec, options?)` - Sync\n\nAnalyzes an already-parsed OpenAPI specification object.\n\n```typescript\nconst report = analyzeOpenAPISync(specObject)\n```\n\n### Options\n\n```typescript\ninterface AnalyzerOptions {\n  format?: 'yaml' | 'json' | 'object'\n  weights?: Partial<Record<CategoryName, number>>\n  disabledRules?: string[]\n  thresholds?: Partial<Record<Grade, number>>\n}\n```\n\n## Available Rules\n\n### Documentation Rules\n- `info-description` - API info has description\n- `operation-description` - Operations have descriptions\n- `operation-summary` - Operations have summaries\n- `parameter-description` - Parameters have descriptions\n- `schema-description` - Schemas have descriptions\n- `tag-description` - Tags have descriptions\n- `response-description` - Responses have descriptions\n- `external-docs` - External documentation links\n\n### Completeness Rules\n- `response-codes` - Appropriate response codes defined\n- `error-responses` - Error responses (4xx, 5xx) defined\n- `request-body-schema` - Request bodies have schemas\n- `content-types` - Content types specified\n- `operation-id` - Operations have unique IDs\n\n### Examples Rules\n- `response-examples` - Responses include examples\n- `parameter-examples` - Parameters include examples\n- `request-body-examples` - Request bodies include examples\n\n### Structure Rules\n- `consistent-naming` - Consistent naming conventions\n- `tags-used` - Operations use tags\n- `path-structure` - Clean path structure\n\n### Security Rules\n- `security-schemes` - Security schemes defined\n- `security-applied` - Security applied to operations\n- `oauth-scopes` - OAuth scopes properly defined\n\n## Grade Thresholds\n\n| Grade | Default Threshold | Meaning |\n|-------|-------------------|---------|\n| A | >= 90 | Excellent - Well documented, complete |\n| B | >= 75 | Good - Minor improvements needed |\n| C | >= 60 | Fair - Several areas need attention |\n| D | >= 40 | Poor - Significant improvements needed |\n| F | < 40 | Failing - Major documentation gaps |\n\n## Requirements\n\n- Node.js >= 18.0.0\n- Supports OpenAPI 3.0.x and 3.1.x\n- Supports Swagger 2.0 (limited)\n\n## License\n\nMIT\n\n## Contributing\n\nContributions welcome! Please open an issue or PR on [GitHub](https://github.com/MarkoVcode/openapi-quality-scorer).\n","readmeFilename":"README.md","_rev":"1-b6e4b7d6c1d79d7361716d195086dc29"}