sh-mcp/eslint.config.js
Adam Moussa a60a5a5794 Add security-weighted test suite + coverage gate; wire tooling
Add tests for the highest-risk surface (build-plan §5, design.md §7.3):
tool-hiding, server-side scope enforcement (incl. forced hidden calls),
audience binding, input-schema validation, finance redaction on egress, audit
emission with hashed args, prompt-injection regression (tool output is data),
rate limiting, MCP conformance (in-memory transport round-trip), OpenAPI 3.1
validity, and local-auth safety. Add HTTP integration tests (supertest) for both
servers and per-package dev-client tests. 405 tests pass.

Wire the coverage gate into vitest.config.ts: 80% overall, with per-file
thresholds on the auth + dispatch crown jewels; exclude deferred real client
stubs, entrypoints, cdk apps, and aws-only config from the gate (documented).
Extend eslint flat config + add .prettierignore to cover servers/. Commit the
updated package-lock.json.
2026-06-26 12:48:26 -04:00

137 lines
4.9 KiB
JavaScript

// @ts-check
import tseslint from '@typescript-eslint/eslint-plugin';
import tsparser from '@typescript-eslint/parser';
/**
* Flat ESLint config for ESLint 9.x.
* Migrated from .eslintrc.cjs which required legacy mode.
*
* Rules mirror the original: recommended + recommended-requiring-type-checking
* plus project-specific overrides.
*/
/** @type {import('eslint').Linter.Config[]} */
const config = [
// ── Global ignores ──────────────────────────────────────────────────────────
{
ignores: [
'**/dist/**',
'**/node_modules/**',
'**/*.d.ts',
'eslint.config.js',
'vitest.config.ts',
],
},
// ── Source files (with project-based type checking) ─────────────────────────
{
files: ['packages/*/src/**/*.ts', 'servers/*/src/**/*.ts'],
languageOptions: {
parser: tsparser,
parserOptions: {
project: [
'./packages/calendar/tsconfig.json',
'./packages/gmail/tsconfig.json',
'./packages/google-maps/tsconfig.json',
'./packages/internal-data/tsconfig.json',
'./packages/knowledge-base/tsconfig.json',
'./packages/payments/tsconfig.json',
'./packages/qbo/tsconfig.json',
'./packages/reminders/tsconfig.json',
'./packages/shared/tsconfig.json',
'./packages/tasks/tsconfig.json',
'./servers/sh-mcp-ops/tsconfig.json',
'./servers/sh-mcp-finance/tsconfig.json',
],
tsconfigRootDir: import.meta.dirname,
},
globals: {
process: 'readonly',
console: 'readonly',
},
},
plugins: {
'@typescript-eslint': tseslint,
},
rules: {
'no-undef': 'off', // TypeScript handles this
'no-unused-vars': 'off', // Use @typescript-eslint version
// Core @typescript-eslint/recommended rules
'@typescript-eslint/ban-ts-comment': 'error',
'@typescript-eslint/no-array-constructor': 'error',
'@typescript-eslint/no-duplicate-enum-values': 'error',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-extra-non-null-assertion': 'error',
'@typescript-eslint/no-misused-new': 'error',
'@typescript-eslint/no-namespace': 'error',
'@typescript-eslint/no-non-null-asserted-optional-chain': 'error',
'@typescript-eslint/no-require-imports': 'error',
'@typescript-eslint/no-this-alias': 'error',
'@typescript-eslint/no-unnecessary-type-constraint': 'error',
'@typescript-eslint/no-unsafe-declaration-merging': 'error',
'@typescript-eslint/no-unused-expressions': 'error',
'@typescript-eslint/prefer-as-const': 'error',
'@typescript-eslint/prefer-namespace-keyword': 'error',
'@typescript-eslint/triple-slash-reference': 'error',
// Type-checked rules (require-type-checking)
'@typescript-eslint/no-floating-promises': 'error',
'@typescript-eslint/no-misused-promises': 'error',
'@typescript-eslint/no-unsafe-argument': 'warn',
'@typescript-eslint/no-unsafe-assignment': 'warn',
'@typescript-eslint/no-unsafe-call': 'warn',
'@typescript-eslint/no-unsafe-member-access': 'warn',
'@typescript-eslint/no-unsafe-return': 'warn',
'@typescript-eslint/require-await': 'warn',
'@typescript-eslint/restrict-template-expressions': 'warn',
// Project-specific overrides
'@typescript-eslint/explicit-function-return-type': 'warn',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
'@typescript-eslint/strict-boolean-expressions': 'warn',
},
},
// ── Test files + CDK synth apps (no project-based type checking) ────────────
// test/ dirs and cdk/ apps are excluded from the package/server tsconfigs, so
// type-checked rules are disabled here to avoid "file not in project" errors.
{
files: ['packages/*/test/**/*.ts', 'servers/*/test/**/*.ts', 'servers/*/cdk/**/*.ts'],
languageOptions: {
parser: tsparser,
parserOptions: {
// No `project` here — avoids "file not found in project" errors for
// test files that are excluded from the package tsconfigss.
// Type-checking rules are disabled below.
},
globals: {
process: 'readonly',
console: 'readonly',
},
},
plugins: {
'@typescript-eslint': tseslint,
},
rules: {
'no-undef': 'off',
'no-unused-vars': 'off',
'@typescript-eslint/no-explicit-any': 'warn',
'@typescript-eslint/no-unused-vars': [
'error',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
},
],
},
},
];
export default config;