Skip to content

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Sep 26, 2025

  • Merge @eggjs/koa-static-cache repository as package at packages/koa-static-cache
  • Update version to 7.0.0-beta.11
  • Replace ESLint with oxlint using --type-aware flag
  • Add tsc --noEmit for type checking
  • Convert tests to use Vitest with ES module imports
  • Configure tsdown for unbundled ESM builds
  • Add missing dependencies to pnpm-workspace.yaml catalog
  • Update all dependencies to use workspace and catalog references
  • Add package to root tsconfig.json references

BREAKING CHANGE: koa-static-cache is now part of the monorepo and uses ES modules

Summary by CodeRabbit

  • New Features

    • Added @eggjs/koa-static-cache: configurable Koa static cache middleware with preload/dynamic loading, prefix/alias support, ETag/Last-Modified, Cache-Control, gzip (including precompressed), buffering/streaming, and TypeScript support.
    • Egg package now publicly exports plugin types for consumers.
  • Documentation

    • Added package README and changelog; included license.
  • Tests

    • Added comprehensive test suite for middleware behaviors; removed one obsolete schedule test.
  • Chores

    • Added package metadata, ignore rules, workspace/tsconfig updates, build/test configs and CI scripts; added CI helper script.

- Merge @eggjs/koa-static-cache repository as package at packages/koa-static-cache
- Update version to 7.0.0-beta.11
- Replace ESLint with oxlint using --type-aware flag
- Add tsc --noEmit for type checking
- Convert tests to use Vitest with ES module imports
- Configure tsdown for unbundled ESM builds
- Add missing dependencies to pnpm-workspace.yaml catalog
- Update all dependencies to use workspace and catalog references
- Add package to root tsconfig.json references

BREAKING CHANGE: koa-static-cache is now part of the monorepo and uses ES modules
@fengmk2 fengmk2 requested a review from Copilot September 26, 2025 13:50
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 26, 2025

Warning

Rate limit exceeded

@fengmk2 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 14 minutes and 28 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between fe6c345 and f86896f.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • .github/workflows/cleanup-cache.yml (2 hunks)
  • package.json (1 hunks)
  • packages/koa-static-cache/test/index.test.ts (1 hunks)
  • plugins/onerror/test/onerror.test.ts (1 hunks)
  • plugins/schedule/test/immediate.test.ts (1 hunks)
  • plugins/schedule/test/schedule-type-worker1.test.ts (2 hunks)
  • plugins/schedule/test/schedule-type-worker2.test.ts (2 hunks)
  • plugins/schedule/test/subscription.test.ts (4 hunks)
  • pnpm-workspace.yaml (5 hunks)
  • scripts/ci.js (1 hunks)

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.

Walkthrough

Adds a new public export entry in packages/egg/package.json and a new package @eggjs/koa-static-cache (implementation, tests, docs, build/test configs). Also updates workspace dependencies, root TypeScript references, CI matrix and root scripts, and plugin package metadata. No runtime changes to existing egg logic.

Changes

Cohort / File(s) Summary of changes
Egg public export update
packages/egg/package.json
Adds export mapping for ./lib/types.plugin in both source and dist exports to expose the plugin types module.
New package: @eggjs/koa-static-cache — implementation
packages/koa-static-cache/src/index.ts
New Koa static-cache middleware with public types, FileManager, loadFile, preload/dynamic loading, alias/prefix handling, buffer vs stream modes, gzip and precompiled gzip support, ETag/MD5, Cache-Control and Last-Modified handling.
New package: @eggjs/koa-static-cache — tests
packages/koa-static-cache/test/index.test.ts
Comprehensive Vitest suite covering configurations, headers, gzip behaviors, alias/prefix, conditional requests, dynamic/preload modes, file-change scenarios, and many edge cases.
New package: @eggjs/koa-static-cache — metadata & docs
packages/koa-static-cache/package.json, packages/koa-static-cache/README.md, packages/koa-static-cache/CHANGELOG.md, packages/koa-static-cache/LICENSE, packages/koa-static-cache/.gitignore
New package metadata, README, changelog, MIT license, and .gitignore added.
New package: @eggjs/koa-static-cache — build & test configs
packages/koa-static-cache/tsconfig.json, packages/koa-static-cache/tsdown.config.ts, packages/koa-static-cache/vitest.config.ts
Adds TypeScript project config, tsdown build config (dts/unbundle/exports), and Vitest config for the package.
Monorepo config updates
pnpm-workspace.yaml, tsconfig.json
Adds workspace/catalog dependencies (fs-readdir-recursive, mime-types, and related types) and adds ./packages/koa-static-cache to root TS project references.
CI and root scripts updates
.github/workflows/ci.yml, package.json, scripts/ci.js
Renames CI job to test, adds strategy.matrix filter (packages/tools/plugins), updates run step to pnpm run ci:${{ matrix.filter }}, adds ci:packages, ci:tools, ci:plugins scripts, and introduces scripts/ci.js to run vitest coverage across subprojects.
Plugins metadata update
plugins/schedule/package.json
Updates repository URL to monorepo, adds repository.directory, homepage, and bugs.url fields.
Removed test
packages/egg/test/lib/plugins/schedule.test.ts
Deleted a skipped clustered test that read logs and asserted occurrences; test file removed.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant KoaApp as Koa App
  participant Middleware as staticCache()
  participant FS as File System
  participant Store as FileManager

  rect rgba(0,128,96,0.06)
    Note over KoaApp,Middleware: Initialization (optional preload)
    KoaApp->>Middleware: app.use(staticCache(options))
    alt preload enabled
      Middleware->>FS: read directory
      FS-->>Middleware: file stats & buffers
      Middleware->>Store: set(path, FileMeta)
    end
  end

  rect rgba(0,64,128,0.06)
    Note over Client,Middleware: Request handling
    Client->>KoaApp: GET /path
    KoaApp->>Middleware: invoke
    alt matches prefix/alias & method allowed
      Middleware->>Store: get(path)
      alt cache hit
        Middleware-->>Client: 200 or 304 with headers/body
      else cache miss and dynamic enabled
        Middleware->>FS: loadFile(path)
        FS-->>Middleware: FileMeta
        Middleware->>Store: set(path, FileMeta)
        Middleware-->>Client: 200 with headers/body
      else cache miss and dynamic disabled
        Middleware-->>KoaApp: pass through
      end
    else not matched
      Middleware-->>KoaApp: pass through
    end
  end

  Note right of Middleware: handles ETag/If-None-Match, Cache-Control, Last-Modified, optional gzip / precompiled gzip
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

