Skip to content

refactor(website): Improve server architecture with domain-driven design#803

Merged
yamadashy merged 9 commits intomainfrom
feat/website-improve
Aug 24, 2025
Merged

refactor(website): Improve server architecture with domain-driven design#803
yamadashy merged 9 commits intomainfrom
feat/website-improve

Conversation

@yamadashy
Copy link
Owner

This PR significantly improves the website server architecture by implementing domain-driven design principles and better separation of concerns.

Summary

Major architectural improvements:

  • Reorganized server code into domain-based structure
  • Extracted action logic from index.ts into dedicated actions directory
  • Created middleware components for better modularity
  • Centralized validation and rate limiting at appropriate architectural layers
  • Simplified request schemas and removed redundant validation

Key Changes

🏗️ Domain-Driven Architecture

  • Created domains/pack/ structure for pack-related business logic
  • Moved utilities to appropriate domain locations (cache.ts, fileUtils.ts, sharedInstance.ts)
  • Consolidated constants into domain-specific locations

🎯 Action Layer Improvements

  • Extracted pack logic from index.ts into dedicated actions/packAction.ts
  • Centralized request validation at action layer using Zod schemas
  • Simplified schema definitions by removing intermediate variables and redundant checks
  • Integrated request schemas directly into packAction for better colocation

🔒 Middleware Architecture

  • Created dedicated middleware directory with modular components:
    • bodyLimit.ts - Request size limiting
    • cloudLogger.ts - Structured logging (renamed from logger.ts)
    • cors.ts - CORS configuration
    • rateLimit.ts - Rate limiting (moved from action layer)
  • Improved middleware ordering for optimal request processing

🛠️ Utilities & Infrastructure

  • Created clientInfo.ts utility for unified client information extraction
  • Enhanced validation.ts with reusable validation functions
  • Removed redundant files (constants.ts, schemas/request.ts, network.ts)
  • Updated imports throughout codebase for new structure

Architecture Benefits

  • 🔄 Clear Separation of Concerns: Each layer has well-defined responsibilities
  • ♻️ Better Code Reusability: Utilities and middleware can be easily reused
  • 🎯 Improved Maintainability: Domain-driven structure makes code easier to navigate
  • 🔒 Enhanced Security: Rate limiting and validation at appropriate architectural boundaries
  • ⚡ Better Performance: Early request blocking and optimized middleware chain

File Changes

New Files:

  • actions/packAction.ts - Consolidated pack endpoint logic
  • middlewares/ - Dedicated middleware components (4 files)
  • domains/pack/ - Pack domain structure (7 files)
  • utils/clientInfo.ts - Unified client information utility

Removed Files:

  • constants.ts - Consolidated into domain files
  • schemas/request.ts - Integrated into packAction
  • network.ts - Replaced with clientInfo utility

Refactored:

  • index.ts - Simplified to focus on server configuration
  • Various utilities moved to appropriate domains

Checklist

  • Run npm run test - All 743 tests pass
  • Run npm run lint - No warnings or errors
  • Validated architectural improvements maintain backward compatibility
  • Confirmed all security measures (rate limiting, validation) remain intact

This refactoring establishes a solid, scalable foundation for future development while maintaining full backward compatibility.

This commit restructures the website server code to follow a domain-driven design pattern, improving maintainability and separation of concerns.

Changes:
- Create src/actions/ directory for API action handlers
- Create src/domains/pack/ directory for pack-related business logic
- Extract pack endpoint logic from index.ts into packAction.ts
- Move processZipFile.ts and remoteRepo.ts to domains/pack/
- Update all import paths to reflect new directory structure
- Simplify index.ts to focus on server configuration and routing

The new structure separates API routing (index.ts), action handlers (actions/),
and domain logic (domains/pack/) for better code organization.
This commit reorganizes the utilities directory by moving pack-specific
utilities into the pack domain structure, following domain-driven design
principles.

Changes:
- Move pack-specific utilities to domains/pack/utils/:
  - cache.ts: PackResult-specific caching functionality
  - fileUtils.ts: ZIP processing and pack-related file operations
  - validation.ts: Pack request validation logic
  - sharedInstance.ts: Pack domain cache and rate limiter instances
- Keep generic utilities in utils/:
  - errorHandler.ts: Application-wide error handling
  - logger.ts: Cross-domain logging functionality
  - memory.ts: Cross-domain memory monitoring
  - network.ts: Cross-domain network utilities
  - processConcurrency.ts: System-wide CPU information
  - rateLimit.ts: Base rate limiting functionality
  - time.ts: Cross-domain time processing
- Update all import paths to reflect new structure
- Maintain separation of concerns between domain-specific and generic utilities

This improves code organization by placing domain-specific logic within
the appropriate domain boundaries while keeping truly generic utilities
accessible across all domains.
This commit creates a dedicated middlewares directory and extracts Hono
middleware configurations from the main server file for better organization
and maintainability.

Changes:
- Create middlewares/ directory for middleware organization
- Extract cloudLogger middleware to middlewares/logger.ts:
  - Move custom logging middleware with request tracking
  - Generate unique request IDs and track request lifecycle
  - Include memory usage and latency monitoring
  - Fix type errors with proper function signatures
- Extract CORS configuration to middlewares/cors.ts:
  - Define allowed origins and headers
  - Handle development and production environments
- Extract body limit middleware to middlewares/bodyLimit.ts:
  - Configure request size limits
  - Handle file size exceeded errors
- Clean up utils/logger.ts:
  - Remove middleware-specific code
  - Export logger instance for reuse
  - Focus on pure logging utilities
- Simplify index.ts:
  - Import middleware from dedicated modules
  - Remove inline middleware configurations
  - Improve code readability and maintainability

