initial commit of actions

This commit is contained in:
Dominik Polakovics Polakovics 2026-01-31 18:56:04 +01:00
commit 949ece5785
44660 changed files with 12034344 additions and 0 deletions

View file

@ -0,0 +1,3 @@
node_modules/**
.idea/**
build/**

View file

@ -0,0 +1,14 @@
{
"extends": "eslint:recommended",
"plugins": [
"filenames"
],
"rules": {
"eol-last": 2,
"filenames/match-regex": [2, "^[a-z-]+$", true],
"filenames/match-exported": 2
},
"env": {
"node": true
}
}

View file

@ -0,0 +1,162 @@
# eslint-plugin-filenames
[![NPM Version](https://img.shields.io/npm/v/eslint-plugin-filenames.svg?style=flat-square)](https://www.npmjs.org/package/eslint-plugin-filenames)
[![Build Status](https://img.shields.io/travis/selaux/eslint-plugin-filenames.svg?style=flat-square)](https://travis-ci.org/selaux/eslint-plugin-filenames)
[![Coverage Status](https://img.shields.io/coveralls/selaux/eslint-plugin-filenames.svg?style=flat-square)](https://coveralls.io/r/selaux/eslint-plugin-filenames?branch=master)
[![Dependencies](https://img.shields.io/david/selaux/eslint-plugin-filenames.svg?style=flat-square)](https://david-dm.org/selaux/eslint-plugin-filenames)
Adds [eslint](http://eslint.org/) rules to ensure consistent filenames for your javascript files.
__Please note__: This plugin will only lint the filenames of the `.js`, `.jsx` files you are linting with eslint. It will ignore other files that are not linted with eslint.
## Enabling the plugin
This plugin requires a version of `eslint>=1.0.0` to be installed as a peer dependency.
Modify your `.eslintrc` file to load the plugin and enable the rules you want to use.
```json
{
"plugins": [
"filenames"
],
"rules": {
"filenames/match-regex": 2,
"filenames/match-exported": 2,
"filenames/no-index": 2
}
}
```
## Rules
### Consistent Filenames via regex (match-regex)
A rule to enforce a certain file naming convention using a regular expression.
The convention can be configured using a regular expression (the default is `camelCase.js`). Additionally
exporting files can be ignored with a second configuration parameter.
```json
"filenames/match-regex": [2, "^[a-z_]+$", true]
```
With these configuration options, `camelCase.js` will be reported as an error while `snake_case.js` will pass.
Additionally the files that have a named default export (according to the logic in the `match-exported` rule) will be
ignored. They could be linted with the `match-exported` rule. Please note that exported function calls are not
respected in this case.
### Matching Exported Values (match-exported)
Match the file name against the default exported value in the module. Files that dont have a default export will
be ignored. The exports of `index.js` are matched against their parent directory.
```js
// Considered problem only if the file isn't named foo.js or foo/index.js
export default function foo() {}
// Considered problem only if the file isn't named Foo.js or Foo/index.js
module.exports = class Foo() {}
// Considered problem only if the file isn't named someVariable.js or someVariable/index.js
module.exports = someVariable;
// Never considered a problem
export default { foo: "bar" };
```
If your filename policy doesn't quite match with your variable naming policy, you can add one or multiple transforms:
```json
"filenames/match-exported": [ 2, "kebab" ]
```
Now, in your code:
```js
// Considered problem only if file isn't named variable-name.js or variable-name/index.js
export default function variableName;
```
Available transforms:
'[snake](https://www.npmjs.com/package/lodash.snakecase)',
'[kebab](https://www.npmjs.com/package/lodash.kebabcase)',
'[camel](https://www.npmjs.com/package/lodash.camelcase)', and
'pascal' (camel-cased with first letter in upper case).
For multiple transforms simply specify an array like this (null in this case stands for no transform):
```json
"filenames/match-exported": [2, [ null, "kebab", "snake" ] ]
```
If you prefer to use suffixes for your files (e.g. `Foo.react.js` for a React component file),
you can use a second configuration parameter. It allows you to remove parts of a filename matching a regex pattern
before transforming and matching against the export.
```json
"filenames/match-exported": [ 2, null, "\\.react$" ]
```
Now, in your code:
```js
// Considered problem only if file isn't named variableName.react.js, variableName.js or variableName/index.js
export default function variableName;
```
If you also want to match exported function calls you can use the third option (a boolean flag).
```json
"filenames/match-exported": [ 2, null, null, true ]
```
Now, in your code:
```js
// Considered problem only if file isn't named functionName.js or functionName/index.js
export default functionName();
```
### Don't allow index.js files (no-index)
Having a bunch of `index.js` files can have negative influence on developer experience, e.g. when
opening files by name. When enabling this rule. `index.js` files will always be considered a problem.
## Changelog
#### 1.3.2
- Fix issue with `match-regex` and `getExportedName`
#### 1.3.1
- Put breaking change from `1.3.0` behind a flag
#### 1.3.0
- Support call expressions as named exports
#### 1.2.0
- Introduce `strip` option for `match-exported`
- Introduce support for multiple transform options
- Introduce `pascal` transform
#### 1.1.0
- Introduce `transform` option for `match-exported`
#### 1.0.0
- Split rule into `match-regex`, `match-exported` and `no-index`
#### 0.2.0
- Add match-exported flags
#### 0.1.2
- Fix example in README
#### 0.1.1
- Fix: Text via stdin always passes
- Tests: Travis builds also run on node 0.12 and iojs now
#### 0.1.0
- Initial Release

View file

@ -0,0 +1,9 @@
"use strict";
module.exports = {
rules: {
"match-regex": require("./lib/rules/match-regex"),
"match-exported": require("./lib/rules/match-exported"),
"no-index": require("./lib/rules/no-index")
}
};

View file

@ -0,0 +1,38 @@
function getNodeName(node, options) {
var op = options || [];
if (node.type === "Identifier") {
return node.name;
}
if (node.id && node.id.type === "Identifier") {
return node.id.name;
}
if (op[2] && node.type === "CallExpression" && node.callee.type === "Identifier") {
return node.callee.name;
}
}
module.exports = function getExportedName(programNode, options) {
for (var i = 0; i < programNode.body.length; i += 1) {
var node = programNode.body[i];
// export default ...
if (node.type === "ExportDefaultDeclaration") {
return getNodeName(node.declaration, options);
}
// module.exports = ...
if (node.type === "ExpressionStatement" &&
node.expression.type === "AssignmentExpression" &&
node.expression.left.type === "MemberExpression" &&
node.expression.left.object.type === "Identifier" &&
node.expression.left.object.name === "module" &&
node.expression.left.property.type === "Identifier" &&
node.expression.left.property.name === "exports"
) {
return getNodeName(node.expression.right, options);
}
}
};

View file

@ -0,0 +1,5 @@
var ignoredFilenames = [ "<text>", "<input>" ];
module.exports = function isIgnoredFilename(filename) {
return ignoredFilenames.indexOf(filename) !== -1;
};

View file

@ -0,0 +1,3 @@
module.exports = function isIndexFile(parsed) {
return parsed.name === 'index';
};

View file

@ -0,0 +1,12 @@
var path = require('path');
module.exports = function parseFilename(filename) {
var ext = path.extname(filename);
return {
dir: path.dirname(filename),
base: path.basename(filename),
ext: ext,
name: path.basename(filename, ext)
}
};

View file

@ -0,0 +1,123 @@
/**
* @fileoverview Rule to ensure that filenames match the exports of the file
* @author Stefan Lau
*/
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
var path = require('path'),
camelCase = require('lodash.camelcase'),
upperFirst = require('lodash.upperfirst'),
parseFilename = require('../common/parseFilename'),
isIgnoredFilename = require('../common/isIgnoredFilename'),
getExportedName = require('../common/getExportedName'),
isIndexFile = require('../common/isIndexFile'),
transforms = {
kebab: require('lodash.kebabcase'),
snake: require('lodash.snakecase'),
camel: camelCase,
pascal: function (name) {
return upperFirst(camelCase(name));
}
},
transformNames = Object.keys(transforms),
transformSchema = { "enum": transformNames.concat([ null ]) };
function getStringToCheckAgainstExport(parsed, replacePattern) {
var dirArray = parsed.dir.split(path.sep);
var lastDirectory = dirArray[dirArray.length - 1];
if (isIndexFile(parsed)) {
return lastDirectory;
} else {
return replacePattern ? parsed.name.replace(replacePattern, '') : parsed.name;
}
}
function getTransformsFromOptions(option) {
var usedTransforms = (option && option.push) ? option : [ option ];
return usedTransforms.map(function (name) {
return transforms[name];
});
}
function transform(exportedName, transforms) {
return transforms.map(function (t) {
return t ? t(exportedName) : exportedName;
});
}
function anyMatch(expectedExport, transformedNames) {
return transformedNames.some(function (name) {
return name === expectedExport;
});
}
function getWhatToMatchMessage(transforms) {
if (transforms.length === 1 && !transforms[0]) {
return "the exported name";
}
if (transforms.length > 1) {
return "any of the exported and transformed names"
}
return "the exported and transformed name";
}
module.exports = function(context) {
return {
"Program": function (node) {
var transforms = getTransformsFromOptions(context.options[0]),
replacePattern = context.options[1] ? new RegExp(context.options[1]) : null,
filename = context.getFilename(),
absoluteFilename = path.resolve(filename),
parsed = parseFilename(absoluteFilename),
shouldIgnore = isIgnoredFilename(filename),
exportedName = getExportedName(node, context.options),
isExporting = Boolean(exportedName),
expectedExport = getStringToCheckAgainstExport(parsed, replacePattern),
transformedNames = transform(exportedName, transforms),
everythingIsIndex = exportedName === 'index' && parsed.name === 'index',
matchesExported = anyMatch(expectedExport, transformedNames) || everythingIsIndex,
reportIf = function (condition, messageForNormalFile, messageForIndexFile) {
var message = (!messageForIndexFile || !isIndexFile(parsed)) ? messageForNormalFile : messageForIndexFile;
if (condition) {
context.report(node, message, {
name: parsed.base,
expectedExport: expectedExport,
exportName: transformedNames.join("', '"),
extension: parsed.ext,
whatToMatch: getWhatToMatchMessage(transforms)
});
}
};
if (shouldIgnore) return;
reportIf(
isExporting && !matchesExported,
"Filename '{{expectedExport}}' must match {{whatToMatch}} '{{exportName}}'.",
"The directory '{{expectedExport}}' must be named '{{exportName}}', after the exported value of its index file."
);
}
}
};
module.exports.schema = [
{
oneOf: [
transformSchema,
{ type: "array", items: transformSchema, minItems: 1 }
]
},
{
type: [ "string", "null" ]
},
{
type: [ "boolean", "null" ]
}
];

