Skip to content

feat: merge extend2 repository into monorepo#5455

Merged
fengmk2 merged 1 commit intonextfrom
extend2
Sep 13, 2025
Merged

feat: merge extend2 repository into monorepo#5455
fengmk2 merged 1 commit intonextfrom
extend2

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Sep 13, 2025

  • Add @eggjs/extend2 package at packages/extend2/
  • Update package.json for monorepo structure with catalog dependencies
  • Configure tsdown build system and vitest testing
  • Add TypeScript configuration extending from root tsconfig.json
  • Update pnpm-workspace.yaml with workspace reference
  • Update CLAUDE.md with extend2 package documentation and TypeScript rules
  • All tests passing (32 tests) with vitest integration

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a new utility package providing robust object merging with shallow/deep modes, safe prototype handling, and predictable array behavior.
  • Documentation
    • Expanded guidelines for creating/testing packages, TypeScript configuration requirements, and package documentation (README, CHANGELOG, LICENSE).
  • Tests
    • Introduced per-package Vitest setup with comprehensive test coverage for the new utility.
  • Chores
    • Migrated dependencies to a local workspace package, updated workspace configuration, and added TypeScript project references and build tooling.

- Add @eggjs/extend2 package at packages/extend2/
- Update package.json for monorepo structure with catalog dependencies
- Configure tsdown build system and vitest testing
- Add TypeScript configuration extending from root tsconfig.json
- Update pnpm-workspace.yaml with workspace reference
- Update CLAUDE.md with extend2 package documentation and TypeScript rules
- All tests passing (32 tests) with vitest integration

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 13, 2025

Walkthrough

Adds a new workspace package @eggjs/extend2 with code, tests, and configs; updates dependent packages to use it instead of a catalog alias; adjusts imports accordingly; updates monorepo configs (pnpm, tsconfig) and documentation to reflect the new package, testing (Vitest), and TypeScript setup requirements.

Changes

Cohort / File(s) Summary of Changes
New package: @eggjs/extend2
packages/extend2/.gitignore, packages/extend2/CHANGELOG.md, packages/extend2/LICENSE, packages/extend2/README.md, packages/extend2/package.json, packages/extend2/src/index.ts, packages/extend2/test/index.test.ts, packages/extend2/tsconfig.json, packages/extend2/tsdown.config.ts, packages/extend2/vitest.config.ts
Introduces a new package implementing extend (shallow/deep merge) with TypeScript, tsdown, and Vitest setup; includes docs, license, changelog, and configuration files.
Dependency resolution: switch to workspace package
packages/core/package.json, packages/egg/package.json, packages/mock/package.json, pnpm-workspace.yaml, tsconfig.json
Replaces extend2 catalog dependency with @eggjs/extend2 workspace reference; removes catalog entry; adds TS project reference to packages/extend2.
Import/source updates
packages/core/src/loader/egg_loader.ts, packages/egg/src/lib/egg.ts, packages/mock/src/lib/mock_httpclient.ts
Updates imports from extend2 to @eggjs/extend2; mock_httpclient.ts receives formatting-only edits without behavior changes.
Docs and repo guidance
CLAUDE.md
Updates docs to include new package, Vitest testing strategy, TypeScript config requirements, and monorepo creation steps.

Sequence Diagram(s)