This separation follows middleware best practices and makes the codebase
more modular while maintaining all existing functionality.
… validation

Major improvements to the website server architecture following domain-driven design principles:

## Validation & Request Handling
- Move request validation from domain functions to packAction (action layer responsibility)
- Consolidate request schemas from separate files into packAction.ts for better colocation
- Create reusable utils/validation.ts for generic validation functionality
- Remove redundant validation.ts from actions directory

## Rate Limiting & Client Information
- Move rate limiting checks from domain functions to action layer
- Create utils/clientInfo.ts utility for centralized client information extraction
- Replace individual IP extraction with structured ClientInfo interface including IP, userAgent, and referer
- Update cloudLogger middleware to use unified clientInfo utility

## Code Organization
- Consolidate FILE_SIZE_LIMITS constants into domains/pack/utils/fileUtils.ts
- Remove unused constants.ts and schemas/request.ts files
- Rename middlewares/logger.ts to cloudLogger.ts with cloudLoggerMiddleware function for clarity
- Clean up domain function signatures by removing clientIp parameters

## Architecture Benefits
- Clear separation of concerns between action, domain, and utility layers
- Centralized validation and rate limiting at appropriate architectural boundaries
- Improved code reusability and maintainability
- Better error handling and client information management

This refactoring establishes a solid foundation for future feature development while maintaining backward compatibility.
…lidation

- Inline schema definitions for better readability and reduced complexity
- Remove intermediate variables (packOptionsSchema, fileSchema, isValidZipFile, ignorePatternRegex)
- Eliminate redundant manual validation checks already covered by Zod schema:
  - Remove manual format enum validation (handled by z.enum)
  - Remove manual file/url existence check (handled by schema refinements)
- Consolidate validation logic entirely within the Zod schema for consistency

This simplification follows the DRY principle and ensures all validation is handled uniformly through the schema-first approach.
- Create dedicated rateLimitMiddleware for better separation of concerns
- Remove rate limiting logic from packAction to focus on business logic
- Apply rate limiting at middleware layer for early request blocking
- Simplify packAction by removing rate limiting imports and checks
- Improve middleware ordering in index.ts for optimal request processing

This architectural improvement follows the middleware pattern and provides:
- Better security through early rate limiting
- Cleaner action layer focused on business logic
- Consistent middleware-based approach for cross-cutting concerns
- Improved reusability for future API endpoints
Copilot AI review requested due to automatic review settings August 24, 2025 14:28
@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Aug 24, 2025

Deploying repomix with  Cloudflare Pages  Cloudflare Pages

Latest commit: b492ebc
Status: ✅  Deploy successful!
Preview URL: https://bee6854c.repomix.pages.dev
Branch Preview URL: https://feat-website-improve.repomix.pages.dev

View logs

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Aug 24, 2025

Note

Other AI code review bot(s) detected

CodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review.

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Adds a modular /api/pack HTTP action with middleware (CORS, body-limit, rate-limit, cloud logger). Refactors pack processing for ZIP uploads and remote repos to rely on direct options, new sanitization utility, and caching. Moves size constants to pack utils, introduces client info utility, and removes legacy schema/validation and network helpers.

Changes

Cohort / File(s) Summary
Routing and Action
website/server/src/index.ts, website/server/src/actions/packAction.ts
Route refactored to use app.post with middleware; new packAction handles form-data, validates inputs, sanitizes patterns, dispatches to ZIP/remote processing, and structured error handling/logging.
Middleware
website/server/src/middlewares/cors.ts, website/server/src/middlewares/bodyLimit.ts, website/server/src/middlewares/cloudLogger.ts, website/server/src/middlewares/rateLimit.ts
New middlewares for CORS, request body size limit, per-request logging with requestId, and IP-based rate limiting; integrated into server.
Pack Processing
website/server/src/domains/pack/processZipFile.ts, website/server/src/domains/pack/remoteRepo.ts
Removed schema validation and client IP rate checks; simplified signatures; use direct format/options, updated CLI flag mapping, cache-key generation, and memory logging.
Pack Utilities and Shared
website/server/src/domains/pack/utils/cache.ts, website/server/src/domains/pack/utils/fileUtils.ts, website/server/src/domains/pack/utils/sharedInstance.ts, website/server/src/domains/pack/utils/validation.ts
Import path adjustments; reintroduced FILE_SIZE_LIMITS and formatFileSize locally; added sanitizePattern under pack utils; updated RateLimiter import; no API changes except added exports.
Constants and Schemas Cleanup
website/server/src/constants.ts, website/server/src/schemas/request.ts, website/server/src/utils/validation.ts
Removed global FILE_SIZE_LIMITS/formatFileSize and entire pack request/schema module; removed sanitizePattern from utils (moved to pack utils).
General Utilities
website/server/src/utils/clientInfo.ts, website/server/src/utils/logger.ts, website/server/src/utils/network.ts
Added clientInfo utility; logger now exported and cloudLogger removed from logger module (replaced by dedicated middleware); removed network IP helper.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant App as Hono App
  participant CORS as CORS MW
  participant BL as BodyLimit MW
  participant RL as RateLimit MW
  participant CL as CloudLogger MW
  participant Action as packAction
  participant Zip as processZipFile
  participant Repo as processRemoteRepo
  participant Cache as RequestCache

  Client->>App: POST /api/pack (form-data)
  App->>CORS: apply
  CORS->>BL: next
  BL->>RL: next
  RL->>CL: next
  CL->>Action: next (requestId set)

  rect rgb(245,245,255)
    note right of Action: Parse form-data, sanitize patterns, build options
    Action->>Cache: (via Zip/Repo) lookup by key
  end

  alt has ZIP file
    Action->>Zip: processZipFile(file, format, options)
    Zip-->>Action: PackResult
  else has repo URL
    Action->>Repo: processRemoteRepo(url, format, options)
    Repo-->>Action: PackResult
  else
    Action-->>Client: 400 error (validation)
  end

  Action-->>Client: JSON PackResult
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/website-improve

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