View file

@ -0,0 +1,40 @@
/**
* @fileoverview Rule to ensure that filenames match a convention (default: camelCase)
* @author Stefan Lau
*/
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
"use strict";
var path = require("path"),
parseFilename = require('../common/parseFilename'),
getExportedName = require('../common/getExportedName'),
isIgnoredFilename = require('../common/isIgnoredFilename');
module.exports = function(context) {
var defaultRegexp = /^([a-z0-9]+)([A-Z][a-z0-9]+)*$/g,
conventionRegexp = context.options[0] ? new RegExp(context.options[0]) : defaultRegexp,
ignoreExporting = context.options[1] ? context.options[1] : false;
return {
"Program": function(node) {
var filename = context.getFilename(),
absoluteFilename = path.resolve(filename),
parsed = parseFilename(absoluteFilename),
shouldIgnore = isIgnoredFilename(filename),
isExporting = Boolean(getExportedName(node)),
matchesRegex = conventionRegexp.test(parsed.name);
if (shouldIgnore) return;
if (ignoreExporting && isExporting) return;
if (!matchesRegex) {
context.report(node, "Filename '{{name}}' does not match the naming convention.", {
name: parsed.base
});
}
}
};
};

View file

@ -0,0 +1,32 @@
/**
* @fileoverview Rule to ensure that there exist no index files
* @author Stefan Lau
*/
//------------------------------------------------------------------------------
// Rule Definition
//------------------------------------------------------------------------------
var path = require('path'),
parseFilename = require('../common/parseFilename'),
isIgnoredFilename = require('../common/isIgnoredFilename'),
isIndexFile = require('../common/isIndexFile');
module.exports = function(context) {
return {
"Program": function(node) {
var filename = context.getFilename(),
absoluteFilename = path.resolve(filename),
parsed = parseFilename(absoluteFilename),
shouldIgnore = isIgnoredFilename(filename),
isIndex = isIndexFile(parsed);
if (shouldIgnore) return;
if (isIndex) {
context.report(node, "'index.js' files are not allowed.");
}
}
};
};

