CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-web-ext

A command line tool to help build, run, and test web extensions

Pending
Overview
Eval results
Files

linting-system.mddocs/

Linting System

Extension validation using Mozilla's addons-linter with configurable output formats, validation rules, and comprehensive error reporting for WebExtension compliance.

Capabilities

Lint Function

Validate extension source code against WebExtension standards and Mozilla's addon policies.

/**
 * Lint an extension using Mozilla's addons-linter
 * @param params - Linting configuration parameters
 * @param options - Optional linter dependencies and settings
 * @returns Promise that resolves when linting completes
 */
function lint(params: LintParams, options?: LintOptions): Promise<void>;

interface LintParams {
  /** Source directory containing the extension */
  sourceDir: string;
  /** Directory for artifacts (used for file filtering) */
  artifactsDir: string;
  /** Output format for linting results */
  output?: 'text' | 'json';
  /** Output only metadata as JSON */
  metadata?: boolean;
  /** Treat warnings as errors (exit with non-zero code) */
  warningsAsErrors?: boolean;
  /** Prettify JSON output */
  pretty?: boolean;
  /** Treat extension as privileged (fewer restrictions) */
  privileged?: boolean;
  /** Extension will be self-hosted (disables AMO-specific messages) */
  selfHosted?: boolean;
  /** Disable colorful shell output */
  boring?: boolean;
  /** Array of glob patterns for files to ignore */
  ignoreFiles?: string[];
  /** Enable verbose logging output */
  verbose?: boolean;
}

interface LintOptions {
  /** Custom linter factory function */
  createLinter?: Function;
  /** Custom file filter factory */
  createFileFilter?: Function;
  /** Should exit process after linting */
  shouldExitProgram?: boolean;
}

Usage Examples:

import { cmd } from "web-ext";

// Basic linting with text output
await cmd.lint({
  sourceDir: './my-extension'
});

// Lint with JSON output and detailed formatting
await cmd.lint({
  sourceDir: './extension',
  output: 'json',
  pretty: true,
  verbose: true
});

// Strict linting (treat warnings as errors)
await cmd.lint({
  sourceDir: './extension',
  warningsAsErrors: true,
  privileged: false,
  selfHosted: false
});

// Lint with custom file filtering
await cmd.lint({
  sourceDir: './src',
  artifactsDir: './build',
  ignoreFiles: ['*.log', 'node_modules/**', 'test/**'],
  output: 'json'
});

Linter Configuration

Advanced configuration options for customizing the linting process.

interface LinterConfig {
  /** Log level for linter output */
  logLevel: 'debug' | 'info' | 'warn' | 'error' | 'fatal';
  /** Include stack traces in output */
  stack: boolean;
  /** Pretty print JSON output */
  pretty: boolean;
  /** Treat extension as privileged */
  privileged: boolean;
  /** Treat warnings as errors */
  warningsAsErrors: boolean;
  /** Output only metadata */
  metadata: boolean;
  /** Output format */
  output: 'text' | 'json';
  /** Disable colors in output */
  boring: boolean;
  /** Extension is self-hosted */
  selfHosted: boolean;
  /** Function to determine if file should be scanned */
  shouldScanFile: (fileName: string) => boolean;
  /** Minimum supported manifest version */
  minManifestVersion: number;
  /** Maximum supported manifest version */
  maxManifestVersion: number;
  /** Command line arguments (for context) */
  _: string[];
}

File Filtering Integration

The linting system integrates with web-ext's file filtering to exclude unwanted files from validation.

interface FileFilter {
  /** Determine if a file should be included in linting */
  wantFile(fileName: string): boolean;
}

Default Excluded Files:

  • **/*.xpi - Firefox extension packages
  • **/*.zip - Zip archives
  • **/.* - Hidden files and directories
  • **/node_modules - Node.js dependencies
  • Build artifacts and temporary files

Linter Factory

Create custom linter instances with specific configurations.

/**
 * Create an addons-linter instance
 * @param config - Linter configuration
 * @returns Configured linter instance
 */
