- Closes #2556 - Closes #2450 **Key intended features:** - go2rtc compatible - 100% test coverage to significantly improve ability to test, maintain and work around browser weirdnesses (e.g. Safari). - Written from the ground up in the style of the rest of the project. **To use:** - Change `live_provider` from `go2rtc` to `go2rtc-experimental`.
118 lines
3.5 KiB
JavaScript
118 lines
3.5 KiB
JavaScript
import path from 'node:path';
|
|
import { fileURLToPath } from 'node:url';
|
|
|
|
import { FlatCompat } from '@eslint/eslintrc';
|
|
import js from '@eslint/js';
|
|
import tsParser from '@typescript-eslint/parser';
|
|
import { defineConfig } from 'eslint/config';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
const compat = new FlatCompat({
|
|
baseDirectory: __dirname,
|
|
recommendedConfig: js.configs.recommended,
|
|
allConfig: js.configs.all,
|
|
});
|
|
|
|
// Local rule: ban the em-dash character (U+2014) anywhere, including comments and
|
|
// strings. The codebase uses a colon or a double hyphen `--` instead. The regex uses
|
|
// the unicode escape so the character never appears literally in this file.
|
|
const noEmDash = {
|
|
meta: {
|
|
type: 'problem',
|
|
docs: { description: 'Disallow the em-dash character; use ":" or "--" instead.' },
|
|
messages: {
|
|
emDash: 'Em-dash character is not allowed; use ":" or "--" instead.',
|
|
},
|
|
},
|
|
create(context) {
|
|
const sourceCode = context.sourceCode ?? context.getSourceCode();
|
|
return {
|
|
Program(node) {
|
|
const text = sourceCode.getText();
|
|
const re = /\u2014/g;
|
|
let match;
|
|
while ((match = re.exec(text)) !== null) {
|
|
context.report({
|
|
node,
|
|
loc: {
|
|
start: sourceCode.getLocFromIndex(match.index),
|
|
end: sourceCode.getLocFromIndex(match.index + 1),
|
|
},
|
|
messageId: 'emDash',
|
|
});
|
|
}
|
|
},
|
|
};
|
|
},
|
|
};
|
|
|
|
export default defineConfig([
|
|
{
|
|
extends: compat.extends('plugin:@typescript-eslint/recommended', 'prettier'),
|
|
|
|
languageOptions: {
|
|
parser: tsParser,
|
|
ecmaVersion: 2020,
|
|
sourceType: 'module',
|
|
},
|
|
|
|
plugins: {
|
|
local: { rules: { 'no-em-dash': noEmDash } },
|
|
},
|
|
|
|
rules: {
|
|
curly: 'error',
|
|
'local/no-em-dash': 'error',
|
|
'@typescript-eslint/consistent-type-definitions': ['error', 'interface'],
|
|
'@typescript-eslint/consistent-type-imports': [
|
|
'error',
|
|
{ fixStyle: 'separate-type-imports' },
|
|
],
|
|
'@typescript-eslint/no-explicit-any': 'error',
|
|
'@typescript-eslint/no-non-null-assertion': 'error',
|
|
'@typescript-eslint/parameter-properties': 'error',
|
|
},
|
|
},
|
|
|
|
// Timers must go through the Timer class (src/utils/timer.ts).
|
|
{
|
|
files: ['src/**/*.ts'],
|
|
rules: {
|
|
'no-restricted-syntax': [
|
|
'error',
|
|
{
|
|
selector:
|
|
'CallExpression > Identifier.callee[name=/^(setTimeout|setInterval)$/]',
|
|
message:
|
|
'Use the Timer class (src/utils/timer.ts) instead of setTimeout/setInterval.',
|
|
},
|
|
{
|
|
selector: 'MemberExpression[property.name=/^(setTimeout|setInterval)$/]',
|
|
message:
|
|
'Use the Timer class (src/utils/timer.ts) instead of window.setTimeout/setInterval.',
|
|
},
|
|
],
|
|
},
|
|
},
|
|
|
|
// A fire-and-forget promise must be marked with `void` to show it is deliberate.
|
|
// To know which calls return a promise, this rule needs type information, so the
|
|
// `project` option below runs the TypeScript type-checker over source while linting.
|
|
// That makes linting source slower. Tests are excluded: they leave promises unawaited
|
|
// freely.
|
|
{
|
|
files: ['src/**/*.ts'],
|
|
languageOptions: {
|
|
parser: tsParser,
|
|
parserOptions: {
|
|
projectService: true,
|
|
tsconfigRootDir: __dirname,
|
|
},
|
|
},
|
|
rules: {
|
|
'@typescript-eslint/no-floating-promises': 'error',
|
|
},
|
|
},
|
|
]);
|