sequenceDiagram
  participant App as App Packages (core/egg/mock)
  participant E2 as @eggjs/extend2
  participant TS as TS/Build Tools

  App->>E2: import { extend }
  note over E2: Provides shallow/deep merge<br/>(arrays treated as primitives)
  App->>E2: extend(true, target, ...sources)
  E2-->>App: merged target

  App->>TS: Build/Test (tsdown, Vitest)
  TS-->>App: dist/*.js, *.d.ts, test results
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

I nudge new leaves in the monorepo glade,
A bundle of extends neatly laid. 🥕
Workspace paths hop into view,
Vitest drums a steady “chew-chew.”
Types align, configs hum, all anew—
I twitch my nose: merge done, true-true!

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat: merge extend2 repository into monorepo" accurately and concisely summarizes the primary change — integrating the extend2 package into the monorepo and updating workspace/dependencies and configs. It is specific, readable, and does not include extraneous file lists or vague language. This matches the required principles for a good PR title.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch extend2

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.

@fengmk2 fengmk2 mentioned this pull request Sep 13, 2025
42 tasks
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 @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 integrates the extend2 utility as a new package within the monorepo, centralizing its management and ensuring consistent development practices. This move streamlines dependencies, standardizes build and test workflows using tsdown and vitest, and updates internal references across core, egg, and mock packages to point to the newly integrated version. The change also updates the monorepo's documentation to reflect the new guidelines for package development, particularly regarding testing and TypeScript configuration.

Highlights

  • New Package Integration: The @eggjs/extend2 utility has been integrated as a new package within the monorepo, centralizing its management.
  • Dependency Updates: Existing usages of extend2 in packages/core, packages/egg, and packages/mock have been updated to reference the new monorepo package.
  • Standardized Development Setup: The new extend2 package includes standardized build configurations using tsdown and testing with vitest.
  • Documentation Enhancements: The monorepo's main documentation (CLAUDE.md) has been updated with new guidelines for package development, specifically covering Vitest testing and consistent TypeScript configuration.
  • Workspace Configuration: The pnpm-workspace.yaml and pnpm-lock.yaml files have been updated to reflect the new package structure and dependencies.
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.

@cloudflare-workers-and-pages
Copy link

Deploying egg with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9bbc5c1
Status:🚫  Build failed.

View logs

@cloudflare-workers-and-pages
Copy link

Deploying egg-v3 with  Cloudflare Pages  Cloudflare Pages

Latest commit: 9bbc5c1
Status:🚫  Build failed.

View logs

@gemini-code-assist
Copy link
Contributor

Warning

Gemini encountered an error creating the review. You can try again by commenting /gemini review.

@socket-security
Copy link

@codecov
Copy link

codecov bot commented Sep 13, 2025

Codecov Report

❌ Patch coverage is 95.65217% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 75.90%. Comparing base (0167869) to head (9bbc5c1).
⚠️ Report is 2 commits behind head on next.

Files with missing lines Patch % Lines
packages/mock/src/lib/mock_httpclient.ts 89.65% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             next    #5455      +/-   ##
==========================================
+ Coverage   75.72%   75.90%   +0.18%     
==========================================
  Files          93       94       +1     
  Lines        5503     5553      +50     
  Branches     1153     1177      +24     
==========================================
+ Hits         4167     4215      +48     
- Misses       1167     1168       +1     
- Partials      169      170       +1     

☔ 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.

@fengmk2 fengmk2 merged commit fca450a into next Sep 13, 2025
13 of 17 checks passed
@fengmk2 fengmk2 deleted the extend2 branch September 13, 2025 13:03
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: 7

🧹 Nitpick comments (12)
packages/extend2/README.md (3)

31-31: Verify LICENSE link path in monorepo.

In a monorepo, the license is typically at repo root. Update the link or add a per-package LICENSE copy.

Apply (if using repo-root license):

-`extend2` is licensed under the [MIT License](LICENSE).
+`extend2` is licensed under the [MIT License](../../LICENSE).

Confirm the correct relative path exists in this repo layout. I can tweak once you confirm.


39-50: Silence markdownlint for auto-generated contributors table.

The generated table triggers MD045 (no alt) and MD056 (column count). Disable these rules just for this block.

Apply:

 <!-- GITCONTRIBUTOR_START -->
 
 ## Contributors
 
+<!-- markdownlint-disable MD045 MD056 -->
 |    <img src="https://avatars.githubusercontent.com/u/45469?v=4" width="100px;"/><br/><sub><b>ljharb</b></sub>](https://github.com/ljharb)<br/>     | [<img src="https://avatars.githubusercontent.com/u/53233?v=4" width="100px;"/><br/><sub><b>justmoon</b></sub>](https://github.com/justmoon)<br/> | [<img src="https://avatars.githubusercontent.com/u/1557266?v=4" width="100px;"/><br/><sub><b>jonmorehouse</b></sub>](https://github.com/jonmorehouse)<br/> | [<img src="https://avatars.githubusercontent.com/u/360661?v=4" width="100px;"/><br/><sub><b>popomore</b></sub>](https://github.com/popomore)<br/> | [<img src="https://avatars.githubusercontent.com/u/2396468?v=4" width="100px;"/><br/><sub><b>greelgorke</b></sub>](https://github.com/greelgorke)<br/> | [<img src="https://avatars.githubusercontent.com/u/273857?v=4" width="100px;"/><br/><sub><b>andyburke</b></sub>](https://github.com/andyburke)<br/> |
@@
 <!-- GITCONTRIBUTOR_END -->
+<!-- markdownlint-enable MD045 MD056 -->

Alternatively, regenerate with alt attributes on the Image tags, but disabling for this auto-updated block is lower maintenance.


25-27: Minor doc clarity: deep clone example.

Consider adding a short example showing array replacement vs merge to illustrate the behavior.

Example:

extend(true, {}, { a: [1,2] }, { a: [3] }) // => { a: [3] }  // replaced, not merged
packages/extend2/.gitignore (1)

1-4: Add common TS/Vitest artifacts to ignore list.

Consider ignoring TS build info and Vitest cache to avoid noisy diffs.

 node_modules
 .tshy*
 coverage
 dist
+*.tsbuildinfo
+.vitest
+.DS_Store
tsconfig.json (1)

33-36: Optional: keep references sorted to reduce churn.

Alphabetizing entries (egg, cluster, core, extend2, koa, mock, supertest, utils, …) makes future diffs smaller. Low priority.

packages/extend2/package.json (1)

41-44: Optional: mark package as side-effect free.

If safe, add "sideEffects": false to help tree-shaking.

   "license": "MIT",
+  "sideEffects": false,
   "files": [
     "dist"
   ],
CLAUDE.md (1)

220-225: Doc clarity: reinforce workspace vs catalog usage (and align earlier section).

This section is correct. Add a note pointing readers to use catalog only for external deps and update the earlier “pnpm Catalog Usage” section (Lines 120–128) to avoid contradicting guidance.

-### Workspace Dependencies
+### Workspace Dependencies
@@
-- Use `workspace:*` for internal package dependencies
-- Use `catalog:` for external dependencies defined in pnpm-workspace.yaml
+- Use `workspace:*` for all internal package-to-package dependencies within this monorepo
+- Use `catalog:` only for external dependencies defined centrally in pnpm-workspace.yaml
+- See also: “pnpm Catalog Usage” (ensure it reflects this rule to avoid contradictions)
packages/extend2/tsconfig.json (1)

1-6: Enable TS project references settings if not inherited.

If composite (and declaration emit) aren’t inherited from the root config, set them here to support tsc -b and d.ts generation to dist.

 {
   "extends": "../../tsconfig.json",
   "compilerOptions": {
-    "baseUrl": "./"
+    "baseUrl": "./",
+    "composite": true,
+    "declaration": true,
+    "declarationMap": true,
+    "outDir": "dist",
+    "rootDir": "src"
   }
 }

If root already enforces these via @eggjs/tsconfig and tsdown, feel free to skip.

packages/mock/src/lib/mock_httpclient.ts (3)

95-102: Use explicit arity check; avoid truthy check on mockResult.

if (!mockResult) wrongly treats valid falsy values (e.g. empty string) as “no third arg”. Prefer mockResult === undefined.

-    if (!mockResult) {
+    if (mockResult === undefined) {
       // app.mockHttpclient(mockUrl, mockResult)
       mockResult = mockMethod as MockResultOptions;
       mockMethods = ['*'];
     }
-    if (!Array.isArray(mockMethods)) {
+    if (!Array.isArray(mockMethods)) {
       mockMethods = [mockMethods];
     }

145-148: Minor: avoid duplicate getMockAgent() calls and clarify origin selection.

Tiny readability/perf cleanup; no behavioral change.

-    const mockPool = originMethod
-      ? getMockAgent(app).get(originMethod)
-      : getMockAgent(app).get(originMethod ?? (origin as string));
+    const agent = getMockAgent(app);
+    const mockPool = originMethod ? agent.get(originMethod) : agent.get(origin as string);

156-186: Avoid mutating user-provided mockResult in normalizeResult.

normalizeResult mutates the incoming object (sets status, headers, converts data). If the same object is reused across mocks, this causes surprising side effects. Make normalizeResult pure and clone before normalization.

Apply to normalizeResult:

-function normalizeResult(result: string | MockResultOptions) {
-  if (typeof result === 'string') {
-    result = { data: result };
-  }
-
-  if (!result.status) {
-    result.status = 200;
-  }
-
-  result.data = result.data || '';
-  if (Buffer.isBuffer(result.data)) {
-    // do nothing
-  } else if (typeof result.data === 'object') {
-    // json
-    result.data = Buffer.from(JSON.stringify(result.data));
-  } else if (typeof result.data === 'string') {
-    // string
-    result.data = Buffer.from(result.data);
-  } else {
-    throw new Error('`mockResult.data` must be buffer, string or json');
-  }
-  result.headers = result.headers ?? {};
-  return result;
-}
+function normalizeResult(result: string | MockResultOptions): Required<MockResultOptions> {
+  const res: MockResultOptions =
+    typeof result === 'string' ? { data: result } : { ...result };
+
+  const status = res.status ?? 200;
+  const headers = res.headers ?? {};
+  const dataInput = (res.data ?? '') as any;
+  let data: Buffer;
+  if (Buffer.isBuffer(dataInput)) {
+    data = dataInput;
+  } else if (typeof dataInput === 'object') {
+    data = Buffer.from(JSON.stringify(dataInput));
+  } else if (typeof dataInput === 'string') {
+    data = Buffer.from(dataInput);
+  } else {
+    throw new Error('`mockResult.data` must be buffer, string or json');
+  }
+  return { data, status, headers, delay: res.delay, persist: res.persist, repeats: res.repeats };
+}

Then this line remains correct and now side-effect free:

-          const result = extend(true, {}, normalizeResult(mockRequestResult!));
+          const result = extend(true, {}, normalizeResult(mockRequestResult!));
packages/extend2/test/index.test.ts (1)

641-652: Protect global mutation with try/finally in “works without Array.isArray”.

If an assertion throws, Array.isArray stays patched, risking flakiness. Wrap restoration in finally.

-  it('works without Array.isArray', () => {
-    const savedIsArray = Array.isArray;
-    (Array as any).isArray = false; // don't delete, to preserve enumerability
-    const target: any[] = [];
-    const source = [1, [2], { 3: true }];
-    assert.deepEqual(
-      extend(true, target, source),
-      [1, [2], { 3: true }],
-      'It works without Array.isArray'
-    );
-    Array.isArray = savedIsArray;
-  });
+  it('works without Array.isArray', () => {
+    const savedIsArray = Array.isArray;
+    try {
+      (Array as any).isArray = false; // don't delete, to preserve enumerability
+      const target: any[] = [];
+      const source = [1, [2], { 3: true }];
+      assert.deepEqual(
+        extend(true, target, source),
+        [1, [2], { 3: true }],
+        'It works without Array.isArray'
+      );
+    } finally {
+      Array.isArray = savedIsArray;
+    }
+  });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0167869 and 9bbc5c1.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (19)
  • CLAUDE.md (4 hunks)
  • packages/core/package.json (1 hunks)
  • packages/core/src/loader/egg_loader.ts (1 hunks)
  • packages/egg/package.json (1 hunks)
  • packages/egg/src/lib/egg.ts (1 hunks)
  • packages/extend2/.gitignore (1 hunks)
  • packages/extend2/CHANGELOG.md (1 hunks)
  • packages/extend2/LICENSE (1 hunks)
  • packages/extend2/README.md (1 hunks)
  • packages/extend2/package.json (1 hunks)
  • packages/extend2/src/index.ts (1 hunks)
  • packages/extend2/test/index.test.ts (1 hunks)
  • packages/extend2/tsconfig.json (1 hunks)
  • packages/extend2/tsdown.config.ts (1 hunks)
  • packages/extend2/vitest.config.ts (1 hunks)
  • packages/mock/package.json (1 hunks)
  • packages/mock/src/lib/mock_httpclient.ts (4 hunks)
  • pnpm-workspace.yaml (0 hunks)
  • tsconfig.json (1 hunks)
💤 Files with no reviewable changes (1)
  • pnpm-workspace.yaml
🧰 Additional context used
📓 Path-based instructions (3)
packages/*/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

