generated from SAP/repository-template
-
Notifications
You must be signed in to change notification settings - Fork 149
Details page for JS rules #2052
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
0111e43
Details page for cql-select rule
chgeo 50a8411
Add script to generate alphabetically ordered menu
daogrady a6233fa
Add stub for no-shared-handler-variables.md
daogrady 4917984
Finish doc for no-shared-handler-variables
daogrady 31e86ec
Add stubbing
daogrady 089d339
Add description for case-sensitive-well-known-events
daogrady d7749d5
Add description for no-deep-sap-cds-imports
daogrady 1152cf9
Add doc
daogrady 3c68f52
Add description for no-cross-service-import rule
daogrady 654ffde
Fix name
daogrady 90f2d0c
Cleanup
daogrady 04291a1
Cleanup
daogrady 5c6a00e
Cleanup
daogrady 6b6427b
Fix example
daogrady 452d0ba
Add caveats
daogrady 9877c15
Fix menu
daogrady 55bc056
More details
daogrady 9858086
Merge branch 'main' into js-rulez
daogrady e4eb4ea
Update tools/cds-lint/rules/no-shared-handler-variable.md
daogrady d78d610
Merge branch 'main' into js-rulez
daogrady 8e52602
Merge branch 'main' into js-rulez
ecklie 11bdb21
edit
renejeglinsky 15a550c
edit
renejeglinsky 87bb0f9
Mention JS rules in overview
daogrady 8ef8513
Merge branch 'main' into js-rulez
daogrady File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| #!/usr/bin/env node | ||
|
|
||
| // eslint plugin rule utility | ||
| // ============================ | ||
| // node index.js generate-menu | ||
| // generates the _menu.md file to make sure all rules are included. | ||
| // node index.js generate-js-stub <rule-name> | ||
| // generates a stub markdown file for a new JS rule with name <rule-name>. | ||
|
|
||
| import * as fs from 'node:fs' | ||
| import * as path from 'node:path' | ||
|
|
||
| const RULES_BASE_PATH = path.join('tools', 'cds-lint', 'rules'); | ||
| const EXAMPLES_BASE_PATH = path.join('tools', 'cds-lint', 'examples'); | ||
| const MENU_FILE_NAME = '_menu.md'; | ||
|
|
||
| /** | ||
| * Get a list of all rule description files. | ||
| * @returns {string[]} An array of rule description file names. | ||
| */ | ||
| const getRuleDescriptionFiles = () => | ||
| fs.readdirSync(RULES_BASE_PATH) | ||
| .filter(file => file.endsWith('.md')) | ||
| .filter(file => !['index.md', MENU_FILE_NAME].includes(file)) | ||
| .sort() | ||
|
|
||
| /** | ||
| * Generates the menu markdown file | ||
| * by completely overriding its current contents. | ||
| * The menu contains links to all rule description files | ||
| * in alphabetical order. | ||
| */ | ||
| function generateMenuMarkdown () { | ||
| const rules = getRuleDescriptionFiles(); | ||
| const menu = rules.map(rule => { | ||
| const clean = rule.replace('.md', ''); | ||
| return `# [${clean}](${clean})` | ||
| }).join('\n'); | ||
| const menuFilePath = path.join(RULES_BASE_PATH, '_menu.md') | ||
| fs.writeFileSync(menuFilePath, menu); | ||
| console.info(`generated menu to ${menuFilePath}`) | ||
| } | ||
|
|
||
| /** | ||
| * Generates a stub markdown file for a new JS rule. | ||
| * The passed ruleName will be placed in the stub template | ||
| * where $RULE_NAME is defined. | ||
| * @param {string} ruleName - The name of the rule. | ||
| */ | ||
| function generateJsRuleStub (ruleName) { | ||
| if (!ruleName) { | ||
| console.error('Please provide a rule name, e.g. "no-shared-handler-variables" as second argument'); | ||
| process.exit(1); | ||
| } | ||
| const stubFilePath = path.join(RULES_BASE_PATH, ruleName + '.md'); | ||
| if (fs.existsSync(stubFilePath)) { | ||
| console.error(`file ${stubFilePath} already exists, will not overwrite`); | ||
| process.exit(2); | ||
| } | ||
| const stub = fs.readFileSync(path.join(import.meta.dirname, 'js-rule-stub.md'), 'utf-8').replaceAll('$RULE_NAME', ruleName); | ||
| fs.writeFileSync(stubFilePath, stub); | ||
| console.info(`generated stub to ${stubFilePath}`); | ||
| const correctPath = path.join(EXAMPLES_BASE_PATH, ruleName, 'correct', 'srv'); | ||
| fs.mkdirSync(correctPath, { recursive: true }); | ||
| const incorrectPath = path.join(EXAMPLES_BASE_PATH, ruleName, 'incorrect', 'srv'); | ||
| fs.mkdirSync(incorrectPath, { recursive: true }); | ||
| console.info(`generated example directories in ${path.join(EXAMPLES_BASE_PATH, ruleName)}`); | ||
| fs.writeFileSync(path.join(correctPath, 'admin-service.js'), '// correct example\n'); | ||
| fs.writeFileSync(path.join(incorrectPath, 'admin-service.js'), '// incorrect example\n'); | ||
| } | ||
|
|
||
| function main (argv) { | ||
| switch (argv[0]) { | ||
| case 'generate-menu': | ||
| generateMenuMarkdown(); | ||
| break; | ||
| case 'generate-js-stub': | ||
| generateJsRuleStub(argv[1]); | ||
| generateMenuMarkdown(); | ||
| break; | ||
| default: | ||
| console.log(`Unknown command: ${argv[0]}. Use one of: generate-menu, generate-stub`); | ||
| } | ||
| } | ||
|
|
||
| main(process.argv.slice(2)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| --- | ||
| status: released | ||
| --- | ||
|
|
||
| <script setup> | ||
| import PlaygroundBadge from '../components/PlaygroundBadge.vue' | ||
| </script> | ||
|
|
||
| # $RULE_NAME | ||
|
|
||
| ## Rule Details | ||
|
|
||
| DETAILS | ||
|
|
||
| #### Version | ||
| This rule was introduced in `@sap/eslint-plugin-cds x.y.z`. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### ✅ Correct example | ||
|
|
||
| DESCRIPTION OF CORRECT EXAMPLE | ||
|
|
||
| ::: code-group | ||
| <<< ../examples/$RULE_NAME/correct/srv/admin-service.js#snippet{js:line-numbers} [srv/admin-service.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="$RULE_NAME" | ||
| kind="correct" | ||
| :files="['srv/admin-service.js']" | ||
| /> | ||
|
|
||
| ### ❌ Incorrect example | ||
|
|
||
| DESCRIPTION OF INCORRECT EXAMPLE | ||
|
|
||
| ::: code-group | ||
| <<< ../examples/$RULE_NAME/incorrect/srv/admin-service.js#snippet{js:line-numbers} [srv/admin-service.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="$RULE_NAME" | ||
| kind="incorrect" | ||
| :files="['srv/admin-service.js']" | ||
| /> |
5 changes: 5 additions & 0 deletions
5
tools/cds-lint/examples/case-sensitive-well-known-events/correct/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const cds = require('@sap/cds') | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { async init() { | ||
| this.on('READ', 'Books', () => {}) // [!code highlight] | ||
| }} |
5 changes: 5 additions & 0 deletions
5
tools/cds-lint/examples/case-sensitive-well-known-events/incorrect/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const cds = require('@sap/cds') | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { async init() { | ||
| this.on('Read', 'Books', () => {}) // [!code error] | ||
| }} |
6 changes: 6 additions & 0 deletions
6
tools/cds-lint/examples/no-cross-service-import/correct/srv/AdminService.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| const cds = require('@sap/cds') | ||
| const { Books } = require('#cds-models/sap/capire/bookshop/AdminService') // [!code highlight] | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { | ||
| // … | ||
| } | ||
6 changes: 6 additions & 0 deletions
6
tools/cds-lint/examples/no-cross-service-import/incorrect/srv/AdminService.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| const cds = require('@sap/cds') | ||
| const { Books } = require('#cds-models/sap/capire/bookshop/CatalogService') // [!code error] | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { | ||
| // … | ||
| } | ||
5 changes: 5 additions & 0 deletions
5
tools/cds-lint/examples/no-deep-sap-cds-import/correct/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const cds = require('@sap/cds') // [!code highlight] | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { | ||
| // … | ||
| } |
5 changes: 5 additions & 0 deletions
5
tools/cds-lint/examples/no-deep-sap-cds-import/incorrect/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| const cdsService = require('@sap/cds/service') // [!code error] | ||
|
|
||
| module.exports = class AdminService extends cdsService.ApplicationService { | ||
| // … | ||
| } |
21 changes: 21 additions & 0 deletions
21
tools/cds-lint/examples/no-shared-handler-variable/correct/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| const cds = require('@sap/cds') | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { async init() { | ||
| this.after('READ', 'Books', async () => { | ||
| // local variable only, no state shared between handlers | ||
| const books = await cds.run(SELECT.from('Books')) // [!code highlight] | ||
| return books | ||
| }) | ||
|
|
||
| this.on('CREATE', 'Books', newBookHandler) | ||
| await super.init() | ||
| } | ||
| } | ||
|
|
||
| /** @type {import('@sap/cds').CRUDEventHandler.On} */ | ||
| async function newBookHandler (req) { | ||
| const { name } = req.data | ||
| // local variable only, no state shared between handlers | ||
| const newBook = await cds.run(INSERT.into('Books').entries({ name })) // [!code highlight] | ||
| return newBook | ||
| } |
24 changes: 24 additions & 0 deletions
24
tools/cds-lint/examples/no-shared-handler-variable/incorrect/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| const cds = require('@sap/cds') | ||
|
|
||
| let lastCreatedBook | ||
| let lastReadBooks | ||
|
|
||
| module.exports = class AdminService extends cds.ApplicationService { async init() { | ||
| this.after('READ', 'Books', async () => { | ||
| // variable from surrounding scope, state is shared between handler calls | ||
| lastReadBooks = await cds.run(SELECT.from('Books')) // [!code error] | ||
| return lastReadBooks | ||
| }) | ||
|
|
||
| this.on('CREATE', 'Books', newBookHandler) | ||
| await super.init() | ||
| } | ||
| } | ||
|
|
||
| /** @type {import('@sap/cds').CRUDEventHandler.On} */ | ||
| async function newBookHandler (req) { | ||
| const { name } = req.data | ||
| // variable from surrounding scope, state is shared between handler calls | ||
| lastCreatedBook = await cds.run(INSERT.into('Books').entries({ name })) // [!code error] | ||
| return lastCreatedBook | ||
| } |
10 changes: 10 additions & 0 deletions
10
tools/cds-lint/examples/use-cql-select-template-strings/correct/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| const cds = require('@sap/cds') | ||
| module.exports = class AdminService extends cds.ApplicationService { init() { | ||
| const { Authors } = cds.entities('AdminService') | ||
|
|
||
| this.before (['CREATE', 'UPDATE'], Authors, async (req) => { | ||
| await SELECT`ID`.from `Authors`.where `name = ${req.data.name}` // [!code highlight] | ||
| }) | ||
|
|
||
| return super.init() | ||
| }} |
10 changes: 10 additions & 0 deletions
10
tools/cds-lint/examples/use-cql-select-template-strings/incorrect/srv/admin-service.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| const cds = require('@sap/cds') | ||
| module.exports = class AdminService extends cds.ApplicationService { init() { | ||
| const { Authors } = cds.entities('AdminService') | ||
|
|
||
| this.before (['CREATE', 'UPDATE'], Authors, async (req) => { | ||
| await SELECT`ID`.from `Authors`.where (`name = ${req.data.name}`) // [!code error] | ||
| }) | ||
|
|
||
| return super.init() | ||
| }} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --- | ||
| status: released | ||
| --- | ||
|
|
||
| <script setup> | ||
| import PlaygroundBadge from '../components/PlaygroundBadge.vue' | ||
| </script> | ||
|
|
||
| # case-sensitive-well-known-events | ||
|
|
||
| ## Rule Details | ||
|
|
||
| This rule identifies registrations to events that are likely well-known event names that must be written in all caps. | ||
|
|
||
| #### Version | ||
| This rule was introduced in `@sap/eslint-plugin-cds 4.0.2`. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### ✅ Correct example | ||
|
|
||
| The following example shows the correctly capitalized event name `READ`: | ||
|
|
||
| ::: code-group | ||
| <<< ../examples/case-sensitive-well-known-events/correct/srv/admin-service.js#snippet{js:line-numbers} [srv/admin-service.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="case-sensitive-well-known-events" | ||
| kind="correct" | ||
| :files="['srv/admin-service.js']" | ||
| /> | ||
|
|
||
| ### ❌ Incorrect example | ||
|
|
||
| This example shows a registration to an event `Read`, which should likely be `READ`. This can lead to unexpected behavior because event names in CAP are case sensitive: | ||
| ::: code-group | ||
| <<< ../examples/case-sensitive-well-known-events/incorrect/srv/admin-service.js#snippet{js:line-numbers} [srv/admin-service.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="case-sensitive-well-known-events" | ||
| kind="incorrect" | ||
| :files="['srv/admin-service.js']" | ||
| /> | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| --- | ||
| status: released | ||
| --- | ||
|
|
||
| <script setup> | ||
| import PlaygroundBadge from '../components/PlaygroundBadge.vue' | ||
| </script> | ||
|
|
||
| # no-cross-service-import | ||
|
|
||
| ## Rule Details | ||
|
|
||
| This rule prevents importing artifacts generated for one service into another service's implementation when using cds-typer. Clear service boundaries make your codebase easier to maintain and understand. | ||
|
|
||
| #### Version | ||
| This rule was introduced in `@sap/eslint-plugin-cds 4.0.2`. | ||
|
|
||
| ## Examples | ||
|
|
||
| ### ✅ Correct example | ||
|
|
||
| The imported entity belongs to `AdminService` and is used within the implementation of `AdminService` itself. This is the recommended approach: | ||
| ::: code-group | ||
| <<< ../examples/no-cross-service-import/correct/srv/AdminService.js#snippet{js:line-numbers} [srv/AdminService.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="no-cross-service-import" | ||
| kind="correct" | ||
| :files="['srv/AdminService.js']" | ||
| /> | ||
|
|
||
| ### ❌ Incorrect example | ||
|
|
||
| An entity from `CatalogService` is imported into the implementation of `AdminService`. This cross-service import is discouraged because it can lead to confusion and maintenance issues: | ||
|
|
||
| ::: code-group | ||
| <<< ../examples/no-cross-service-import/incorrect/srv/AdminService.js#snippet{js:line-numbers} [srv/AdminService.js] | ||
| ::: | ||
| <PlaygroundBadge | ||
| name="no-cross-service-import" | ||
| kind="incorrect" | ||
| :files="['srv/AdminService.js']" | ||
| /> |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.