‼️ IMPORTANT
Auto-reply has been disabled for this repository in the CodeRabbit settings. The CodeRabbit bot will not respond to your replies unless it is explicitly tagged.

  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@claude
Copy link
Contributor

claude bot commented Aug 24, 2025

Claude encountered an error —— View job


I'll analyze this and get back to you.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of Changes

Hello @yamadashy, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant refactoring of the website server's architecture, moving towards a more robust and scalable design based on Domain-Driven Design (DDD) principles. The primary goal is to improve the separation of concerns by creating distinct layers for actions, middleware, and domain-specific logic. This refactoring centralizes validation and rate limiting, streamlines utility functions, and simplifies the main server entry point, laying a solid foundation for future development while enhancing maintainability, security, and performance.

Highlights

  • Domain-Driven Architecture Implementation: The server codebase has been restructured to follow Domain-Driven Design (DDD) principles. This includes creating a dedicated domains/pack/ directory to encapsulate all business logic related to the 'pack' functionality, moving relevant utilities (cache, fileUtils, sharedInstance) into this domain, and consolidating constants within domain-specific locations.
  • Action Layer Refinement: The core logic for the '/api/pack' endpoint has been extracted from index.ts into a new dedicated action file, actions/packAction.ts. Request validation is now centralized at this action layer using Zod schemas, with simplified schema definitions and direct integration for better colocation.
  • Modular Middleware Architecture: A new middlewares/ directory has been introduced to house modular middleware components. This includes dedicated middleware for body size limiting (bodyLimit.ts), structured cloud logging (cloudLogger.ts), CORS configuration (cors.ts), and rate limiting (rateLimit.ts). This improves modularity and ensures proper middleware ordering.
  • Utility and Infrastructure Streamlining: New utilities like clientInfo.ts have been created for unified client information extraction. Redundant files such as constants.ts, schemas/request.ts, and network.ts have been removed, with their functionalities either absorbed into new structures or relocated. Imports across the codebase have been updated to reflect these changes.
  • Enhanced Maintainability, Security, and Performance: These architectural changes lead to a clearer separation of concerns, making the codebase easier to understand and navigate. Utilities and middleware are now more reusable, enhancing overall code maintainability. Security is improved through centralized validation and rate limiting at appropriate layers, and performance benefits from early request blocking and an optimized middleware chain.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@codecov
Copy link

codecov bot commented Aug 24, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.41%. Comparing base (30322d6) to head (b492ebc).
⚠️ Report is 10 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #803   +/-   ##
=======================================
  Coverage   87.41%   87.41%           
=======================================
  Files         113      113           
  Lines        6493     6493           
  Branches     1331     1331           
=======================================
  Hits         5676     5676           
  Misses        817      817           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This is an excellent pull request that significantly improves the server architecture by implementing domain-driven design principles. The separation of concerns is much clearer with the introduction of actions, domain logic, and middleware layers. The code is now more modular, maintainable, and easier to follow. I have a few suggestions to further improve code quality and maintainability.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
website/server/src/domains/pack/processZipFile.ts (2)

190-197: Fix directory traversal check: startsWith(destPath) is unsafe; use path.resolve + path.relative

Using startsWith() on normalized paths can yield false positives (e.g., "/tmp/repomix" vs "/tmp/repomix-evil"). Switch to resolve/relative, consistent with fileUtils.extractZip().

Apply:

-      const normalizedPath = path.normalize(path.join(destPath, entryPath));
-      if (!normalizedPath.startsWith(destPath)) {
+      const fullPath = path.resolve(destPath, entryPath);
+      const relativePath = path.relative(destPath, fullPath);
+      if (relativePath.startsWith('..') || path.isAbsolute(relativePath)) {
         throw new AppError(
           `Security violation: Potential directory traversal attack detected in path: ${entryPath}`,
           400,
         );
       }

71-72: Deduplicate ZIP extraction logic; reuse extractZip() from fileUtils

This file reimplements ZIP bomb/path traversal checks already present in domains/pack/utils/fileUtils.ts. Duplicating the logic risks drift and future security gaps. Call extractZip() and remove extractZipWithSecurity().

Proposed change:

-import { unzip } from 'fflate';
+import { unzip } from 'fflate'; // (can be removed if extractZipWithSecurity is deleted)
+import { extractZip } from './utils/fileUtils.js'
@@
-    // Extract the ZIP file to the temporary directory with enhanced security checks
-    await extractZipWithSecurity(file, tempDirPath);
+    // Extract the ZIP file to the temporary directory with enhanced security checks
+    await extractZip(file, tempDirPath);
@@
-/**
- * Enhanced ZIP extraction with security checks using fflate
- */
-async function extractZipWithSecurity(file: File, destPath: string): Promise<void> {
-  ...
-}
+// (No longer needed: extraction handled by extractZip in fileUtils)

I can push a follow-up commit that removes the local function and dead imports.

Also applies to: 137-244

website/server/src/domains/pack/utils/fileUtils.ts (1)

147-153: Tighten temp directory validation to prevent accidental deletion outside os.tmpdir()

Using includes('repomix-') is weak and could match unintended paths. Ensure the directory lives under os.tmpdir() and its basename starts with the expected prefix.

Apply:

 export const cleanupTempDirectory = async (directory: string): Promise<void> => {
   try {
-    if (!directory.includes('repomix-')) {
-      throw new AppError('Invalid temporary directory path');
-    }
+    const tmpRoot = path.resolve(os.tmpdir());
+    const resolved = path.resolve(directory);
+    const rel = path.relative(tmpRoot, resolved);
+    const base = path.basename(resolved);
+    if (rel.startsWith('..') || path.isAbsolute(rel) || !base.startsWith('repomix-')) {
+      throw new AppError('Invalid temporary directory path');
+    }
     await fs.rm(directory, { recursive: true, force: true });
   } catch (error) {
     if (error instanceof AppError) {
       throw error;
     }
     console.error(`Failed to cleanup temporary directory: ${directory}`, error);
   }
 };
🧹 Nitpick comments (26)
website/server/src/domains/pack/utils/cache.ts (2)

17-22: Interval can keep the process alive; store and unref/clear it

setInterval inside the constructor may prevent the process from exiting and can’t be cleared externally. Store the timer, call .unref() in Node, and expose a dispose() to clear it when shutting down (e.g., during tests or server reloads).

Apply within constructor and class fields:

 export class RequestCache<T> {
-  private cache: Map<string, CacheEntry> = new Map();
+  private cache: Map<string, CacheEntry> = new Map();
+  private cleanupTimer?: ReturnType<typeof setInterval>;
   private readonly ttl: number;

   constructor(ttlInSeconds = 60) {
     this.ttl = ttlInSeconds * 1000;

     // Set up periodic cache cleanup
-    setInterval(() => this.cleanup(), ttlInSeconds * 1000);
+    this.cleanupTimer = setInterval(() => this.cleanup(), ttlInSeconds * 1000);
+    // Allow the event loop to exit even if the timer is pending (Node.js only)
+    (this.cleanupTimer as any).unref?.();
   }

And add a disposer outside this range:

// Call when tearing down the app or tests
dispose(): void {
  if (this.cleanupTimer) {
    clearInterval(this.cleanupTimer);
    this.cleanupTimer = undefined;
  }
}

74-86: Cache key should be stable and compact; avoid raw JSON of options

Using JSON.stringify(options) in the key can be non-deterministic across equivalent objects (key order), produce very long keys, and may accidentally encode sensitive values. Prefer a stable, hashed key.

Example minimal change (introduce a hash and keep inputs readable):

+import { createHash } from 'node:crypto';
...
 export function generateCacheKey(
   identifier: string,
   format: string,
   options: PackOptions,
   type: 'url' | 'file',
 ): string {
-  return JSON.stringify({
-    identifier,
-    format,
-    options,
-    type,
-  });
+  const payload = { identifier, format, options, type };
+  const json = JSON.stringify(payload, Object.keys(payload).sort());
+  const hash = createHash('sha256').update(json).digest('hex');
+  return `v1:${hash}`;
 }

If you need full stability, consider a proper stable-stringify for options (sorted recursively).

website/server/src/middlewares/cors.ts (1)

11-13: Origin suffix check can fail with ports; parse URL hostname

origin.endsWith('.repomix.pages.dev') will fail for https://foo.repomix.pages.dev:443. Parse and check the hostname instead. Also, hoist allowedOrigins to module scope to avoid per-request allocation.

-import { cors } from 'hono/cors';
+import { cors } from 'hono/cors';

-export const corsMiddleware = cors({
-  origin: (origin) => {
-    const allowedOrigins = ['http://localhost:5173', 'https://repomix.com', 'https://api.repomix.com'];
+const allowedOrigins = ['http://localhost:5173', 'https://repomix.com', 'https://api.repomix.com'] as const;
+
+export const corsMiddleware = cors({
+  origin: (origin) => {
     if (!origin || allowedOrigins.includes(origin)) {
       return origin;
     }
 
-    if (origin.endsWith('.repomix.pages.dev')) {
+    try {
+      const { hostname } = new URL(origin);
+      if (hostname.endsWith('.repomix.pages.dev')) {
+        return origin;
+      }
+    } catch {
+      // Invalid origin; fall through and reject
+    }
     return origin;
-    }
-
-    return null;
+    return null;
   },
   allowMethods: ['GET', 'POST', 'OPTIONS'],
   allowHeaders: ['Content-Type'],
   maxAge: 86400,
   credentials: true,
 });
website/server/src/utils/clientInfo.ts (1)

9-25: Trust model for client IPs: prefer trusted proxy headers and basic validation

Current precedence trusts x-forwarded-for first, which is client-controlled unless sanitized by a trusted proxy/CDN. In many setups (e.g., Cloudflare), cf-connecting-ip is the most trustworthy. Consider:

  • Prefer cf-connecting-ip when present.
  • Optionally gate x-forwarded-for usage behind a TRUST_PROXY=true env.
  • Minimal validation to ensure the first token is a plausible IPv4/IPv6.

Example tweak (order and basic guard):

-  const ip =
-    c.req.header('x-forwarded-for')?.split(',')[0]?.trim() ||
-    c.req.header('x-real-ip') ||
-    c.req.header('cf-connecting-ip') ||
-    '0.0.0.0';
+  const xf = c.req.header('x-forwarded-for')?.split(',')[0]?.trim();
+  const cf = c.req.header('cf-connecting-ip');
+  const xr = c.req.header('x-real-ip');
+  const pick = cf || xr || (process.env.TRUST_PROXY === 'true' ? xf : undefined);
+  const ip = pick && pick.length <= 64 ? pick : '0.0.0.0';

If you’d like, I can add a tiny isValidIp() helper to keep this tidy.

website/server/src/middlewares/rateLimit.ts (2)

4-4: Remove unused import

AppError is not used.

-import { AppError } from '../utils/errorHandler.js';

10-16: Return retry hints with 429

Add Retry-After to help clients back off gracefully and optionally expose remaining seconds.

-    if (!rateLimiter.isAllowed(clientInfo.ip)) {
-      const remainingTime = Math.ceil(rateLimiter.getRemainingTime(clientInfo.ip) / 1000);
-      return c.json({
-        error: `Rate limit exceeded. Please try again in ${remainingTime} seconds.`,
-      }, 429);
-    }
+    if (!rateLimiter.isAllowed(clientInfo.ip)) {
+      const remainingTime = Math.ceil(rateLimiter.getRemainingTime(clientInfo.ip) / 1000);
+      return c.json(
+        { error: `Rate limit exceeded. Please try again in ${remainingTime} seconds.` },
+        429,
+        {
+          'Retry-After': String(remainingTime),
+          'X-RateLimit-Remaining-Seconds': String(remainingTime),
+        },
+      );
+    }
website/server/src/utils/logger.ts (1)

6-23: Optional: export factory for testing/customization

If you ever need to inject a test logger or add default meta (service/version), consider exporting createLogger as a named export.

-function createLogger() {
+export function createLogger() {
   const transports: winston.transport[] = [
     new winston.transports.Console({
       format: winston.format.combine(winston.format.timestamp(), winston.format.json()),
     }),
   ];
website/server/src/domains/pack/processZipFile.ts (3)

74-80: Avoid writing artifacts to process.cwd(); read/delete directly from temp dir

Copying the output file into CWD increases IO and broadens the blast radius if something goes wrong. Read from the temp directory and let cleanupTempDirectory remove it.

Apply:

-  const outputFilePath = `repomix-output-${randomUUID()}.txt`;
+  const outputFileName = `repomix-output-${randomUUID()}.txt`;
@@
-    output: outputFilePath,
+    output: outputFileName,
@@
-    const result = await runDefaultAction([tempDirPath], tempDirPath, cliOptions);
-    await copyOutputToCurrentDirectory(tempDirPath, process.cwd(), result.config.output.filePath);
+    const result = await runDefaultAction([tempDirPath], tempDirPath, cliOptions);
+    const outputFullPath = path.join(tempDirPath, path.basename(result.config.output.filePath));
@@
-    const content = await fs.readFile(outputFilePath, 'utf-8');
+    const content = await fs.readFile(outputFullPath, 'utf-8');
@@
-    // Clean up the output file
-    try {
-      await fs.unlink(outputFilePath);
-    } catch (err) {
-      // Ignore file deletion errors
-      console.warn('Failed to cleanup output file:', err);
-    }
+    // No explicit unlink needed; temp dir cleanup removes the file

Also applies to: 125-131, 38-43


30-36: Cache key includes user-provided filename; consider hashing to reduce PII leakage

Including file.name in the cache key can leak user information if keys are logged/observable. Use a hash of name/size/mtime instead, or omit the name entirely.

Apply:

-  const cacheKey = generateCacheKey(`${file.name}-${file.size}-${file.lastModified}`, format, options, 'file');
+  const identifier = crypto.createHash('sha256')
+    .update(`${file.name}|${file.size}|${file.lastModified}`)
+    .digest('hex');
+  const cacheKey = generateCacheKey(identifier, format, options, 'file');

Note: add import crypto from 'node:crypto'; or reuse randomUUID with a map if hashing feels heavy.


117-121: Use centralized logger instead of console.error/warn

For consistency with cloud logging and request correlation, route errors through the shared logger and include the requestId if available.

Also applies to: 128-130

website/server/src/domains/pack/utils/sharedInstance.ts (1)

6-8: Make rate limits configurable via environment variables

Hardcoding 10/3 rpm is restrictive in production and too generous for some deployments. Parameterize via env (e.g., PACK_RATE_LIMIT_PER_MIN, PACK_RATE_LIMIT_WINDOW_MS) with sane defaults.

Apply:

-export const rateLimiter = new RateLimiter(60_000, process.env.NODE_ENV === 'development' ? 10 : 3);
+const windowMs = Number(process.env.PACK_RATE_LIMIT_WINDOW_MS ?? 60_000);
+const maxReq = Number(process.env.PACK_RATE_LIMIT_PER_MIN ?? (process.env.NODE_ENV === 'development' ? 10 : 3));
+export const rateLimiter = new RateLimiter(windowMs, maxReq);
website/server/src/middlewares/bodyLimit.ts (1)

5-12: Harden onError: type-safe requestId and include allowed size in message

c.get returns unknown; pass a typed, nullable value and include a human-readable limit in the error.

Apply:

-import { FILE_SIZE_LIMITS } from '../domains/pack/utils/fileUtils.js';
+import { FILE_SIZE_LIMITS, formatFileSize } from '../domains/pack/utils/fileUtils.js';
@@
-  onError: (c) => {
-    const requestId = c.get('requestId');
-    const response = createErrorResponse('File size too large', requestId);
+  onError: (c) => {
+    const requestId = c.get<string>('requestId') ?? '';
+    const response = createErrorResponse(
+      `Request body too large. Max allowed: ${formatFileSize(FILE_SIZE_LIMITS.MAX_REQUEST_SIZE)}`,
+      requestId
+    );
     return c.json(response, 413);
   },
website/server/src/domains/pack/utils/fileUtils.ts (2)

16-18: Normalize file size formatting

formatFileSize currently returns many decimals. Round to two decimals for cleaner messages.

Apply:

-export const formatFileSize = (bytes: number): string => {
-  return `${bytes / 1024 / 1024}MB`;
-};
+export const formatFileSize = (bytes: number): string => `${(bytes / 1024 / 1024).toFixed(2)}MB`;

20-27: Avoid ZIP limit duplication across files

ZIP_SECURITY_LIMITS are defined here and in processZipFile.ts. Centralize in this module (exported) and reuse everywhere to prevent drift.

website/server/src/index.ts (4)

34-34: 30s timeout is likely too low for /api/pack; scope it to the route and raise to avoid premature timeouts.

Remote repo packing and ZIP extraction can exceed 30s under load. Recommend applying a larger timeout only to /api/pack to avoid affecting other API routes.

Apply this diff:

-// Set timeout for API routes
-app.use('/api', timeout(30000));
+// Set a more generous timeout only for the pack route
+app.use('/api/pack', timeout(120000));

If you’ve observed 504s/aborts in logs, consider 180–300s for worst-case large repos.


28-28: Expose X-Request-Id to browsers.

You’re emitting requestId across logs; letting the client read it helps with support/debugging. Add CORS exposeHeaders for X-Request-Id.

Outside this file, update website/server/src/middlewares/cors.ts:

 export const corsMiddleware = cors({
   origin: (origin) => {
@@
   allowMethods: ['GET', 'POST', 'OPTIONS'],
   allowHeaders: ['Content-Type'],
+  exposeHeaders: ['X-Request-Id'],
   maxAge: 86400,
   credentials: true,
 });

36-38: Consider registering the logger first to capture pre-timeout/early middleware failures.

Current order is fine, but placing cloudLogger before timeout gives you start/end/error logs even if the timeout middleware short-circuits.


40-40: Unify rate-limit error shape and communicate Retry-After.

The rate limiter returns a plain { error } payload. For consistency with other failures (body limit, pack errors), return createErrorResponse() with requestId and set Retry-After.

Outside this file, update website/server/src/middlewares/rateLimit.ts:

 export function rateLimitMiddleware() {
   return async function rateLimitMiddleware(c: Context, next: Next) {
     const clientInfo = getClientInfo(c);
 
     // Check rate limit
     if (!rateLimiter.isAllowed(clientInfo.ip)) {
       const remainingTime = Math.ceil(rateLimiter.getRemainingTime(clientInfo.ip) / 1000);
-      return c.json({
-        error: `Rate limit exceeded. Please try again in ${remainingTime} seconds.`,
-      }, 429);
+      const requestId = c.get('requestId');
+      c.header('Retry-After', remainingTime.toString());
+      return c.json(
+        createErrorResponse(`Rate limit exceeded. Please try again in ${remainingTime} seconds.`, requestId),
+        429
+      );
     }
 
     await next();
   };
 }

Make sure to import createErrorResponse at the top.

website/server/src/middlewares/cloudLogger.ts (3)

15-17: Avoid deprecated String.prototype.substr; use slice.

substr is deprecated; slice is clearer and standard.

-function generateRequestId(): string {
-  return `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
-}
+function generateRequestId(): string {
+  return `req-${Date.now()}-${Math.random().toString(36).slice(2, 11)}`;
+}

46-56: Surface X-Request-Id on all successful responses.

Add the header after next() so it’s present on the final Response.

   try {
     // Execute the request
     await next();
 
+    // Ensure request id is observable to clients
+    c.header('X-Request-Id', requestId);
+
     // Calculate response time and memory usage
     const responseTime = calculateLatency(startTime);
     const memoryUsage = getMemoryUsage();
 
     // Log successful request completion
     logger.info({

Also applies to: 58-69


70-98: Also set X-Request-Id for error responses.

Setting the header before rethrowing increases the chance the app/global error handler keeps it.

   } catch (error) {
+    // Attach request id for error responses, too
+    c.header('X-Request-Id', requestId);
     // Calculate response time even for errors
     const responseTime = calculateLatency(startTime);
     const memoryUsage = getMemoryUsage();
@@
     // Re-throw the error to be handled by Hono's error handler
     throw error;
   }

Note: If you later add app.onError in index.ts to standardize error JSON, it can also set X-Request-Id.

website/server/src/domains/pack/remoteRepo.ts (3)

10-12: Type the format parameter narrowly to prevent invalid styles.

We already validate format upstream; narrow the type here for safety and self-documentation.

-export async function processRemoteRepo(repoUrl: string, format: string, options: PackOptions): Promise<PackResult> {
+export async function processRemoteRepo(
+  repoUrl: string,
+  format: 'xml' | 'markdown' | 'plain',
+  options: PackOptions
+): Promise<PackResult> {

104-118: Use structured logger instead of console for consistency.

Replace console.error/warn with logError/logWarning to keep logs uniform and parseable.

-  } catch (error) {
-    console.error('Error in remote action:', error);
+  } catch (error) {
+    logError('Error in remote action', error instanceof Error ? error : new Error('Unknown error'), {
+      repository: repoUrl,
+    });
@@
-    } catch (err) {
-      // Ignore file deletion errors
-      console.warn('Failed to cleanup output file:', err);
+    } catch (err) {
+      // Ignore file deletion errors
+      logError('Failed to cleanup output file', err instanceof Error ? err : new Error(String(err)), {
+        repository: repoUrl,
+      });

Make sure to import logError from ../../utils/logger.js.


75-83: Inconsistent topFiles sorting metric between remoteRepo.ts and processZipFile.ts

In remoteRepo.ts (lines 75–83), you sort topFiles by tokenCount, whereas in processZipFile.ts (lines 93–100) you sort by charCount. This discrepancy can lead to unexpected ordering for clients. I recommend choosing a single metric—tokenCount is likely more indicative of relevance—and updating the other implementation to match.

• remoteRepo.ts (lines 75–83):

  topFiles: Object.entries(packResult.fileCharCounts)
    .map(([path, charCount]) => ({
      path,
      charCount: charCount as number,
      tokenCount: packResult.fileTokenCounts[path] || 0,
    }))
    .sort((a, b) => b.tokenCount - a.tokenCount)   // sorts by tokenCount
    .slice(0, cliOptions.topFilesLen),

• processZipFile.ts (lines 93–100):

  topFiles: Object.entries(packResult.fileCharCounts)
    .map(([path, charCount]) => ({
      path,
      charCount: charCount as number,
      tokenCount: packResult.fileTokenCounts[path] || 0,
    }))
    .sort((a, b) => b.charCount - a.charCount)     // sorts by charCount
    .slice(0, cliOptions.topFilesLen),

To align both, update processZipFile.ts as follows:

-  .sort((a, b) => b.charCount - a.charCount)
+  .sort((a, b) => b.tokenCount - a.tokenCount)
website/server/src/actions/packAction.ts (2)

1-12: Avoid magic numbers: reuse central file size limits.

Align the 10MB limit with the shared FILE_SIZE_LIMITS to keep constraints in one place.

 import { sanitizePattern } from '../domains/pack/utils/validation.js';
+import { FILE_SIZE_LIMITS } from '../domains/pack/utils/fileUtils.js';
-      .refine((file) => file.size <= 10 * 1024 * 1024, {
+      .refine((file) => file.size <= FILE_SIZE_LIMITS.MAX_ZIP_SIZE, {
         // 10MB limit
         message: 'File size must be less than 10MB',
       })

91-99: Don’t pass empty pattern strings downstream; omit them.

Empty strings can change CLI semantics vs. undefined. Only include keys when non-empty after sanitization.

-    const sanitizedIncludePatterns = sanitizePattern(validatedData.options.includePatterns);
-    const sanitizedIgnorePatterns = sanitizePattern(validatedData.options.ignorePatterns);
+    const sanitizedIncludePatterns = sanitizePattern(validatedData.options.includePatterns);
+    const sanitizedIgnorePatterns = sanitizePattern(validatedData.options.ignorePatterns);
@@
-    const sanitizedOptions = {
-      ...validatedData.options,
-      includePatterns: sanitizedIncludePatterns,
-      ignorePatterns: sanitizedIgnorePatterns,
-    };
+    const sanitizedOptions = {
+      ...validatedData.options,
+      ...(sanitizedIncludePatterns ? { includePatterns: sanitizedIncludePatterns } : {}),
+      ...(sanitizedIgnorePatterns ? { ignorePatterns: sanitizedIgnorePatterns } : {}),
+    };
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 30322d6 and 07c886d.

📒 Files selected for processing (18)
  • website/server/src/actions/packAction.ts (1 hunks)
  • website/server/src/constants.ts (0 hunks)
  • website/server/src/domains/pack/processZipFile.ts (3 hunks)
  • website/server/src/domains/pack/remoteRepo.ts (2 hunks)
  • website/server/src/domains/pack/utils/cache.ts (1 hunks)
  • website/server/src/domains/pack/utils/fileUtils.ts (1 hunks)
  • website/server/src/domains/pack/utils/sharedInstance.ts (1 hunks)
  • website/server/src/domains/pack/utils/validation.ts (1 hunks)
  • website/server/src/index.ts (2 hunks)
  • website/server/src/middlewares/bodyLimit.ts (1 hunks)
  • website/server/src/middlewares/cloudLogger.ts (1 hunks)
  • website/server/src/middlewares/cors.ts (1 hunks)
  • website/server/src/middlewares/rateLimit.ts (1 hunks)
  • website/server/src/schemas/request.ts (0 hunks)
  • website/server/src/utils/clientInfo.ts (1 hunks)
  • website/server/src/utils/logger.ts (1 hunks)
  • website/server/src/utils/network.ts (0 hunks)
  • website/server/src/utils/validation.ts (0 hunks)
💤 Files with no reviewable changes (4)
  • website/server/src/utils/network.ts
  • website/server/src/constants.ts
  • website/server/src/utils/validation.ts
  • website/server/src/schemas/request.ts
🧰 Additional context used
🧬 Code graph analysis (7)
website/server/src/domains/pack/processZipFile.ts (3)
website/server/src/utils/errorHandler.ts (1)
  • AppError (3-11)
website/server/src/domains/pack/utils/cache.ts (1)
  • generateCacheKey (74-86)
website/server/src/domains/pack/utils/sharedInstance.ts (1)
  • cache (6-6)
website/server/src/middlewares/bodyLimit.ts (2)
website/server/src/domains/pack/utils/fileUtils.ts (1)
  • FILE_SIZE_LIMITS (8-13)
website/server/src/utils/logger.ts (1)
  • createErrorResponse (36-42)
website/server/src/actions/packAction.ts (7)
website/server/src/utils/clientInfo.ts (1)
  • getClientInfo (9-25)
website/server/src/utils/validation.ts (1)
  • validateRequest (4-14)
website/server/src/domains/pack/utils/validation.ts (1)
  • sanitizePattern (1-23)
website/server/src/domains/pack/processZipFile.ts (1)
  • processZipFile (25-132)
website/server/src/utils/logger.ts (3)
  • createErrorResponse (36-42)
  • logInfo (52-57)
  • logError (66-77)
website/server/src/domains/pack/remoteRepo.ts (1)
  • processRemoteRepo (10-120)
website/server/src/utils/errorHandler.ts (1)
  • handlePackError (13-40)
website/server/src/middlewares/cloudLogger.ts (4)
website/server/src/utils/clientInfo.ts (1)
  • getClientInfo (9-25)
website/server/src/utils/time.ts (1)
  • calculateLatency (17-23)
website/server/src/utils/memory.ts (2)
  • getMemoryUsage (21-39)
  • formatMemoryUsage (44-46)
src/shared/logger.ts (1)
  • error (34-38)
website/server/src/middlewares/rateLimit.ts (2)
website/server/src/utils/clientInfo.ts (1)
  • getClientInfo (9-25)
website/server/src/domains/pack/utils/sharedInstance.ts (1)
  • rateLimiter (7-7)
website/server/src/domains/pack/remoteRepo.ts (3)
website/server/src/utils/errorHandler.ts (1)
  • AppError (3-11)
website/server/src/domains/pack/utils/cache.ts (1)
  • generateCacheKey (74-86)
website/server/src/domains/pack/utils/sharedInstance.ts (1)
  • cache (6-6)
website/server/src/index.ts (5)
website/server/src/middlewares/cors.ts (1)
  • corsMiddleware (3-21)
website/server/src/middlewares/cloudLogger.ts (1)
  • cloudLoggerMiddleware (20-98)
website/server/src/middlewares/rateLimit.ts (1)
  • rateLimitMiddleware (6-20)
website/server/src/middlewares/bodyLimit.ts (1)
  • bodyLimitMiddleware (5-12)
website/server/src/actions/packAction.ts (1)
  • packAction (69-151)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test (windows-latest, 22.x)
  • GitHub Check: Build and run (macos-latest, 20.x)
  • GitHub Check: Build and run (windows-latest, 22.x)
  • GitHub Check: Cloudflare Pages
🔇 Additional comments (13)
website/server/src/domains/pack/utils/cache.ts (1)

3-3: Import path update aligns with centralized types module

The new PackOptions import path matches the PR’s move to src/types.js. No issues.

website/server/src/middlewares/cors.ts (2)

3-21: Solid CORS middleware; whitelist and credentials look correct

The origin callback correctly restricts to specific domains, and credentials: true pairs with echoing the exact Origin. Methods/headers and maxAge are reasonable defaults.


18-19: CORS allowed headers verified

I’ve searched the entire website/server/src directory for any reads of Authorization, X-Requested-With, X-API-Key (and related custom headers) and found no matches. That means none of the existing endpoints rely on those headers, so leaving

allowHeaders: ['Content-Type'],

is sufficient and no changes are required.

If in the future you introduce endpoints that expect other client-sent headers (e.g. Authorization, X-Requested-With), simply extend the array at that time.

website/server/src/middlewares/rateLimit.ts (1)

6-20: LGTM — middleware shape and IP extraction integration look good

The middleware cleanly composes with getClientInfo and a shared limiter instance. Naming and control flow are clear.

website/server/src/utils/logger.ts (1)

25-26: Centralizing a single logger instance is a good simplification

Exporting logger directly from here decouples transport config from middleware. Nice cleanup.

website/server/src/domains/pack/processZipFile.ts (1)

41-56: Verify repomix’s CliOptions fields

I wasn’t able to locate a local node_modules/repomix to confirm the exact shape of CliOptions. Please validate that the option names you’re passing here (and on lines 53–54) still match repomix’s current API. In your project root (or in website/server if that’s where dependencies live), run something like:

rg -nP 'interface\s+CliOptions|type\s+CliOptions' -C2 node_modules/repomix
rg -nP 'parsableStyle|fileSummary|directoryStructure|outputShowLineNumbers|compress' -C2 node_modules/repomix

Ensure fields like parsableStyle, fileSummary, directoryStructure, etc., are still defined exactly as named in repomix’s CliOptions.

website/server/src/domains/pack/utils/sharedInstance.ts (1)

1-2: LGTM on import path realignment

Types and RateLimiter paths now reference centralized locations; this matches the modularization elsewhere.

website/server/src/domains/pack/utils/fileUtils.ts (1)

84-88: Nice use of path.resolve/relative and duplicate-path guard

The traversal prevention and duplicate detection are solid and more robust than startsWith checks. Good job.

Also applies to: 105-111

website/server/src/index.ts (2)

5-10: Modularization and middleware wiring look solid.

Imports cleanly switch the app to action + middleware layers. Good separation of concerns.


46-46: Route-level body limit on the pack endpoint is exactly right.

Keeps uploads bounded without constraining unrelated endpoints.

website/server/src/middlewares/cloudLogger.ts (1)

21-27: LGTM: requestId stored in context for per-request tracing.

This enables correlating logs and responses across the stack.

website/server/src/actions/packAction.ts (2)

101-112: LGTM: clear branching between ZIP and URL flows with unified result type.

Validation guards the one-of input; good handoff to domain functions.


114-139: Good operational logging payload.

Including requestId, client info, and summary metrics will make troubleshooting and telemetry much easier.

- Add calculateMemoryDiff function to utils/memory.ts for memory usage comparison
- Replace logMemoryUsage with detailed before/after memory tracking in packAction
- Include memory diff calculation in Pack operation completed logs
- Add input type (file/url) information to operation logs for better monitoring
- Use FILE_SIZE_LIMITS constant instead of hardcoded value in packAction.ts
- Remove redundant URL validation check (Zod schema already validates)
- Use createErrorResponse for consistent error handling in rateLimit.ts
- Add try-catch for JSON.parse with proper error handling
- Enhance sanitizePattern to block Windows absolute and UNC paths for security
- Replace non-null assertion with type casting for better linting compliance
- Move createErrorResponse function and ErrorResponse interface from logger.ts to utils/http.ts
- Update imports across packAction.ts, rateLimit.ts, and bodyLimit.ts
- Improve separation of concerns: logging utilities vs HTTP response utilities
- Maintains consistent error response format across the application
@yamadashy yamadashy merged commit 4d166b5 into main Aug 24, 2025
58 checks passed
@yamadashy yamadashy deleted the feat/website-improve branch August 24, 2025 14:53
@yamadashy yamadashy restored the feat/website-improve branch August 24, 2025 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants