diff --git a/tools/spectral/ipa/__tests__/collectionIdentifierCamelCase.test.js b/tools/spectral/ipa/__tests__/collectionIdentifierCamelCase.test.js index 9f67d12763..5dd568047d 100644 --- a/tools/spectral/ipa/__tests__/collectionIdentifierCamelCase.test.js +++ b/tools/spectral/ipa/__tests__/collectionIdentifierCamelCase.test.js @@ -45,7 +45,7 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Resources' in path '/Resources' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Resources' in path '/Resources' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/Resources'], severity: DiagnosticSeverity.Warning, }, @@ -62,7 +62,7 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'resource_groups' in path '/resource_groups' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'resource_groups' in path '/resource_groups' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/resource_groups'], severity: DiagnosticSeverity.Warning, }, @@ -79,7 +79,7 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'resource-groups' in path '/resource-groups' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'resource-groups' in path '/resource-groups' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/resource-groups'], severity: DiagnosticSeverity.Warning, }, @@ -96,7 +96,7 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Resources' in path '/Resources:createResource' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Resources' in path '/Resources:createResource' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/Resources:createResource'], severity: DiagnosticSeverity.Warning, }, @@ -113,7 +113,7 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'resourcesAPI' in path '/resourcesAPI' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'resourcesAPI' in path '/resourcesAPI' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/resourcesAPI'], severity: DiagnosticSeverity.Warning, }, @@ -145,21 +145,21 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path '/api//users' contains double slashes (//) which is not allowed. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path '/api//users' contains double slashes (//) which is not allowed. http://go/ipa-spectral#IPA-102", path: ['paths', '/api//users'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path '/resources///{resourceId}' contains double slashes (//) which is not allowed. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path '/resources///{resourceId}' contains double slashes (//) which is not allowed. http://go/ipa-spectral#IPA-102", path: ['paths', '/resources///{resourceId}'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path '//doubleSlashAtStart' contains double slashes (//) which is not allowed. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path '//doubleSlashAtStart' contains double slashes (//) which is not allowed. http://go/ipa-spectral#IPA-102", path: ['paths', '//doubleSlashAtStart'], severity: DiagnosticSeverity.Warning, }, @@ -186,21 +186,21 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'API' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'API' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/API/Resource_groups/{userId}/User-profiles'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Resource_groups' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Resource_groups' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/API/Resource_groups/{userId}/User-profiles'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'User-profiles' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'User-profiles' in path '/API/Resource_groups/{userId}/User-profiles' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/API/Resource_groups/{userId}/User-profiles'], severity: DiagnosticSeverity.Warning, }, @@ -217,14 +217,14 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Valid' in path '/api/Valid/Invalid_resource/{id}:validCustomMethod' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Valid' in path '/api/Valid/Invalid_resource/{id}:validCustomMethod' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/api/Valid/Invalid_resource/{id}:validCustomMethod'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Invalid_resource' in path '/api/Valid/Invalid_resource/{id}:validCustomMethod' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Invalid_resource' in path '/api/Valid/Invalid_resource/{id}:validCustomMethod' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/api/Valid/Invalid_resource/{id}:validCustomMethod'], severity: DiagnosticSeverity.Warning, }, @@ -241,14 +241,14 @@ testRule('xgen-IPA-102-collection-identifier-camelCase', [ { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path '/api//Invalid_segment//resources' contains double slashes (//) which is not allowed. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path '/api//Invalid_segment//resources' contains double slashes (//) which is not allowed. http://go/ipa-spectral#IPA-102", path: ['paths', '/api//Invalid_segment//resources'], severity: DiagnosticSeverity.Warning, }, { code: 'xgen-IPA-102-collection-identifier-camelCase', message: - "Collection identifiers must be in camelCase. Path segment 'Invalid_segment' in path '/api//Invalid_segment//resources' is not in camelCase. http://go/ipa/102", + "Collection identifiers must be in camelCase. Path segment 'Invalid_segment' in path '/api//Invalid_segment//resources' is not in camelCase. http://go/ipa-spectral#IPA-102", path: ['paths', '/api//Invalid_segment//resources'], severity: DiagnosticSeverity.Warning, }, diff --git a/tools/spectral/ipa/rulesets/IPA-102.yaml b/tools/spectral/ipa/rulesets/IPA-102.yaml index 756f3412e3..cfc5c5a1b8 100644 --- a/tools/spectral/ipa/rulesets/IPA-102.yaml +++ b/tools/spectral/ipa/rulesets/IPA-102.yaml @@ -3,17 +3,21 @@ rules: xgen-IPA-102-collection-identifier-camelCase: - description: >- - Collection identifiers must be in camelCase. Logic includes:
- - All path segments that are not path parameters
- - Only the resource identifier part before any colon in custom method paths (e.g., `resource` in `/resource:customMethod`)
- - Path parameters should also follow camelCase naming
- - Certain values can be exempted via the ignoredValues configuration (e.g., 'v1', 'v2') that can be supplied as `ignoredValues` - argument to the rule
- - Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
- - Double slashes (//) are not allowed in paths
- http://go/ipa/102 - message: '{{error}} http://go/ipa/102' + description: | + Collection identifiers must be in camelCase. + + ##### Implementation details + Rule checks for the following conditions: + + - All path segments that are not path parameters + - Only the resource identifier part before any colon in custom method paths (e.g., `resource` in `/resource:customMethod`) + - Path parameters should also follow camelCase naming + - Certain values can be exempted via the ignoredValues configuration that can be supplied as `ignoredValues` + argument to the rule + - Paths with `x-xgen-IPA-exception` for this rule are excluded from validation + - Double slashes (//) are not allowed in paths + + message: '{{error}} http://go/ipa-spectral#IPA-102' severity: warn given: $.paths then: diff --git a/tools/spectral/ipa/rulesets/README.md b/tools/spectral/ipa/rulesets/README.md index 68dc2e78c1..ec0f038b34 100644 --- a/tools/spectral/ipa/rulesets/README.md +++ b/tools/spectral/ipa/rulesets/README.md @@ -6,95 +6,202 @@ All Spectral rules used in the IPA validation are defined in rulesets grouped by ## Rulesets -The tables below lists all available rules, their descriptions and severity level. +Below is a list of all available rules, their descriptions and severity levels. ### IPA-005 -For rule definitions, see [IPA-005.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-005.yaml). +Rule is based on [http://go/ipa/IPA-5](http://go/ipa/IPA-5). + +#### xgen-IPA-005-exception-extension-format + + ![error](https://img.shields.io/badge/error-red) +IPA exception extensions must follow the correct format. http://go/ipa/5 + -| Rule Name | Description | Severity | -| --------------------------------------- | ------------------------------------------------------------------------ | -------- | -| xgen-IPA-005-exception-extension-format | IPA exception extensions must follow the correct format. http://go/ipa/5 | error | ### IPA-102 -For rule definitions, see [IPA-102.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-102.yaml). +Rule is based on [http://go/ipa/IPA-102](http://go/ipa/IPA-102). + +#### xgen-IPA-102-path-alternate-resource-name-path-param + + ![error](https://img.shields.io/badge/error-red) +Paths should alternate between resource names and path params. http://go/ipa/102 + +#### xgen-IPA-102-collection-identifier-camelCase + + ![warn](https://img.shields.io/badge/warning-yellow) +Collection identifiers must be in camelCase. + + ##### Implementation details + Rule checks for the following conditions: + + - All path segments that are not path parameters + - Only the resource identifier part before any colon in custom method paths (e.g., `resource` in `/resource:customMethod`) + - Path parameters should also follow camelCase naming + - Certain values can be exempted via the ignoredValues configuration that can be supplied as `ignoredValues` + argument to the rule + - Paths with `x-xgen-IPA-exception` for this rule are excluded from validation + - Double slashes (//) are not allowed in paths + + +#### xgen-IPA-102-collection-identifier-pattern + + ![warn](https://img.shields.io/badge/warning-yellow) +Collection identifiers must begin with a lowercase letter and contain only ASCII letters and numbers. http://go/ipa/102 + -| Rule Name | Description | Severity | -| ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| xgen-IPA-102-path-alternate-resource-name-path-param | Paths should alternate between resource names and path params. http://go/ipa/102 | error | -| xgen-IPA-102-collection-identifier-camelCase | Collection identifiers must be in camelCase. Logic includes:
- All path segments that are not path parameters
- Only the resource identifier part before any colon in custom method paths (e.g., `resource` in `/resource:customMethod`)
- Path parameters should also follow camelCase naming
- Certain values can be exempted via the ignoredValues configuration (e.g., 'v1', 'v2') that can be supplied as `ignoredValues` argument to the rule
- Paths with `x-xgen-IPA-exception` for this rule are excluded from validation
- Double slashes (//) are not allowed in paths
http://go/ipa/102 | warn | -| xgen-IPA-102-collection-identifier-pattern | Collection identifiers must begin with a lowercase letter and contain only ASCII letters and numbers. http://go/ipa/102 | warn | ### IPA-104 -For rule definitions, see [IPA-104.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-104.yaml). +Rule is based on [http://go/ipa/IPA-104](http://go/ipa/IPA-104). + +#### xgen-IPA-104-resource-has-GET + + ![warn](https://img.shields.io/badge/warning-yellow) +APIs must provide a Get method for resources. http://go/ipa/104 + +#### xgen-IPA-104-get-method-returns-single-resource + + ![warn](https://img.shields.io/badge/warning-yellow) +The purpose of the Get method is to return data from a single resource. http://go/ipa/104 + +#### xgen-IPA-104-get-method-response-code-is-200 + + ![warn](https://img.shields.io/badge/warning-yellow) +The Get method must return a 200 OK response. http://go/ipa/104 + +#### xgen-IPA-104-get-method-returns-response-suffixed-object + + ![warn](https://img.shields.io/badge/warning-yellow) +The Get method of a resource should return a "Response" suffixed object. http://go/ipa/104 + +#### xgen-IPA-104-get-method-response-has-no-input-fields + + ![warn](https://img.shields.io/badge/warning-yellow) +The Get method response object must not include writeOnly properties (fields that should be used only on creation or update, ie output fields). http://go/ipa/104 + +#### xgen-IPA-104-get-method-no-request-body + + ![warn](https://img.shields.io/badge/warning-yellow) +The Get method request must not include a body. http://go/ipa/104 + -| Rule Name | Description | Severity | -| -------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -| xgen-IPA-104-resource-has-GET | APIs must provide a Get method for resources. http://go/ipa/104 | warn | -| xgen-IPA-104-get-method-returns-single-resource | The purpose of the Get method is to return data from a single resource. http://go/ipa/104 | warn | -| xgen-IPA-104-get-method-response-code-is-200 | The Get method must return a 200 OK response. http://go/ipa/104 | warn | -| xgen-IPA-104-get-method-returns-response-suffixed-object | The Get method of a resource should return a "Response" suffixed object. http://go/ipa/104 | warn | -| xgen-IPA-104-get-method-response-has-no-input-fields | The Get method response object must not include writeOnly properties (fields that should be used only on creation or update, ie output fields). http://go/ipa/104 | warn | -| xgen-IPA-104-get-method-no-request-body | The Get method request must not include a body. http://go/ipa/104 | warn | ### IPA-105 -For rule definitions, see [IPA-105.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-105.yaml). +Rule is based on [http://go/ipa/IPA-105](http://go/ipa/IPA-105). + +#### xgen-IPA-105-list-method-response-code-is-200 + + ![warn](https://img.shields.io/badge/warning-yellow) +The List method must return a 200 OK response. http://go/ipa/105 + +#### xgen-IPA-105-list-method-no-request-body + + ![warn](https://img.shields.io/badge/warning-yellow) +The List method request must not include a body. http://go/ipa/105 + +#### xgen-IPA-105-resource-has-list + + ![warn](https://img.shields.io/badge/warning-yellow) +APIs must provide a List method for resources. http://go/ipa/105 + -| Rule Name | Description | Severity | -| --------------------------------------------- | ------------------------------------------------------------------ | -------- | -| xgen-IPA-105-list-method-response-code-is-200 | The List method must return a 200 OK response. http://go/ipa/105 | warn | -| xgen-IPA-105-list-method-no-request-body | The List method request must not include a body. http://go/ipa/105 | warn | -| xgen-IPA-105-resource-has-list | APIs must provide a List method for resources. http://go/ipa/105 | warn | ### IPA-106 -For rule definitions, see [IPA-106.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-106.yaml). +Rule is based on [http://go/ipa/IPA-106](http://go/ipa/IPA-106). + +#### xgen-IPA-106-create-method-request-body-is-request-suffixed-object + + ![warn](https://img.shields.io/badge/warning-yellow) +The Create method request should be a Request suffixed object. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. + +#### xgen-IPA-106-create-method-should-not-have-query-parameters + + ![warn](https://img.shields.io/badge/warning-yellow) +Create operations should not use query parameters. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. + +#### xgen-IPA-106-create-method-request-body-is-get-method-response + + ![warn](https://img.shields.io/badge/warning-yellow) +Request body content of the Create method and response content of the Get method should refer to the same resource. http://go/ipa/106 readOnly/writeOnly properties will be ignored. This rule applies only to POST requests targeting resource collection URIs. + +#### xgen-IPA-106-create-method-request-has-no-readonly-fields + + ![warn](https://img.shields.io/badge/warning-yellow) +Create method Request object must not include fields with readOnly:true. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. + +#### xgen-IPA-106-create-method-response-code-is-201 + + ![warn](https://img.shields.io/badge/warning-yellow) +Create methods must return a 201 Created response code. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. + -| Rule Name | Description | Severity | -| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| xgen-IPA-106-create-method-request-body-is-request-suffixed-object | The Create method request should be a Request suffixed object. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. | warn | -| xgen-IPA-106-create-method-should-not-have-query-parameters | Create operations should not use query parameters. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. | warn | -| xgen-IPA-106-create-method-request-body-is-get-method-response | Request body content of the Create method and response content of the Get method should refer to the same resource. http://go/ipa/106 readOnly/writeOnly properties will be ignored. This rule applies only to POST requests targeting resource collection URIs. | warn | -| xgen-IPA-106-create-method-request-has-no-readonly-fields | Create method Request object must not include fields with readOnly:true. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. | warn | -| xgen-IPA-106-create-method-response-code-is-201 | Create methods must return a 201 Created response code. http://go/ipa/106 This rule applies only to POST requests targeting resource collection URIs. | warn | ### IPA-108 -For rule definitions, see [IPA-108.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-108.yaml). +Rule is based on [http://go/ipa/IPA-108](http://go/ipa/IPA-108). + +#### xgen-IPA-108-delete-response-should-be-empty + + ![warn](https://img.shields.io/badge/warning-yellow) +Delete method response should not have schema reference to object. http://go/ipa/108 + +#### xgen-IPA-108-delete-method-return-204-response + + ![warn](https://img.shields.io/badge/warning-yellow) +DELETE method must return 204 No Content. http://go/ipa/108 + +#### xgen-IPA-108-delete-include-404-response + + ![warn](https://img.shields.io/badge/warning-yellow) +DELETE method must include 404 response and return it when resource not found. http://go/ipa/108 + +#### xgen-IPA-108-delete-request-no-body + + ![warn](https://img.shields.io/badge/warning-yellow) +DELETE method must not have request body. http://go/ipa/108 + -| Rule Name | Description | Severity | -| ---------------------------------------------- | ------------------------------------------------------------------------------------------------ | -------- | -| xgen-IPA-108-delete-response-should-be-empty | Delete method response should not have schema reference to object. http://go/ipa/108 | warn | -| xgen-IPA-108-delete-method-return-204-response | DELETE method must return 204 No Content. http://go/ipa/108 | warn | -| xgen-IPA-108-delete-include-404-response | DELETE method must include 404 response and return it when resource not found. http://go/ipa/108 | warn | -| xgen-IPA-108-delete-request-no-body | DELETE method must not have request body. http://go/ipa/108 | warn | ### IPA-109 -For rule definitions, see [IPA-109.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-109.yaml). +Rule is based on [http://go/ipa/IPA-109](http://go/ipa/IPA-109). + +#### xgen-IPA-109-custom-method-must-be-GET-or-POST + + ![error](https://img.shields.io/badge/error-red) +The HTTP method for custom methods must be GET or POST. http://go/ipa/109 + +#### xgen-IPA-109-custom-method-must-use-camel-case + + ![error](https://img.shields.io/badge/error-red) +The custom method must use camelCase format. http://go/ipa/109 + -| Rule Name | Description | Severity | -| ---------------------------------------------- | ------------------------------------------------------------------------- | -------- | -| xgen-IPA-109-custom-method-must-be-GET-or-POST | The HTTP method for custom methods must be GET or POST. http://go/ipa/109 | error | -| xgen-IPA-109-custom-method-must-use-camel-case | The custom method must use camelCase format. http://go/ipa/109 | error | ### IPA-113 -For rule definitions, see [IPA-113.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-113.yaml). +Rule is based on [http://go/ipa/IPA-113](http://go/ipa/IPA-113). + +#### xgen-IPA-113-singleton-must-not-have-id + + ![warn](https://img.shields.io/badge/warning-yellow) +Singleton resources must not have a user-provided or system-generated ID. http://go/ipa/113 + -| Rule Name | Description | Severity | -| --------------------------------------- | ------------------------------------------------------------------------------------------- | -------- | -| xgen-IPA-113-singleton-must-not-have-id | Singleton resources must not have a user-provided or system-generated ID. http://go/ipa/113 | warn | ### IPA-123 -For rule definitions, see [IPA-123.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/IPA-123.yaml). +Rule is based on [http://go/ipa/IPA-123](http://go/ipa/IPA-123). + +#### xgen-IPA-123-enum-values-must-be-upper-snake-case + + ![error](https://img.shields.io/badge/error-red) +Enum values must be UPPER_SNAKE_CASE. http://go/ipa/123 + -| Rule Name | Description | Severity | -| ------------------------------------------------- | ------------------------------------------------------- | -------- | -| xgen-IPA-123-enum-values-must-be-upper-snake-case | Enum values must be UPPER_SNAKE_CASE. http://go/ipa/123 | error | diff --git a/tools/spectral/ipa/scripts/generateRulesetReadme.js b/tools/spectral/ipa/scripts/generateRulesetReadme.js index 5e39fa18b6..3dd588e557 100644 --- a/tools/spectral/ipa/scripts/generateRulesetReadme.js +++ b/tools/spectral/ipa/scripts/generateRulesetReadme.js @@ -2,7 +2,6 @@ import fs from 'node:fs'; import path from 'path'; import { fileURLToPath } from 'url'; import spectral from '@stoplight/spectral-core'; -import { markdownTable } from 'markdown-table'; import { loadRuleset } from '../utils.js'; const dirname = path.dirname(fileURLToPath(import.meta.url)); @@ -26,7 +25,7 @@ fs.writeFile(readmeFilePath, fileContent, (error) => { async function getRulesetsSection() { let content = - '## Rulesets\n\n' + 'The tables below lists all available rules, their descriptions and severity level.\n\n'; + '## Rulesets\n\n' + 'Below is a list of all available rules, their descriptions and severity levels.\n\n'; const rules = await getAllRules(); const ruleNames = Object.keys(rules); @@ -34,27 +33,50 @@ async function getRulesetsSection() { ipaNumbers.forEach((ipaNumber) => { const ipaRules = filterRulesByIpaNumber(ipaNumber, rules); - const table = generateRulesetTable(ipaRules); - content += - `### ${ipaNumber}\n\n` + `For rule definitions, see ${getIpaRulesetUrl(ipaNumber)}.\n\n` + `${table}\n\n`; + const sections = generateRulesetSections(ipaRules); + content += `### ${ipaNumber}\n\n` + `Rule is based on ${getIpaRulesetUrl(ipaNumber)}.\n\n` + `${sections}\n\n`; }); return content; } -function generateRulesetTable(rules) { - const table = [['Rule Name', 'Description', 'Severity']]; - const tableRows = []; - +function generateRulesetSections(rules) { + let sections = ''; const ruleNames = Object.keys(rules); - ruleNames.forEach((ruleName) => { - const rule = rules[ruleName]; - tableRows.push([ruleName, rule.description, rule.definition.severity]); + const sortedRuleEntries = ruleNames + .map((ruleName) => ({ + name: ruleName, + description: rules[ruleName].description, + severity: rules[ruleName].definition.severity, + })) + .sort((a, b) => { + if (a.severity < b.severity) { + return -1; + } else if (a.severity > b.severity) { + return 1; + } + return 0; + }); + + sortedRuleEntries.forEach((rule) => { + const severityFormatted = formatSeverity(rule.severity); + sections += `#### ${rule.name}\n\n ${severityFormatted} \n${rule.description}\n\n`; }); - tableRows.sort(sortBySeverity); - tableRows.forEach((row) => table.push(row)); - return markdownTable(table); + return sections; +} + +function formatSeverity(severity) { + switch (severity.toLowerCase()) { + case 'info': + return '![info](https://img.shields.io/badge/info-green)'; + case 'warn': + return '![warn](https://img.shields.io/badge/warning-yellow)'; + case 'error': + return '![error](https://img.shields.io/badge/error-red)'; + default: + return `\`${severity}\``; + } } async function getAllRules() { @@ -76,7 +98,12 @@ function getIpaNumbers(ruleNames) { } function getIpaRulesetUrl(ipaNumber) { - return `[${ipaNumber}.yaml](https://github.com/mongodb/openapi/blob/main/tools/spectral/ipa/rulesets/${ipaNumber}.yaml)`; + const parts = ipaNumber.split('-'); + if (parts.length > 1) { + parts[1] = parts[1].replace(/^0+/, ''); + } + const ipaNumberFormatted = parts.join('-'); + return `[http://go/ipa/${ipaNumberFormatted}](http://go/ipa/${ipaNumberFormatted})`; } function filterRulesByIpaNumber(ipaNumber, rules) { @@ -89,12 +116,3 @@ function filterRulesByIpaNumber(ipaNumber, rules) { }; }, {}); } - -function sortBySeverity(a, b) { - if (a[2] < b[2]) { - return -1; - } else if (a[2] > b[2]) { - return 1; - } - return 0; -}