aberlaas-lint 2.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,9 @@
1
+ MIT License
2
+
3
+ Copyright (c) Tim Carry (tim@pixelastic.com)
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,194 @@
1
+ import js from '@eslint/js';
2
+ import globals from 'globals';
3
+ import pluginN from 'eslint-plugin-n';
4
+ import pluginImport from 'eslint-plugin-import';
5
+ import pluginJsdoc from 'eslint-plugin-jsdoc';
6
+ import pluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
7
+ // Note:
8
+ // It is currently required to manually add typescript and
9
+ // @typescript-eslint/utils to aberlaas for the plugin to work
10
+ // See: https://github.com/vitest-dev/eslint-plugin-vitest/issues/543
11
+ import pluginVitest from '@vitest/eslint-plugin';
12
+ import { nodeVersion } from 'aberlaas-versions';
13
+
14
+ export default [
15
+ {
16
+ name: 'aberlaas/base',
17
+ files: ['**/*.js'],
18
+ ignores: ['node_modules/*', '.yarn/*'],
19
+ languageOptions: {
20
+ ecmaVersion: 'latest',
21
+ sourceType: 'module',
22
+ globals: {
23
+ ...globals.nodeBuiltin,
24
+ ...globals.browser,
25
+ ...pluginN.configs['flat/recommended'].languageOptions.globals,
26
+ },
27
+ },
28
+ linterOptions: {
29
+ reportUnusedDisableDirectives: 'warn',
30
+ },
31
+ plugins: {
32
+ import: pluginImport.flatConfigs.recommended.plugins.import,
33
+ jsdoc: pluginJsdoc.configs['flat/recommended'].plugins.jsdoc,
34
+ n: pluginN.configs['flat/recommended'].plugins.n,
35
+ prettier: pluginPrettierRecommended.plugins.prettier,
36
+ },
37
+ rules: {
38
+ ...js.configs.recommended.rules,
39
+ ...pluginImport.flatConfigs.recommended.rules,
40
+ ...pluginJsdoc.configs['flat/recommended'].plugins.rules,
41
+ ...pluginN.configs['flat/recommended'].plugins.rules,
42
+ 'dot-notation': ['error'],
43
+ 'max-len': [
44
+ 'error',
45
+ {
46
+ code: 80,
47
+ ignoreComments: true,
48
+ ignoreRegExpLiterals: true,
49
+ ignoreStrings: true,
50
+ ignoreTemplateLiterals: true,
51
+ ignoreTrailingComments: true,
52
+ ignoreUrls: true,
53
+ // Ignore long lines in test headers, allowing us to write descriptive
54
+ // tests
55
+ ignorePattern: '^\\s*it\\(',
56
+ },
57
+ ],
58
+ 'no-console': ['off'],
59
+ 'no-irregular-whitespace': ['error', { skipRegExps: true }],
60
+ 'no-restricted-properties': [
61
+ 'error',
62
+ {
63
+ object: 'module',
64
+ property: 'export',
65
+ message: 'Typo: Use module.exports instead',
66
+ },
67
+ {
68
+ object: '_',
69
+ property: 'contains',
70
+ message: 'Typo: Use _.includes instead',
71
+ },
72
+ ],
73
+ 'no-unused-vars': [
74
+ 'error',
75
+ {
76
+ argsIgnorePattern: '^_.',
77
+ varsIgnorePattern: '^_.',
78
+ caughtErrorsIgnorePattern: '^_.',
79
+ },
80
+ ],
81
+ 'no-shadow': ['error'],
82
+ 'object-shorthand': ['error', 'always'],
83
+ 'quote-props': ['error', 'consistent-as-needed'],
84
+ quotes: ['error', 'single', { avoidEscape: true }],
85
+ 'sort-imports': ['error', { ignoreDeclarationSort: true }],
86
+ // Node
87
+ 'n/no-unsupported-features/es-syntax': [
88
+ 'error',
89
+ { version: `>=${nodeVersion}` },
90
+ ],
91
+ // Import
92
+ 'import/first': ['error'],
93
+ 'import/no-cycle': ['error', { ignoreExternal: true, disableScc: true }],
94
+ 'import/order': ['error'],
95
+ 'import/newline-after-import': ['error'],
96
+ // Ignoring this rule for lint-staged, as it seem to have a missing .main
97
+ // field in its package.json
98
+ // See: https://github.com/lint-staged/lint-staged/issues/1474
99
+ 'import/no-unresolved': ['error', { ignore: ['lint-staged'] }],
100
+ // JSDoc
101
+ 'jsdoc/check-param-names': ['warn'],
102
+ 'jsdoc/check-types': ['warn'],
103
+ 'jsdoc/no-undefined-types': ['warn'],
104
+ 'jsdoc/check-alignment': ['warn'],
105
+ 'jsdoc/check-examples': ['off'],
106
+ 'jsdoc/check-syntax': ['warn'],
107
+ 'jsdoc/check-tag-names': ['warn'],
108
+ 'jsdoc/require-jsdoc': ['warn'],
109
+ 'jsdoc/require-param': ['warn'],
110
+ 'jsdoc/require-param-description': ['warn'],
111
+ 'jsdoc/require-param-name': ['warn'],
112
+ 'jsdoc/require-param-type': ['warn'],
113
+ 'jsdoc/require-returns': ['warn'],
114
+ 'jsdoc/require-returns-check': ['warn'],
115
+ 'jsdoc/require-returns-description': ['warn'],
116
+ 'jsdoc/require-returns-type': ['warn'],
117
+ 'jsdoc/valid-types': ['warn'],
118
+ // Prettier
119
+ ...pluginPrettierRecommended.rules,
120
+ },
121
+ settings: {
122
+ // eslint-plugin-import doesn't currently support the "exports" syntax in
123
+ // package.json. This is supposed to allow mapping between custom
124
+ // entrypoints and files on disk.
125
+ // For example, it doesn't understand "import * from 'vitest/config';" as
126
+ // "vitest/config/" isn't really an existing filepath, but a mapping defined
127
+ // in vitest package.json
128
+ //
129
+ // Until this is fixed (see
130
+ // https://github.com/import-js/eslint-plugin-import/issues/2430)
131
+ // we manually define the most common extensions
132
+ 'import/resolver': {
133
+ node: { extensions: ['.js', '.cjs', '.mjs', '.d.ts'] },
134
+ },
135
+ },
136
+ },
137
+ {
138
+ name: 'aberlaas/vitest',
139
+ files: ['**/__tests__/**/*.js'],
140
+ languageOptions: {
141
+ globals: {
142
+ afterAll: true,
143
+ afterEach: true,
144
+ beforeAll: true,
145
+ beforeEach: true,
146
+ describe: true,
147
+ expect: true,
148
+ it: true,
149
+ test: true,
150
+ vitest: true,
151
+ vi: true,
152
+ captureOutput: false,
153
+ dedent: false,
154
+ fdescribe: false,
155
+ fit: false,
156
+ testName: false,
157
+ xdescribe: false,
158
+ xit: false,
159
+ },
160
+ },
161
+ plugins: {
162
+ vitest: pluginVitest,
163
+ },
164
+ rules: {
165
+ ...pluginVitest.configs.recommended.rules,
166
+ 'no-restricted-globals': [
167
+ 'error',
168
+ { name: 'fit', message: 'No focused test' },
169
+ { name: 'fdescribe', message: 'No focused tests' },
170
+ { name: 'xit', message: 'No skipped test' },
171
+ { name: 'xdescribe', message: 'No skipped tests' },
172
+ ],
173
+ // In tests, we like to have the variable 'current' hold the object
174
+ // under test. The import/no-named-as-default-member would have warned
175
+ // us about using current.foo rather than foo directly, so we disable
176
+ // it.
177
+ 'import/no-named-as-default-member': ['off'],
178
+ 'vitest/consistent-test-it': ['warn', { fn: 'it' }],
179
+ // Disabling vitest/no-identical-title
180
+ // It can make eslint crash when used with fit/xit/fdescribe/xdescribe
181
+ // See: https://github.com/veritem/eslint-plugin-vitest/issues/310
182
+ 'vitest/no-identical-title': ['off'],
183
+ 'vitest/prefer-to-contain': ['error'],
184
+ },
185
+ },
186
+ {
187
+ name: 'aberlaas/scripts',
188
+ files: ['**/scripts/**/*.js'],
189
+ rules: { 'no-process-exit': ['off'] },
190
+ },
191
+ {
192
+ ignores: ['**/docs/**/*.js'],
193
+ },
194
+ ];
@@ -0,0 +1,4 @@
1
+ export default {
2
+ singleQuote: true,
3
+ printWidth: 80,
4
+ };
@@ -0,0 +1,38 @@
1
+ // Initially exported from
2
+ // https://github.com/stylelint/stylelint-config-recommended/blob/master/index.js
3
+ export default {
4
+ rules: {
5
+ 'at-rule-no-unknown': [
6
+ true,
7
+ {
8
+ ignoreAtRules: ['screen', 'tailwind'],
9
+ },
10
+ ],
11
+ 'block-no-empty': true,
12
+ 'color-no-invalid-hex': true,
13
+ 'comment-no-empty': true,
14
+ 'declaration-property-value-no-unknown': true,
15
+ 'declaration-block-no-duplicate-properties': [
16
+ true,
17
+ {
18
+ ignore: ['consecutive-duplicates-with-different-values'],
19
+ },
20
+ ],
21
+ 'declaration-block-no-redundant-longhand-properties': true,
22
+ 'declaration-block-no-shorthand-property-overrides': true,
23
+ 'font-family-no-duplicate-names': true,
24
+ 'function-calc-no-unspaced-operator': true,
25
+ 'function-linear-gradient-no-nonstandard-direction': true,
26
+ 'keyframe-declaration-no-important': true,
27
+ 'media-feature-name-no-unknown': true,
28
+ 'no-empty-source': true,
29
+ 'no-invalid-double-slash-comments': true,
30
+ 'property-no-unknown': true,
31
+ 'selector-pseudo-class-no-unknown': true,
32
+ 'selector-pseudo-element-no-unknown': true,
33
+ 'selector-type-no-unknown': true,
34
+ 'shorthand-property-no-redundant-values': true,
35
+ 'string-no-newline': true,
36
+ 'unit-no-unknown': true,
37
+ },
38
+ };
@@ -0,0 +1,81 @@
1
+ import ciInfo from 'ci-info';
2
+ import { exists, firostError, run, which } from 'firost';
3
+ import helper from 'aberlaas-helper';
4
+ import lintYml from './yml.js';
5
+
6
+ export default {
7
+ configPath: '.circleci/config.yml',
8
+ /**
9
+ * Find all relevant files
10
+ * @returns {Array} Array of files
11
+ */
12
+ async getInputFiles() {
13
+ return await helper.findHostFiles([this.configPath]);
14
+ },
15
+ /**
16
+ * Check if the code is currently running on CircleCI
17
+ * @returns {boolean} True if running on CircleCI, false otherwise
18
+ */
19
+ isRunningOnCircleCi() {
20
+ return ciInfo.CIRCLE;
21
+ },
22
+ /**
23
+ * Check if the circleci binary is available in the $PATH
24
+ * @returns {boolean} True if available, false otherwise
25
+ */
26
+ async hasCircleCiBin() {
27
+ const binary = await which('circleci');
28
+ return !!binary;
29
+ },
30
+ /**
31
+ * Validate the CircleCI config file.
32
+ * @returns {boolean} True if valid, throws an error if not
33
+ */
34
+ async validateConfig() {
35
+ await run('circleci config validate', { stdout: false });
36
+ },
37
+ /**
38
+ * Lint the file, both for yml issues and if possible circleci specifics
39
+ * @returns {boolean} True on success
40
+ */
41
+ async run() {
42
+ const absoluteConfigPath = helper.hostPath(this.configPath);
43
+ const hasConfigFile = await exists(absoluteConfigPath);
44
+ const isRunningOnCircleCi = this.isRunningOnCircleCi();
45
+
46
+ // Stop early if no config file, or if running on CircleCI
47
+ if (!hasConfigFile || isRunningOnCircleCi) {
48
+ return true;
49
+ }
50
+
51
+ // Lint as yml first
52
+ await lintYml.run([absoluteConfigPath]);
53
+
54
+ // Stop early if no circleci bin available
55
+ if (!(await this.hasCircleCiBin())) {
56
+ return true;
57
+ }
58
+
59
+ // Validate the config
60
+ try {
61
+ await this.validateConfig();
62
+ } catch (error) {
63
+ const errorMessage = `CircleCI config error on ${this.configPath}\n${error.message}`;
64
+ throw firostError('CircleCiLintError', errorMessage);
65
+ }
66
+
67
+ return true;
68
+ },
69
+ /**
70
+ * Autofix yml issues in file
71
+ * @returns {boolean} True on success
72
+ */
73
+ async fix() {
74
+ const absoluteConfigPath = helper.hostPath(this.configPath);
75
+ // Fix yml issues
76
+ await lintYml.fix([absoluteConfigPath]);
77
+
78
+ // Check for file errors so it still fails if file is invalid
79
+ await this.run();
80
+ },
81
+ };
package/lib/css.js ADDED
@@ -0,0 +1,73 @@
1
+ import stylelint from 'stylelint';
2
+ import { _ } from 'golgoth';
3
+ import { firostError } from 'firost';
4
+ import helper from 'aberlaas-helper';
5
+ import stylelintConfig from '../configs/stylelint.js';
6
+ import { fix as prettierFix } from './helpers/prettier.js';
7
+
8
+ export default {
9
+ /**
10
+ * Find all relevant files
11
+ * @param {Array} userPatterns Patterns to narrow the search down
12
+ * @returns {Array} Array of files
13
+ */
14
+ async getInputFiles(userPatterns) {
15
+ const filePatterns = _.isEmpty(userPatterns)
16
+ ? ['./**/*.css']
17
+ : userPatterns;
18
+ return await helper.findHostFiles(filePatterns, ['.css']);
19
+ },
20
+ /**
21
+ * Lint all files and display results.
22
+ * @param {Array} userPatterns Patterns to narrow the search down
23
+ * @param {string} userConfigFile Custom config file to use
24
+ * @param {object} userOptions Options to pass to ESLint, including fix
25
+ * @returns {boolean} True on success
26
+ */
27
+ async run(userPatterns, userConfigFile, userOptions = {}) {
28
+ // Options
29
+ const options = { fix: false, ...userOptions };
30
+
31
+ // Files
32
+ const files = await this.getInputFiles(userPatterns);
33
+ if (_.isEmpty(files)) {
34
+ return true;
35
+ }
36
+
37
+ // Config
38
+ const config = await helper.getConfig(
39
+ userConfigFile,
40
+ 'stylelint.config.js',
41
+ stylelintConfig,
42
+ );
43
+
44
+ const result = await stylelint.lint({
45
+ config,
46
+ files,
47
+ formatter: 'string',
48
+ ...options,
49
+ });
50
+
51
+ if (result.errored) {
52
+ throw firostError('ERROR_CSS_LINT', result.report);
53
+ }
54
+ return true;
55
+ },
56
+ /**
57
+ * Autofix files in place
58
+ * @param {Array} userPatterns Patterns to narrow the search down
59
+ * @param {string} userConfigFile Custom config file to use
60
+ * @returns {boolean} True on success
61
+ */
62
+ async fix(userPatterns, userConfigFile) {
63
+ const files = await this.getInputFiles(userPatterns);
64
+ if (_.isEmpty(files)) {
65
+ return true;
66
+ }
67
+ // Try to pretiffy as much as we can
68
+ await prettierFix(files);
69
+ // Still run a lint on it so it can fail if not everything is fixed
70
+ await this.run(userPatterns, userConfigFile, { fix: true });
71
+ return true;
72
+ },
73
+ };
package/lib/js.js ADDED
@@ -0,0 +1,75 @@
1
+ import { _ } from 'golgoth';
2
+ import { firostError } from 'firost';
3
+ import { ESLint } from 'eslint';
4
+ import helper from 'aberlaas-helper';
5
+ import eslintConfig from '../configs/eslint.js';
6
+
7
+ export default {
8
+ /**
9
+ * Find all relevant files
10
+ * @param {Array} userPatterns Patterns to narrow the search down
11
+ * @returns {Array} Array of files
12
+ */
13
+ async getInputFiles(userPatterns) {
14
+ const filePatterns = _.isEmpty(userPatterns) ? ['./**/*.js'] : userPatterns;
15
+
16
+ return await helper.findHostFiles(filePatterns, ['.js']);
17
+ },
18
+ /**
19
+ * Lint all files and display results.
20
+ * @param {Array} userPatterns Patterns to narrow the search down
21
+ * @param {string} userConfigFile Custom config file to use
22
+ * @param {object} userOptions Options to pass to ESLint, including fix
23
+ * @returns {boolean} True on success
24
+ */
25
+ async run(userPatterns, userConfigFile, userOptions = {}) {
26
+ // Options
27
+ const options = { fix: false, ...userOptions };
28
+
29
+ // Files to lint
30
+ const files = await this.getInputFiles(userPatterns);
31
+ if (_.isEmpty(files)) {
32
+ return true;
33
+ }
34
+
35
+ // Config file
36
+ const config = await helper.getConfig(
37
+ userConfigFile,
38
+ 'eslint.config.js',
39
+ eslintConfig,
40
+ );
41
+
42
+ // Run the actual lint
43
+ const eslint = new ESLint({
44
+ ...options,
45
+ overrideConfigFile: true,
46
+ overrideConfig: config,
47
+ });
48
+ const results = await eslint.lintFiles(files);
49
+
50
+ // Fix
51
+ if (options.fix) {
52
+ await ESLint.outputFixes(results);
53
+ }
54
+
55
+ // All good, we can stop
56
+ const errorCount = _.chain(results).map('errorCount').sum().value();
57
+ if (errorCount == 0) {
58
+ return true;
59
+ }
60
+
61
+ // Format errors
62
+ const formatter = await eslint.loadFormatter('stylish');
63
+ const errorText = formatter.format(results);
64
+ throw firostError('JavaScriptLintError', errorText);
65
+ },
66
+ /**
67
+ * Autofix files in place
68
+ * @param {Array} userPatterns Patterns to narrow the search down
69
+ * @param {string} userConfigFile Custom config file to use
70
+ * @returns {boolean} True on success
71
+ */
72
+ async fix(userPatterns, userConfigFile) {
73
+ return await this.run(userPatterns, userConfigFile, { fix: true });
74
+ },
75
+ };
package/lib/json.js ADDED
@@ -0,0 +1,60 @@
1
+ import path from 'path';
2
+ import { _, pMap } from 'golgoth';
3
+ import { firostError, read } from 'firost';
4
+ import helper from 'aberlaas-helper';
5
+ import { fix as prettierFix } from './helpers/prettier.js';
6
+
7
+ export default {
8
+ /**
9
+ * Find all relevant files
10
+ * @param {Array} userPatterns Patterns to narrow the search down
11
+ * @returns {Array} Array of files
12
+ */
13
+ async getInputFiles(userPatterns) {
14
+ const filePatterns = _.isEmpty(userPatterns)
15
+ ? ['./**/*.json']
16
+ : userPatterns;
17
+ return await helper.findHostFiles(filePatterns, ['.json']);
18
+ },
19
+ /**
20
+ * Lint all files and display results.
21
+ * @param {Array} userPatterns Patterns to narrow the search down
22
+ * @returns {boolean} True on success
23
+ */
24
+ async run(userPatterns) {
25
+ const files = await this.getInputFiles(userPatterns);
26
+ if (_.isEmpty(files)) {
27
+ return true;
28
+ }
29
+
30
+ let hasErrors = false;
31
+ const errorMessages = [];
32
+ await pMap(files, async (filepath) => {
33
+ try {
34
+ JSON.parse(await read(filepath));
35
+ } catch (error) {
36
+ hasErrors = true;
37
+ const relativePath = path.relative(helper.hostRoot(), filepath);
38
+ errorMessages.push(`Invalid JSON: ${relativePath}`);
39
+ errorMessages.push(error.message);
40
+ }
41
+ });
42
+
43
+ if (hasErrors) {
44
+ throw firostError('JsonLintError', errorMessages.join('\n'));
45
+ }
46
+ return true;
47
+ },
48
+ /**
49
+ * Autofix files in place
50
+ * @param {Array} userPatterns Patterns to narrow the search down
51
+ * @returns {boolean} True on success
52
+ */
53
+ async fix(userPatterns) {
54
+ const files = await this.getInputFiles(userPatterns);
55
+ if (_.isEmpty(files)) {
56
+ return true;
57
+ }
58
+ await prettierFix(files);
59
+ },
60
+ };
package/lib/main.js ADDED
@@ -0,0 +1,62 @@
1
+ import { _, pMap } from 'golgoth';
2
+ import { consoleError, firostError, firostImport } from 'firost';
3
+
4
+ export default {
5
+ /**
6
+ * List of all available linters, along with the --flag name
7
+ **/
8
+ linters: {
9
+ circleci: './circleci.js',
10
+ css: './css.js',
11
+ json: './json.js',
12
+ js: './js.js',
13
+ yml: './yml.js',
14
+ },
15
+
16
+ /**
17
+ * Returns a linter, based on its name
18
+ * @param {string} linterType Name of the linter
19
+ * @returns {object} Linter
20
+ **/
21
+ async getLinter(linterType) {
22
+ const linterPath = this.linters[linterType];
23
+ if (!linterPath) {
24
+ return false;
25
+ }
26
+
27
+ return await firostImport(linterPath);
28
+ },
29
+ /**
30
+ * Wrapper to lint all supported formats
31
+ * @param {object} cliArgs CLI Argument object, as created by minimist
32
+ * @returns {boolean} True on success
33
+ */
34
+ async run(cliArgs = {}) {
35
+ const allTypesKeys = _.keys(this.linters);
36
+ const userTypes = _.intersection(_.keys(cliArgs), allTypesKeys);
37
+ const typesToLint = _.isEmpty(userTypes) ? allTypesKeys : userTypes;
38
+
39
+ let hasErrors = false;
40
+ await pMap(typesToLint, async (type) => {
41
+ const methodName = cliArgs.fix ? 'fix' : 'run';
42
+ try {
43
+ const linter = await this.getLinter(type);
44
+
45
+ const configFile = _.get(cliArgs, `config.${type}`);
46
+ const userPatterns = _.get(cliArgs, '_');
47
+
48
+ await linter[methodName](userPatterns, configFile);
49
+ } catch (error) {
50
+ this.__consoleError(error.message);
51
+ hasErrors = true;
52
+ }
53
+ });
54
+
55
+ if (hasErrors) {
56
+ throw firostError('ERROR_LINT', 'Error while linting files');
57
+ }
58
+
59
+ return true;
60
+ },
61
+ __consoleError: consoleError,
62
+ };
package/lib/yml.js ADDED
@@ -0,0 +1,62 @@
1
+ import path from 'path';
2
+ import { firostError, read } from 'firost';
3
+ import { _, pMap } from 'golgoth';
4
+ import yamlLint from 'yaml-lint';
5
+ import helper from 'aberlaas-helper';
6
+ import { fix as prettierFix } from './helpers/prettier.js';
7
+
8
+ export default {
9
+ /**
10
+ * Find all relevant files
11
+ * @param {Array} userPatterns Patterns to narrow the search down
12
+ * @returns {Array} Array of files
13
+ */
14
+ async getInputFiles(userPatterns) {
15
+ const filePatterns = _.isEmpty(userPatterns)
16
+ ? ['./**/*.yml', './**/*.yaml']
17
+ : userPatterns;
18
+ return await helper.findHostFiles(filePatterns, ['.yml', '.yaml']);
19
+ },
20
+ /**
21
+ * Lint all files and display results.
22
+ * @param {Array} userPatterns Patterns to narrow the search down
23
+ * @returns {boolean} True on success
24
+ */
25
+ async run(userPatterns) {
26
+ const files = await this.getInputFiles(userPatterns);
27
+ if (_.isEmpty(files)) {
28
+ return true;
29
+ }
30
+
31
+ let hasErrors = false;
32
+ const errorMessages = [];
33
+ await pMap(files, async (filepath) => {
34
+ const input = await read(filepath);
35
+ try {
36
+ await yamlLint.lint(input);
37
+ } catch (error) {
38
+ hasErrors = true;
39
+ const relativePath = path.relative(helper.hostRoot(), filepath);
40
+ errorMessages.push(`Invalid YAML: ${relativePath}`);
41
+ errorMessages.push(error.message);
42
+ }
43
+ });
44
+
45
+ if (hasErrors) {
46
+ throw firostError('YamlLintError', errorMessages.join('\n'));
47
+ }
48
+ return true;
49
+ },
50
+ /**
51
+ * Autofix files in place
52
+ * @param {Array} userPatterns Patterns to narrow the search down
53
+ * @returns {boolean} True on success
54
+ */
55
+ async fix(userPatterns) {
56
+ const files = await this.getInputFiles(userPatterns);
57
+ if (_.isEmpty(files)) {
58
+ return true;
59
+ }
60
+ await prettierFix(files);
61
+ },
62
+ };
package/package.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "aberlaas-lint",
3
+ "type": "module",
4
+ "description": "aberlaas lint command: Lint files",
5
+ "version": "2.10.0",
6
+ "repository": "pixelastic/aberlaas",
7
+ "homepage": "https://projects.pixelastic.com/aberlaas/",
8
+ "author": "Tim Carry (@pixelastic)",
9
+ "license": "MIT",
10
+ "files": [
11
+ "lib/*.js",
12
+ "configs/*.js"
13
+ ],
14
+ "exports": {
15
+ ".": "./lib/main.js",
16
+ "./configs/eslint": "./configs/eslint.js",
17
+ "./configs/prettier": "./configs/prettier.js",
18
+ "./configs/stylelint": "./configs/stylelint.js"
19
+ },
20
+ "main": "./lib/main.js",
21
+ "engines": {
22
+ "node": ">=18.18.0"
23
+ },
24
+ "scripts": {
25
+ "build": "../../scripts/local/build",
26
+ "build:prod": "../../scripts/local/build-prod",
27
+ "cms": "../../scripts/local/cms",
28
+ "serve": "../../scripts/local/serve",
29
+ "ci": "../../scripts/local/ci",
30
+ "release": "../../scripts/local/release",
31
+ "update": "node ../../scripts/meta/update.js",
32
+ "test:meta": "../../scripts/local/test-meta",
33
+ "test": "../../scripts/local/test",
34
+ "test:watch": "../../scripts/local/test-watch",
35
+ "compress": "../../scripts/local/compress",
36
+ "lint": "../../scripts/local/lint",
37
+ "lint:fix": "../../scripts/local/lint-fix"
38
+ },
39
+ "dependencies": {
40
+ "@eslint/js": "9.12.0",
41
+ "@typescript-eslint/utils": "8.8.1",
42
+ "@vitest/eslint-plugin": "1.1.7",
43
+ "aberlaas-helper": "^2.10.0",
44
+ "aberlaas-versions": "^2.10.0",
45
+ "ci-info": "4.0.0",
46
+ "eslint": "9.12.0",
47
+ "eslint-config-prettier": "9.1.0",
48
+ "eslint-plugin-import": "2.31.0",
49
+ "eslint-plugin-jsdoc": "50.3.1",
50
+ "eslint-plugin-n": "17.11.1",
51
+ "eslint-plugin-prettier": "5.2.1",
52
+ "firost": "4.3.0",
53
+ "golgoth": "2.4.0",
54
+ "prettier": "3.3.3",
55
+ "stylelint": "16.9.0",
56
+ "typescript": "5.6.3",
57
+ "yaml-lint": "1.7.0"
58
+ },
59
+ "gitHead": "bcdaf87c198a588e02b5539c222f611e356d3079"
60
+ }