packages/*/package.json: Use "workspace:*" for internal workspace dependencies in each package.json
Reference external dependencies via pnpm catalog using "catalog:" in package.json

Files:

  • packages/core/package.json
  • packages/egg/package.json
  • packages/mock/package.json
  • packages/extend2/package.json
packages/egg/package.json

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain hybrid CommonJS/ESM exports configuration in packages/egg/package.json

Files:

  • packages/egg/package.json
packages/*/tsdown.config.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Each package must include tsdown.config.ts configured for unbundled ESM builds

Files:

  • packages/extend2/tsdown.config.ts
🧠 Learnings (8)
📓 Common learnings
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/egg/package.json : Maintain hybrid CommonJS/ESM exports configuration in packages/egg/package.json
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in each package.json
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/{egg,core}/tsconfig.json : Enable and keep TypeScript strict mode in packages/egg and packages/core tsconfig.json

Applied to files:

  • packages/extend2/tsconfig.json
  • CLAUDE.md
  • tsconfig.json
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/*/tsdown.config.ts : Each package must include tsdown.config.ts configured for unbundled ESM builds

Applied to files:

  • packages/extend2/tsconfig.json
  • CLAUDE.md
  • packages/extend2/tsdown.config.ts
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/egg/package.json : Maintain hybrid CommonJS/ESM exports configuration in packages/egg/package.json

Applied to files:

  • packages/core/src/loader/egg_loader.ts
  • CLAUDE.md
  • packages/core/package.json
  • packages/egg/package.json
  • packages/egg/src/lib/egg.ts
  • packages/mock/package.json
  • packages/extend2/package.json
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/egg/src/config/plugin.ts : Define built-in Egg plugin configurations in TypeScript at packages/egg/src/config/plugin.ts (not .js)

Applied to files:

  • packages/core/src/loader/egg_loader.ts
  • CLAUDE.md
  • packages/egg/src/lib/egg.ts
  • packages/extend2/tsdown.config.ts
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/*/package.json : Use "workspace:*" for internal workspace dependencies in each package.json

Applied to files:

  • packages/core/package.json
  • packages/egg/package.json
  • packages/mock/package.json
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/egg/src/config/config.default.ts : Keep the default framework configuration in packages/egg/src/config/config.default.ts

Applied to files:

  • packages/extend2/tsdown.config.ts
📚 Learning: 2025-09-11T14:43:56.705Z
Learnt from: CR
PR: eggjs/egg#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-11T14:43:56.705Z
Learning: Applies to packages/*/package.json : Reference external dependencies via pnpm catalog using "catalog:" in package.json

Applied to files:

  • packages/mock/package.json
🧬 Code graph analysis (3)
packages/extend2/src/index.ts (1)
packages/core/src/loader/egg_loader.ts (1)
  • obj (1114-1137)
packages/extend2/test/index.test.ts (1)
packages/extend2/src/index.ts (1)
  • extend (29-85)
packages/mock/src/lib/mock_httpclient.ts (4)
packages/mock/src/app/extend/agent.ts (1)
  • mockHttpClient (28-33)
packages/mock/src/app/extend/application.ts (1)
  • mockHttpClient (329-335)
packages/mock/src/lib/mock_agent.ts (1)
  • getMockAgent (18-37)
packages/extend2/src/index.ts (1)
  • extend (29-85)
🪛 markdownlint-cli2 (0.17.2)
packages/extend2/README.md

43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


43-43: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


45-45: Images should have alternate text (alt text)

(MD045, no-alt-text)


46-46: Images should have alternate text (alt text)

(MD045, no-alt-text)


46-46: Images should have alternate text (alt text)

(MD045, no-alt-text)


46-46: Table column count
Expected: 6; Actual: 2; Too few cells, row will be missing data

(MD056, table-column-count)

⏰ 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). (8)
  • GitHub Check: Test / Test (windows-latest, 24)
  • GitHub Check: Test / Test (windows-latest, 22)
  • GitHub Check: Test / Test (macos-latest, 24)
  • GitHub Check: Test / Test (macos-latest, 22)
  • GitHub Check: Test / Test (ubuntu-latest, 22)
  • GitHub Check: Test / Test (ubuntu-latest, 24)
  • GitHub Check: Socket Security: Pull Request Alerts
  • GitHub Check: Cloudflare Pages: egg-v3
🔇 Additional comments (14)
tsconfig.json (1)

33-36: Root TS project reference added — verify composite build locally.

I couldn't run tsc in the sandbox (no node_modules/tsc) and @eggjs/tsconfig is external, so I can't confirm whether "composite": true is inherited. Root tsconfig.json references ./packages/extend2; packages/extend2/tsconfig.json extends ../../tsconfig.json and has no explicit "composite". Locally run:

pnpm -w exec tsc -b --verbose

Confirm the build succeeds including packages/extend2 and that only dist/ artifacts are emitted (no stray .ts outputs). If the build fails or the base config doesn't set "composite": true, add "composite": true (and declaration settings as needed) to packages/extend2/tsconfig.json or ensure @eggjs/tsconfig enables it. Files: tsconfig.json, packages/extend2/tsconfig.json.

packages/extend2/LICENSE (1)

1-23: LGTM — MIT license text and notices look correct.

packages/core/package.json (1)

47-55: Switch to internal workspace dependency is correct.

"@eggjs/extend2": "workspace:*" aligns with our workspace policy and replaces the catalog indirection. No further action.

packages/extend2/CHANGELOG.md (1)

3-21: Changelog entries look consistent and traceable.

Version, date, Node engine changes, and commit links are clear.

packages/extend2/package.json (1)

45-52: Confirm dev-time exports to TS sources matches repo convention.

Mapping "." to ./src/index.ts is fine for dev (Vitest/esbuild). Confirm consumers only see dist via publishConfig.exports after publish.

packages/core/src/loader/egg_loader.ts (1)

16-16: Ensure @eggjs/extend2 is declared as a dependency ('workspace:*') in each package that imports it

Found imports in: packages/core/src/loader/egg_loader.ts:16; packages/egg/src/lib/egg.ts:26; packages/mock/src/lib/mock_httpclient.ts:2.
No package.json in the scan (root package.json and site/package.json) declares @eggjs/extend2, and package.json files for those packages were not discovered — add dependencies["@eggjs/extend2"] = "workspace:*" to each package.json or confirm where the dependency is declared.

packages/mock/package.json (1)

106-106: Dependency correctly migrated to the workspace package.

"@eggjs/extend2": "workspace:*" aligns with our internal dependency policy.

Optionally standardize other internal deps to "workspace:*" (e.g., any "workspace:" without a range). Use the script in my earlier comment (step 4) to list offenders.

packages/egg/src/lib/egg.ts (1)

26-26: Import path update LGTM.

No behavioral change; matches new workspace package.

packages/egg/package.json (1)

137-137: Good: switched to @eggjs/extend2 with workspace:*.

This adheres to our workspace dependency rule.

packages/extend2/tsdown.config.ts (1)

1-12: Build config looks sound for unbundled ESM + dts.

No changes needed.

packages/extend2/vitest.config.ts (1)

1-13: Per-package Vitest config is minimal and correct.

Patterns target tests and exclude fixtures/benchmarks.

packages/extend2/src/index.ts (1)

61-63: Prototype pollution guard is present.

Skipping __proto__ and only deep-merging plain objects is appropriate for our config merge use cases.

If you want to mirror legacy behavior exactly, confirm array handling (replace vs. merge) matches the old extend2. Our current code replaces arrays; verify with existing tests.

Also applies to: 71-79

packages/mock/src/lib/mock_httpclient.ts (1)

2-2: Import switch OK — named extend export confirmed.
packages/extend2/src/index.ts exports a named extend (line 29) and a default (line 87).

packages/extend2/test/index.test.ts (1)

3-3: No change required — default export present.
packages/extend2/src/index.ts:87 contains export default extend;, so import extend from '../src/index.js' is valid.

Comment on lines +8 to +14
"publishConfig": {
"tag": "latest",
"exports": {
".": "./dist/index.js",
"./package.json": "./package.json"
}
},
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

Ensure public access on publish.

Scoped packages default to restricted access on first publish. Add publishConfig.access: "public" to avoid publish failures.

   "publishConfig": {
     "tag": "latest",
+    "access": "public",
     "exports": {
       ".": "./dist/index.js",
       "./package.json": "./package.json"
     }
   },
📝 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
"publishConfig": {
"tag": "latest",
"exports": {
".": "./dist/index.js",
"./package.json": "./package.json"
}
},
"publishConfig": {
"tag": "latest",
"access": "public",
"exports": {
".": "./dist/index.js",
"./package.json": "./package.json"
}
},
🤖 Prompt for AI Agents
In packages/extend2/package.json around lines 8-14 the publishConfig object
lacks the access field so the scoped package will be restricted on first
publish; add "access": "public" into the publishConfig object (i.e.,
publishConfig.access = "public") so npm publishes the package as public and
avoids first-publish failures.

Comment on lines +16 to +22
"scripts": {
"build": "tsdown",
"clean": "rimraf dist",
"lint": "oxlint",
"test": "vitest run",
"prepublishOnly": "pnpm run build"
},
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

clean script will fail without rimraf in devDependencies.

Add rimraf (catalog) or replace with an existing tool. This breaks local/CI clean commands otherwise.

   "scripts": {
     "build": "tsdown",
-    "clean": "rimraf dist",
+    "clean": "rimraf dist",
     "lint": "oxlint",
     "test": "vitest run",
     "prepublishOnly": "pnpm run build"
   },
@@
   "devDependencies": {
     "@eggjs/tsconfig": "catalog:",
     "@types/node": "catalog:",
+    "rimraf": "catalog:",
     "oxlint": "catalog:",
     "tsdown": "catalog:",
     "typescript": "catalog:",
     "vitest": "catalog:"
   },
📝 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
"scripts": {
"build": "tsdown",
"clean": "rimraf dist",
"lint": "oxlint",
"test": "vitest run",
"prepublishOnly": "pnpm run build"
},
"scripts": {
"build": "tsdown",
"clean": "rimraf dist",
"lint": "oxlint",
"test": "vitest run",
"prepublishOnly": "pnpm run build"
},
"devDependencies": {
"@eggjs/tsconfig": "catalog:",
"@types/node": "catalog:",
"rimraf": "catalog:",
"oxlint": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:",
"vitest": "catalog:"
},
🤖 Prompt for AI Agents
packages/extend2/package.json lines 16-22: the "clean" script references rimraf
which isn't listed in devDependencies so the script will fail locally/CI; fix by
either adding rimraf to devDependencies (pick a maintained version, e.g. latest
semver) and run pnpm install, or change the "clean" script to use an existing
tool in the repo/OS (e.g., a cross-platform Node-based removal or an available
package) and ensure package.json and lockfiles are updated accordingly.

Comment on lines +1 to +3
# extend2

Forked from [node-extend], the difference is overriding array as primitive when deep clone.
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

Rename to scoped package and clarify behavior.

  • Use the scoped name everywhere to match the new workspace package.
  • Minor wording nit: this is a deep merge utility; clarify the “arrays as primitive” rule.

Apply:

-# extend2
+# @eggjs/extend2
@@
-Forked from [node-extend], the difference is overriding array as primitive when deep clone.
+Forked from [node-extend]. Difference: when performing a deep merge, arrays are treated as primitives (replaced, not merged/concatenated).
📝 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
# extend2
Forked from [node-extend], the difference is overriding array as primitive when deep clone.
# @eggjs/extend2
Forked from [node-extend]. Difference: when performing a deep merge, arrays are treated as primitives (replaced, not merged/concatenated).
🤖 Prompt for AI Agents
In packages/extend2/README.md around lines 1 to 3, update the package name to
the scoped workspace name everywhere and clarify that this utility performs a
deep merge (not just clone) and treats arrays as primitives during deep merge —
i.e., arrays are replaced rather than merged. Change wording to use the scoped
package identifier consistently and replace “deep clone” with “deep merge” while
explicitly stating the arrays-as-primitive behavior.

Comment on lines +5 to +9
[![NPM version][npm-image]][npm-url]
[![Node.js CI](https://github.com/eggjs/extend2/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/extend2/actions/workflows/nodejs.yml)
[![Test coverage][codecov-image]][codecov-url]
[![Known Vulnerabilities][snyk-image]][snyk-url]
[![npm download][download-image]][download-url]
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

⚠️ Potential issue

Fix badges and links: current ones point to the old standalone package/repo.

Update npm badges to the scoped package and drop repo-specific badges (CI/Codecov/Snyk) until they’re wired for the monorepo.

Apply:

-[![NPM version][npm-image]][npm-url]
-[![Node.js CI](https://github.com/eggjs/extend2/actions/workflows/nodejs.yml/badge.svg)](https://github.com/eggjs/extend2/actions/workflows/nodejs.yml)
-[![Test coverage][codecov-image]][codecov-url]
-[![Known Vulnerabilities][snyk-image]][snyk-url]
-[![npm download][download-image]][download-url]
+[![NPM version][npm-image]][npm-url]
+[![npm download][download-image]][download-url]
@@
-[npm-image]: https://img.shields.io/npm/v/extend2.svg?style=flat-square
-[npm-url]: https://npmjs.org/package/extend2
-[codecov-image]: https://codecov.io/gh/eggjs/extend2/branch/master/graph/badge.svg
-[codecov-url]: https://codecov.io/gh/eggjs/extend2
-[snyk-image]: https://snyk.io/test/npm/extend2/badge.svg?style=flat-square
-[snyk-url]: https://snyk.io/test/npm/extend2
-[download-image]: https://img.shields.io/npm/dm/extend2.svg?style=flat-square
-[download-url]: https://npmjs.org/package/extend2
+[npm-image]: https://img.shields.io/npm/v/%40eggjs%2Fextend2.svg?style=flat-square
+[npm-url]: https://npmjs.org/package/@eggjs/extend2
+[download-image]: https://img.shields.io/npm/dm/%40eggjs%2Fextend2.svg?style=flat-square
+[download-url]: https://npmjs.org/package/@eggjs/extend2

If you prefer to keep CI/Codecov badges, point them to eggjs/egg with the right workflow name/Codecov flag. I can adjust once you confirm the paths.

Also applies to: 11-18

🤖 Prompt for AI Agents
In packages/extend2/README.md around lines 5-9 (and similarly lines 11-18), the
badges currently point to the old standalone package/repo; update the npm badge
to reference the scoped package @eggjs/extend2 (replace npm-url and npm-image
targets accordingly) and remove or comment out the repo-specific badges
(CI/Codecov/Snyk) unless you wire them for the monorepo; if you choose to keep
CI/Codecov badges instead, change their URLs to point to the eggjs/egg
repository and correct the workflow name/Codecov flag so they reflect the
monorepo pipelines.

Comment on lines +22 to +27
```ts
import { extend } from 'extend2';

// for deep clone
extend(true, {}, object1, objectN);
```
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

Correct import path in usage.

The example currently imports from the unscoped package.

Apply:

-import { extend } from 'extend2';
+import { extend } from '@eggjs/extend2';
📝 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
```ts
import { extend } from 'extend2';
// for deep clone
extend(true, {}, object1, objectN);
```
🤖 Prompt for AI Agents
In packages/extend2/README.md around lines 22-27, the usage example imports from
the unscoped name 'extend2'; update the example to import from this package's
actual scoped name as declared in packages/extend2/package.json (replace
'extend2' with the scoped package "name" field), so the README's import line
uses the correct scoped package path and matches package.json.

Comment on lines +29 to +35
export function extend<T = Record<string, any>>(
deepOrTarget?: unknown,
...objects: unknown[]
): T {
// extend(deep, target, obj1, obj2, ...)
// extend(target, obj1, obj2, ...)
let target = deepOrTarget as any;
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

Add overloads for proper TS inference (parity with prior extend2 typings).

Current signature returns Record<string, any> by default, losing type info at call sites like extend(true, {}, a, b). Provide overloads that infer intersection types.

Apply:

@@
-export function extend<T = Record<string, any>>(
-  deepOrTarget?: unknown,
-  ...objects: unknown[]
-): T {
+// Overloads for better inference
+export function extend<T, U>(target: T, source: U): T & U;
+export function extend<T, U, V>(target: T, source1: U, source2: V): T & U & V;
+export function extend<T, U, V, W>(target: T, s1: U, s2: V, s3: W): T & U & V & W;
+export function extend<T>(target: T, ...sources: any[]): T;
+export function extend<T, U>(deep: boolean, target: T, source: U): T & U;
+export function extend<T, U, V>(deep: boolean, target: T, s1: U, s2: V): T & U & V;
+export function extend<T, U, V, W>(deep: boolean, target: T, s1: U, s2: V, s3: W): T & U & V & W;
+export function extend<T>(deepOrTarget?: unknown, ...objects: unknown[]): T {

Committable suggestion skipped: line range outside the PR's diff.

import { extend } from '@eggjs/extend2';
import type { Dispatcher, Headers, BodyInit } from 'urllib';

import { getMockAgent } from './mock_agent.ts';
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

Fix ESM import extension: use .js instead of .ts in import specifiers.

With NodeNext/Bundler ESM, importing “.ts” will break at runtime after build. Point to the emitted “.js”.

Apply:

-import { getMockAgent } from './mock_agent.ts';
+import { getMockAgent } from './mock_agent.js';
📝 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
import { getMockAgent } from './mock_agent.ts';
import { getMockAgent } from './mock_agent.js';
🤖 Prompt for AI Agents
In packages/mock/src/lib/mock_httpclient.ts around line 5, the import specifier
currently uses a .ts extension which will fail under NodeNext/Bundler ESM after
build; change the import to point to the emitted .js file (import { getMockAgent
} from './mock_agent.js';) and update any other local imports in this file to
use .js extensions so runtime resolution works with the built output.

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