-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from NangoHQ/khaliq/nan-1989-script-guidelines
add more rules
- Loading branch information
Showing
8 changed files
with
373 additions
and
1 deletion.
There are no files selected for viewing
This file contains 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 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 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,75 @@ | ||
import { RuleTester } from 'eslint'; | ||
import { describe, it } from 'vitest'; | ||
import includeDocsForEndpoints from './include-docs-for-endpoints'; | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: require.resolve('@typescript-eslint/parser'), | ||
parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, | ||
}); | ||
|
||
describe('include-docs-for-endpoints', () => { | ||
it('should enforce documentation URLs for endpoint properties', () => { | ||
ruleTester.run('include-docs-for-endpoints', includeDocsForEndpoints, { | ||
valid: [ | ||
{ | ||
code: ` | ||
const config: ProxyConfiguration = { | ||
// https://developers.zoom.us/docs/api/meetings/#tag/meetings/POST/users/{userId}/meetings | ||
endpoint: '/users/me/meetings', | ||
data: zoomInput, | ||
retries: 10 | ||
}; | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
const config: ProxyConfiguration = { | ||
// See API docs: https://api.example.com/docs | ||
endpoint: '/api/v1/users', | ||
retries: 10 | ||
}; | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
const config: ProxyConfiguration = { | ||
/* Documentation: https://api.example.com/docs */ | ||
endpoint: '/api/v1/users', | ||
retries: 10 | ||
}; | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
const config: ProxyConfiguration = { | ||
endpoint: '/users/me/meetings', | ||
data: zoomInput, | ||
retries: 10 | ||
}; | ||
`, | ||
errors: [ | ||
{ | ||
message: 'Endpoint properties should include a documentation URL in a comment above', | ||
}, | ||
], | ||
}, | ||
{ | ||
code: ` | ||
const config: ProxyConfiguration = { | ||
// Configuration for user meetings | ||
endpoint: '/users/me/meetings', | ||
retries: 10 | ||
}; | ||
`, | ||
errors: [ | ||
{ | ||
message: 'Endpoint properties should include a documentation URL in a comment above', | ||
}, | ||
], | ||
}, | ||
], | ||
}); | ||
}); | ||
}); |
This file contains 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,61 @@ | ||
import { Rule } from 'eslint'; | ||
import { Node, ObjectExpression, Property } from 'estree'; | ||
|
||
const includeDocsForEndpoints: Rule.RuleModule = { | ||
meta: { | ||
type: 'suggestion', | ||
docs: { | ||
description: 'Enforce documentation URLs for endpoint properties in ProxyConfiguration', | ||
category: 'Best Practices', | ||
recommended: true, | ||
}, | ||
schema: [], | ||
}, | ||
create(context) { | ||
return { | ||
Property(node: Property) { | ||
if (isEndpointProperty(node)) { | ||
const ancestors = context.getAncestors(); | ||
const isProxyConfig = ancestors.some(ancestor => | ||
ancestor.type === 'VariableDeclarator' && | ||
(ancestor as any).id?.typeAnnotation?.typeAnnotation?.typeName?.name === 'ProxyConfiguration' | ||
); | ||
|
||
if (isProxyConfig) { | ||
const sourceCode = context.getSourceCode(); | ||
const comments = sourceCode.getCommentsBefore(node); | ||
|
||
if (!comments.length || !hasDocumentationUrl(comments)) { | ||
context.report({ | ||
node, | ||
message: 'Endpoint properties should include a documentation URL in a comment above', | ||
}); | ||
} | ||
} | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
|
||
function isEndpointProperty(node: Property): boolean { | ||
return ( | ||
node.type === 'Property' && | ||
node.key.type === 'Identifier' && | ||
node.key.name === 'endpoint' | ||
); | ||
} | ||
|
||
function hasDocumentationUrl(comments: any[]): boolean { | ||
return comments.some(comment => { | ||
const commentText = comment.value.trim().toLowerCase(); | ||
return ( | ||
commentText.includes('http://') || | ||
commentText.includes('https://') || | ||
commentText.includes('docs') || | ||
commentText.includes('api') | ||
); | ||
}); | ||
} | ||
|
||
export default includeDocsForEndpoints; |
This file contains 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,49 @@ | ||
import { RuleTester } from 'eslint'; | ||
import { describe, it } from 'vitest'; | ||
import noTryCatchUnlessExplicitlyAllowed from './no-try-catch-unless-explicitly-allowed'; | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: require.resolve('@typescript-eslint/parser'), | ||
parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, | ||
}); | ||
|
||
describe('no-try-catch-unless-explicitly-allowed', () => { | ||
it('should enforce try-catch restrictions', () => { | ||
ruleTester.run('no-try-catch-unless-explicitly-allowed', noTryCatchUnlessExplicitlyAllowed, { | ||
valid: [ | ||
{ | ||
code: ` | ||
// @allowTryCatch | ||
try { | ||
await nango.get({}); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
`, | ||
}, | ||
{ | ||
code: ` | ||
/* @allowTryCatch */ | ||
try { | ||
await nango.post({}); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
try { | ||
await nango.get({}); | ||
} catch (error) { | ||
console.error(error); | ||
} | ||
`, | ||
errors: [{ message: 'Try-catch blocks are not allowed unless explicitly marked with @allowTryCatch comment. It is best practice to allow the Nango platform to handle errors. Override this if you need to handle errors explicitly with special cases.' }], | ||
}, | ||
], | ||
}); | ||
}); | ||
}); |
This file contains 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,35 @@ | ||
import { Rule } from 'eslint'; | ||
import { Node, TryStatement } from 'estree'; | ||
|
||
const noTryCatchUnlessExplicitlyAllowed: Rule.RuleModule = { | ||
meta: { | ||
type: 'problem', | ||
docs: { | ||
description: 'Disallow try-catch blocks unless explicitly allowed via comments', | ||
category: 'Best Practices', | ||
recommended: true, | ||
}, | ||
schema: [], | ||
}, | ||
create(context) { | ||
return { | ||
TryStatement(node: TryStatement) { | ||
const sourceCode = context.getSourceCode(); | ||
const comments = sourceCode.getCommentsBefore(node); | ||
|
||
const isAllowed = comments.some(comment => | ||
comment.value.trim().toLowerCase().includes('@allowtrycatch') | ||
); | ||
|
||
if (!isAllowed) { | ||
context.report({ | ||
node, | ||
message: 'Try-catch blocks are not allowed unless explicitly marked with @allowTryCatch comment. It is best practice to allow the Nango platform to handle errors. Override this if you need to handle errors explicitly with special cases.', | ||
}); | ||
} | ||
}, | ||
}; | ||
}, | ||
}; | ||
|
||
export default noTryCatchUnlessExplicitlyAllowed; |
This file contains 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,47 @@ | ||
import { RuleTester } from 'eslint'; | ||
import { describe, it } from 'vitest'; | ||
import queryParamsInParamsObject from './query-params-in-params-object'; | ||
|
||
const ruleTester = new RuleTester({ | ||
parser: require.resolve('@typescript-eslint/parser'), | ||
parserOptions: { ecmaVersion: 2018, sourceType: 'module' }, | ||
}); | ||
|
||
describe('query-params-in-params-object', () => { | ||
it('should enforce query parameters in params object', () => { | ||
ruleTester.run('query-params-in-params-object', queryParamsInParamsObject, { | ||
valid: [ | ||
{ | ||
code: ` | ||
await nango.get({ | ||
endpoint: 'api/users', | ||
params: { | ||
page: '1', | ||
limit: '10' | ||
} | ||
}); | ||
`, | ||
}, | ||
], | ||
invalid: [ | ||
{ | ||
code: ` | ||
await nango.get({ | ||
endpoint: 'api/users?page=1&limit=10' | ||
}); | ||
`, | ||
errors: [{ message: 'Query parameters should be in the params object instead of the endpoint URL' }], | ||
output: ` | ||
await nango.get({ | ||
endpoint: 'api/users', | ||
params: { | ||
"page": "1", | ||
"limit": "10" | ||
} | ||
}); | ||
`, | ||
}, | ||
], | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.