I nibble bytes and stash them tight,
Preload the moon, compress by night.
ETags hum soft, gzips snug and small,
I hop through routes and answer the call.
New exports sprout — a carrot for all. 🐇

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title clearly identifies that this PR adds a feature to migrate the koa-static-cache package into the monorepo, succinctly summarizing the main change and following conventional commit style.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 26, 2025

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: f86896f
Status:🚫  Build failed.

View logs

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @fengmk2, 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 significantly refactors the @eggjs/koa-static-cache package by integrating it into the main monorepo. This move streamlines its development workflow, updates its build and testing infrastructure to modern standards, and ensures compatibility with the latest Node.js versions. The changes aim to improve maintainability, leverage shared monorepo tooling, and provide a more robust static file serving middleware for Koa applications.

Highlights

  • Monorepo Integration: The @eggjs/koa-static-cache package has been merged into the monorepo at packages/koa-static-cache, centralizing its development and management.
  • Version Update & Breaking Change: The package version has been updated to 7.0.0-beta.11, introducing a breaking change that drops support for Node.js versions older than 20.19.0.
  • Modernized Tooling: The project's development tooling has been upgraded, replacing ESLint with OXLint (using the --type-aware flag) for linting, and migrating tests to Vitest with ES module imports. Type checking is now enforced with tsc --noEmit.
  • ESM Build Configuration: The tsdown tool has been configured to enable unbundled ES module builds, ensuring modern module compatibility.
  • Dependency Management: Missing dependencies have been added to the pnpm-workspace.yaml catalog, and all dependencies now utilize workspace and catalog references for consistent management within the monorepo.
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 by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

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 pull request 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.

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Sep 26, 2025

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: f86896f
Status:🚫  Build failed.

View logs

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.

Pull Request Overview

This PR migrates the @eggjs/koa-static-cache package from its separate repository into the main eggjs monorepo as a new package. The migration involves updating the package to use ES modules, replacing ESLint with oxlint, converting tests to Vitest, and configuring tsdown for unbundled ESM builds. The package version has been updated to 7.0.0-beta.11, representing a breaking change as it now uses ES modules.

Key Changes

  • Migration of koa-static-cache as a new monorepo package
  • Conversion to ES modules with tsdown build configuration
  • Test migration from traditional Node.js test framework to Vitest
  • Addition of new dependencies to the monorepo's catalog system

Reviewed Changes

Copilot reviewed 12 out of 14 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-workspace.yaml Added missing dependencies to catalog for the migrated package
packages/koa-static-cache/vitest.config.ts Vitest configuration for the new package
packages/koa-static-cache/tsdown.config.ts Build configuration using tsdown for unbundled ESM output
packages/koa-static-cache/tsconfig.json TypeScript configuration extending root config
packages/koa-static-cache/test/index.test.ts Comprehensive test suite converted to use Vitest and ES module imports
packages/koa-static-cache/src/index.ts Main static cache middleware implementation with TypeScript interfaces
packages/koa-static-cache/package.json Package configuration with ES module setup and monorepo dependencies
packages/koa-static-cache/README.md Documentation for the static cache middleware
packages/koa-static-cache/LICENSE MIT license file
packages/koa-static-cache/CHANGELOG.md Complete version history and changelog
packages/koa-static-cache/.gitignore Git ignore rules for the package
packages/egg/package.json Updated exports to include new types.plugin module
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

filter?: FileFilter | string[];
/**
* dynamic load file which not cached on initialization
* Default to `false
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

Missing closing quote in JSDoc comment. Should be 'Default to false'

Suggested change
* Default to `false
* Default to `false`

Copilot uses AI. Check for mistakes.
Comment on lines +121 to +128
return this.store ? this.store.get(key) : this.map![key];
}

set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
this.map![key] = value;
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

Use of non-null assertion operator (!) assumes this.map is always defined when this.store is not available. Consider adding a guard clause or initializing this.map in the constructor to make this safer.

Suggested change
return this.store ? this.store.get(key) : this.map![key];
}
set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
this.map![key] = value;
if (this.store) {
return this.store.get(key);
}
if (!this.map) {
// Defensive: should never happen, but avoids runtime error
return undefined;
}
return this.map[key];
}
set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
if (!this.map) {
// Defensive: should never happen, but avoids runtime error
this.map = Object.create(null);
}
this.map[key] = value;

Copilot uses AI. Check for mistakes.
Comment on lines +115 to +128
} else {
this.map = store || Object.create(null);
}
}

get(key: string) {
return this.store ? this.store.get(key) : this.map![key];
}

set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
this.map![key] = value;
Copy link

Copilot AI Sep 26, 2025

Choose a reason for hiding this comment

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

Use of non-null assertion operator (!) assumes this.map is always defined when this.store is not available. Consider adding a guard clause or initializing this.map in the constructor to make this safer.

Suggested change
} else {
this.map = store || Object.create(null);
}
}
get(key: string) {
return this.store ? this.store.get(key) : this.map![key];
}
set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
this.map![key] = value;
this.map = Object.create(null);
} else {
this.map = store || Object.create(null);
}
}
get(key: string) {
return this.store ? this.store.get(key) : this.map[key];
}
set(key: string, value: FileMeta) {
if (this.store) {
return this.store.set(key, value);
}
this.map[key] = value;

Copilot uses AI. Check for mistakes.
@socket-security
Copy link

socket-security bot commented Sep 26, 2025

No dependency changes detected. Learn more about Socket for GitHub.

👍 No dependency changes detected in pull request

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 pull request successfully migrates the @eggjs/koa-static-cache package into the monorepo, updating its dependencies, build tooling, and tests. The changes are well-structured and comprehensive. My review includes a few points for improvement: a high-severity performance issue related to blocking I/O in the dynamic file loading logic, a medium-severity suggestion to improve the robustness of a test case, and a minor typo fix in the README documentation.

if (!stats) return await next();
if (!stats.isFile()) return await next();

file = loadFile(filename, dir, options, files);
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The loadFile function uses synchronous file system operations (statSync and readFileSync), which will block the Node.js event loop. When running in dynamic mode, this function is called from within an async middleware, which can lead to significant performance degradation under load. It's crucial to use asynchronous I/O operations here.

I recommend creating an async version of loadFile that uses fs.promises.stat and fs.promises.readFile, and then await it here. The synchronous version can be kept for the initial preload phase, which is not asynchronous.


#### Using a LRU cache to avoid OOM when dynamic mode enabled

You can pass in a lru cache instance which has tow methods: `get(key)` and `set(key, value)`.
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

There is a small typo in this line. It should be "two" instead of "tow".

Suggested change
You can pass in a lru cache instance which has tow methods: `get(key)` and `set(key, value)`.
You can pass in a lru cache instance which has two methods: `get(key)` and `set(key, value)`.

.get('/test/index.test.ts')
.expect(200)
.expect('Cache-Control', 'public, max-age=0')
.expect('Content-Type', /video\/mp2t/);
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The test asserts that a .ts file has the content type video/mp2t. This is due to a known issue in the mime-types library. While the test currently passes because of this, it's brittle as it depends on incorrect behavior from a dependency. It would be more robust to either test with a file that has a common and correctly identified MIME type (like .txt or .html), or to mock mime.lookup to control the returned MIME type for the test.

@codecov
Copy link

codecov bot commented Sep 26, 2025

Codecov Report

❌ Patch coverage is 89.10891% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 76.50%. Comparing base (6ed4ed2) to head (f86896f).
⚠️ Report is 1 commits behind head on next.

Files with missing lines Patch % Lines
packages/koa-static-cache/src/index.ts 89.10% 11 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5546      +/-   ##
==========================================
+ Coverage   76.21%   76.50%   +0.28%     
==========================================
  Files         130      131       +1     
  Lines        4390     4491     +101     
  Branches      631      651      +20     
==========================================
+ Hits         3346     3436      +90     
- Misses        973      984      +11     
  Partials       71       71              

☔ 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

@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: 6

🧹 Nitpick comments (7)
packages/koa-static-cache/README.md (2)

39-47: Docs: use ESM imports in examples (package is ESM).

Examples use require(), but package.json is ESM-only ("type": "module"). Prefer ESM import, and optionally show CJS interop via createRequire/dynamic import.

Proposed snippet:

import path from 'node:path';
import { staticCache } from '@eggjs/koa-static-cache';

app.use(
  staticCache(path.join(process.cwd(), 'public'), {
    maxAge: 365 * 24 * 60 * 60,
  })
);

Optionally add CJS note:

// CommonJS interop
const { createRequire } = require('node:module');
const require = createRequire(__filename);
const { staticCache } = require('@eggjs/koa-static-cache');

26-27: Clarify CJS support claim.

Text says “support CommonJS and ESM both” but this release is ESM-only. Reword and/or add a CJS interop note.

packages/koa-static-cache/CHANGELOG.md (1)

32-57: Consider normalizing list indentation to satisfy markdownlint.

The auto-generated block uses tabs; optional to reformat to spaces if you gate on markdownlint.

packages/koa-static-cache/package.json (1)

31-46: Align devDependencies with catalog where available.

Switch @types entries to “catalog:” (present in catalog). Keep ylru as-is unless you add it to catalog.

Apply this diff:

   "devDependencies": {
@@
-    "@types/fs-readdir-recursive": "^1.1.3",
-    "@types/mime-types": "^2.1.4",
+    "@types/fs-readdir-recursive": "catalog:",
+    "@types/mime-types": "catalog:",

Based on learnings

packages/koa-static-cache/test/index.test.ts (2)

11-11: Close servers to avoid descriptor leaks across tests

Import afterAll so you can close long-lived servers created in this file.

-import { describe, it } from 'vitest';
+import { describe, it, afterAll } from 'vitest';

37-37: Ensure servers are closed after tests

Create servers are never closed; under Vitest 3’s parallelism this can cause flaky port usage and FD leaks.

Add the following near the bottom of the file (after server declarations):

afterAll(() => {
  try { server.close(); } catch {}
  try { server2.close(); } catch {}
  try { server3.close(); } catch {}
  try { server5.close(); } catch {}
});

Also applies to: 49-49, 61-61, 86-86

packages/koa-static-cache/src/index.ts (1)

285-301: Minor: precompiled .gz lookup shouldn’t append “.gz” to URL key

If an aliased or prefixed path maps to a gz file on disk, the keying as filename + '.gz' assumes a sibling entry; fine for preload but can miss dynamic .gz when not preloaded. Optional: try direct disk check when usePrecompiledGzip is true and gzFile not in cache.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ed4ed2 and 423d6df.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (13)
  • packages/egg/package.json (2 hunks)
  • packages/koa-static-cache/.gitignore (1 hunks)
  • packages/koa-static-cache/CHANGELOG.md (1 hunks)
  • packages/koa-static-cache/LICENSE (1 hunks)
  • packages/koa-static-cache/README.md (1 hunks)
  • packages/koa-static-cache/package.json (1 hunks)
  • packages/koa-static-cache/src/index.ts (1 hunks)
  • packages/koa-static-cache/test/index.test.ts (1 hunks)
  • packages/koa-static-cache/tsconfig.json (1 hunks)
  • packages/koa-static-cache/tsdown.config.ts (1 hunks)
  • packages/koa-static-cache/vitest.config.ts (1 hunks)
  • pnpm-workspace.yaml (4 hunks)
  • tsconfig.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (16)
packages/*/package.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use "workspace:*" for internal workspace dependencies in package.json

Files:

  • packages/egg/package.json
  • packages/koa-static-cache/package.json
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/package.json: All packages must provide a typecheck script using "tsc --noEmit"
All packages must use oxlint for linting with the command "oxlint --type-aware" (no ESLint configs)

Files:

  • packages/egg/package.json
  • packages/koa-static-cache/package.json
pnpm-workspace.yaml

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Files:

  • pnpm-workspace.yaml
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • packages/koa-static-cache/vitest.config.ts
  • packages/koa-static-cache/src/index.ts
  • packages/koa-static-cache/tsdown.config.ts
  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown

Files:

  • packages/koa-static-cache/vitest.config.ts
  • packages/koa-static-cache/src/index.ts
  • packages/koa-static-cache/tsdown.config.ts
  • packages/koa-static-cache/test/index.test.ts
packages/**/src/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use TypeScript for all source files in packages (no JavaScript source files)

Files:

  • packages/koa-static-cache/src/index.ts
packages/*/tsconfig.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"

Files:

  • packages/koa-static-cache/tsconfig.json
{tsconfig.json,packages/*/tsconfig.json}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Enable strict TypeScript mode across all packages

Files:

  • packages/koa-static-cache/tsconfig.json
  • tsconfig.json
{packages,plugins,tools,examples,site}/**/tsconfig.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools,examples,site}/**/tsconfig.json: All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")
Enable TypeScript strict mode in all packages (compilerOptions.strict: true)

Files:

  • packages/koa-static-cache/tsconfig.json
tsconfig.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Root tsconfig.json must include all packages in the references array

Files:

  • tsconfig.json
packages/*/tsdown.config.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Each package must provide a tsdown.config.ts for unbundled ESM builds

Files:

  • packages/koa-static-cache/tsdown.config.ts
{packages,plugins,tools}/**/tsdown.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Packages should use tsdown for builds (presence of tsdown.config.ts)

Files:

  • packages/koa-static-cache/tsdown.config.ts
packages/**/test/**/*.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions

Files:

  • packages/koa-static-cache/test/index.test.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Files:

  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Test files should follow the pattern test/**/*.test.ts

Files:

  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions

Files:

  • packages/koa-static-cache/test/index.test.ts
🧠 Learnings (25)
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/*.js

Applied to files:

  • packages/egg/package.json
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/*.ts : Re-export types thoughtfully to keep the public API stable

Applied to files:

  • packages/egg/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugin package.json must include peerDependencies { "egg": "workspace:*" }

Applied to files:

  • packages/egg/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.{ts,tsx} : Use explicit return types for public APIs

Applied to files:

  • packages/egg/package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/ : All Egg plugins must live under plugins/ and follow the standard plugin structure (src/, test/, package.json with eggPlugin, tsdown.config.ts)

Applied to files:

  • packages/egg/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Applied to files:

  • pnpm-workspace.yaml
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Use pnpm catalog mode: external deps referenced as "catalog:" and internal workspace deps as "workspace:*"

Applied to files:

  • pnpm-workspace.yaml
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
  • packages/koa-static-cache/tsconfig.json
  • packages/koa-static-cache/tsdown.config.ts
  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to plugins/**/vitest.config.ts : All new plugins must use Vitest and include vitest.config.ts

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/test/**/*.test.ts : Test files should follow the pattern test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Mirror the repository test pattern when adding new suites

Applied to files:

  • packages/koa-static-cache/vitest.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsconfig.json : All sub-project tsconfig.json files must extend from the root via "extends": "../../tsconfig.json"

Applied to files:

  • packages/koa-static-cache/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : All sub-project tsconfig.json files must extend the root tsconfig.json ("extends": "../../tsconfig.json")

Applied to files:

  • packages/koa-static-cache/tsconfig.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to {packages,plugins,tools,examples,site}/**/tsconfig.json : Enable TypeScript strict mode in all packages (compilerOptions.strict: true)

Applied to files:

  • packages/koa-static-cache/tsconfig.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to tsconfig.json : Root tsconfig.json must include all packages in the references array

Applied to files:

  • tsconfig.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/tsdown.config.ts : Packages should use tsdown for builds (presence of tsdown.config.ts)

Applied to files:

  • packages/koa-static-cache/tsdown.config.ts
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must provide a tsdown.config.ts for unbundled ESM builds

Applied to files:

  • packages/koa-static-cache/tsdown.config.ts
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/tsdown.config.ts : All plugins must use the standard tsdown config: entry: 'src/**/*.ts', unbundle: true, dts: true, exports.devExports: true

Applied to files:

  • packages/koa-static-cache/tsdown.config.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
🧬 Code graph analysis (3)
packages/koa-static-cache/vitest.config.ts (1)
packages/egg/src/lib/types.ts (1)
  • defineConfig (109-111)
packages/koa-static-cache/tsdown.config.ts (1)
packages/egg/src/lib/types.ts (1)
  • defineConfig (109-111)
packages/koa-static-cache/test/index.test.ts (1)
packages/koa-static-cache/src/index.ts (1)
  • staticCache (139-321)
🪛 markdownlint-cli2 (0.18.1)
packages/koa-static-cache/README.md

26-26: Bare URL used

(MD034, no-bare-urls)

packages/koa-static-cache/CHANGELOG.md

28-28: Bare URL used

(MD034, no-bare-urls)


30-30: Bare URL used

(MD034, no-bare-urls)


37-37: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


37-37: Hard tabs
Column: 1

(MD010, no-hard-tabs)


38-38: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


38-38: Hard tabs
Column: 1

(MD010, no-hard-tabs)


39-39: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


39-39: Hard tabs
Column: 1

(MD010, no-hard-tabs)


42-42: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


42-42: Hard tabs
Column: 1

(MD010, no-hard-tabs)


43-43: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


43-43: Hard tabs
Column: 1

(MD010, no-hard-tabs)


44-44: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


44-44: Hard tabs
Column: 1

(MD010, no-hard-tabs)


47-47: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


47-47: Hard tabs
Column: 1

(MD010, no-hard-tabs)


48-48: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


48-48: Hard tabs
Column: 1

(MD010, no-hard-tabs)


51-51: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


51-51: Hard tabs
Column: 1

(MD010, no-hard-tabs)


52-52: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


52-52: Hard tabs
Column: 1

(MD010, no-hard-tabs)


53-53: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


53-53: Hard tabs
Column: 1

(MD010, no-hard-tabs)


54-54: Unordered list indentation
Expected: 2; Actual: 1

(MD007, ul-indent)


54-54: Hard tabs
Column: 1

(MD010, no-hard-tabs)


63-63: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


66-66: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


67-67: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


68-68: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


69-69: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


71-71: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


74-74: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


75-75: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


77-77: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


80-80: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)


81-81: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


82-82: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


84-84: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


87-87: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


89-89: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


92-92: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


93-93: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


95-95: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


98-98: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


100-100: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


103-103: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


105-105: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


108-108: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


110-110: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


113-113: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


115-115: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


118-118: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


120-120: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


123-123: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


125-125: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


128-128: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


130-130: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


133-133: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


134-134: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


136-136: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


139-139: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


141-141: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


144-144: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


146-146: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


149-149: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


151-151: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


154-154: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


156-156: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


159-159: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


161-161: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


164-164: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


166-166: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


169-169: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


170-170: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


172-172: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


175-175: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


176-176: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


177-177: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


178-178: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


180-180: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


183-183: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


185-185: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


188-188: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


190-190: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


193-193: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


194-194: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


196-196: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


199-199: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


200-200: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


202-202: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


205-205: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


206-206: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


208-208: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


211-211: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


212-212: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


213-213: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


215-215: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


218-218: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


220-220: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


223-223: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


224-224: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


225-225: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


227-227: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


230-230: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


231-231: Unordered list indentation
Expected: 0; Actual: 2

(MD007, ul-indent)


233-233: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


236-236: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)


238-238: Heading style
Expected: atx; Actual: setext

(MD003, heading-style)


241-241: Unordered list indentation
Expected: 0; Actual: 1

(MD007, ul-indent)

🪛 GitHub Check: CodeQL
packages/koa-static-cache/src/index.ts

[failure] 162-162: Polynomial regular expression used on uncontrolled data
This regular expression that depends on library input may run slow on strings with many repetitions of '/'.
This regular expression that depends on library input may run slow on strings with many repetitions of '/'.


[failure] 334-334: Potential file system race condition
The file may have changed since it was checked.

⏰ 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). (13)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (macos-latest, 24)
  • GitHub Check: Test egg-bin (macos-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Test packages (ubuntu-latest, 24)
  • GitHub Check: Test packages (macos-latest, 22)
  • GitHub Check: Test packages (macos-latest, 24)
  • GitHub Check: Test packages (ubuntu-latest, 22)
  • GitHub Check: Test packages (windows-latest, 24)
  • GitHub Check: Test packages (windows-latest, 22)
🔇 Additional comments (11)
packages/egg/package.json (1)

50-51: LGTM – new export paths are wired correctly

./lib/types.plugin is now exposed consistently in both runtime and source exports, matching the existing pattern for lib modules.

Also applies to: 100-101

packages/koa-static-cache/LICENSE (1)

1-22: License looks correct.

MIT text and attributions are fine.

tsconfig.json (1)

54-57: Good addition to project references.

Including ./packages/koa-static-cache in root references aligns TS project refs.

packages/koa-static-cache/.gitignore (1)

1-11: Reasonable ignores.

Covers node, build, test artifacts. Retaining .eslintcache ignore is harmless.

pnpm-workspace.yaml (1)

8-190: Catalog entries added correctly.

New deps are defined in catalog. Ensure all packages reference them with "catalog:" tokens.

If any package.json still pins versions for these deps, switch to "catalog:" (see comment on package.json in this PR). Based on learnings

packages/koa-static-cache/CHANGELOG.md (1)

8-13: Engines note matches package.json.

Dropping Node < 20.19.0 here aligns with engines in package.json.

packages/koa-static-cache/package.json (1)

57-66: Export mapping strategy is acceptable.

Using source export in dev and publishConfig.exports to dist is fine with tsdown/Vitest.

Confirm tests run without prebuilding (vitest should transpile TS via Vite). If not, consider pointing exports to dist during dev as well.

packages/koa-static-cache/tsdown.config.ts (1)

3-10: LGTM: tsdown config matches our standard unbundled ESM setup

Entry, unbundle, dts, and devExports are correctly configured.

Based on learnings

packages/koa-static-cache/vitest.config.ts (1)

3-7: LGTM: Vitest discovery pattern is correct

Config aligns with our test layout conventions.

Based on learnings

packages/koa-static-cache/src/index.ts (2)

162-166: Regex micro-optimization not required; false-positive risk from static analysis

The trailing-slash and leading-slash regexes here are linear-time and operate on trusted config (options.prefix). No action needed.

If you still want to harden, replace with slice checks:

-  options.prefix = (options.prefix ?? '').replace(/\/*$/, '/');
+  let prefix = options.prefix ?? '';
+  while (prefix.endsWith('/')) prefix = prefix.slice(0, -1);
+  options.prefix = prefix + '/';

239-266: Header casing and semantics are OK

  • Vary: Accept-Encoding set when gzip enabled.
  • Cache-Control fallback uses maxAge; cacheControl function handled in loadFile.
  • ETag and Content-MD5 align with tests.

Please confirm we’re intentionally exposing Content-MD5 (non-standard/deprecated) for backwards compat with existing clients.

Comment on lines +25 to +30
"dependencies": {
"@eggjs/compressible": "^3.0.0",
"fs-readdir-recursive": "^1.1.0",
"mime-types": "^2.1.35",
"utility": "catalog:"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Use pnpm catalog tokens for external deps.

Per workspace policy, reference versions via “catalog:”. The catalog already defines these.

Apply this diff:

   "dependencies": {
-    "@eggjs/compressible": "^3.0.0",
-    "fs-readdir-recursive": "^1.1.0",
-    "mime-types": "^2.1.35",
+    "@eggjs/compressible": "catalog:",
+    "fs-readdir-recursive": "catalog:",
+    "mime-types": "catalog:",
     "utility": "catalog:"
   },

As per coding guidelines

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"dependencies": {
"@eggjs/compressible": "^3.0.0",
"fs-readdir-recursive": "^1.1.0",
"mime-types": "^2.1.35",
"utility": "catalog:"
},
"dependencies": {
"@eggjs/compressible": "catalog:",
"fs-readdir-recursive": "catalog:",
"mime-types": "catalog:",
"utility": "catalog:"
},
🤖 Prompt for AI Agents
In packages/koa-static-cache/package.json around lines 25 to 30, several
external dependencies are pinned to explicit versions instead of using the
workspace pnpm catalog tokens; replace the version strings for
"@eggjs/compressible", "fs-readdir-recursive", and "mime-types" with their
corresponding catalog tokens (e.g., "catalog:@eggjs/compressible",
"catalog:fs-readdir-recursive", "catalog:mime-types") so all external deps
reference the catalog as required by workspace policy.

Comment on lines +127 to +131
You can pass in a lru cache instance which has tow methods: `get(key)` and `set(key, value)`.

```js
const LRU = require('lru-cache');
const files = new LRU({ max: 1000 });
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix typo: “tow methods” → “two methods”.

Minor docs nit.

Apply this diff:

-You can pass in a lru cache instance which has tow methods: `get(key)` and `set(key, value)`.
+You can pass in an LRU cache instance which has two methods: `get(key)` and `set(key, value)`.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
You can pass in a lru cache instance which has tow methods: `get(key)` and `set(key, value)`.
```js
const LRU = require('lru-cache');
const files = new LRU({ max: 1000 });
You can pass in an LRU cache instance which has two methods: `get(key)` and `set(key, value)`.
🤖 Prompt for AI Agents
In packages/koa-static-cache/README.md around lines 127 to 131, fix the typo in
the sentence "You can pass in a lru cache instance which has tow methods:
`get(key)` and `set(key, value)`." by changing "tow" to "two" so it reads "two
methods"; update the line in the README accordingly.

Comment on lines +226 to +231
const fullpath = path.join(dir, filename);
// files that can be accessed should be under options.dir
if (!fullpath.startsWith(dir)) {
return await next();
}

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Fix path traversal check (startsWith on joined paths is unsafe)

Using startsWith on a joined path allows bypasses like /var/www-bad. Resolve and compare via path.relative to guarantee containment.

-      const fullpath = path.join(dir, filename);
-      // files that can be accessed should be under options.dir
-      if (!fullpath.startsWith(dir)) {
-        return await next();
-      }
+      const fullpath = path.resolve(dir, filename);
+      // ensure path stays under dir (prevent traversal)
+      const rel = path.relative(dir, fullpath);
+      if (rel.startsWith('..') || path.isAbsolute(rel)) {
+        return await next();
+      }

Comment on lines +333 to +341
const stats = statSync(filename);
const buffer = readFileSync(filename);

obj.cacheControl = typeof options.cacheControl === 'function' ? options.cacheControl(filename) : options.cacheControl; // if cacheControl is a function, it will be called with the filename
obj.maxAge = (typeof obj.maxAge === 'number' ? obj.maxAge : options.maxAge) || 0;
obj.type = obj.mime = mime.lookup(pathname) || 'application/octet-stream';
obj.mtime = stats.mtime;
obj.length = stats.size;
obj.md5 = crypto.createHash('md5').update(buffer).digest('base64');
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid TOCTOU and reduce mismatch between size/md5/mtime

Current order can read a different file version than was stat’ed; also length should come from the buffer to stay consistent.

-  const stats = statSync(filename);
-  const buffer = readFileSync(filename);
+  const buffer = readFileSync(filename);
+  const stats = statSync(filename);
@@
-  obj.length = stats.size;
+  obj.length = buffer.length;

Note: loadFile runs on the request path in dynamic mode; the sync I/O will block the event loop under load. Consider an async load path (stream hashing via crypto and fs.promises) for dynamic mode while keeping sync for preload.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const stats = statSync(filename);
const buffer = readFileSync(filename);
obj.cacheControl = typeof options.cacheControl === 'function' ? options.cacheControl(filename) : options.cacheControl; // if cacheControl is a function, it will be called with the filename
obj.maxAge = (typeof obj.maxAge === 'number' ? obj.maxAge : options.maxAge) || 0;
obj.type = obj.mime = mime.lookup(pathname) || 'application/octet-stream';
obj.mtime = stats.mtime;
obj.length = stats.size;
obj.md5 = crypto.createHash('md5').update(buffer).digest('base64');
const buffer = readFileSync(filename);
const stats = statSync(filename);
obj.cacheControl =
typeof options.cacheControl === 'function'
? options.cacheControl(filename)
: options.cacheControl; // if cacheControl is a function, it will be called with the filename
obj.maxAge = (typeof obj.maxAge === 'number' ? obj.maxAge : options.maxAge) || 0;
obj.type = obj.mime = mime.lookup(pathname) || 'application/octet-stream';
obj.mtime = stats.mtime;
obj.length = buffer.length;
obj.md5 = crypto.createHash('md5').update(buffer).digest('base64');
🧰 Tools
🪛 GitHub Check: CodeQL

[failure] 334-334: Potential file system race condition
The file may have changed since it was checked.

🤖 Prompt for AI Agents
In packages/koa-static-cache/src/index.ts around lines 333 to 341, the code
currently stats the file then reads it which can cause TOCTOU (time-of-check vs
time-of-use) and mismatch between stats.size and the actual buffer length; fix
by opening the file descriptor and using fstat on that fd, then read the file
contents from the same fd (so stat and read refer to the identical inode state),
compute md5 from the buffer and set length from buffer.byteLength, set mtime
from the fstat result, and finally close the fd; additionally, for dynamic mode
consider implementing an async path that streams and hashes via crypto with
fs.promises to avoid blocking the event loop while keeping the existing
synchronous preload behavior.

Comment on lines +1 to +6
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./"
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Enable strict mode explicitly in package tsconfig.

To comply with repo guidelines, set compilerOptions.strict: true here (don’t rely on inheritance).

Apply this diff:

 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
+    "strict": true,
     "baseUrl": "./"
   }
 }

As per coding guidelines

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"baseUrl": "./"
}
}
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"strict": true,
"baseUrl": "./"
}
}
🤖 Prompt for AI Agents
In packages/koa-static-cache/tsconfig.json around lines 1 to 6, the package
tsconfig currently relies on inherited compiler settings but must explicitly
enable strict mode; add "strict": true to the "compilerOptions" object (do not
rely on inheritance) so the file contains a top-level compilerOptions.strict set
to true.

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 (1)
plugins/schedule/package.json (1)

70-77: Add the required clean script.

Per the plugin package.json guidelines, we need a clean script (usually rimraf dist). Please reintroduce it to keep the plugin consistent with the monorepo standard.

   "scripts": {
+    "clean": "rimraf dist",
     "build": "tsdown",
     "typecheck": "tsc --noEmit",
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 423d6df and 09642d0.

📒 Files selected for processing (3)
  • packages/koa-static-cache/package.json (1 hunks)
  • packages/koa-static-cache/test/index.test.ts (1 hunks)
  • plugins/schedule/package.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
packages/*/package.json

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use "workspace:*" for internal workspace dependencies in package.json

Files:

  • packages/koa-static-cache/package.json
{packages,plugins,tools}/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/package.json: All packages must provide a typecheck script using "tsc --noEmit"
All packages must use oxlint for linting with the command "oxlint --type-aware" (no ESLint configs)

Files:

  • packages/koa-static-cache/package.json
  • plugins/schedule/package.json
plugins/**/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

plugins/**/package.json: Plugin package.json must include peerDependencies { "egg": "workspace:" }
Plugin package.json exports should point to TypeScript sources for development and publishConfig.exports should mirror to dist/
.js
Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)

Files:

  • plugins/schedule/package.json
packages/**/test/**/*.test.ts

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

packages/**/test/**/*.test.ts: Name test files as test/**/*.test.ts and run them with Vitest
Use import { describe, it } from 'vitest' in tests
Use Node.js built-in assert module for test assertions

Files:

  • packages/koa-static-cache/test/index.test.ts
**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/*.ts: Prefer TypeScript and ESM: write sources and exports in .ts (ESM-first) rather than CommonJS
Use two-space indentation, trailing commas, and semicolons (Prettier/oxlint defaults)
Name files in lowercase with hyphens (e.g., loader-context.ts)
Name classes in PascalCase
Name functions and variables in camelCase
Re-export types thoughtfully to keep the public API stable

Files:

  • packages/koa-static-cache/test/index.test.ts
**/test/**/*.test.ts

📄 CodeRabbit inference engine (AGENTS.md)

**/test/**/*.test.ts: Place test suites following Vitest discovery: /test//*.test.ts
Mirror the repository test pattern when adding new suites

Files:

  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/test/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Test files should follow the pattern test/**/*.test.ts

Files:

  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/*.test.ts

📄 CodeRabbit inference engine (CLAUDE.md)

In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions

Files:

  • packages/koa-static-cache/test/index.test.ts
{packages,plugins,tools}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

{packages,plugins,tools}/**/*.{ts,tsx}: Prefer interfaces over type aliases for object shapes in TypeScript
Use explicit return types for public APIs
Use readonly modifiers where appropriate
Avoid the any type; prefer unknown when the type is truly unknown

Files:

  • packages/koa-static-cache/test/index.test.ts
🧠 Learnings (7)
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Use pnpm catalog mode: external deps referenced as "catalog:" and internal workspace deps as "workspace:*"

Applied to files:

  • packages/koa-static-cache/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to pnpm-workspace.yaml : Define dependency versions via the catalog section in pnpm-workspace.yaml and reference them with "catalog:"

Applied to files:

  • packages/koa-static-cache/package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in package.json

Applied to files:

  • packages/koa-static-cache/package.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/cookies/test/**/*.test.ts : cookies package uses Mocha; test files follow test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: For features affecting HTTP or process orchestration, add regression tests that exercise both the CommonJS and TypeScript example apps

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to tools/egg-bin/test/**/*.test.ts : egg-bin uses Mocha; test files follow test/**/*.test.ts

Applied to files:

  • packages/koa-static-cache/test/index.test.ts
🧬 Code graph analysis (1)
packages/koa-static-cache/test/index.test.ts (1)
packages/koa-static-cache/src/index.ts (1)
  • staticCache (139-321)
⏰ 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). (13)
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (macos-latest, 24)
  • GitHub Check: Test egg-bin (macos-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Test packages (macos-latest, 24)
  • GitHub Check: Test packages (ubuntu-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Test packages (windows-latest, 24)
  • GitHub Check: Test packages (windows-latest, 22)
  • GitHub Check: Test packages (ubuntu-latest, 24)
  • GitHub Check: Test packages (macos-latest, 22)
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (1)
packages/koa-static-cache/package.json (1)

38-48: Use catalog tokens for devDependencies

Per the monorepo catalog policy, external packages should be referenced through catalog:. Please align the remaining devDependencies with that convention.

-    "@types/fs-readdir-recursive": "^1.1.3",
-    "@types/mime-types": "^2.1.4",
+    "@types/fs-readdir-recursive": "catalog:",
+    "@types/mime-types": "catalog:",
@@
-    "ylru": "^2.0.0"
+    "ylru": "catalog:"

[ suggest_essential_refactor ]
As per coding guidelines

Comment on lines +54 to +55
"test": "npm run lint:fix && vitest run",
"ci": "vitest run --coverage",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Avoid auto-fixing during npm run test

Running lint:fix inside the test script mutates sources before tests execute, which is risky for CI and local runs. Swap it for the non-mutating lint command.

-    "test": "npm run lint:fix && vitest run",
+    "test": "npm run lint && vitest run",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"test": "npm run lint:fix && vitest run",
"ci": "vitest run --coverage",
"test": "npm run lint && vitest run",
"ci": "vitest run --coverage",
🤖 Prompt for AI Agents
In packages/koa-static-cache/package.json around lines 54-55 the "test" script
runs "npm run lint:fix && vitest run", which auto-mutes source files before
tests; change it to use the non-mutating lint command (e.g., "npm run lint &&
vitest run" or the equivalent lint script that doesn't apply fixes) so tests run
against unmodified sources; update the "test" script accordingly and leave the
"ci" script unchanged.

Comment on lines +124 to +136
const server = app.listen();
await request(server).get('/src/index.ts').expect(200);
});

it('should default options.dir works fine', async () => {
const app = new Koa();
app.use(
staticCache({
dir: path.join(__dirname, '..'),
})
);
const server = app.listen();
await request(server).get('/src/index.ts').expect(200);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Close app.listen() servers in tests

app.listen() starts a live server that never gets closed here (and the same pattern repeats throughout the suite), so the handles stay open and Vitest will hang/flake once enough of these accumulate. Supertest can drive the Koa callback directly—no need to spin up a listener. Please update each case to avoid leaking sockets.

-    const server = app.listen();
-    await request(server).get('/src/index.ts').expect(200);
+    await request(app.callback()).get('/src/index.ts').expect(200);

Apply the same fix anywhere else this pattern appears in the file.

🤖 Prompt for AI Agents
In packages/koa-static-cache/test/index.test.ts around lines 124 to 136, the
tests call app.listen() which starts real servers and leaks sockets; replace
usage of request(server) with request(app.callback()) (or pass app.callback()
directly into supertest) so no listener is created, and remove or close any
app.listen() calls; apply this same change wherever app.listen() is used in this
test file so tests no longer spin up real servers or leak handles.

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: 1

🧹 Nitpick comments (2)
package.json (1)

40-42: Use pnpm workspace filters for CI scripts
All packages, tools, and plugins define test:cov and include a local vitest.config.ts, so invoking tests via workspace filters will honor each config:

-    "ci:packages": "pnpm run test:cov packages/*",
-    "ci:tools": "pnpm run test:cov tools/*",
-    "ci:plugins": "pnpm run test:cov plugins/*",
+    "ci:packages": "pnpm -r --filter \"./packages/*\" run test:cov",
+    "ci:tools":    "pnpm -r --filter \"./tools/*\"    run test:cov",
+    "ci:plugins":  "pnpm -r --filter \"./plugins/*\"  run test:cov",
.github/workflows/ci.yml (1)

82-84: Run tests per-package to respect Vitest configs
Replace your CI step with:

- run: pnpm run ci:${{ matrix.filter }}
+ run: pnpm -r --filter "./${{ matrix.filter }}/*" run test

Once you’ve added per-package coverage scripts (e.g. test:cov), switch to run test:cov or use run test -- --coverage.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 09642d0 and 08fe348.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml (2 hunks)
  • package.json (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)

Applied to files:

  • package.json
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/package.json : All packages must provide a typecheck script using "tsc --noEmit"

Applied to files:

  • package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • package.json
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts

Applied to files:

  • package.json
⏰ 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). (13)
  • GitHub Check: Test (ubuntu-latest, 24, packages)
  • GitHub Check: Test (windows-latest, 22, tools)
  • GitHub Check: Test (ubuntu-latest, 24, plugins)
  • GitHub Check: Test (ubuntu-latest, 22, plugins)
  • GitHub Check: Test (ubuntu-latest, 22, packages)
  • GitHub Check: Test (macos-latest, 24, packages)
  • GitHub Check: Test (windows-latest, 24, packages)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Test (macos-latest, 22, plugins)
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (macos-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
🔇 Additional comments (2)
.github/workflows/ci.yml (2)

51-51: Job rename looks good

Renaming the job to test is clear and consistent with the new matrix split.


63-64: Concurrency group expansion is correct

Including matrix.filter in the concurrency key prevents cross-scope cancellations. Good call.

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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 75d9662 and fe6c345.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • package.json (1 hunks)
  • packages/egg/test/lib/plugins/schedule.test.ts (0 hunks)
  • scripts/ci.js (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/egg/test/lib/plugins/schedule.test.ts
🧰 Additional context used
🧠 Learnings (6)
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to plugins/**/package.json : Plugins must include scripts: build (tsdown), clean (rimraf dist), typecheck (tsc --noEmit), lint (oxlint --type-aware), lint:fix, test (runs lint:fix then vitest), prepublishOnly (build)

Applied to files:

  • package.json
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Name test files as test/**/*.test.ts and run them with Vitest

Applied to files:

  • package.json
  • scripts/ci.js
📚 Learning: 2025-09-18T07:56:17.417Z
Learnt from: CR
PR: eggjs/egg#0
File: AGENTS.md:0-0
Timestamp: 2025-09-18T07:56:17.417Z
Learning: Applies to **/test/**/*.test.ts : Place test suites following Vitest discovery: **/test/**/*.test.ts

Applied to files:

  • scripts/ci.js
📚 Learning: 2025-09-26T12:42:04.197Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.197Z
Learning: Applies to packages/{egg,core,utils,mock,cluster,koa,supertest,extend2}/vitest.config.ts : Each package (except cookies) should include a Vitest configuration file vitest.config.ts

Applied to files:

  • scripts/ci.js
📚 Learning: 2025-09-26T12:42:04.198Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-26T12:42:04.198Z
Learning: Applies to {packages,plugins,tools}/**/*.test.ts : In Vitest tests, import from vitest (e.g., import { describe, it } from 'vitest') and use Node.js assert for assertions

Applied to files:

  • scripts/ci.js
📚 Learning: 2025-09-14T08:41:30.618Z
Learnt from: CR
PR: eggjs/egg#0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-09-14T08:41:30.618Z
Learning: Applies to packages/**/test/**/*.test.ts : Use import { describe, it } from 'vitest' in tests

Applied to files:

  • scripts/ci.js
🪛 GitHub Check: CodeQL
scripts/ci.js

[warning] 24-24: Shell command built from environment values
This shell command depends on an uncontrolled file name.


[warning] 24-24: Indirect uncontrolled command line
This command depends on an unsanitized command-line argument.

⏰ 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). (20)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Test (ubuntu-latest, 22, tools)
  • GitHub Check: Test (ubuntu-latest, 24, plugins)
  • GitHub Check: Test (windows-latest, 24, plugins)
  • GitHub Check: Test (windows-latest, 22, plugins)
  • GitHub Check: Test (windows-latest, 24, packages)
  • GitHub Check: Test (ubuntu-latest, 24, packages)
  • GitHub Check: Test (ubuntu-latest, 22, plugins)
  • GitHub Check: Test (windows-latest, 24, tools)
  • GitHub Check: Test (ubuntu-latest, 22, packages)
  • GitHub Check: Test (macos-latest, 24, plugins)
  • GitHub Check: Test (windows-latest, 22, packages)
  • GitHub Check: Test (macos-latest, 24, packages)
  • GitHub Check: Test egg-bin (windows-latest, 24)
  • GitHub Check: Test egg-bin (windows-latest, 22)
  • GitHub Check: Test egg-bin (macos-latest, 24)
  • GitHub Check: Test egg-bin (ubuntu-latest, 24)
  • GitHub Check: Test egg-bin (macos-latest, 22)
  • GitHub Check: Test egg-bin (ubuntu-latest, 22)
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (2)
package.json (1)

40-42: LGTM; confirm build still runs after matrixed CI scripts

The new ci:* scripts align with the matrix (packages/tools/plugins). Ensure the previous postci build step is still executed in CI, since postci only runs after the plain “ci” script. Options:

  • Trigger a separate build step in the workflow after the matrix job, or
  • Chain build in each ci:* script (less ideal due to duplicate work).
scripts/ci.js (1)

7-14: Per-package Vitest configs are already honored
Root vitest.config.ts uses defineConfig({ test: { projects: ['packages/','plugins/','tools/*'] } }), which loads each package’s own vitest.config.ts; a separate defineWorkspace call isn’t needed.

Likely an incorrect or invalid review comment.

@fengmk2 fengmk2 merged commit 7123cc8 into next Sep 26, 2025
34 of 37 checks passed
@fengmk2 fengmk2 deleted the koa-static-cache branch September 26, 2025 16:03
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.

1 participant