function createLinter(config: LinterConfig): AddonLinter;

interface AddonLinter {
  /** Run the linter and return results */
  run(): Promise<LintResult>;
}

interface LintResult {
  /** Total number of errors found */
  errorCount: number;
  /** Total number of warnings found */
  warningCount: number;
  /** Array of error and warning messages */
  messages: LintMessage[];
  /** Extension metadata */
  metadata: ExtensionMetadata;
  /** Summary information */
  summary: LintSummary;
}

Lint Results

Detailed structure of linting results for programmatic processing.

interface LintMessage {
  /** Unique identifier for the message type */
  code: string;
  /** Severity level */
  type: 'error' | 'warning' | 'notice';
  /** Human-readable message */
  message: string;
  /** File where the issue was found */
  file?: string;
  /** Line number of the issue */
  line?: number;
  /** Column number of the issue */
  column?: number;
  /** Additional context or description */
  description?: string;
}

interface ExtensionMetadata {
  /** Extension name */
  name: string;
  /** Extension version */
  version: string;
  /** Manifest version */
  manifestVersion: number;
  /** Extension type */
  type: string;
  /** Extension ID */
  id?: string;
  /** Required permissions */
  permissions?: string[];
  /** Content scripts information */
  contentScripts?: object[];
}

interface LintSummary {
  /** Total files scanned */
  totalFiles: number;
  /** Total errors found */
  errors: number;
  /** Total warnings found */
  warnings: number;
  /** Total notices */
  notices: number;
}

Output Formats

The linter supports multiple output formats for different use cases.

Text Output

Human-readable console output with colors and formatting:

Validation Summary:

errors          0
notices         0
warnings        1

Code               Message                                    File:Line
MANIFEST_UNUSED_   /permissions/storage is unused            manifest.json:15:1
UPDATE

Your add-on uses deprecated functionality that has been removed from Firefox 71+...

JSON Output

Machine-readable JSON format for automated processing:

{
  "count": {
    "errors": 0,
    "notices": 0,
    "warnings": 1
  },
  "summary": {
    "errors": 0,
    "notices": 0,
    "warnings": 1
  },
  "metadata": {
    "name": "My Extension",
    "version": "1.0.0",
    "manifestVersion": 2
  },
  "messages": [
    {
      "code": "MANIFEST_UNUSED_UPDATE",
      "message": "/permissions/storage is unused",
      "description": "Your extension uses...",
      "file": "manifest.json",
      "line": 15,
      "column": 1,
      "type": "warning"
    }
  ]
}

Validation Rules

The linter validates extensions against comprehensive rule sets:

Manifest Validation

  • Required fields (name, version, manifest_version)
  • Permission usage and requirements
  • API compatibility across manifest versions
  • File references and resource validation

Code Analysis

  • JavaScript syntax and best practices
  • Content Security Policy compliance
  • API usage validation
  • Deprecated API detection

Asset Validation

  • Icon file formats and sizes
  • Locale file structure and content
  • HTML file validation
  • CSS compatibility

Security Checks

  • Potentially dangerous patterns
  • External resource usage
  • Permission scope validation
  • Content script injection safety

Error Handling

The linting system provides detailed error reporting:

  • Manifest errors: Invalid JSON, missing required fields, malformed values
  • File errors: Missing referenced files, invalid file formats
  • Code errors: Syntax errors, deprecated API usage, security issues
  • Permission errors: Unused permissions, insufficient permissions for API usage
  • Compatibility errors: Features not supported in target Firefox versions

Usage Example for Error Handling:

try {
  await cmd.lint({
    sourceDir: './extension',
    warningsAsErrors: true
  });
  console.log('Extension passed all validation checks!');
} catch (error) {
  console.error('Linting failed:', error.message);
  // Linter will have already output detailed validation results
}

Install with Tessl CLI

npx tessl i tessl/npm-web-ext

docs

android-development.md

build-system.md

extension-runners.md

index.md

linting-system.md

logging-system.md

main-api.md

signing-publishing.md

tile.json