New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@roq/eslint-plugin

Package Overview
Dependencies
Maintainers
6
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@roq/eslint-plugin - npm Package Compare versions

Comparing version 1.0.2 to 1.0.3

tests/dummies/backend/auth/dtos/sample.ts

2

constants.js

@@ -8,3 +8,3 @@ const path = require('path');

const resourceIdentifiers = {
backend: ['decorators', 'dtos', 'entities', 'enums', 'guards', 'interfaces', 'loaders', 'mappers', 'models', 'repositories', 'resolvers', 'services', 'strategies', 'scalars', 'schemas'],
backend: ['decorators', 'dtos', 'entities', 'enums', 'guards', 'interfaces', 'loaders', 'mappers', 'models', 'repositories', 'resolvers', 'services', 'strategies', 'scalars', 'schemas', 'config'],
frontend: ['components', 'configuration', 'layouts', 'pages', 'shared', 'slices', 'styles', 'utils', 'views'],

@@ -11,0 +11,0 @@ frontendCommon: ['interfaces', 'roq-hooks', 'roq-ui'],

@@ -8,3 +8,3 @@ const path = require('path');

const getPathPatterns = (backendBasePattern, frontendBasePattern, backendModuleList) => {
const getPathPatterns = (backendBasePattern, frontendBasePattern) => {
const pathPatterns = { backend: {}, frontend: {} };

@@ -14,5 +14,2 @@ for (const resource of resourceIdentifiers.backend) {

}
for (const resource of backendModuleList) {
pathPatterns.backend[resource] = [backendBasePattern, resource].join(escapedSep);
}

@@ -35,3 +32,2 @@ for (const resource of resourceIdentifiers.frontend) {

let frontendTestsPattern = '';
const backendModuleList = [];

@@ -58,22 +54,4 @@ if (pluginSettings) {

}
const backendPath = backendBasePath || 'backend/src';
try {
const [backendPathInitToken] = backendPath.split('/').filter((e) => e !== '');
const rootPath = path.resolve('./').replace(backendPathInitToken, '');
const dirContents = fs.readdirSync(path.resolve(rootPath, backendPath), { withFileTypes: true });
dirContents.forEach((e) => {
if (e.isDirectory()) {
const nestedDirContents = fs.readdirSync(path.resolve(rootPath, backendPath, e.name),
{ withFileTypes: true });
if (nestedDirContents.some((el) => el.isFile())) {
backendModuleList.push(e.name);
} else {
nestedDirContents.forEach(({ name: moduleName }) => {
backendModuleList.push([e.name, moduleName].join(escapedSep));
});
}
}
});
} catch (_) { /* */ }
const pathPatterns = getPathPatterns(backendBasePattern, frontendBasePattern, backendModuleList);
const pathPatterns = getPathPatterns(backendBasePattern, frontendBasePattern);
return {

@@ -85,3 +63,2 @@ backendBasePattern,

frontendTestsPattern,
backendModuleList,
};

@@ -92,4 +69,10 @@ }

const isBackendModule = (dirPath) => {
const filesInDir = fs.readdirSync(dirPath);
return filesInDir.includes('services') || filesInDir.includes('resolvers') || filesInDir.includes('models');
};
module.exports = {
get,
isBackendModule,
};

@@ -67,3 +67,2 @@ const {

backendTestsPattern,
backendModuleList,
} = executionContext.get(context);

@@ -101,6 +100,6 @@ const errorReportObject = {

5) in dtos allow both "arg-type" and "dto" as suffix
6) in frontend components should have a suffix "component".
*/
const backendModuleRootPaths = backendModuleList.map((e) => new RegExp(`${pathPatterns.backend[e]}$`));
const isBackendModuleRoot = backendModuleRootPaths.some((e) => e.test(dirPath));
const isBackendModuleRoot = executionContext.isBackendModule(dirPath);
const isDTO = (new RegExp(pathPatterns.backend.dtos, 'g')).test(dirPath);

@@ -110,4 +109,13 @@ const isReactHook = new RegExp(`${[pathPatterns.frontend['roq-hooks'], allowedNamingPattern].join(escapedSep)}$`).test(dirPath);

const isView = (new RegExp(`${[pathPatterns.frontend.views, allowedNamingPattern].join(escapedSep)}$`)).test(dirPath);
const isComponent = (new RegExp(`${[pathPatterns.frontend.components, allowedNamingPattern].join(escapedSep)}$`)).test(dirPath);
if (isBackendModuleRoot) { // type has to be module
if (isComponent) {
parentType = 'component';
const suffixCheck = checkSuffixMismatch(file, parentType);
mismatchType = suffixCheck.mismatchType;
if (mismatchType) {
expectedFileName = suffixCheck.expectedFileName;
isExceptionalMismatch = true;
}
} else if (isBackendModuleRoot) { // type has to be module
parentType = 'module';

@@ -114,0 +122,0 @@ const suffixCheck = checkSuffixMismatch(file, parentType);

@@ -9,3 +9,9 @@ const { fileContext } = require('../../helper');

if (isUnsuitableDirectory) {
const functionWithDecoratorCheck = directoryType === 'entity'
&& node.parent
&& node.parent.parent
&& node.parent.parent.type === 'FunctionExpression'
&& node.parent.parent.parent.decorators;
if (!functionWithDecoratorCheck && isUnsuitableDirectory) {
context.report({

@@ -12,0 +18,0 @@ loc: node.loc,

@@ -5,3 +5,3 @@ const {

const { fileContext } = require('../../helper');
const { fileContext, executionContext } = require('../../helper');

@@ -51,3 +51,3 @@ const dirChecked = [];

const dirName = dirPath.split(sep).slice(-1)[0];
let dirName = dirPath.split(sep).slice(-1)[0];
let desiredCasing = 'lowerCased';

@@ -58,2 +58,9 @@ let desiredSeparators = 'any';

const { frontendBasePattern } = executionContext.get(context);
const frontendCheck = new RegExp(frontendBasePattern).test(dirPath);
if (frontendCheck && dirName.startsWith('[') && dirName.endsWith(']')) {
dirName = dirName.slice(1, -1);
}
if (ruleOptions && ruleOptions[0]) {

@@ -60,0 +67,0 @@ desiredCasing = ruleOptions[0].casing || 'lowerCased';

const {
escapedSep,
sep,
} = require('../../constants');

@@ -20,2 +21,3 @@ const { fileContext, executionContext } = require('../../helper');

invalidPageResource: 'Default Export name should match parent directory name (when pascalCased). Expected {{expectedPageName}}',
invalidNestedPageResource: 'Default Export name in case of nested pages, can only include directory names in order (when pascalCased, ignoring directory names enclosed in []).',
},

@@ -31,2 +33,4 @@ schema: [],

const dirPath = parentDir.absolutePath;
const dirPathParts = dirPath.split(sep);
const dirName = dirPathParts.slice(-1)[0];

@@ -40,2 +44,13 @@ const isPage = new RegExp(pathPatterns.frontend.pages, 'g').test(dirPath);

if (ruleExecutionRequired) {
const checkPagesDirIndex = (name) => name === 'pages';
const pagesDirIndex = dirPathParts.findIndex(checkPagesDirIndex);
let pagesPathArr = dirPathParts.slice(pagesDirIndex + 1);
if (pagesPathArr[0] === 'components') {
pagesPathArr = pagesPathArr.slice(1);
}
const checkDirNameIndex = (element) => element === dirName;
const isNestedPageResource = pagesPathArr.findIndex(checkDirNameIndex) >= 1;
reportingObj.Program = (node) => {

@@ -51,2 +66,27 @@ const defaultDeclarations = node.body.filter((e) => e.type === 'ExportDefaultDeclaration');

});
} else if (isNestedPageResource) {
const orderedDirectorySequence = [];
pagesPathArr.forEach((dir) => {
if (!dir.startsWith('[') && !dir.endsWith(']')) {
orderedDirectorySequence.push(
...(fileContext.getWordsFromCaseDifferedStrings(dir).map(
(word) => word.charAt(0).toUpperCase() + word.slice(1),
)),
);
}
});
orderedDirectorySequence.push('Page'); // this is for efficient name matching
const exportedPageName = defaultDeclarations[0].declaration.name;
const wordsInExportedName = exportedPageName.split(/(?=[A-Z])/);
let previousWordAtIndex = 0;
const isInvalidName = !exportedPageName.endsWith('Page') || wordsInExportedName.length <= 1 || wordsInExportedName.some((word) => {
previousWordAtIndex = orderedDirectorySequence.indexOf(word, previousWordAtIndex);
return previousWordAtIndex === -1;
});
if (isInvalidName) {
context.report({
node: defaultDeclarations[0],
messageId: 'invalidNestedPageResource',
});
}
} else if (defaultDeclarations[0].declaration.name !== expectedPageName) {

@@ -53,0 +93,0 @@ context.report({

{
"name": "@roq/eslint-plugin",
"version": "1.0.2",
"version": "1.0.3",
"main": "index.js",

@@ -5,0 +5,0 @@ "scripts": {

@@ -20,2 +20,12 @@ const { RuleTester } = require('eslint');

},
{
code: '@Entity()\n'
+ 'export class anyEntity {\n'
+ ' @BeforeInsert()\n'
+ ' convertToJson(): void {\n'
+ ' if (this.parameters) this.parameters = JSON.parse(this.parameters);\n'
+ ' }\n'
+ '}',
filename: 'backend/src/auth/entities/refresh-token.entity.ts',
},
],

@@ -22,0 +32,0 @@ invalid: [

const { RuleTester } = require('eslint');
const ruleUnderTest = require('../../../lib/rules/no-invalid-dirname');
const ruleTesterInstance = new RuleTester({ parserOptions: { ecmaVersion: 2021 } });
const ruleTesterInstance = new RuleTester({
parserOptions: { ecmaVersion: 2021 },
settings: {
'roq-linter': {
backendBasePath: 'backend/src',
frontendBasePath: 'frontend/src',
backendTestsBasePath: 'backend/tests',
},
},
});

@@ -9,2 +18,6 @@ ruleTesterInstance.run('no-invalid-dirname', ruleUnderTest, {

{
code: '// File Path : frontend/src/pages/users/edit/[name]/index.tsx',
filename: 'frontend/src/pages/users/edit/[name]/index.tsx',
},
{
code: '// File Path : backend/src/auth/auth.module.ts',

@@ -104,3 +117,21 @@ filename: 'backend/src/auth/auth.module.ts',

},
{
code: '// File Path : frontend/src/pages/users/edit/test[name]/index.tsx',
errors: [
{
messageId: 'invalidDirName',
data: {
dirName: 'test[name]',
expectedDescription: 'It should be a lowerCased string without numbers and with hyphen separator(s)',
},
line: 1,
column: 1,
endLine: 1,
endColumn: 66,
},
],
filename: 'frontend/src/pages/users/edit/test[name]/index.tsx',
options: [{ casing: 'lowerCased', allowedSeparator: 'hyphen', noNumerics: true }],
},
],
});

@@ -32,2 +32,12 @@ const { RuleTester } = require('eslint');

},
{
code: `/* UsersEditPage definition */
export default UsersEditPage;`,
filename: 'frontend/src/pages/users/edit/[id]/index.tsx',
},
{
code: `/* UsersCreateNewTestPage definition */
export default UsersCreateNewTestPage;`,
filename: 'frontend/src/pages/users/create/new/test/index.tsx',
},
],

@@ -86,3 +96,31 @@ invalid: [

},
{
code: `/* AnyOtherDirNamePage definition */
export default AnyOtherDirNamePage;`,
errors: [
{
messageId: 'invalidNestedPageResource',
line: 2,
column: 7,
endLine: 2,
endColumn: 42,
},
],
filename: 'frontend/src/pages/users/edit/[id]/index.tsx',
},
{
code: `/* TestUsersPage definition */
export default TestUsersPage;`,
errors: [
{
messageId: 'invalidNestedPageResource',
line: 2,
column: 7,
endLine: 2,
endColumn: 36,
},
],
filename: 'frontend/src/pages/users/edit/test/[id]/index.tsx',
},
],
});
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc