The register test detected narrowings by modelling config shapes, and each review round found one more shape it did not model (a basePath global ignore, a rule src never declares, a widened glob filed under a narrow row, a substring check on a CI line, knip.json beside knip.jsonc). It now compares instead: gates.snapshot.json holds ESLint's effective config for every code file and the lines that run each lane, and any difference fails until it is regenerated. The register is read off the snapshot's configs, which surfaced the ui/ and lib/ test scopes the sampling never reached. The complexity ratchet also names a wrapped function by its binding (const onSave = useCallback(() => ...)), not as "useCallback callback".
2372 lines
98 KiB
JSON
2372 lines
98 KiB
JSON
{
|
|
"eslint": {
|
|
"configs": {
|
|
"FocusSafeButton.tsx + AnchoredPopover.tsx": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"local/focus-safe-disabled": [0],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./(?!\\.\\./)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./\\.\\./components/(?!ui/)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not call a domain API slice. Take the data as props.",
|
|
"regex": "^\\.\\./\\.\\./lib/api(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"design-lab": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": { "local/literal-a11y-text": [0] },
|
|
"settings": null
|
|
},
|
|
"e2e": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "82 names, sha1 29467d490e30",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [
|
|
"local/button-primitive",
|
|
"local/focus-safe-disabled",
|
|
"local/glyph-link",
|
|
"local/input-primitive",
|
|
"local/jsx-comment-text",
|
|
"local/literal-a11y-text",
|
|
"local/locale-format",
|
|
"local/sortable-a11y",
|
|
"local/surface-role",
|
|
"no-console",
|
|
"no-restricted-globals",
|
|
"no-restricted-properties",
|
|
"no-restricted-syntax",
|
|
"react-hooks/capitalized-calls",
|
|
"react-hooks/component-hook-factories",
|
|
"react-hooks/config",
|
|
"react-hooks/error-boundaries",
|
|
"react-hooks/exhaustive-deps",
|
|
"react-hooks/exhaustive-effect-dependencies",
|
|
"react-hooks/gating",
|
|
"react-hooks/globals",
|
|
"react-hooks/hooks",
|
|
"react-hooks/immutability",
|
|
"react-hooks/incompatible-library",
|
|
"react-hooks/invariant",
|
|
"react-hooks/memo-dependencies",
|
|
"react-hooks/memoized-effect-dependencies",
|
|
"react-hooks/no-deriving-state-in-effects",
|
|
"react-hooks/preserve-manual-memoization",
|
|
"react-hooks/purity",
|
|
"react-hooks/refs",
|
|
"react-hooks/rule-suppression",
|
|
"react-hooks/rules-of-hooks",
|
|
"react-hooks/set-state-in-effect",
|
|
"react-hooks/set-state-in-render",
|
|
"react-hooks/static-components",
|
|
"react-hooks/syntax",
|
|
"react-hooks/todo",
|
|
"react-hooks/unsupported-syntax",
|
|
"react-hooks/use-memo",
|
|
"react-hooks/void-use-memo",
|
|
"react-refresh/only-export-components"
|
|
],
|
|
"plugins": ["@", "@eslint-community/eslint-comments", "@typescript-eslint", "playwright"],
|
|
"rules": {
|
|
"@typescript-eslint/no-unused-expressions": [
|
|
2,
|
|
{ "allowShortCircuit": false, "allowTaggedTemplates": false, "allowTernary": false }
|
|
],
|
|
"playwright/no-focused-test": [2],
|
|
"playwright/no-skipped-test": [2]
|
|
},
|
|
"settings": null
|
|
},
|
|
"js configs": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "82 names, sha1 29467d490e30",
|
|
"parser": "(unnamed parser)",
|
|
"parserOptions": { "sourceType": "module" },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [
|
|
"@typescript-eslint/ban-ts-comment",
|
|
"@typescript-eslint/no-array-constructor",
|
|
"@typescript-eslint/no-deprecated",
|
|
"@typescript-eslint/no-duplicate-enum-values",
|
|
"@typescript-eslint/no-empty-object-type",
|
|
"@typescript-eslint/no-explicit-any",
|
|
"@typescript-eslint/no-extra-non-null-assertion",
|
|
"@typescript-eslint/no-floating-promises",
|
|
"@typescript-eslint/no-misused-new",
|
|
"@typescript-eslint/no-namespace",
|
|
"@typescript-eslint/no-non-null-asserted-optional-chain",
|
|
"@typescript-eslint/no-require-imports",
|
|
"@typescript-eslint/no-this-alias",
|
|
"@typescript-eslint/no-unnecessary-type-constraint",
|
|
"@typescript-eslint/no-unsafe-declaration-merging",
|
|
"@typescript-eslint/no-unsafe-function-type",
|
|
"@typescript-eslint/no-unused-expressions",
|
|
"@typescript-eslint/no-unused-vars",
|
|
"@typescript-eslint/no-wrapper-object-types",
|
|
"@typescript-eslint/prefer-as-const",
|
|
"@typescript-eslint/prefer-namespace-keyword",
|
|
"@typescript-eslint/triple-slash-reference",
|
|
"local/button-primitive",
|
|
"local/focus-safe-disabled",
|
|
"local/glyph-link",
|
|
"local/input-primitive",
|
|
"local/jsx-comment-text",
|
|
"local/literal-a11y-text",
|
|
"local/locale-format",
|
|
"local/sortable-a11y",
|
|
"local/surface-role",
|
|
"no-array-constructor",
|
|
"no-console",
|
|
"no-new-symbol",
|
|
"no-restricted-globals",
|
|
"no-restricted-properties",
|
|
"no-restricted-syntax",
|
|
"no-unused-expressions",
|
|
"no-var",
|
|
"prefer-const",
|
|
"prefer-rest-params",
|
|
"prefer-spread",
|
|
"react-hooks/capitalized-calls",
|
|
"react-hooks/component-hook-factories",
|
|
"react-hooks/config",
|
|
"react-hooks/error-boundaries",
|
|
"react-hooks/exhaustive-deps",
|
|
"react-hooks/exhaustive-effect-dependencies",
|
|
"react-hooks/gating",
|
|
"react-hooks/globals",
|
|
"react-hooks/hooks",
|
|
"react-hooks/immutability",
|
|
"react-hooks/incompatible-library",
|
|
"react-hooks/invariant",
|
|
"react-hooks/memo-dependencies",
|
|
"react-hooks/memoized-effect-dependencies",
|
|
"react-hooks/no-deriving-state-in-effects",
|
|
"react-hooks/preserve-manual-memoization",
|
|
"react-hooks/purity",
|
|
"react-hooks/refs",
|
|
"react-hooks/rule-suppression",
|
|
"react-hooks/rules-of-hooks",
|
|
"react-hooks/set-state-in-effect",
|
|
"react-hooks/set-state-in-render",
|
|
"react-hooks/static-components",
|
|
"react-hooks/syntax",
|
|
"react-hooks/todo",
|
|
"react-hooks/unsupported-syntax",
|
|
"react-hooks/use-memo",
|
|
"react-hooks/void-use-memo",
|
|
"react-refresh/only-export-components"
|
|
],
|
|
"plugins": ["@", "@eslint-community/eslint-comments"],
|
|
"rules": {
|
|
"constructor-super": [2],
|
|
"getter-return": [2, { "allowImplicit": false }],
|
|
"no-class-assign": [2],
|
|
"no-const-assign": [2],
|
|
"no-dupe-args": [2],
|
|
"no-dupe-class-members": [2],
|
|
"no-dupe-keys": [2],
|
|
"no-func-assign": [2],
|
|
"no-import-assign": [2],
|
|
"no-new-native-nonconstructor": [2],
|
|
"no-obj-calls": [2],
|
|
"no-redeclare": [2, { "builtinGlobals": true }],
|
|
"no-setter-return": [2],
|
|
"no-this-before-super": [2],
|
|
"no-undef": [2, { "typeof": false }],
|
|
"no-unreachable": [2],
|
|
"no-unsafe-negation": [2, { "enforceForOrderingRelations": false }],
|
|
"no-unused-vars": [2],
|
|
"no-with": [2]
|
|
},
|
|
"settings": null
|
|
},
|
|
"lib tests": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh",
|
|
"vitest"
|
|
],
|
|
"rules": {
|
|
"local/button-primitive": [0],
|
|
"local/glyph-link": [0],
|
|
"local/input-primitive": [0],
|
|
"local/literal-a11y-text": [0],
|
|
"local/surface-role": [0],
|
|
"no-restricted-globals": [
|
|
0,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "lib/ sits below components/: it may not import from components/, not even a type. Move the shared piece down into lib/.",
|
|
"regex": "^(\\.\\./)+components(/|$)"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"no-restricted-properties": [
|
|
0,
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "window",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "globalThis",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/api/core.ts `beacon` (E22 S4).",
|
|
"object": "navigator",
|
|
"property": "sendBeacon"
|
|
}
|
|
],
|
|
"vitest/no-disabled-tests": [2],
|
|
"vitest/no-focused-tests": [2, { "fixable": true }]
|
|
},
|
|
"settings": null
|
|
},
|
|
"lib/api/core.ts": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"no-restricted-globals": [
|
|
2,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "lib/ sits below components/: it may not import from components/, not even a type. Move the shared piece down into lib/.",
|
|
"regex": "^(\\.\\./)+components(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"lib/http.ts": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"no-restricted-globals": [
|
|
2,
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "lib/ sits below components/: it may not import from components/, not even a type. Move the shared piece down into lib/.",
|
|
"regex": "^(\\.\\./)+components(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"lib/messagesSocket.ts": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"no-restricted-globals": [
|
|
2,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "lib/ sits below components/: it may not import from components/, not even a type. Move the shared piece down into lib/.",
|
|
"regex": "^(\\.\\./)+components(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"src": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"@babel/object-curly-spacing": [0],
|
|
"@babel/semi": [0],
|
|
"@eslint-community/eslint-comments/no-unlimited-disable": [2],
|
|
"@eslint-community/eslint-comments/require-description": [2, { "ignore": [] }],
|
|
"@stylistic/array-bracket-newline": [0],
|
|
"@stylistic/array-bracket-spacing": [0],
|
|
"@stylistic/array-element-newline": [0],
|
|
"@stylistic/arrow-parens": [0],
|
|
"@stylistic/arrow-spacing": [0],
|
|
"@stylistic/block-spacing": [0],
|
|
"@stylistic/brace-style": [0],
|
|
"@stylistic/comma-dangle": [0],
|
|
"@stylistic/comma-spacing": [0],
|
|
"@stylistic/comma-style": [0],
|
|
"@stylistic/computed-property-spacing": [0],
|
|
"@stylistic/dot-location": [0],
|
|
"@stylistic/eol-last": [0],
|
|
"@stylistic/func-call-spacing": [0],
|
|
"@stylistic/function-call-argument-newline": [0],
|
|
"@stylistic/function-call-spacing": [0],
|
|
"@stylistic/function-paren-newline": [0],
|
|
"@stylistic/generator-star-spacing": [0],
|
|
"@stylistic/implicit-arrow-linebreak": [0],
|
|
"@stylistic/indent": [0],
|
|
"@stylistic/indent-binary-ops": [0],
|
|
"@stylistic/js/array-bracket-newline": [0],
|
|
"@stylistic/js/array-bracket-spacing": [0],
|
|
"@stylistic/js/array-element-newline": [0],
|
|
"@stylistic/js/arrow-parens": [0],
|
|
"@stylistic/js/arrow-spacing": [0],
|
|
"@stylistic/js/block-spacing": [0],
|
|
"@stylistic/js/brace-style": [0],
|
|
"@stylistic/js/comma-dangle": [0],
|
|
"@stylistic/js/comma-spacing": [0],
|
|
"@stylistic/js/comma-style": [0],
|
|
"@stylistic/js/computed-property-spacing": [0],
|
|
"@stylistic/js/dot-location": [0],
|
|
"@stylistic/js/eol-last": [0],
|
|
"@stylistic/js/func-call-spacing": [0],
|
|
"@stylistic/js/function-call-argument-newline": [0],
|
|
"@stylistic/js/function-call-spacing": [0],
|
|
"@stylistic/js/function-paren-newline": [0],
|
|
"@stylistic/js/generator-star-spacing": [0],
|
|
"@stylistic/js/implicit-arrow-linebreak": [0],
|
|
"@stylistic/js/indent": [0],
|
|
"@stylistic/js/jsx-quotes": [0],
|
|
"@stylistic/js/key-spacing": [0],
|
|
"@stylistic/js/keyword-spacing": [0],
|
|
"@stylistic/js/linebreak-style": [0],
|
|
"@stylistic/js/lines-around-comment": [0],
|
|
"@stylistic/js/max-len": [0],
|
|
"@stylistic/js/max-statements-per-line": [0],
|
|
"@stylistic/js/multiline-ternary": [0],
|
|
"@stylistic/js/new-parens": [0],
|
|
"@stylistic/js/newline-per-chained-call": [0],
|
|
"@stylistic/js/no-confusing-arrow": [0],
|
|
"@stylistic/js/no-extra-parens": [0],
|
|
"@stylistic/js/no-extra-semi": [0],
|
|
"@stylistic/js/no-floating-decimal": [0],
|
|
"@stylistic/js/no-mixed-operators": [0],
|
|
"@stylistic/js/no-mixed-spaces-and-tabs": [0],
|
|
"@stylistic/js/no-multi-spaces": [0],
|
|
"@stylistic/js/no-multiple-empty-lines": [0],
|
|
"@stylistic/js/no-tabs": [0],
|
|
"@stylistic/js/no-trailing-spaces": [0],
|
|
"@stylistic/js/no-whitespace-before-property": [0],
|
|
"@stylistic/js/nonblock-statement-body-position": [0],
|
|
"@stylistic/js/object-curly-newline": [0],
|
|
"@stylistic/js/object-curly-spacing": [0],
|
|
"@stylistic/js/object-property-newline": [0],
|
|
"@stylistic/js/one-var-declaration-per-line": [0],
|
|
"@stylistic/js/operator-linebreak": [0],
|
|
"@stylistic/js/padded-blocks": [0],
|
|
"@stylistic/js/quote-props": [0],
|
|
"@stylistic/js/quotes": [0],
|
|
"@stylistic/js/rest-spread-spacing": [0],
|
|
"@stylistic/js/semi": [0],
|
|
"@stylistic/js/semi-spacing": [0],
|
|
"@stylistic/js/semi-style": [0],
|
|
"@stylistic/js/space-before-blocks": [0],
|
|
"@stylistic/js/space-before-function-paren": [0],
|
|
"@stylistic/js/space-in-parens": [0],
|
|
"@stylistic/js/space-infix-ops": [0],
|
|
"@stylistic/js/space-unary-ops": [0],
|
|
"@stylistic/js/switch-colon-spacing": [0],
|
|
"@stylistic/js/template-curly-spacing": [0],
|
|
"@stylistic/js/template-tag-spacing": [0],
|
|
"@stylistic/js/wrap-iife": [0],
|
|
"@stylistic/js/wrap-regex": [0],
|
|
"@stylistic/js/yield-star-spacing": [0],
|
|
"@stylistic/jsx-child-element-spacing": [0],
|
|
"@stylistic/jsx-closing-bracket-location": [0],
|
|
"@stylistic/jsx-closing-tag-location": [0],
|
|
"@stylistic/jsx-curly-newline": [0],
|
|
"@stylistic/jsx-curly-spacing": [0],
|
|
"@stylistic/jsx-equals-spacing": [0],
|
|
"@stylistic/jsx-first-prop-new-line": [0],
|
|
"@stylistic/jsx-indent": [0],
|
|
"@stylistic/jsx-indent-props": [0],
|
|
"@stylistic/jsx-max-props-per-line": [0],
|
|
"@stylistic/jsx-newline": [0],
|
|
"@stylistic/jsx-one-expression-per-line": [0],
|
|
"@stylistic/jsx-props-no-multi-spaces": [0],
|
|
"@stylistic/jsx-quotes": [0],
|
|
"@stylistic/jsx-tag-spacing": [0],
|
|
"@stylistic/jsx-wrap-multilines": [0],
|
|
"@stylistic/jsx/jsx-child-element-spacing": [0],
|
|
"@stylistic/jsx/jsx-closing-bracket-location": [0],
|
|
"@stylistic/jsx/jsx-closing-tag-location": [0],
|
|
"@stylistic/jsx/jsx-curly-newline": [0],
|
|
"@stylistic/jsx/jsx-curly-spacing": [0],
|
|
"@stylistic/jsx/jsx-equals-spacing": [0],
|
|
"@stylistic/jsx/jsx-first-prop-new-line": [0],
|
|
"@stylistic/jsx/jsx-indent": [0],
|
|
"@stylistic/jsx/jsx-indent-props": [0],
|
|
"@stylistic/jsx/jsx-max-props-per-line": [0],
|
|
"@stylistic/key-spacing": [0],
|
|
"@stylistic/keyword-spacing": [0],
|
|
"@stylistic/linebreak-style": [0],
|
|
"@stylistic/lines-around-comment": [0],
|
|
"@stylistic/max-len": [0],
|
|
"@stylistic/max-statements-per-line": [0],
|
|
"@stylistic/member-delimiter-style": [0],
|
|
"@stylistic/multiline-ternary": [0],
|
|
"@stylistic/new-parens": [0],
|
|
"@stylistic/newline-per-chained-call": [0],
|
|
"@stylistic/no-confusing-arrow": [0],
|
|
"@stylistic/no-extra-parens": [0],
|
|
"@stylistic/no-extra-semi": [0],
|
|
"@stylistic/no-floating-decimal": [0],
|
|
"@stylistic/no-mixed-operators": [0],
|
|
"@stylistic/no-mixed-spaces-and-tabs": [0],
|
|
"@stylistic/no-multi-spaces": [0],
|
|
"@stylistic/no-multiple-empty-lines": [0],
|
|
"@stylistic/no-tabs": [0],
|
|
"@stylistic/no-trailing-spaces": [0],
|
|
"@stylistic/no-whitespace-before-property": [0],
|
|
"@stylistic/nonblock-statement-body-position": [0],
|
|
"@stylistic/object-curly-newline": [0],
|
|
"@stylistic/object-curly-spacing": [0],
|
|
"@stylistic/object-property-newline": [0],
|
|
"@stylistic/one-var-declaration-per-line": [0],
|
|
"@stylistic/operator-linebreak": [0],
|
|
"@stylistic/padded-blocks": [0],
|
|
"@stylistic/quote-props": [0],
|
|
"@stylistic/quotes": [0],
|
|
"@stylistic/rest-spread-spacing": [0],
|
|
"@stylistic/semi": [0],
|
|
"@stylistic/semi-spacing": [0],
|
|
"@stylistic/semi-style": [0],
|
|
"@stylistic/space-before-blocks": [0],
|
|
"@stylistic/space-before-function-paren": [0],
|
|
"@stylistic/space-in-parens": [0],
|
|
"@stylistic/space-infix-ops": [0],
|
|
"@stylistic/space-unary-ops": [0],
|
|
"@stylistic/switch-colon-spacing": [0],
|
|
"@stylistic/template-curly-spacing": [0],
|
|
"@stylistic/template-tag-spacing": [0],
|
|
"@stylistic/ts/block-spacing": [0],
|
|
"@stylistic/ts/brace-style": [0],
|
|
"@stylistic/ts/comma-dangle": [0],
|
|
"@stylistic/ts/comma-spacing": [0],
|
|
"@stylistic/ts/func-call-spacing": [0],
|
|
"@stylistic/ts/function-call-spacing": [0],
|
|
"@stylistic/ts/indent": [0],
|
|
"@stylistic/ts/key-spacing": [0],
|
|
"@stylistic/ts/keyword-spacing": [0],
|
|
"@stylistic/ts/lines-around-comment": [0],
|
|
"@stylistic/ts/member-delimiter-style": [0],
|
|
"@stylistic/ts/no-extra-parens": [0],
|
|
"@stylistic/ts/no-extra-semi": [0],
|
|
"@stylistic/ts/object-curly-spacing": [0],
|
|
"@stylistic/ts/quotes": [0],
|
|
"@stylistic/ts/semi": [0],
|
|
"@stylistic/ts/space-before-blocks": [0],
|
|
"@stylistic/ts/space-before-function-paren": [0],
|
|
"@stylistic/ts/space-infix-ops": [0],
|
|
"@stylistic/ts/type-annotation-spacing": [0],
|
|
"@stylistic/type-annotation-spacing": [0],
|
|
"@stylistic/type-generic-spacing": [0],
|
|
"@stylistic/type-named-tuple-spacing": [0],
|
|
"@stylistic/wrap-iife": [0],
|
|
"@stylistic/wrap-regex": [0],
|
|
"@stylistic/yield-star-spacing": [0],
|
|
"@typescript-eslint/ban-ts-comment": [2],
|
|
"@typescript-eslint/block-spacing": [0],
|
|
"@typescript-eslint/brace-style": [0],
|
|
"@typescript-eslint/comma-dangle": [0],
|
|
"@typescript-eslint/comma-spacing": [0],
|
|
"@typescript-eslint/func-call-spacing": [0],
|
|
"@typescript-eslint/indent": [0],
|
|
"@typescript-eslint/key-spacing": [0],
|
|
"@typescript-eslint/keyword-spacing": [0],
|
|
"@typescript-eslint/lines-around-comment": [0],
|
|
"@typescript-eslint/member-delimiter-style": [0],
|
|
"@typescript-eslint/no-array-constructor": [2],
|
|
"@typescript-eslint/no-deprecated": [2],
|
|
"@typescript-eslint/no-duplicate-enum-values": [2],
|
|
"@typescript-eslint/no-empty-object-type": [2],
|
|
"@typescript-eslint/no-explicit-any": [2],
|
|
"@typescript-eslint/no-extra-non-null-assertion": [2],
|
|
"@typescript-eslint/no-extra-parens": [0],
|
|
"@typescript-eslint/no-extra-semi": [0],
|
|
"@typescript-eslint/no-floating-promises": [
|
|
2,
|
|
{
|
|
"allowForKnownSafeCalls": [
|
|
{
|
|
"from": "package",
|
|
"name": [
|
|
"invalidateQueries",
|
|
"refetchQueries",
|
|
"cancelQueries",
|
|
"resetQueries",
|
|
"prefetchQuery",
|
|
"prefetchInfiniteQuery"
|
|
],
|
|
"package": "@tanstack/query-core"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"@typescript-eslint/no-misused-new": [2],
|
|
"@typescript-eslint/no-namespace": [2],
|
|
"@typescript-eslint/no-non-null-asserted-optional-chain": [2],
|
|
"@typescript-eslint/no-require-imports": [2],
|
|
"@typescript-eslint/no-this-alias": [2],
|
|
"@typescript-eslint/no-unnecessary-type-constraint": [2],
|
|
"@typescript-eslint/no-unsafe-declaration-merging": [2],
|
|
"@typescript-eslint/no-unsafe-function-type": [2],
|
|
"@typescript-eslint/no-unused-expressions": [
|
|
2,
|
|
{ "allowShortCircuit": true, "allowTaggedTemplates": false, "allowTernary": true }
|
|
],
|
|
"@typescript-eslint/no-unused-vars": [0],
|
|
"@typescript-eslint/no-wrapper-object-types": [2],
|
|
"@typescript-eslint/object-curly-spacing": [0],
|
|
"@typescript-eslint/prefer-as-const": [2],
|
|
"@typescript-eslint/prefer-namespace-keyword": [2],
|
|
"@typescript-eslint/quotes": [0],
|
|
"@typescript-eslint/semi": [0],
|
|
"@typescript-eslint/space-before-blocks": [0],
|
|
"@typescript-eslint/space-before-function-paren": [0],
|
|
"@typescript-eslint/space-infix-ops": [0],
|
|
"@typescript-eslint/triple-slash-reference": [2],
|
|
"@typescript-eslint/type-annotation-spacing": [0],
|
|
"array-bracket-newline": [0],
|
|
"array-bracket-spacing": [0],
|
|
"array-element-newline": [0],
|
|
"arrow-parens": [0],
|
|
"arrow-spacing": [0],
|
|
"babel/object-curly-spacing": [0],
|
|
"babel/quotes": [0],
|
|
"babel/semi": [0],
|
|
"block-spacing": [0],
|
|
"brace-style": [0],
|
|
"comma-dangle": [0],
|
|
"comma-spacing": [0],
|
|
"comma-style": [0],
|
|
"computed-property-spacing": [0],
|
|
"constructor-super": [0],
|
|
"curly": [0, "all"],
|
|
"dot-location": [0],
|
|
"eol-last": [0],
|
|
"flowtype/boolean-style": [0],
|
|
"flowtype/delimiter-dangle": [0],
|
|
"flowtype/generic-spacing": [0],
|
|
"flowtype/object-type-curly-spacing": [0],
|
|
"flowtype/object-type-delimiter": [0],
|
|
"flowtype/quotes": [0],
|
|
"flowtype/semi": [0],
|
|
"flowtype/space-after-type-colon": [0],
|
|
"flowtype/space-before-generic-bracket": [0],
|
|
"flowtype/space-before-type-colon": [0],
|
|
"flowtype/union-intersection-spacing": [0],
|
|
"for-direction": [2],
|
|
"func-call-spacing": [0],
|
|
"function-call-argument-newline": [0],
|
|
"function-paren-newline": [0],
|
|
"generator-star": [0],
|
|
"generator-star-spacing": [0],
|
|
"getter-return": [0, { "allowImplicit": false }],
|
|
"implicit-arrow-linebreak": [0],
|
|
"indent": [0],
|
|
"indent-legacy": [0],
|
|
"jsx-quotes": [0],
|
|
"key-spacing": [0],
|
|
"keyword-spacing": [0],
|
|
"linebreak-style": [0],
|
|
"lines-around-comment": [0],
|
|
"local/button-primitive": [2],
|
|
"local/focus-safe-disabled": [2],
|
|
"local/glyph-link": [2],
|
|
"local/input-primitive": [2],
|
|
"local/jsx-comment-text": [2],
|
|
"local/literal-a11y-text": [2],
|
|
"local/locale-format": [2],
|
|
"local/sortable-a11y": [2],
|
|
"local/surface-role": [2],
|
|
"max-len": [0],
|
|
"max-statements-per-line": [0],
|
|
"multiline-ternary": [0],
|
|
"new-parens": [0],
|
|
"newline-per-chained-call": [0],
|
|
"no-array-constructor": [0],
|
|
"no-arrow-condition": [0],
|
|
"no-async-promise-executor": [2],
|
|
"no-case-declarations": [2],
|
|
"no-class-assign": [0],
|
|
"no-comma-dangle": [0],
|
|
"no-compare-neg-zero": [2],
|
|
"no-cond-assign": [2, "except-parens"],
|
|
"no-confusing-arrow": [0],
|
|
"no-console": [2, {}],
|
|
"no-const-assign": [0],
|
|
"no-constant-binary-expression": [2],
|
|
"no-constant-condition": [2, { "checkLoops": "allExceptWhileTrue" }],
|
|
"no-control-regex": [2],
|
|
"no-debugger": [2],
|
|
"no-delete-var": [2],
|
|
"no-dupe-args": [0],
|
|
"no-dupe-class-members": [0],
|
|
"no-dupe-else-if": [2],
|
|
"no-dupe-keys": [0],
|
|
"no-duplicate-case": [2],
|
|
"no-empty": [2, { "allowEmptyCatch": false }],
|
|
"no-empty-character-class": [2],
|
|
"no-empty-pattern": [2, { "allowObjectPatternsAsParameters": false }],
|
|
"no-empty-static-block": [2],
|
|
"no-ex-assign": [2],
|
|
"no-extra-boolean-cast": [2, {}],
|
|
"no-extra-parens": [0],
|
|
"no-extra-semi": [0],
|
|
"no-fallthrough": [
|
|
2,
|
|
{ "allowEmptyCase": false, "reportUnusedFallthroughComment": false }
|
|
],
|
|
"no-floating-decimal": [0],
|
|
"no-func-assign": [0],
|
|
"no-global-assign": [2, { "exceptions": [] }],
|
|
"no-import-assign": [0],
|
|
"no-invalid-regexp": [2, {}],
|
|
"no-irregular-whitespace": [
|
|
2,
|
|
{
|
|
"skipComments": false,
|
|
"skipJSXText": false,
|
|
"skipRegExps": false,
|
|
"skipStrings": true,
|
|
"skipTemplates": false
|
|
}
|
|
],
|
|
"no-loss-of-precision": [2],
|
|
"no-misleading-character-class": [2, { "allowEscape": false }],
|
|
"no-mixed-operators": [0],
|
|
"no-mixed-spaces-and-tabs": [0],
|
|
"no-multi-spaces": [0],
|
|
"no-multiple-empty-lines": [0],
|
|
"no-new-native-nonconstructor": [0],
|
|
"no-new-symbol": [0],
|
|
"no-nonoctal-decimal-escape": [2],
|
|
"no-obj-calls": [0],
|
|
"no-octal": [2],
|
|
"no-prototype-builtins": [2],
|
|
"no-redeclare": [0, { "builtinGlobals": true }],
|
|
"no-regex-spaces": [2],
|
|
"no-reserved-keys": [0],
|
|
"no-restricted-globals": [
|
|
2,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-properties": [
|
|
2,
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "window",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "globalThis",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/api/core.ts `beacon` (E22 S4).",
|
|
"object": "navigator",
|
|
"property": "sendBeacon"
|
|
}
|
|
],
|
|
"no-restricted-syntax": [
|
|
2,
|
|
{
|
|
"message": "fetchNextPage() cancels and re-sends a page already loading: call fetchNextPage(NEXT_PAGE) (lib/nextPage.ts).",
|
|
"selector": "CallExpression[arguments.length=0]:matches([callee.name='fetchNextPage'], [callee.property.name='fetchNextPage'])"
|
|
},
|
|
{
|
|
"message": "`enabled:hover:` misses a focused FocusSafeButton (aria-disabled): use `act:hover:` (index.css).",
|
|
"selector": "Literal[value=/(^|\\s)enabled:hover:/]"
|
|
},
|
|
{
|
|
"message": "`enabled:hover:` misses a focused FocusSafeButton (aria-disabled): use `act:hover:` (index.css).",
|
|
"selector": "TemplateElement[value.raw=/(^|\\s)enabled:hover:/]"
|
|
},
|
|
{
|
|
"message": "a class split by an interpolation (`${x}hover:…`): Tailwind never sees it whole and emits no CSS; write the class literally (a shared guard is the `act:` variant).",
|
|
"selector": "TemplateLiteral > TemplateElement:not(:first-child)[value.raw=/^([a-z][\\w-]*:[\\w\\[!-]|:[a-z\\[!])/]"
|
|
},
|
|
{
|
|
"message": "No native <select>: use ui/SegmentedToggle for a short fixed set, ui/FilterSelect for a longer one or a user's own list.",
|
|
"selector": "JSXOpeningElement[name.name='select']"
|
|
},
|
|
{
|
|
"message": "px-frozen font size doesn't scale with --font-scale: use text-2xs/text-3xs or text-[Nrem], not text-[Npx] (R10 S2).",
|
|
"selector": "Literal[value=/text-\\[[\\d.]+px\\]/]"
|
|
},
|
|
{
|
|
"message": "px-frozen font size doesn't scale with --font-scale: use text-2xs/text-3xs or text-[Nrem], not text-[Npx] (R10 S2).",
|
|
"selector": "TemplateElement[value.raw=/text-\\[[\\d.]+px\\]/]"
|
|
},
|
|
{
|
|
"message": "px-frozen box size doesn't scale with --font-scale: use the spacing scale (w-37.5, max-w-60), not w-[Npx].",
|
|
"selector": "Literal[value=/(^|[\\s:])(min-|max-)?(w|h|size|left|right|top|bottom|inset|gap|p[xytrbl]?|m[xytrbl]?)-\\[[\\d.]+px\\]/]"
|
|
},
|
|
{
|
|
"message": "px-frozen box size doesn't scale with --font-scale: use the spacing scale (w-37.5, max-w-60), not w-[Npx].",
|
|
"selector": "TemplateElement[value.raw=/(^|[\\s:])(min-|max-)?(w|h|size|left|right|top|bottom|inset|gap|p[xytrbl]?|m[xytrbl]?)-\\[[\\d.]+px\\]/]"
|
|
},
|
|
{
|
|
"message": "px-frozen box size doesn't scale with --font-scale: give a grid column's minimum in rem (minmax(9.375rem,1fr)), not minmax(Npx,…).",
|
|
"selector": "Literal[value=/minmax\\([\\d.]+px,/]"
|
|
},
|
|
{
|
|
"message": "px-frozen box size doesn't scale with --font-scale: give a grid column's minimum in rem (minmax(9.375rem,1fr)), not minmax(Npx,…).",
|
|
"selector": "TemplateElement[value.raw=/minmax\\([\\d.]+px,/]"
|
|
},
|
|
{
|
|
"message": "z-index off the layer scale: use a named level (z-under, z-base, z-menu, z-chrome, z-panel, z-rail, z-overlay, z-popover, z-tooltip), not z-N or z-[…].",
|
|
"selector": "Literal[value=/(^|[\\s:])-?z-([1-9]\\d*|\\[[^\\]]+\\])(?![\\w-])/]"
|
|
},
|
|
{
|
|
"message": "z-index off the layer scale: use a named level (z-under, z-base, z-menu, z-chrome, z-panel, z-rail, z-overlay, z-popover, z-tooltip), not z-N or z-[…].",
|
|
"selector": "TemplateElement[value.raw=/(^|[\\s:])-?z-([1-9]\\d*|\\[[^\\]]+\\])(?![\\w-])/]"
|
|
},
|
|
{
|
|
"message": "hover by a colour swap: use the B3 layer (`state-layer`, Pressable `layer`, `state-filled` on a fill), not hover:bg-card / bg-border / opacity-N.",
|
|
"selector": "Literal[value=/(^|[\\s:])hover:(bg-(card|border|surface|muted)(?![\\w-])|bg-\\(--(hover|press)\\)|opacity-)/]"
|
|
},
|
|
{
|
|
"message": "hover by a colour swap: use the B3 layer (`state-layer`, Pressable `layer`, `state-filled` on a fill), not hover:bg-card / bg-border / opacity-N.",
|
|
"selector": "TemplateElement[value.raw=/(^|[\\s:])hover:(bg-(card|border|surface|muted)(?![\\w-])|bg-\\(--(hover|press)\\)|opacity-)/]"
|
|
},
|
|
{
|
|
"message": "a palette colour: use a semantic token (text-rating, bg-live, bg-media-chrome, text-danger, …; DESIGN.md Tokens), not text-amber-500.",
|
|
"selector": "Literal[value=/(^|[\\s:])(text|bg|border|fill|stroke|from|via|to|ring|outline|decoration|divide|caret|shadow)-(red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|slate|gray|zinc|neutral|stone)-\\d/]"
|
|
},
|
|
{
|
|
"message": "a palette colour: use a semantic token (text-rating, bg-live, bg-media-chrome, text-danger, …; DESIGN.md Tokens), not text-amber-500.",
|
|
"selector": "TemplateElement[value.raw=/(^|[\\s:])(text|bg|border|fill|stroke|from|via|to|ring|outline|decoration|divide|caret|shadow)-(red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|slate|gray|zinc|neutral|stone)-\\d/]"
|
|
},
|
|
{
|
|
"message": "a static label with an edge reads as a pressable chip: use ui/Badge (flat, tonal) for a label that does nothing.",
|
|
"selector": "JSXOpeningElement[name.name='span'] JSXAttribute[name.name='className'] Literal[value=/^(?=.*(^|\\s)rounded-(full|md|lg|xl|2xl)(\\s|$))(?=.*(^|\\s)border(\\s|$))/]"
|
|
},
|
|
{
|
|
"message": "a static label with an edge reads as a pressable chip: use ui/Badge (flat, tonal) for a label that does nothing.",
|
|
"selector": "JSXOpeningElement[name.name='span'] JSXAttribute[name.name='className'] TemplateElement[value.raw=/^(?=.*(^|\\s)rounded-(full|md|lg|xl|2xl)(\\s|$))(?=.*(^|\\s)border(\\s|$))/]"
|
|
}
|
|
],
|
|
"no-self-assign": [2, { "props": true }],
|
|
"no-setter-return": [0],
|
|
"no-shadow-restricted-names": [2, { "reportGlobalThis": false }],
|
|
"no-space-before-semi": [0],
|
|
"no-spaced-func": [0],
|
|
"no-sparse-arrays": [2],
|
|
"no-tabs": [0],
|
|
"no-this-before-super": [0],
|
|
"no-trailing-spaces": [0],
|
|
"no-undef": [0, { "typeof": false }],
|
|
"no-unexpected-multiline": [0],
|
|
"no-unreachable": [0],
|
|
"no-unsafe-finally": [2],
|
|
"no-unsafe-negation": [0, { "enforceForOrderingRelations": false }],
|
|
"no-unsafe-optional-chaining": [2, { "disallowArithmeticOperators": false }],
|
|
"no-unused-expressions": [
|
|
0,
|
|
{
|
|
"allowShortCircuit": false,
|
|
"allowTaggedTemplates": false,
|
|
"allowTernary": false,
|
|
"enforceForJSX": false,
|
|
"ignoreDirectives": false
|
|
}
|
|
],
|
|
"no-unused-labels": [2],
|
|
"no-unused-private-class-members": [2],
|
|
"no-unused-vars": [0],
|
|
"no-useless-backreference": [2],
|
|
"no-useless-catch": [2],
|
|
"no-useless-escape": [2, { "allowRegexCharacters": [] }],
|
|
"no-var": [2],
|
|
"no-whitespace-before-property": [0],
|
|
"no-with": [0],
|
|
"no-wrap-func": [0],
|
|
"nonblock-statement-body-position": [0],
|
|
"object-curly-newline": [0],
|
|
"object-curly-spacing": [0],
|
|
"object-property-newline": [0],
|
|
"one-var-declaration-per-line": [0],
|
|
"operator-linebreak": [0],
|
|
"padded-blocks": [0],
|
|
"prefer-const": [2, { "destructuring": "any", "ignoreReadBeforeAssign": false }],
|
|
"prefer-rest-params": [2],
|
|
"prefer-spread": [2],
|
|
"quote-props": [0],
|
|
"quotes": [0],
|
|
"react-hooks/capitalized-calls": [2],
|
|
"react-hooks/component-hook-factories": [2],
|
|
"react-hooks/config": [2],
|
|
"react-hooks/error-boundaries": [2],
|
|
"react-hooks/exhaustive-deps": [1],
|
|
"react-hooks/exhaustive-effect-dependencies": [2],
|
|
"react-hooks/gating": [2],
|
|
"react-hooks/globals": [2],
|
|
"react-hooks/hooks": [2],
|
|
"react-hooks/immutability": [2],
|
|
"react-hooks/incompatible-library": [1],
|
|
"react-hooks/invariant": [2],
|
|
"react-hooks/memo-dependencies": [2],
|
|
"react-hooks/memoized-effect-dependencies": [2],
|
|
"react-hooks/no-deriving-state-in-effects": [2],
|
|
"react-hooks/preserve-manual-memoization": [2],
|
|
"react-hooks/purity": [2],
|
|
"react-hooks/refs": [2],
|
|
"react-hooks/rule-suppression": [2],
|
|
"react-hooks/rules-of-hooks": [2],
|
|
"react-hooks/set-state-in-effect": [2],
|
|
"react-hooks/set-state-in-render": [2],
|
|
"react-hooks/static-components": [2],
|
|
"react-hooks/syntax": [2],
|
|
"react-hooks/todo": [2],
|
|
"react-hooks/unsupported-syntax": [1],
|
|
"react-hooks/use-memo": [2],
|
|
"react-hooks/void-use-memo": [2],
|
|
"react-refresh/only-export-components": [1, { "allowConstantExport": true }],
|
|
"react/jsx-child-element-spacing": [0],
|
|
"react/jsx-closing-bracket-location": [0],
|
|
"react/jsx-closing-tag-location": [0],
|
|
"react/jsx-curly-newline": [0],
|
|
"react/jsx-curly-spacing": [0],
|
|
"react/jsx-equals-spacing": [0],
|
|
"react/jsx-first-prop-new-line": [0],
|
|
"react/jsx-indent": [0],
|
|
"react/jsx-indent-props": [0],
|
|
"react/jsx-max-props-per-line": [0],
|
|
"react/jsx-newline": [0],
|
|
"react/jsx-one-expression-per-line": [0],
|
|
"react/jsx-props-no-multi-spaces": [0],
|
|
"react/jsx-space-before-closing": [0],
|
|
"react/jsx-tag-spacing": [0],
|
|
"react/jsx-wrap-multilines": [0],
|
|
"require-yield": [2],
|
|
"rest-spread-spacing": [0],
|
|
"semi": [0],
|
|
"semi-spacing": [0],
|
|
"semi-style": [0],
|
|
"space-after-function-name": [0],
|
|
"space-after-keywords": [0],
|
|
"space-before-blocks": [0],
|
|
"space-before-function-paren": [0],
|
|
"space-before-function-parentheses": [0],
|
|
"space-before-keywords": [0],
|
|
"space-in-brackets": [0],
|
|
"space-in-parens": [0],
|
|
"space-infix-ops": [0],
|
|
"space-return-throw-case": [0],
|
|
"space-unary-ops": [0],
|
|
"space-unary-word-ops": [0],
|
|
"standard/array-bracket-even-spacing": [0],
|
|
"standard/computed-property-even-spacing": [0],
|
|
"standard/object-curly-even-spacing": [0],
|
|
"switch-colon-spacing": [0],
|
|
"template-curly-spacing": [0],
|
|
"template-tag-spacing": [0],
|
|
"unicorn/empty-brace-spaces": [0],
|
|
"unicorn/no-nested-ternary": [0],
|
|
"unicorn/number-literal-case": [0],
|
|
"unicorn/template-indent": [0],
|
|
"use-isnan": [2, { "enforceForIndexOf": false, "enforceForSwitchCase": true }],
|
|
"valid-typeof": [2, { "requireStringLiterals": false }],
|
|
"vue/array-bracket-newline": [0],
|
|
"vue/array-bracket-spacing": [0],
|
|
"vue/array-element-newline": [0],
|
|
"vue/arrow-spacing": [0],
|
|
"vue/block-spacing": [0],
|
|
"vue/block-tag-newline": [0],
|
|
"vue/brace-style": [0],
|
|
"vue/comma-dangle": [0],
|
|
"vue/comma-spacing": [0],
|
|
"vue/comma-style": [0],
|
|
"vue/dot-location": [0],
|
|
"vue/func-call-spacing": [0],
|
|
"vue/html-closing-bracket-newline": [0],
|
|
"vue/html-closing-bracket-spacing": [0],
|
|
"vue/html-end-tags": [0],
|
|
"vue/html-indent": [0],
|
|
"vue/html-quotes": [0],
|
|
"vue/html-self-closing": [0],
|
|
"vue/key-spacing": [0],
|
|
"vue/keyword-spacing": [0],
|
|
"vue/max-attributes-per-line": [0],
|
|
"vue/max-len": [0],
|
|
"vue/multiline-html-element-content-newline": [0],
|
|
"vue/multiline-ternary": [0],
|
|
"vue/mustache-interpolation-spacing": [0],
|
|
"vue/no-extra-parens": [0],
|
|
"vue/no-multi-spaces": [0],
|
|
"vue/no-spaces-around-equal-signs-in-attribute": [0],
|
|
"vue/object-curly-newline": [0],
|
|
"vue/object-curly-spacing": [0],
|
|
"vue/object-property-newline": [0],
|
|
"vue/operator-linebreak": [0],
|
|
"vue/quote-props": [0],
|
|
"vue/script-indent": [0],
|
|
"vue/singleline-html-element-content-newline": [0],
|
|
"vue/space-in-parens": [0],
|
|
"vue/space-infix-ops": [0],
|
|
"vue/space-unary-ops": [0],
|
|
"vue/template-curly-spacing": [0],
|
|
"wrap-iife": [0],
|
|
"wrap-regex": [0],
|
|
"yield-star-spacing": [0]
|
|
},
|
|
"settings": null
|
|
},
|
|
"src tests": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh",
|
|
"vitest"
|
|
],
|
|
"rules": {
|
|
"local/button-primitive": [0],
|
|
"local/glyph-link": [0],
|
|
"local/input-primitive": [0],
|
|
"local/literal-a11y-text": [0],
|
|
"local/surface-role": [0],
|
|
"no-restricted-globals": [
|
|
0,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-properties": [
|
|
0,
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "window",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "globalThis",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/api/core.ts `beacon` (E22 S4).",
|
|
"object": "navigator",
|
|
"property": "sendBeacon"
|
|
}
|
|
],
|
|
"vitest/no-disabled-tests": [2],
|
|
"vitest/no-focused-tests": [2, { "fixable": true }]
|
|
},
|
|
"settings": null
|
|
},
|
|
"src/lib": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "lib/ sits below components/: it may not import from components/, not even a type. Move the shared piece down into lib/.",
|
|
"regex": "^(\\.\\./)+components(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"ts configs": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "82 names, sha1 29467d490e30",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [
|
|
"local/button-primitive",
|
|
"local/focus-safe-disabled",
|
|
"local/glyph-link",
|
|
"local/input-primitive",
|
|
"local/jsx-comment-text",
|
|
"local/literal-a11y-text",
|
|
"local/locale-format",
|
|
"local/sortable-a11y",
|
|
"local/surface-role",
|
|
"no-console",
|
|
"no-restricted-globals",
|
|
"no-restricted-properties",
|
|
"no-restricted-syntax",
|
|
"react-hooks/capitalized-calls",
|
|
"react-hooks/component-hook-factories",
|
|
"react-hooks/config",
|
|
"react-hooks/error-boundaries",
|
|
"react-hooks/exhaustive-deps",
|
|
"react-hooks/exhaustive-effect-dependencies",
|
|
"react-hooks/gating",
|
|
"react-hooks/globals",
|
|
"react-hooks/hooks",
|
|
"react-hooks/immutability",
|
|
"react-hooks/incompatible-library",
|
|
"react-hooks/invariant",
|
|
"react-hooks/memo-dependencies",
|
|
"react-hooks/memoized-effect-dependencies",
|
|
"react-hooks/no-deriving-state-in-effects",
|
|
"react-hooks/preserve-manual-memoization",
|
|
"react-hooks/purity",
|
|
"react-hooks/refs",
|
|
"react-hooks/rule-suppression",
|
|
"react-hooks/rules-of-hooks",
|
|
"react-hooks/set-state-in-effect",
|
|
"react-hooks/set-state-in-render",
|
|
"react-hooks/static-components",
|
|
"react-hooks/syntax",
|
|
"react-hooks/todo",
|
|
"react-hooks/unsupported-syntax",
|
|
"react-hooks/use-memo",
|
|
"react-hooks/void-use-memo",
|
|
"react-refresh/only-export-components"
|
|
],
|
|
"plugins": ["@", "@eslint-community/eslint-comments", "@typescript-eslint"],
|
|
"rules": {
|
|
"@typescript-eslint/no-unused-expressions": [
|
|
2,
|
|
{ "allowShortCircuit": false, "allowTaggedTemplates": false, "allowTernary": false }
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"ui": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh"
|
|
],
|
|
"rules": {
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./(?!\\.\\./)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./\\.\\./components/(?!ui/)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not call a domain API slice. Take the data as props.",
|
|
"regex": "^\\.\\./\\.\\./lib/api(/|$)"
|
|
}
|
|
]
|
|
}
|
|
]
|
|
},
|
|
"settings": null
|
|
},
|
|
"ui tests": {
|
|
"languageOptions": {
|
|
"ecmaVersion": 2022,
|
|
"globals": "1169 names, sha1 aee621727a03",
|
|
"parser": "typescript-eslint/parser",
|
|
"parserOptions": { "projectService": true, "tsconfigRootDir": "." },
|
|
"sourceType": "module"
|
|
},
|
|
"linterOptions": { "reportUnusedDisableDirectives": 2 },
|
|
"notApplied": [],
|
|
"plugins": [
|
|
"@",
|
|
"@eslint-community/eslint-comments",
|
|
"@typescript-eslint",
|
|
"local",
|
|
"react-hooks",
|
|
"react-refresh",
|
|
"vitest"
|
|
],
|
|
"rules": {
|
|
"local/button-primitive": [0],
|
|
"local/glyph-link": [0],
|
|
"local/input-primitive": [0],
|
|
"local/literal-a11y-text": [0],
|
|
"local/surface-role": [0],
|
|
"no-restricted-globals": [
|
|
0,
|
|
{
|
|
"message": "Use the logged request layer: `fetch` belongs to src/lib/http.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "fetch"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `XMLHttpRequest` belongs to src/lib/api/core.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "XMLHttpRequest"
|
|
},
|
|
{
|
|
"message": "Use the logged request layer: `WebSocket` belongs to src/lib/messagesSocket.ts only (E22 S4 — a request outside it never reaches the client log).",
|
|
"name": "WebSocket"
|
|
},
|
|
{
|
|
"message": "No `EventSource` without a logged owner module (E22 S4).",
|
|
"name": "EventSource"
|
|
}
|
|
],
|
|
"no-restricted-imports": [
|
|
2,
|
|
{
|
|
"patterns": [
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./(?!\\.\\./)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not import a feature component. Invert the dependency (take a prop/render-prop) or keep the component outside ui/.",
|
|
"regex": "^\\.\\./\\.\\./components/(?!ui/)"
|
|
},
|
|
{
|
|
"message": "components/ui/ is domain-free: a platform component may not call a domain API slice. Take the data as props.",
|
|
"regex": "^\\.\\./\\.\\./lib/api(/|$)"
|
|
}
|
|
]
|
|
}
|
|
],
|
|
"no-restricted-properties": [
|
|
0,
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "window",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/http.ts `send` (E22 S4).",
|
|
"object": "globalThis",
|
|
"property": "fetch"
|
|
},
|
|
{
|
|
"message": "Use lib/api/core.ts `beacon` (E22 S4).",
|
|
"object": "navigator",
|
|
"property": "sendBeacon"
|
|
}
|
|
],
|
|
"vitest/no-disabled-tests": [2],
|
|
"vitest/no-focused-tests": [2, { "fixable": true }]
|
|
},
|
|
"settings": null
|
|
}
|
|
},
|
|
"files": {
|
|
"(not linted)": [],
|
|
"FocusSafeButton.tsx + AnchoredPopover.tsx": [
|
|
"src/components/ui/AnchoredPopover.tsx",
|
|
"src/components/ui/FocusSafeButton.tsx"
|
|
],
|
|
"design-lab": [
|
|
"src/design-lab/DesignLab.tsx",
|
|
"src/design-lab/batchA.tsx",
|
|
"src/design-lab/batchB.tsx",
|
|
"src/design-lab/batchC.tsx",
|
|
"src/design-lab/batchCActions.tsx",
|
|
"src/design-lab/batchD.tsx",
|
|
"src/design-lab/labKit.tsx",
|
|
"src/design-lab/labTokens.ts"
|
|
],
|
|
"e2e": [
|
|
"e2e/channel.spec.ts",
|
|
"e2e/feed.spec.ts",
|
|
"e2e/global.setup.ts",
|
|
"e2e/helpers.ts",
|
|
"e2e/nav.spec.ts",
|
|
"e2e/player.spec.ts",
|
|
"e2e/settings.spec.ts"
|
|
],
|
|
"js configs": ["eslint.config.js", "postcss.config.js"],
|
|
"lib tests": [
|
|
"src/lib/accountPinnedStores.dom.test.ts",
|
|
"src/lib/actionErrors.test.ts",
|
|
"src/lib/activeAccount.dom.test.ts",
|
|
"src/lib/adminUsers.test.ts",
|
|
"src/lib/api/adminLogs.dom.test.ts",
|
|
"src/lib/api/core.test.ts",
|
|
"src/lib/api/diagnostics.dom.test.ts",
|
|
"src/lib/api/discover.dom.test.ts",
|
|
"src/lib/api/downloads.contract.test.ts",
|
|
"src/lib/api/facade.test.ts",
|
|
"src/lib/api/feed.test.ts",
|
|
"src/lib/api/plex.dom.test.ts",
|
|
"src/lib/api/plexFilters.dom.test.ts",
|
|
"src/lib/api/plexLang.dom.test.ts",
|
|
"src/lib/api/tagModes.test.ts",
|
|
"src/lib/auditGroups.test.ts",
|
|
"src/lib/browserBackgroundPlay.dom.test.ts",
|
|
"src/lib/buttonPrimitive.contract.test.ts",
|
|
"src/lib/captureTab.dom.test.ts",
|
|
"src/lib/channelDetailPoll.backfill.dom.test.tsx",
|
|
"src/lib/channelDetailPoll.test.ts",
|
|
"src/lib/channelOrder.dom.test.ts",
|
|
"src/lib/channelWriteFailures.dom.test.tsx",
|
|
"src/lib/channelsUrlState.dom.test.ts",
|
|
"src/lib/chatDock.dom.test.ts",
|
|
"src/lib/chipLane.contract.test.ts",
|
|
"src/lib/chipOverflow.test.ts",
|
|
"src/lib/columnSort.test.ts",
|
|
"src/lib/controlRules.contract.test.ts",
|
|
"src/lib/cropGeometry.test.ts",
|
|
"src/lib/dateFilter.test.ts",
|
|
"src/lib/detailLog.dom.test.ts",
|
|
"src/lib/diagnostics.dom.test.ts",
|
|
"src/lib/diagnostics.session.dom.test.ts",
|
|
"src/lib/downloadActions.test.ts",
|
|
"src/lib/downloadFailure.test.ts",
|
|
"src/lib/downloads.test.ts",
|
|
"src/lib/e2ee.test.ts",
|
|
"src/lib/fadeEdge.contract.test.ts",
|
|
"src/lib/feedSort.yt.test.ts",
|
|
"src/lib/focusSafe.contract.test.ts",
|
|
"src/lib/format.test.ts",
|
|
"src/lib/gates.contract.test.ts",
|
|
"src/lib/globalKeymap.dom.test.tsx",
|
|
"src/lib/headings.contract.test.ts",
|
|
"src/lib/history.dom.test.ts",
|
|
"src/lib/history.nav.dom.test.ts",
|
|
"src/lib/history.navPosition.dom.test.tsx",
|
|
"src/lib/history.navRestore.reload.dom.test.tsx",
|
|
"src/lib/history.subview.dom.test.ts",
|
|
"src/lib/hoverAndLink.contract.test.ts",
|
|
"src/lib/http.test.ts",
|
|
"src/lib/inputPrimitive.contract.test.ts",
|
|
"src/lib/issueDraft.test.ts",
|
|
"src/lib/jobResult.dom.test.ts",
|
|
"src/lib/jsxCommentText.contract.test.ts",
|
|
"src/lib/keymap.sequence.test.ts",
|
|
"src/lib/keymap.test.ts",
|
|
"src/lib/layerStack.dom.test.ts",
|
|
"src/lib/layerStack.integration.dom.test.tsx",
|
|
"src/lib/lazyWithPreload.dom.test.tsx",
|
|
"src/lib/linkify.test.ts",
|
|
"src/lib/listNav.dom.test.tsx",
|
|
"src/lib/listNav.scope.dom.test.tsx",
|
|
"src/lib/listPaging.test.ts",
|
|
"src/lib/literalA11yText.contract.test.ts",
|
|
"src/lib/localeFormat.contract.test.ts",
|
|
"src/lib/log.contract.test.ts",
|
|
"src/lib/log.test.ts",
|
|
"src/lib/logHooks.dom.test.ts",
|
|
"src/lib/logsUrlState.test.ts",
|
|
"src/lib/messagesSocket.test.ts",
|
|
"src/lib/moveInList.test.ts",
|
|
"src/lib/mutationFailures.contract.test.ts",
|
|
"src/lib/navPosition.wiring.contract.test.ts",
|
|
"src/lib/navRing.contract.test.ts",
|
|
"src/lib/networkBoundary.contract.test.ts",
|
|
"src/lib/nextPage.contract.test.ts",
|
|
"src/lib/nextPage.dom.test.ts",
|
|
"src/lib/nextPage.wiring.contract.test.ts",
|
|
"src/lib/nodeEngine.contract.test.ts",
|
|
"src/lib/notifications.actionTtl.dom.test.ts",
|
|
"src/lib/pageKeys.dom.test.tsx",
|
|
"src/lib/pageMeta.test.ts",
|
|
"src/lib/panelLayout.dom.test.ts",
|
|
"src/lib/parseId.test.ts",
|
|
"src/lib/playerModalHooks.apiload.dom.test.tsx",
|
|
"src/lib/playerModalHooks.progress.dom.test.tsx",
|
|
"src/lib/playerQueue.test.ts",
|
|
"src/lib/playerStage.contract.test.ts",
|
|
"src/lib/playerVolume.test.ts",
|
|
"src/lib/playlistView.test.ts",
|
|
"src/lib/plexBackdrop.dom.test.tsx",
|
|
"src/lib/plexFinishMargin.contract.test.ts",
|
|
"src/lib/plexImage.contract.test.ts",
|
|
"src/lib/plexImage.test.ts",
|
|
"src/lib/plexPlayerHooks.controls.dom.test.tsx",
|
|
"src/lib/plexPlayerHooks.subtitle.dom.test.tsx",
|
|
"src/lib/plexQueue.test.ts",
|
|
"src/lib/plexRating.test.ts",
|
|
"src/lib/plexStats.test.ts",
|
|
"src/lib/plexUrlState.dom.test.ts",
|
|
"src/lib/pxBox.contract.test.ts",
|
|
"src/lib/pythonEngine.contract.test.ts",
|
|
"src/lib/queryClient.dom.test.ts",
|
|
"src/lib/queryKeys.test.ts",
|
|
"src/lib/reactEngine.contract.test.ts",
|
|
"src/lib/reinsert.test.ts",
|
|
"src/lib/releaseNotes.test.ts",
|
|
"src/lib/repoScripts.contract.test.ts",
|
|
"src/lib/rovingHighlight.contract.test.ts",
|
|
"src/lib/saveLanguage.dom.test.ts",
|
|
"src/lib/savedViews.test.ts",
|
|
"src/lib/sortableA11y.contract.test.ts",
|
|
"src/lib/sourceSize.contract.test.ts",
|
|
"src/lib/staleBuild.dom.test.ts",
|
|
"src/lib/store.dom.test.tsx",
|
|
"src/lib/subscriptionCache.test.ts",
|
|
"src/lib/surfaceRole.contract.test.ts",
|
|
"src/lib/tabState.dom.test.ts",
|
|
"src/lib/theme.contract.test.ts",
|
|
"src/lib/theme.test.ts",
|
|
"src/lib/touchTarget.contract.test.ts",
|
|
"src/lib/uiBoundary.contract.test.ts",
|
|
"src/lib/urlState.dom.test.ts",
|
|
"src/lib/useCardPager.dom.test.tsx",
|
|
"src/lib/useChipOverflowFit.dom.test.tsx",
|
|
"src/lib/useDebounced.dom.test.ts",
|
|
"src/lib/useDismiss.dom.test.tsx",
|
|
"src/lib/useFilterState.dom.test.ts",
|
|
"src/lib/useFocusKeeper.dom.test.tsx",
|
|
"src/lib/useFocusKeeper.restore.dom.test.tsx",
|
|
"src/lib/useHoverFocusWithin.dom.test.tsx",
|
|
"src/lib/usePlexCollectionTitles.dom.test.tsx",
|
|
"src/lib/usePref.dom.test.ts",
|
|
"src/lib/usePref.saveFailure.dom.test.ts",
|
|
"src/lib/useSortState.dom.test.ts",
|
|
"src/lib/useTags.dom.test.tsx",
|
|
"src/lib/useUndoable.dom.test.ts",
|
|
"src/lib/useUrlMirror.dom.test.ts",
|
|
"src/lib/verifyEntry.dom.test.tsx",
|
|
"src/lib/viewportUnits.contract.test.ts",
|
|
"src/lib/vocab.dom.test.ts",
|
|
"src/lib/zLayer.contract.test.ts"
|
|
],
|
|
"lib/api/core.ts": ["src/lib/api/core.ts"],
|
|
"lib/http.ts": ["src/lib/http.ts"],
|
|
"lib/messagesSocket.ts": ["src/lib/messagesSocket.ts"],
|
|
"src": [
|
|
"src/App.tsx",
|
|
"src/components/About.tsx",
|
|
"src/components/AboutCell.tsx",
|
|
"src/components/AccountPanel.tsx",
|
|
"src/components/ActiveFilterChips.tsx",
|
|
"src/components/AddToPlaylist.tsx",
|
|
"src/components/AdminLogs.tsx",
|
|
"src/components/AdminUsers.tsx",
|
|
"src/components/AppCommandPalette.tsx",
|
|
"src/components/AuditEarlierRuns.tsx",
|
|
"src/components/AuditLog.tsx",
|
|
"src/components/BootGate.tsx",
|
|
"src/components/ChannelAbout.tsx",
|
|
"src/components/ChannelDiscovery.tsx",
|
|
"src/components/ChannelLayoutGrid.tsx",
|
|
"src/components/ChannelLink.tsx",
|
|
"src/components/ChannelNameLink.tsx",
|
|
"src/components/ChannelPage.tsx",
|
|
"src/components/ChannelPicker.tsx",
|
|
"src/components/ChannelStatsPopover.tsx",
|
|
"src/components/ChannelTags.tsx",
|
|
"src/components/Channels.tsx",
|
|
"src/components/ChannelsProvider.tsx",
|
|
"src/components/ChatDock.tsx",
|
|
"src/components/ChatThread.tsx",
|
|
"src/components/ConfigPanel.tsx",
|
|
"src/components/ConfirmProvider.tsx",
|
|
"src/components/DateFilterSelect.tsx",
|
|
"src/components/DebugRecorder.tsx",
|
|
"src/components/DemoBanner.tsx",
|
|
"src/components/DiagnosticsSettings.tsx",
|
|
"src/components/DownloadButton.tsx",
|
|
"src/components/DownloadCenter.tsx",
|
|
"src/components/DownloadDialog.tsx",
|
|
"src/components/ErrorBoundary.tsx",
|
|
"src/components/ErrorDialog.tsx",
|
|
"src/components/ExcludedChannelList.tsx",
|
|
"src/components/Feed.tsx",
|
|
"src/components/FeedFiltersProvider.tsx",
|
|
"src/components/FeedScopeToggle.tsx",
|
|
"src/components/FeedViewProvider.tsx",
|
|
"src/components/FilterRail.tsx",
|
|
"src/components/Header.tsx",
|
|
"src/components/Home.tsx",
|
|
"src/components/IssueComposer.tsx",
|
|
"src/components/KeyGate.tsx",
|
|
"src/components/LanguageSwitcher.tsx",
|
|
"src/components/LibraryPlayer.tsx",
|
|
"src/components/LogLine.tsx",
|
|
"src/components/MediaResumeButtons.tsx",
|
|
"src/components/Messages.tsx",
|
|
"src/components/MyLogViewer.tsx",
|
|
"src/components/NavSidebar.tsx",
|
|
"src/components/NavigationProvider.tsx",
|
|
"src/components/NotificationsPanel.tsx",
|
|
"src/components/OnboardingWizard.tsx",
|
|
"src/components/PaletteLauncher.tsx",
|
|
"src/components/PersonalViewsModal.tsx",
|
|
"src/components/PlayerModal.tsx",
|
|
"src/components/PlaylistLimitsHint.tsx",
|
|
"src/components/Playlists.tsx",
|
|
"src/components/PlaylistsProvider.tsx",
|
|
"src/components/PlaylistsRail.tsx",
|
|
"src/components/PlexBrowse.tsx",
|
|
"src/components/PlexCollectionEditor.tsx",
|
|
"src/components/PlexCollectionView.tsx",
|
|
"src/components/PlexDiscover.tsx",
|
|
"src/components/PlexInfo.tsx",
|
|
"src/components/PlexLibraryPicker.tsx",
|
|
"src/components/PlexMenu.tsx",
|
|
"src/components/PlexPlayer.tsx",
|
|
"src/components/PlexPlayerSettings.tsx",
|
|
"src/components/PlexPlaylistAdd.tsx",
|
|
"src/components/PlexPlaylistView.tsx",
|
|
"src/components/PlexProvider.tsx",
|
|
"src/components/PlexScopeToggle.tsx",
|
|
"src/components/PlexSearchBox.tsx",
|
|
"src/components/PlexSidebar.tsx",
|
|
"src/components/PlexStatsOverlay.tsx",
|
|
"src/components/PlexViewBridge.tsx",
|
|
"src/components/PlexViewToggle.tsx",
|
|
"src/components/PosterTile.tsx",
|
|
"src/components/PrefsProvider.tsx",
|
|
"src/components/ProfileEditor.tsx",
|
|
"src/components/ReleaseNotes.tsx",
|
|
"src/components/SavedViewsPopover.tsx",
|
|
"src/components/SavedViewsProvider.tsx",
|
|
"src/components/Scheduler.tsx",
|
|
"src/components/SearchBar.tsx",
|
|
"src/components/SelectedViewChip.tsx",
|
|
"src/components/SettingsPanel.tsx",
|
|
"src/components/SetupWizard.tsx",
|
|
"src/components/ShareDialog.tsx",
|
|
"src/components/Sidebar.tsx",
|
|
"src/components/Stats.tsx",
|
|
"src/components/SyncStatus.tsx",
|
|
"src/components/TagFilterChips.tsx",
|
|
"src/components/TagManager.tsx",
|
|
"src/components/UpNextCard.tsx",
|
|
"src/components/UploadDialog.tsx",
|
|
"src/components/UserPicker.tsx",
|
|
"src/components/VerifyBanner.tsx",
|
|
"src/components/VersionBanner.tsx",
|
|
"src/components/VideoCard.tsx",
|
|
"src/components/VideoEditor.tsx",
|
|
"src/components/VideoFollowUp.tsx",
|
|
"src/components/VideoInfoCard.tsx",
|
|
"src/components/VideoMenu.tsx",
|
|
"src/components/ViewSwitcher.tsx",
|
|
"src/components/VirtualFeed.tsx",
|
|
"src/components/WatchPage.tsx",
|
|
"src/components/Welcome.tsx",
|
|
"src/components/WizardProvider.tsx",
|
|
"src/components/YearFilter.tsx",
|
|
"src/components/auditColumns.tsx",
|
|
"src/components/channelCells.tsx",
|
|
"src/components/channelColumns.tsx",
|
|
"src/components/channelSync.ts",
|
|
"src/components/channelsContext.ts",
|
|
"src/components/comfortPin.tsx",
|
|
"src/components/compilerSkips.testkit.ts",
|
|
"src/components/confirmContext.ts",
|
|
"src/components/copyItems.tsx",
|
|
"src/components/descriptionLinks.tsx",
|
|
"src/components/downloadAdmin.tsx",
|
|
"src/components/downloadModals.tsx",
|
|
"src/components/downloadRow.tsx",
|
|
"src/components/downloadTitle.ts",
|
|
"src/components/facetOption.ts",
|
|
"src/components/feedFiltersContext.ts",
|
|
"src/components/feedFiltersInit.ts",
|
|
"src/components/feedViewContext.ts",
|
|
"src/components/legal/LegalLayout.tsx",
|
|
"src/components/legal/PrivacyPolicy.tsx",
|
|
"src/components/legal/Terms.tsx",
|
|
"src/components/legal/useHungarian.ts",
|
|
"src/components/logLineParts.ts",
|
|
"src/components/modulePages.tsx",
|
|
"src/components/moduleRegistry.tsx",
|
|
"src/components/navigationContext.ts",
|
|
"src/components/navigationInit.ts",
|
|
"src/components/playerModalControls.tsx",
|
|
"src/components/playlistColumns.tsx",
|
|
"src/components/playlistsContext.ts",
|
|
"src/components/playlistsInit.ts",
|
|
"src/components/plexBrowseLists.tsx",
|
|
"src/components/plexCards.tsx",
|
|
"src/components/plexContext.ts",
|
|
"src/components/plexDetailAside.tsx",
|
|
"src/components/plexDetailUi.tsx",
|
|
"src/components/plexPlayable.ts",
|
|
"src/components/plexPlayerControls.tsx",
|
|
"src/components/plexSubUrl.ts",
|
|
"src/components/plexViewContext.ts",
|
|
"src/components/plexViews.tsx",
|
|
"src/components/prefsContext.ts",
|
|
"src/components/savedViewsContext.ts",
|
|
"src/components/useChannelActions.tsx",
|
|
"src/components/useDebugRecording.ts",
|
|
"src/components/useDownloadActions.tsx",
|
|
"src/components/usePlaylistActions.tsx",
|
|
"src/components/usePlexActiveFilters.ts",
|
|
"src/components/usePlexCardActions.tsx",
|
|
"src/components/usePlexPlaylistEdits.ts",
|
|
"src/components/useTagSuggestions.ts",
|
|
"src/components/useVideoActions.tsx",
|
|
"src/components/welcomeMode.ts",
|
|
"src/components/wizardContext.ts",
|
|
"src/i18n/appCopy.ts",
|
|
"src/i18n/index.ts",
|
|
"src/main.tsx",
|
|
"src/vite-env.d.ts"
|
|
],
|
|
"src tests": [
|
|
"src/components/AdminLogs.dom.test.tsx",
|
|
"src/components/AdminUsers.dom.test.tsx",
|
|
"src/components/AppCommandPalette.dom.test.tsx",
|
|
"src/components/BootGate.dom.test.tsx",
|
|
"src/components/ChannelLayoutGrid.dom.test.tsx",
|
|
"src/components/ChannelNameLink.dom.test.tsx",
|
|
"src/components/ChannelPage.backfill.dom.test.tsx",
|
|
"src/components/ChannelPage.banner.dom.test.tsx",
|
|
"src/components/ChannelPage.busyFocus.dom.test.tsx",
|
|
"src/components/ChannelPage.fold.dom.test.tsx",
|
|
"src/components/ChannelPage.watchState.dom.test.tsx",
|
|
"src/components/ChannelStatsPopover.dom.test.tsx",
|
|
"src/components/ChannelTags.suggest.dom.test.tsx",
|
|
"src/components/ChannelsProvider.dom.test.tsx",
|
|
"src/components/ConfigPanel.choice.dom.test.tsx",
|
|
"src/components/ConfigPanel.field.dom.test.tsx",
|
|
"src/components/ConfigPanel.sections.dom.test.tsx",
|
|
"src/components/DateFilterSelect.dom.test.tsx",
|
|
"src/components/DebugRecorder.dom.test.tsx",
|
|
"src/components/DiagnosticsSettings.dom.test.tsx",
|
|
"src/components/DownloadCenter.confirm.dom.test.tsx",
|
|
"src/components/DownloadCenter.menu.dom.test.tsx",
|
|
"src/components/ErrorBoundary.message.dom.test.tsx",
|
|
"src/components/ErrorBoundary.staleBuild.dom.test.tsx",
|
|
"src/components/ExcludedChannelList.dom.test.tsx",
|
|
"src/components/Feed.countStale.dom.test.tsx",
|
|
"src/components/Feed.nextPageFailed.dom.test.tsx",
|
|
"src/components/Feed.reset.dom.test.tsx",
|
|
"src/components/Feed.ytsort.dom.test.tsx",
|
|
"src/components/FeedFiltersProvider.dom.test.ts",
|
|
"src/components/FeedFiltersProvider.seed.dom.test.tsx",
|
|
"src/components/Home.dom.test.tsx",
|
|
"src/components/Home.pin.dom.test.tsx",
|
|
"src/components/IssueComposer.dom.test.tsx",
|
|
"src/components/LibraryPlayer.dom.test.tsx",
|
|
"src/components/Messages.keyboard.dom.test.tsx",
|
|
"src/components/MyLogViewer.dom.test.tsx",
|
|
"src/components/NavigationProvider.dom.test.tsx",
|
|
"src/components/NotificationsPanel.menu.dom.test.tsx",
|
|
"src/components/OnboardingWizard.dialog.dom.test.tsx",
|
|
"src/components/OnboardingWizard.escape.dom.test.tsx",
|
|
"src/components/PaletteLauncher.dom.test.tsx",
|
|
"src/components/PersonalViewsModal.dom.test.tsx",
|
|
"src/components/PlayerModal.dom.test.tsx",
|
|
"src/components/PlaylistEditFailures.dom.test.tsx",
|
|
"src/components/PlaylistLimitsHint.dom.test.tsx",
|
|
"src/components/Playlists.dom.test.tsx",
|
|
"src/components/PlaylistsRail.rename.dom.test.tsx",
|
|
"src/components/PlexCollectionView.dom.test.tsx",
|
|
"src/components/PlexDiscover.dom.test.tsx",
|
|
"src/components/PlexInfo.dom.test.tsx",
|
|
"src/components/PlexLibraryPicker.dom.test.tsx",
|
|
"src/components/PlexMenu.dom.test.tsx",
|
|
"src/components/PlexPersonView.dom.test.tsx",
|
|
"src/components/PlexPlayer.backspace.dom.test.tsx",
|
|
"src/components/PlexPlayer.controls.dom.test.tsx",
|
|
"src/components/PlexPlayer.hls.dom.test.tsx",
|
|
"src/components/PlexPlayer.session.dom.test.tsx",
|
|
"src/components/PlexPlayer.strictmode.dom.test.tsx",
|
|
"src/components/PlexPlayer.tabtrap.dom.test.tsx",
|
|
"src/components/PlexPlayerSettings.dom.test.tsx",
|
|
"src/components/PlexPlaylistReorder.dom.test.tsx",
|
|
"src/components/PlexPlaylistView.header.dom.test.tsx",
|
|
"src/components/PlexPlaylistView.menu.dom.test.tsx",
|
|
"src/components/PlexProvider.dom.test.tsx",
|
|
"src/components/PlexScopeToggle.dom.test.tsx",
|
|
"src/components/PlexSearchBox.dom.test.tsx",
|
|
"src/components/PlexSidebar.picker.dom.test.tsx",
|
|
"src/components/PlexViewToggle.dom.test.tsx",
|
|
"src/components/PrefsProvider.dom.test.tsx",
|
|
"src/components/SavedViewsPopover.dom.test.tsx",
|
|
"src/components/SavedViewsProvider.dom.test.tsx",
|
|
"src/components/Scheduler.dom.test.tsx",
|
|
"src/components/Scheduler.menu.dom.test.tsx",
|
|
"src/components/SearchBar.dom.test.tsx",
|
|
"src/components/SearchBar.keys.dom.test.tsx",
|
|
"src/components/SettingsPanel.account.dom.test.tsx",
|
|
"src/components/SettingsPanel.downloadAuth.dom.test.tsx",
|
|
"src/components/ShareDialog.dom.test.tsx",
|
|
"src/components/TagFilterChips.dom.test.tsx",
|
|
"src/components/UpNextCard.dom.test.tsx",
|
|
"src/components/UploadDialog.dom.test.tsx",
|
|
"src/components/VideoCard.actions.dom.test.tsx",
|
|
"src/components/VideoCard.channel.dom.test.tsx",
|
|
"src/components/VideoCard.nav.dom.test.tsx",
|
|
"src/components/VideoEditor.partial.dom.test.tsx",
|
|
"src/components/VideoInfoCard.dom.test.tsx",
|
|
"src/components/VideoMenu.dom.test.tsx",
|
|
"src/components/WatchPage.dom.test.tsx",
|
|
"src/components/WriteFailureReporting.dom.test.tsx",
|
|
"src/components/accountPanel.dom.test.tsx",
|
|
"src/components/adminInvites.dom.test.tsx",
|
|
"src/components/adminPendingAccess.dom.test.tsx",
|
|
"src/components/auditColumns.dom.test.tsx",
|
|
"src/components/authCardStates.dom.test.tsx",
|
|
"src/components/channelChipNames.dom.test.tsx",
|
|
"src/components/channelColumns.dom.test.tsx",
|
|
"src/components/channelsTagRow.contract.test.ts",
|
|
"src/components/clientLogWiring.dom.test.tsx",
|
|
"src/components/comfortPin.dom.test.ts",
|
|
"src/components/comfortPin.langSwitch.dom.test.tsx",
|
|
"src/components/compilerCoverage.contract.test.ts",
|
|
"src/components/descriptionLinks.dom.test.tsx",
|
|
"src/components/downloadAdmin.dom.test.tsx",
|
|
"src/components/downloadRow.dom.test.tsx",
|
|
"src/components/facetOption.test.ts",
|
|
"src/components/formAlerts.dom.test.tsx",
|
|
"src/components/legal/legalBodies.contract.dom.test.tsx",
|
|
"src/components/listNav.wiring.contract.test.ts",
|
|
"src/components/mediaPicture.contract.test.ts",
|
|
"src/components/navigation.dom.test.ts",
|
|
"src/components/playlistsInit.test.ts",
|
|
"src/components/plexCards.dom.test.tsx",
|
|
"src/components/plexCards.lang.dom.test.tsx",
|
|
"src/components/plexCards.langSwitch.dom.test.tsx",
|
|
"src/components/plexShow.aside.dom.test.tsx",
|
|
"src/components/plexSubUrl.test.ts",
|
|
"src/components/plexViews.restart.dom.test.tsx",
|
|
"src/components/tagChipNames.dom.test.tsx",
|
|
"src/components/useChannelActions.dom.test.tsx",
|
|
"src/components/usePlaylistActions.dom.test.tsx",
|
|
"src/components/usePlexActiveFilters.dom.test.tsx",
|
|
"src/components/usePlexPlaylistEdits.dom.test.tsx",
|
|
"src/components/useTagSuggestions.dom.test.tsx",
|
|
"src/components/useVideoActions.dom.test.tsx",
|
|
"src/components/welcomeMode.dom.test.ts",
|
|
"src/components/welcomeMode.render.dom.test.tsx",
|
|
"src/i18n/appCopy.dom.test.ts",
|
|
"src/i18n/backendIds.contract.test.ts",
|
|
"src/i18n/copyRule.test.ts",
|
|
"src/i18n/parity.test.ts",
|
|
"src/i18n/plurals.test.ts",
|
|
"src/i18n/unusedKeys.contract.test.ts",
|
|
"src/jsxWhitespace.dom.test.tsx"
|
|
],
|
|
"src/lib": [
|
|
"src/lib/actionErrors.ts",
|
|
"src/lib/activeAccount.ts",
|
|
"src/lib/adminUsers.ts",
|
|
"src/lib/adminUsersTab.ts",
|
|
"src/lib/api.ts",
|
|
"src/lib/api/account.ts",
|
|
"src/lib/api/admin.ts",
|
|
"src/lib/api/auth.ts",
|
|
"src/lib/api/channels.ts",
|
|
"src/lib/api/diagnostics.ts",
|
|
"src/lib/api/discover.ts",
|
|
"src/lib/api/downloads.ts",
|
|
"src/lib/api/feed.ts",
|
|
"src/lib/api/messaging.ts",
|
|
"src/lib/api/notifications.ts",
|
|
"src/lib/api/playlists.ts",
|
|
"src/lib/api/plex.ts",
|
|
"src/lib/api/quota.ts",
|
|
"src/lib/api/savedViews.ts",
|
|
"src/lib/api/setup.ts",
|
|
"src/lib/api/sync.ts",
|
|
"src/lib/api/tagModes.ts",
|
|
"src/lib/api/tags.ts",
|
|
"src/lib/auditGroups.ts",
|
|
"src/lib/backgroundTarget.ts",
|
|
"src/lib/brandIcons.ts",
|
|
"src/lib/browserBackgroundPlay.ts",
|
|
"src/lib/captureTab.ts",
|
|
"src/lib/channelDetailPoll.ts",
|
|
"src/lib/channelLayout.ts",
|
|
"src/lib/channelOrder.ts",
|
|
"src/lib/channelsUrlState.ts",
|
|
"src/lib/chatDock.ts",
|
|
"src/lib/chipOverflow.ts",
|
|
"src/lib/clipboard.ts",
|
|
"src/lib/collate.ts",
|
|
"src/lib/colorMath.ts",
|
|
"src/lib/columnSort.ts",
|
|
"src/lib/cropGeometry.ts",
|
|
"src/lib/dateFilter.ts",
|
|
"src/lib/debugRecorder.ts",
|
|
"src/lib/diagnostics.ts",
|
|
"src/lib/documentTitle.ts",
|
|
"src/lib/downloadActions.ts",
|
|
"src/lib/downloadFailure.ts",
|
|
"src/lib/downloads.ts",
|
|
"src/lib/e2ee.ts",
|
|
"src/lib/entryUrl.ts",
|
|
"src/lib/errorDialog.ts",
|
|
"src/lib/feedSort.ts",
|
|
"src/lib/feedView.ts",
|
|
"src/lib/filterLog.ts",
|
|
"src/lib/format.ts",
|
|
"src/lib/fullscreen.ts",
|
|
"src/lib/hints.ts",
|
|
"src/lib/history.ts",
|
|
"src/lib/homeIntent.ts",
|
|
"src/lib/hueTile.ts",
|
|
"src/lib/issueDraft.ts",
|
|
"src/lib/jobResult.ts",
|
|
"src/lib/keymap.ts",
|
|
"src/lib/layerStack.ts",
|
|
"src/lib/lazyWithPreload.ts",
|
|
"src/lib/linkify.tsx",
|
|
"src/lib/lintProbe.testkit.ts",
|
|
"src/lib/listNav.ts",
|
|
"src/lib/listPaging.ts",
|
|
"src/lib/log.ts",
|
|
"src/lib/logHooks.ts",
|
|
"src/lib/logsUrlState.ts",
|
|
"src/lib/mediaLog.ts",
|
|
"src/lib/mediaSource.ts",
|
|
"src/lib/messaging.ts",
|
|
"src/lib/modules.ts",
|
|
"src/lib/moveInList.ts",
|
|
"src/lib/nav.ts",
|
|
"src/lib/nextPage.ts",
|
|
"src/lib/notifications.ts",
|
|
"src/lib/onboarding.ts",
|
|
"src/lib/pageMeta.ts",
|
|
"src/lib/panelLayout.ts",
|
|
"src/lib/parseId.ts",
|
|
"src/lib/playerModalHooks.ts",
|
|
"src/lib/playerModes.ts",
|
|
"src/lib/playerQueue.ts",
|
|
"src/lib/playerVolume.ts",
|
|
"src/lib/playlistName.ts",
|
|
"src/lib/playlistView.ts",
|
|
"src/lib/plexDetail.ts",
|
|
"src/lib/plexImage.ts",
|
|
"src/lib/plexPlayerHooks.ts",
|
|
"src/lib/plexPlayerPrefs.ts",
|
|
"src/lib/plexQueue.ts",
|
|
"src/lib/plexRating.ts",
|
|
"src/lib/plexSearch.ts",
|
|
"src/lib/plexSort.ts",
|
|
"src/lib/plexStats.ts",
|
|
"src/lib/plexUrlState.ts",
|
|
"src/lib/plexWatch.ts",
|
|
"src/lib/progressCache.ts",
|
|
"src/lib/queryClient.ts",
|
|
"src/lib/queryKeys.ts",
|
|
"src/lib/reinsert.ts",
|
|
"src/lib/releaseNotes.ts",
|
|
"src/lib/saveLanguage.ts",
|
|
"src/lib/savedViews.ts",
|
|
"src/lib/seekableEnd.ts",
|
|
"src/lib/sortOptions.ts",
|
|
"src/lib/sourceSize.testkit.ts",
|
|
"src/lib/staleBuild.ts",
|
|
"src/lib/storage.ts",
|
|
"src/lib/store.ts",
|
|
"src/lib/subscriptionCache.ts",
|
|
"src/lib/tableColumns.ts",
|
|
"src/lib/tagPicks.ts",
|
|
"src/lib/textSelection.ts",
|
|
"src/lib/theme.ts",
|
|
"src/lib/toastDock.ts",
|
|
"src/lib/urlState.ts",
|
|
"src/lib/useActiveFilters.ts",
|
|
"src/lib/useCardPager.ts",
|
|
"src/lib/useChannelNames.ts",
|
|
"src/lib/useChannelPriority.ts",
|
|
"src/lib/useChannelTagActions.ts",
|
|
"src/lib/useChipOverflowFit.ts",
|
|
"src/lib/useDebounced.ts",
|
|
"src/lib/useDismiss.ts",
|
|
"src/lib/useFilterFold.ts",
|
|
"src/lib/useFilterState.ts",
|
|
"src/lib/useFocusKeeper.ts",
|
|
"src/lib/useHoverFocusWithin.ts",
|
|
"src/lib/useLatest.ts",
|
|
"src/lib/useLiveQuery.ts",
|
|
"src/lib/useMe.ts",
|
|
"src/lib/useMediaQuery.ts",
|
|
"src/lib/usePlexCollectionTitles.ts",
|
|
"src/lib/usePref.ts",
|
|
"src/lib/useScrollEdges.ts",
|
|
"src/lib/useScrollFade.ts",
|
|
"src/lib/useSortState.ts",
|
|
"src/lib/useTags.ts",
|
|
"src/lib/useUndoable.ts",
|
|
"src/lib/useUrlMirror.ts",
|
|
"src/lib/useVerifyEntry.ts",
|
|
"src/lib/version.ts",
|
|
"src/lib/vocab.ts",
|
|
"src/lib/youtube.ts",
|
|
"src/lib/youtubeErrors.ts"
|
|
],
|
|
"ts configs": [
|
|
"devOnlyGuard.ts",
|
|
"playwright.config.ts",
|
|
"reactPlugin.ts",
|
|
"vite.config.ts",
|
|
"vitest.config.ts"
|
|
],
|
|
"ui": [
|
|
"src/components/ui/ActionMenu.tsx",
|
|
"src/components/ui/Avatar.tsx",
|
|
"src/components/ui/BackToTop.tsx",
|
|
"src/components/ui/Badge.tsx",
|
|
"src/components/ui/Banner.tsx",
|
|
"src/components/ui/Button.tsx",
|
|
"src/components/ui/Carousel.tsx",
|
|
"src/components/ui/Chip.tsx",
|
|
"src/components/ui/ClampedText.tsx",
|
|
"src/components/ui/ColumnSortControl.tsx",
|
|
"src/components/ui/Combobox.tsx",
|
|
"src/components/ui/CommandPalette.tsx",
|
|
"src/components/ui/ContextMenu.tsx",
|
|
"src/components/ui/CountBadge.tsx",
|
|
"src/components/ui/DataTable.tsx",
|
|
"src/components/ui/DraftSaveBar.tsx",
|
|
"src/components/ui/DragHandle.tsx",
|
|
"src/components/ui/FilterChipGroup.tsx",
|
|
"src/components/ui/FilterFold.tsx",
|
|
"src/components/ui/FilterSelect.tsx",
|
|
"src/components/ui/Headings.tsx",
|
|
"src/components/ui/HiddenFilterCue.tsx",
|
|
"src/components/ui/IconButton.tsx",
|
|
"src/components/ui/InlineNotice.tsx",
|
|
"src/components/ui/Input.tsx",
|
|
"src/components/ui/ItemCount.tsx",
|
|
"src/components/ui/KeyboardHelp.tsx",
|
|
"src/components/ui/LinkButton.tsx",
|
|
"src/components/ui/MatchToggle.tsx",
|
|
"src/components/ui/MediaCard.tsx",
|
|
"src/components/ui/MediaPreview.tsx",
|
|
"src/components/ui/MenuCheck.tsx",
|
|
"src/components/ui/Modal.tsx",
|
|
"src/components/ui/MoreButton.tsx",
|
|
"src/components/ui/NativeControls.tsx",
|
|
"src/components/ui/NavGrid.tsx",
|
|
"src/components/ui/NavRail.tsx",
|
|
"src/components/ui/OrderButtons.tsx",
|
|
"src/components/ui/Overlay.tsx",
|
|
"src/components/ui/PageMenu.tsx",
|
|
"src/components/ui/PageScroller.tsx",
|
|
"src/components/ui/PageShell.tsx",
|
|
"src/components/ui/Pager.tsx",
|
|
"src/components/ui/PanelGroup.tsx",
|
|
"src/components/ui/PanelGroups.tsx",
|
|
"src/components/ui/Pressable.tsx",
|
|
"src/components/ui/PriorityStepper.tsx",
|
|
"src/components/ui/QueryState.tsx",
|
|
"src/components/ui/RelativeTime.tsx",
|
|
"src/components/ui/SegmentedToggle.tsx",
|
|
"src/components/ui/SelectTrigger.tsx",
|
|
"src/components/ui/SidePanel.tsx",
|
|
"src/components/ui/Skeleton.tsx",
|
|
"src/components/ui/SkipLink.tsx",
|
|
"src/components/ui/SortControl.tsx",
|
|
"src/components/ui/StatTiles.tsx",
|
|
"src/components/ui/Tabs.tsx",
|
|
"src/components/ui/Toaster.tsx",
|
|
"src/components/ui/Tooltip.tsx",
|
|
"src/components/ui/UndoToolbar.tsx",
|
|
"src/components/ui/VirtualGrid.tsx",
|
|
"src/components/ui/anchoredPopoverHooks.ts",
|
|
"src/components/ui/backToTopState.ts",
|
|
"src/components/ui/buttonStyles.ts",
|
|
"src/components/ui/chipStyles.ts",
|
|
"src/components/ui/dialogFocus.ts",
|
|
"src/components/ui/fieldStyles.ts",
|
|
"src/components/ui/form.tsx",
|
|
"src/components/ui/gridColumns.ts",
|
|
"src/components/ui/landmarks.ts",
|
|
"src/components/ui/mediaCardStyles.ts",
|
|
"src/components/ui/menuGroups.ts",
|
|
"src/components/ui/overlayOrder.ts",
|
|
"src/components/ui/pageHeading.ts",
|
|
"src/components/ui/pageMenuItems.ts",
|
|
"src/components/ui/pageMenuSlot.ts",
|
|
"src/components/ui/pageToolbarSlot.ts",
|
|
"src/components/ui/pagerContent.ts",
|
|
"src/components/ui/progressiveRows.ts",
|
|
"src/components/ui/readAhead.ts",
|
|
"src/components/ui/reveal.ts",
|
|
"src/components/ui/scrollFold.ts",
|
|
"src/components/ui/sortableA11y.ts",
|
|
"src/components/ui/stickyTop.ts",
|
|
"src/components/ui/surfaces.ts",
|
|
"src/components/ui/tabPanel.ts",
|
|
"src/components/ui/tableAlign.ts",
|
|
"src/components/ui/tableHeader.tsx",
|
|
"src/components/ui/toastLevels.ts",
|
|
"src/components/ui/useContextMenu.ts",
|
|
"src/components/ui/useMediaPreview.ts",
|
|
"src/components/ui/useOrderItems.tsx",
|
|
"src/components/ui/useReturnFocus.ts"
|
|
],
|
|
"ui tests": [
|
|
"src/components/ui/ActionMenu.dom.test.tsx",
|
|
"src/components/ui/AnchoredPopover.dom.test.tsx",
|
|
"src/components/ui/AnchoredPopover.returnFocus.dom.test.tsx",
|
|
"src/components/ui/Avatar.dom.test.tsx",
|
|
"src/components/ui/BackToTop.dom.test.tsx",
|
|
"src/components/ui/Banner.dom.test.tsx",
|
|
"src/components/ui/Button.dom.test.tsx",
|
|
"src/components/ui/Carousel.dom.test.tsx",
|
|
"src/components/ui/Chip.dom.test.tsx",
|
|
"src/components/ui/ClampedText.dom.test.tsx",
|
|
"src/components/ui/Combobox.dom.test.tsx",
|
|
"src/components/ui/CommandPalette.dom.test.tsx",
|
|
"src/components/ui/CommandPalette.ordering.dom.test.tsx",
|
|
"src/components/ui/ContextMenu.dom.test.tsx",
|
|
"src/components/ui/DataTable.fixedLayout.dom.test.tsx",
|
|
"src/components/ui/DataTable.keyboard.dom.test.tsx",
|
|
"src/components/ui/DataTable.progressive.dom.test.tsx",
|
|
"src/components/ui/FilterChipGroup.dom.test.tsx",
|
|
"src/components/ui/FilterFold.dom.test.tsx",
|
|
"src/components/ui/FilterSelect.dom.test.tsx",
|
|
"src/components/ui/FocusSafeButton.select.dom.test.tsx",
|
|
"src/components/ui/HiddenFilterCue.dom.test.tsx",
|
|
"src/components/ui/IconButton.dom.test.tsx",
|
|
"src/components/ui/Input.dom.test.tsx",
|
|
"src/components/ui/ItemCount.dom.test.tsx",
|
|
"src/components/ui/KeyboardHelp.dom.test.tsx",
|
|
"src/components/ui/MatchToggle.dom.test.tsx",
|
|
"src/components/ui/Modal.dom.test.tsx",
|
|
"src/components/ui/Modal.fullscreen.dom.test.tsx",
|
|
"src/components/ui/Modal.purpose.dom.test.tsx",
|
|
"src/components/ui/Modal.strictmode.dom.test.tsx",
|
|
"src/components/ui/NavRail.dom.test.tsx",
|
|
"src/components/ui/OrderButtons.dom.test.tsx",
|
|
"src/components/ui/PageMenu.dom.test.tsx",
|
|
"src/components/ui/PageScroller.dom.test.tsx",
|
|
"src/components/ui/PageShell.dom.test.tsx",
|
|
"src/components/ui/Pager.dom.test.tsx",
|
|
"src/components/ui/PanelGroups.dom.test.tsx",
|
|
"src/components/ui/PriorityStepper.dom.test.tsx",
|
|
"src/components/ui/QueryState.dom.test.tsx",
|
|
"src/components/ui/RelativeTime.dom.test.tsx",
|
|
"src/components/ui/SegmentedToggle.dom.test.tsx",
|
|
"src/components/ui/SidePanel.drawer.dom.test.tsx",
|
|
"src/components/ui/SkipLink.dom.test.tsx",
|
|
"src/components/ui/SortControl.dom.test.tsx",
|
|
"src/components/ui/StatTiles.dom.test.tsx",
|
|
"src/components/ui/Tabs.dom.test.tsx",
|
|
"src/components/ui/Toaster.dom.test.tsx",
|
|
"src/components/ui/Toaster.hosts.test.ts",
|
|
"src/components/ui/Toaster.strictmode.dom.test.tsx",
|
|
"src/components/ui/Tooltip.layer.dom.test.tsx",
|
|
"src/components/ui/dialogFocus.dom.test.tsx",
|
|
"src/components/ui/form.dom.test.tsx",
|
|
"src/components/ui/gridColumns.test.ts",
|
|
"src/components/ui/hiddenFilterCue.contract.test.ts",
|
|
"src/components/ui/mediaRail.contract.test.ts",
|
|
"src/components/ui/menuCheck.contract.test.ts",
|
|
"src/components/ui/pageMenuScope.contract.test.ts",
|
|
"src/components/ui/pressableSelectable.contract.test.ts",
|
|
"src/components/ui/readAhead.test.ts",
|
|
"src/components/ui/scrollFold.test.ts",
|
|
"src/components/ui/sortableA11y.dom.test.tsx",
|
|
"src/components/ui/stickyTop.dom.test.tsx",
|
|
"src/components/ui/tailwindScan.contract.test.ts",
|
|
"src/components/ui/uiI18n.contract.test.ts",
|
|
"src/components/ui/useItemTriggers.dom.test.ts",
|
|
"src/components/ui/useReturnFocus.dom.test.tsx"
|
|
]
|
|
}
|
|
},
|
|
"lanes": {
|
|
".gitea/workflows/check.yml": [
|
|
"name: gate",
|
|
"on:",
|
|
" push:",
|
|
" branches: [\"**\"]",
|
|
" pull_request:",
|
|
"jobs:",
|
|
" frontend:",
|
|
" runs-on: ubuntu-latest",
|
|
" container: node:24-bookworm",
|
|
" defaults:",
|
|
" run:",
|
|
" working-directory: frontend",
|
|
" steps:",
|
|
" - uses: actions/checkout@v4",
|
|
" - run: npm ci",
|
|
" - run: npm run typecheck",
|
|
" - run: npm run lint",
|
|
" - run: npm run format:check",
|
|
" - run: npm run knip",
|
|
" - run: npm run test",
|
|
" - run: npx vite build",
|
|
" - run: npm audit --omit=dev --audit-level=high",
|
|
" backend:",
|
|
" runs-on: ubuntu-latest",
|
|
" container: nikolaik/python-nodejs:python3.12-nodejs24",
|
|
" services:",
|
|
" postgres:",
|
|
" image: postgres:16-alpine",
|
|
" env:",
|
|
" POSTGRES_USER: siftlode",
|
|
" POSTGRES_PASSWORD: siftlode",
|
|
" POSTGRES_DB: siftlode_test",
|
|
" options: >-",
|
|
" --health-cmd \"pg_isready -U siftlode -d siftlode_test\"",
|
|
" --health-interval 2s",
|
|
" --health-timeout 3s",
|
|
" --health-retries 30",
|
|
" env:",
|
|
" DATABASE_URL: postgresql+psycopg://siftlode:siftlode@postgres:5432/siftlode_test",
|
|
" SIFTLODE_TEST_REQUIRE_DB: \"1\"",
|
|
" steps:",
|
|
" - uses: actions/checkout@v4",
|
|
" - run: apt-get update && apt-get install -y --no-install-recommends ffmpeg postgresql-client",
|
|
" - name: Wait for Postgres",
|
|
" run: until pg_isready -h postgres -U siftlode -d siftlode_test; do sleep 1; done",
|
|
" - run: pip install --no-cache-dir -r backend/requirements.lock -r backend/requirements-dev.txt",
|
|
" - name: ruff",
|
|
" run: python -m ruff check --config backend/ruff.toml backend scripts",
|
|
" - name: ruff format --check",
|
|
" run: python -m ruff format --check --config backend/ruff.toml backend scripts",
|
|
" - name: basedpyright",
|
|
" run: python -m basedpyright --project pyrightconfig.json",
|
|
" working-directory: backend",
|
|
" - name: basedpyright baseline is committed",
|
|
" run: git diff --exit-code -- backend/.basedpyright/baseline.json",
|
|
" - name: pytest",
|
|
" run: python -m pytest",
|
|
" working-directory: backend",
|
|
" - name: pip-audit",
|
|
" run: pip install --no-cache-dir pip-audit && pip-audit -r backend/requirements.lock"
|
|
],
|
|
"backend/Dockerfile.test": [
|
|
"FROM python:3.12-slim",
|
|
"WORKDIR /app",
|
|
"RUN apt-get update \\",
|
|
" && apt-get install -y --no-install-recommends ffmpeg \\",
|
|
" && rm -rf /var/lib/apt/lists/*",
|
|
"COPY requirements.lock requirements-dev.txt ./",
|
|
"RUN pip install --no-cache-dir -r requirements.lock -r requirements-dev.txt"
|
|
],
|
|
"backend/docker-compose.test.yml": [
|
|
"services:",
|
|
" testdb:",
|
|
" image: postgres:16-alpine",
|
|
" environment:",
|
|
" POSTGRES_USER: siftlode",
|
|
" POSTGRES_PASSWORD: siftlode",
|
|
" POSTGRES_DB: siftlode_test",
|
|
" tmpfs:",
|
|
" - /var/lib/postgresql/data # ephemeral + fast; the schema is rebuilt per run",
|
|
" healthcheck:",
|
|
" test: [\"CMD-SHELL\", \"pg_isready -U siftlode -d siftlode_test\"]",
|
|
" interval: 1s",
|
|
" timeout: 3s",
|
|
" retries: 30",
|
|
" test:",
|
|
" build:",
|
|
" context: .",
|
|
" dockerfile: Dockerfile.test",
|
|
" depends_on:",
|
|
" testdb:",
|
|
" condition: service_healthy",
|
|
" environment:",
|
|
" DATABASE_URL: postgresql+psycopg://siftlode:siftlode@testdb:5432/siftlode_test",
|
|
" SIFTLODE_TEST_REQUIRE_DB: \"1\"",
|
|
" volumes:",
|
|
" - ./:/app",
|
|
" working_dir: /app",
|
|
" command:",
|
|
" - sh",
|
|
" - -c",
|
|
" - 'python -m pytest --cov=app --cov-report= ; rc=$$?; echo \">> backend coverage (app/) $$(python -m coverage report --format=total)% of lines\"; exit $$rc'"
|
|
],
|
|
"frontend/.prettierignore": [
|
|
"dist",
|
|
"node_modules",
|
|
"playwright-report",
|
|
"test-results",
|
|
"e2e/.auth",
|
|
"package-lock.json"
|
|
],
|
|
"frontend/package.json scripts": {
|
|
"build": "npm run typecheck:app && npm run typecheck:node && vite build",
|
|
"dev": "vite",
|
|
"e2e": "playwright test",
|
|
"format": "prettier --write .",
|
|
"format:check": "prettier --check .",
|
|
"knip": "knip && knip --production",
|
|
"lint": "eslint . --max-warnings 0",
|
|
"preview": "vite preview",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"typecheck": "npm run typecheck:app && npm run typecheck:node && npm run typecheck:e2e",
|
|
"typecheck:app": "tsc --noEmit -p tsconfig.json",
|
|
"typecheck:e2e": "tsc --noEmit -p e2e/tsconfig.json",
|
|
"typecheck:node": "tsc -p tsconfig.node.json"
|
|
},
|
|
"frontend/vitest.config.ts": [
|
|
"import { defineConfig } from \"vitest/config\";",
|
|
"import { reactWithCompiler } from \"./reactPlugin\";",
|
|
"export default defineConfig({",
|
|
" plugins: [reactWithCompiler()],",
|
|
" test: {",
|
|
" include: [\"src/**/*.test.{ts,tsx}\"],",
|
|
" environment: \"node\",",
|
|
" coverage: {",
|
|
" provider: \"v8\",",
|
|
" include: [\"src/**/*.{ts,tsx}\"],",
|
|
" exclude: [\"src/**/*.test.{ts,tsx}\", \"src/**/*.testkit.ts\", \"src/**/*.d.ts\"],",
|
|
" reporter: [\"text-summary\"],",
|
|
" },",
|
|
" },",
|
|
"});"
|
|
]
|
|
}
|
|
}
|