View file

@ -0,0 +1,50 @@
{
"name": "eslint-plugin-filenames",
"version": "1.3.2",
"description": "Eslint rule for consistent filenames.",
"main": "index.js",
"scripts": {
"test": "npm run lint && npm run unit-test --coverage && npm run check-coverage",
"lint": "eslint .",
"unit-test": "istanbul test --dir build/coverage _mocha test -- --recursive --reporter dot",
"check-coverage": "istanbul check-coverage --statement 100 --branch 100 --function 100 --lines 100",
"report-coverage-html": "istanbul report --dir build/coverage html",
"coveralls": "cat ./build/coverage/lcov.info | coveralls"
},
"dependencies": {
"lodash.camelcase": "4.3.0",
"lodash.kebabcase": "4.1.1",
"lodash.snakecase": "4.1.1",
"lodash.upperfirst": "4.3.1"
},
"devDependencies": {
"chai": "3.5.0",
"coveralls": "2.13.0",
"eslint": "^2.0.0",
"eslint-plugin-filenames": "^1.0.0",
"istanbul": "0.4.5",
"mocha": "3.2.0",
"sinon": "2.1.0"
},
"peerDependencies": {
"eslint": "*"
},
"repository": {
"type": "git",
"url": "git://github.com/selaux/eslint-plugin-filenames.git"
},
"author": "Stefan Lau <github@stefanlau.com>",
"license": "MIT",
"bugs": {
"url": "https://github.com/selaux/eslint-plugin-filenames/issues"
},
"homepage": "https://github.com/selaux/eslint-plugin-filenames",
"keywords": [
"eslint",
"eslintplugin",
"eslint-plugin",
"file",
"filename",
"path"
]
}