Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@fengmk2
Copy link
Member

@fengmk2 fengmk2 commented Dec 13, 2025

e.g.: only allow <= 80MB tgz to sync

largePackageVersionSize: 80 * 1024 * 1024

Summary by CodeRabbit

  • New Features

    • Added configuration option to set size threshold for large package versions
    • Packages exceeding the threshold can be selectively allowed via whitelist
    • Package size details now included in sync progress logs
  • Tests

    • Added test coverage for large package version handling scenarios

✏️ Tip: You can customize this high-level summary in your review settings.

e.g.: only allow <= 80MB tgz to sync
```ts
largePackageVersionSize: 80 * 1024 * 1024
```
@fengmk2 fengmk2 requested review from Copilot and elrrrrrrr December 13, 2025 12:14
@fengmk2 fengmk2 self-assigned this Dec 13, 2025
@fengmk2 fengmk2 added the enhancement New feature or request label Dec 13, 2025
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 13, 2025

Note

Other AI code review bot(s) detected

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

Walkthrough

This pull request introduces a feature to control syncing of large package versions based on a configurable size threshold and an unpkg whitelist. A new configuration parameter largePackageVersionSize is added, and PackageVersionFileService gains a method to validate large packages against the whitelist. PackageSyncerService now checks package sizes during sync and conditionally permits large versions based on whitelist approval.

Changes

Cohort / File(s) Summary
Configuration
app/port/config.ts, config/config.default.ts
Added new largePackageVersionSize property to config interface and set to Number.MAX_SAFE_INTEGER in default config.
Whitelist & Version File Service
app/core/service/PackageVersionFileService.ts
Exported UNPKG_WHITE_LIST_URL constant, added private state for allowed large packages with version ranges, extended whitelist update flow to populate large packages data, and added public method isAllowLargePackageVersion() to validate large package versions against whitelist.
Package Syncer Service
app/core/service/PackageSyncerService.ts
Introduced dependency on PackageVersionFileService, normalized tarball access with optional chaining, added large-package size enforcement logic in both main and diff-based processing paths, and augmented log messages with tarball size information.
Test Coverage
test/core/service/PackageSyncerService/executeTask.test.ts, test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
Added test cases for large package version blocking and allowing scenarios, including configuration mocking and log assertions for both sync paths.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • Size checking logic consistency: Verify that large-package handling is identical across both version processing paths (main and diff-based).
  • Whitelist validation: Review the isAllowLargePackageVersion() method logic for semver matching and feature flag handling.
  • Test coverage: Confirm both test files exercise all new code paths and edge cases around the size threshold boundary.

Possibly related PRs

Suggested reviewers

  • elrrrrrrr

Poem

🐰 A whitelist appears, so big packages can play,
But only the blessed ones get synced today,
Size checks and thresholds keep syncing in line,
Now large bundles dance—if permitted they shine! ✨

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 accurately describes the main feature: a configurable limit for .tgz package file sizes. It aligns with the PR's core objective and the changes across PackageSyncerService, PackageVersionFileService, and configuration files.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch limit-tgz-max-size

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.

@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 introduces a crucial feature to manage the storage and bandwidth consumption associated with package synchronization. It enables the system to enforce a configurable maximum size for .tgz package versions, preventing the accidental or intentional syncing of overly large packages. To maintain flexibility, a whitelisting mechanism is also provided, allowing specific large packages to be synchronized if explicitly approved, ensuring that critical dependencies are not inadvertently blocked.

Highlights

  • Configurable Tarball Size Limit: Introduced a new configuration option, largePackageVersionSize, allowing administrators to define a maximum size for .tgz package versions during synchronization. By default, this limit is set to Number.MAX_SAFE_INTEGER.
  • Large Package Version Blocking: The PackageSyncerService now checks the size of incoming tarballs. If a package version's tarball exceeds the configured largePackageVersionSize, its synchronization will be blocked, preventing it from being stored.
  • Whitelisting for Large Packages: An extension to the unpkg-white-list mechanism has been implemented, allowing specific large package versions to bypass the size limit. A new isAllowLargePackageVersion method in PackageVersionFileService handles this check.
  • Improved Logging and Error Messages: Error messages and synchronization logs have been updated to clearly indicate when a package is blocked due to its size, including the actual size, the allowed size, and a reference to the unpkg-white-list URL.
  • Comprehensive Test Coverage: New test cases have been added to PackageSyncerService to validate the functionality of blocking and allowing large package versions based on the new configuration and whitelisting rules.
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.

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 introduces a feature to limit the size of tgz files that can be synced, controlled by a new configuration largePackageVersionSize. Packages exceeding this size are rejected unless they are on a whitelist. The changes are well-implemented across the configuration, services, and tests.

My main feedback is to address code duplication in PackageSyncerService.ts where the size check logic is repeated. Extracting this into a helper method would improve maintainability. Additionally, in PackageVersionFileService.ts, improving type safety by defining a specific interface for the unpkg-white-list manifest instead of using as any would be beneficial.

Overall, this is a good addition to the project.

Comment on lines +870 to +881
const size = dist.size;
if (size && size > this.config.cnpmcore.largePackageVersionSize) {
const isAllowLargePackageVersion = await this.packageVersionFileService.isAllowLargePackageVersion(
scope,
name,
version,
);
if (!isAllowLargePackageVersion) {
lastErrorMessage = `large package version size: ${size}, allow size: ${this.config.cnpmcore.largePackageVersionSize}, see ${UNPKG_WHITE_LIST_URL}`;
logs.push(`[${isoNow()}] ❌ [${syncIndex}] Synced version ${version} fail, ${lastErrorMessage}`);
await this.taskService.appendTaskLog(task, logs.join('\n'));
logs = [];
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This block of code for checking large package sizes is duplicated in syncPackageWithPackument (lines 1362-1373). To improve maintainability and avoid potential inconsistencies, consider extracting this logic into a private helper method.

For example, you could create a method like _ensurePackageSizeAllowed that encapsulates this check and returns whether to continue the loop.

Comment on lines 116 to +118
this.#unpkgWhiteListAllowPackages = manifest.allowPackages ?? ({} as any);
// oxlint-disable-next-line typescript-eslint/no-explicit-any
this.#unpkgWhiteListAllowScopes = manifest.allowScopes ?? ([] as any);
this.#unpkgWhiteListAllowLargePackages = manifest.allowLargePackages ?? ({} 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.

medium

Using as any bypasses type safety. To improve type safety and code clarity, you could define a specific interface for the unpkg-white-list manifest that includes the custom properties allowPackages, allowScopes, and allowLargePackages. Then, you can cast the manifest object to this new interface. This would eliminate the need for as any and provide better type checking.

Example:

interface UnpkgWhiteListManifest extends PackageJSONType {
  allowPackages?: Record<string, { version: string; }>;
  allowScopes?: string[];
  allowLargePackages?: Record<string, { version: string; }>;
}

// ... inside updateUnpkgWhiteList method
if (!manifest) return;
const unpkgManifest = manifest as UnpkgWhiteListManifest;
this.#unpkgWhiteListCurrentVersion = unpkgManifest.version;
this.#unpkgWhiteListAllowPackages = unpkgManifest.allowPackages ?? {};
this.#unpkgWhiteListAllowScopes = unpkgManifest.allowScopes ?? [];
this.#unpkgWhiteListAllowLargePackages = unpkgManifest.allowLargePackages ?? {};

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

♻️ Duplicate comments (2)
app/core/service/PackageSyncerService.ts (1)

870-887: Guard largePackageVersionSize semantics to avoid “accidentally block everything/nothing”.
Current check assumes this.config.cnpmcore.largePackageVersionSize is a valid positive number. If it’s 0, undefined, or mis-typed, behavior can be surprising. Consider treating non-positive/undefined as “disabled”, and use typeof === 'number' guards.
Also, the same logic exists twice (classic vs packument path) — already noted in past reviews.

@@
-      const size = dist.size;
-      if (size && size > this.config.cnpmcore.largePackageVersionSize) {
+      const size = dist.size;
+      const maxSize = this.config.cnpmcore.largePackageVersionSize;
+      if (typeof size === 'number' && typeof maxSize === 'number' && maxSize > 0 && size > maxSize) {
         const isAllowLargePackageVersion = await this.packageVersionFileService.isAllowLargePackageVersion(
           scope,
           name,
           version,
         );
@@
-          lastErrorMessage = `large package version size: ${size}, allow size: ${this.config.cnpmcore.largePackageVersionSize}, see ${UNPKG_WHITE_LIST_URL}`;
+          lastErrorMessage = `large package version size: ${size}, allow size: ${maxSize}, see ${UNPKG_WHITE_LIST_URL}`;
What is the default value (and intended “disabled” behavior) of `largePackageVersionSize` in cnpmcore’s config/schema/docs?

Also applies to: 892-893, 1368-1386, 1391-1392

app/core/service/PackageVersionFileService.ts (1)

53-60: Replace as any whitelist parsing with a typed manifest shape; add explicit return type.
The new allowLargePackages support is fine, but it extends the existing as any pattern (which bypasses strict TS). Prefer a dedicated interface for the unpkg-white-list manifest and set isAllowLargePackageVersion(...): Promise<boolean>. This matches repo “strict TS” guidance.

Also applies to: 115-125, 128-138

🧹 Nitpick comments (5)
config/config.default.ts (1)

59-60: Make largePackageVersionSize configurable via env (keeps default behavior but improves operability).

Right now it’s effectively “unlimited unless code overrides config”. Consider wiring it to an env var like the rest of the config surface:

-  largePackageVersionSize: Number.MAX_SAFE_INTEGER,
+  largePackageVersionSize: env('CNPMCORE_CONFIG_LARGE_PACKAGE_VERSION_SIZE', 'number', Number.MAX_SAFE_INTEGER),
app/port/config.ts (1)

157-160: Clarify units/semantics in the config doc (bytes, and behavior when size is missing).

Suggested tweak:

   /**
-   * allow large package version size, default is MAX_SAFE_INTEGER
+   * Max allowed package tarball size in bytes for syncing; default is MAX_SAFE_INTEGER (no limit).
+   * Note: if upstream metadata lacks `dist.size`, behavior should be defined (skip check vs. fallback to download size).
    */
   largePackageVersionSize: number;
test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts (1)

2157-2229: Good coverage for “oversize blocked” and “oversize allowed by whitelist”; consider de-brittling assertions.

Two small hardening tweaks:

  1. Avoid hard-coding the whitelist URL string in regex (import and use the exported constant instead, if available), so tests won’t break on URL changes.
  2. In the “block” test, consider removing mock.error(NPMRegistry.prototype, 'downloadTarball') and/or explicitly asserting it was not called; otherwise, a regression that incorrectly downloads despite oversize could still “pass” due to the forced error masking the root cause.

(Also optional: in the “allow” test, assert PackageVersionFileService.prototype.isAllowLargePackageVersion was called with the expected package name/version.)

test/core/service/PackageSyncerService/executeTask.test.ts (2)

14-15: Good coverage addition for the “allow” path; consider isolating mocks to avoid order-dependent failures.
The new tests are valuable, but should mock large package version size block currently relies on the whitelist data not being present (so the service returns false). To make it deterministic, explicitly stub PackageVersionFileService.prototype.isAllowLargePackageVersion to false in the block test (and restore afterward).


2181-2253: Potential cross-test leakage via mock(app.config.cnpmcore, ...) and prototype stubs.
Both new tests patch app.config.cnpmcore and (in the allow test) patch a prototype method; if mocks aren’t auto-restored per test in this repo, later tests can become flaky. Suggest adding explicit restore for these patches within the test(s) (or a local afterEach(async () => mock.restore()) in this file/describe). Based on learnings, tests should keep mocks scoped and cleaned up.

@@
     it('should mock large package version size block', async () => {
@@
+      mock(PackageVersionFileService.prototype, 'isAllowLargePackageVersion', async () => false);
@@
       assert.match(
         log,
         /Synced version 2.0.0 fail, large package version size: 104857601, allow size: 104857600, see https:\/\/github\.com\/cnpm\/unpkg-white-list/,
       );
+      await mock.restore();
     });
@@
     it('should mock large package version size allow', async () => {
@@
       assert.match(log, /Synced version 2.0.0 size: 104857601 too large, it is allowed to sync by unpkg white list/);
       app.mockAgent().assertNoPendingInterceptors();
+      await mock.restore();
     });
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between deb3748 and 0cc1765.

📒 Files selected for processing (6)
  • app/core/service/PackageSyncerService.ts (4 hunks)
  • app/core/service/PackageVersionFileService.ts (5 hunks)
  • app/port/config.ts (1 hunks)
  • config/config.default.ts (1 hunks)
  • test/core/service/PackageSyncerService/executeTask.test.ts (2 hunks)
  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{js,ts,tsx,jsx}

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

**/*.{js,ts,tsx,jsx}: Use single quotes in JavaScript/TypeScript code (from Prettier configuration)
Use 2-space indentation (from Prettier configuration)
Maintain 120 character line width maximum (from Prettier configuration)
Use trailing commas in ES5 syntax (from Prettier configuration)
Avoid parentheses in arrow functions when possible (from Prettier configuration)
Maximum of 6 function parameters (from Oxlint configuration)
Warn on console usage (from Oxlint configuration)
Disallow anonymous default exports (from Oxlint configuration)
Use ES modules (import/export) syntax throughout

Files:

  • app/port/config.ts
  • config/config.default.ts
  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • app/core/service/PackageVersionFileService.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
  • app/core/service/PackageSyncerService.ts
**/*.{ts,tsx}

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

**/*.{ts,tsx}: Use strict TypeScript with comprehensive type definitions - avoid any types, use proper typing or unknown
Export types and interfaces for reusability in TypeScript

Files:

  • app/port/config.ts
  • config/config.default.ts
  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • app/core/service/PackageVersionFileService.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
  • app/core/service/PackageSyncerService.ts
**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.ts: Use strict TypeScript with proper typing - avoid any types, use proper typing or unknown instead
Use ES modules with import/export syntax throughout the codebase
Use single quotes (') for strings
Use 2-space indentation
Enforce 120 character line width
Use ES5 trailing commas
Limit functions to a maximum of 6 parameters
Do not use console statements - use logger instead

Files:

  • app/port/config.ts
  • config/config.default.ts
  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • app/core/service/PackageVersionFileService.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
  • app/core/service/PackageSyncerService.ts
test/**/*.test.ts

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

test/**/*.test.ts: Test files must use .test.ts suffix
Tests must use @eggjs/mock for mocking and testing
Tests must use assert from node:assert/strict for assertions
Test files should be organized in test/ directory mirroring source structure
Mock external dependencies using mock() from @eggjs/mock in tests
Use realistic test data created through TestUtil helper methods
Clean up after tests - database is reset between test files
Test both success and failure cases - error paths are equally important
Test files should follow naming pattern: describe('[HTTP_METHOD /api/path] functionName()', ...)

test/**/*.test.ts: Test files must use .test.ts suffix
Use @eggjs/mock for mocking in test files
Use assert from node:assert/strict in test files
Test files must mirror source structure in test/ directory and test both success and error cases

Files:

  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
app/core/service/**/*.ts

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

app/core/service/**/*.ts: Services must implement core business logic without HTTP concerns or direct database access
Services must use @SingletonProto() for service lifecycle management
Services must orchestrate multiple repositories and entities, managing transactions and events

Files:

  • app/core/service/PackageVersionFileService.ts
  • app/core/service/PackageSyncerService.ts
🧠 Learnings (11)
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to test/**/*.test.ts : Test both success and failure cases - error paths are equally important

Applied to files:

  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to app/core/service/**/*.ts : Services must orchestrate multiple repositories and entities, managing transactions and events

Applied to files:

  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
  • app/core/service/PackageSyncerService.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to test/**/*.test.ts : Mock external dependencies using `mock()` from `eggjs/mock` in tests

Applied to files:

  • test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts
  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to **/*.{ts,tsx} : Use strict TypeScript with comprehensive type definitions - avoid `any` types, use proper typing or `unknown`

Applied to files:

  • app/core/service/PackageVersionFileService.ts
📚 Learning: 2025-11-29T15:42:56.815Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-29T15:42:56.815Z
Learning: Applies to **/*.ts : Use strict TypeScript with proper typing - avoid `any` types, use proper typing or `unknown` instead

Applied to files:

  • app/core/service/PackageVersionFileService.ts
📚 Learning: 2025-11-29T15:42:56.815Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-29T15:42:56.815Z
Learning: Applies to test/**/*.test.ts : Use `eggjs/mock` for mocking in test files

Applied to files:

  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:56.815Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-29T15:42:56.815Z
Learning: Applies to test/**/*.test.ts : Test files must mirror source structure in `test/` directory and test both success and error cases

Applied to files:

  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to test/**/*.test.ts : Tests must use `eggjs/mock` for mocking and testing

Applied to files:

  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to test/**/*.test.ts : Use realistic test data created through `TestUtil` helper methods

Applied to files:

  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:56.815Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-29T15:42:56.815Z
Learning: Applies to test/**/*.test.ts : Use `assert` from `node:assert/strict` in test files

Applied to files:

  • test/core/service/PackageSyncerService/executeTask.test.ts
📚 Learning: 2025-11-29T15:42:37.586Z
Learnt from: CR
Repo: cnpm/cnpmcore PR: 0
File: .github/copilot-instructions.md:0-0
Timestamp: 2025-11-29T15:42:37.586Z
Learning: Applies to **/*.{ts,tsx} : Export types and interfaces for reusability in TypeScript

Applied to files:

  • app/core/service/PackageSyncerService.ts
🧬 Code graph analysis (3)
app/core/service/PackageVersionFileService.ts (2)
app/core/entity/Package.ts (1)
  • fullname (63-65)
app/common/PackageUtil.ts (1)
  • getFullname (25-27)
test/core/service/PackageSyncerService/executeTask.test.ts (1)
test/TestUtil.ts (2)
  • app (167-172)
  • TestUtil (66-402)
app/core/service/PackageSyncerService.ts (2)
app/common/LogUtil.ts (1)
  • isoNow (1-3)
app/core/service/PackageVersionFileService.ts (2)
  • isAllowLargePackageVersion (128-138)
  • UNPKG_WHITE_LIST_URL (24-24)
⏰ 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). (15)
  • GitHub Check: test on mysql (node@22, shard@2/3, enableJSONBuilder@true)
  • GitHub Check: test on mysql (node@22, shard@1/3, enableJSONBuilder@true)
  • GitHub Check: test on mysql (node@22, shard@2/3, enableJSONBuilder@false)
  • GitHub Check: test on mysql (node@24, shard@1/3, enableJSONBuilder@true)
  • GitHub Check: test on mysql (node@24, shard@1/3, enableJSONBuilder@false)
  • GitHub Check: test on mysql (node@20, shard@2/3, enableJSONBuilder@true)
  • GitHub Check: test on mysql (node@20, shard@2/3, enableJSONBuilder@false)
  • GitHub Check: test on mysql (node@20, shard@1/3, enableJSONBuilder@false)
  • GitHub Check: test on postgresql (node@22, shard@0/3)
  • GitHub Check: test on postgresql (node@24, shard@2/3)
  • GitHub Check: test on postgresql (node@20, shard@0/3)
  • GitHub Check: test on postgresql (node@20, shard@1/3)
  • GitHub Check: test on postgresql (node@20, shard@2/3)
  • GitHub Check: test-deployment
  • GitHub Check: build-and-push-image
🔇 Additional comments (3)
test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts (1)

14-15: Import addition is appropriate for the new whitelist-size tests.

app/core/service/PackageSyncerService.ts (1)

36-38: LGTM: service wiring for PackageVersionFileService + shared URL constant.
Clean DI + reuse of UNPKG_WHITE_LIST_URL keeps log messaging consistent.

Also applies to: 86-88

app/core/service/PackageVersionFileService.ts (1)

24-25: Good: exporting UNPKG_WHITE_LIST_URL reduces string duplication across services/tests.

@elrrrrrrr elrrrrrrr enabled auto-merge December 13, 2025 12:22
@elrrrrrrr elrrrrrrr disabled auto-merge December 13, 2025 12:22
@elrrrrrrr elrrrrrrr merged commit a631fad into master Dec 13, 2025
36 checks passed
@elrrrrrrr elrrrrrrr deleted the limit-tgz-max-size branch December 13, 2025 12:22
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 pull request adds a configurable size limit for package tarballs during synchronization, allowing administrators to block large packages from being synced while optionally whitelisting specific packages that exceed the limit.

Key Changes

  • Introduces largePackageVersionSize configuration option (default: Number.MAX_SAFE_INTEGER) to set maximum allowed package tarball size
  • Adds whitelist support for large packages through the existing unpkg-white-list mechanism
  • Includes comprehensive test coverage for both blocking and allowing large packages

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
config/config.default.ts Adds default configuration for largePackageVersionSize set to MAX_SAFE_INTEGER (effectively unlimited by default)
app/port/config.ts Defines TypeScript interface for the new largePackageVersionSize configuration option
app/core/service/PackageVersionFileService.ts Exports UNPKG_WHITE_LIST_URL constant, adds isAllowLargePackageVersion method for whitelist checking, and tracks large package whitelist from unpkg-white-list package
app/core/service/PackageSyncerService.ts Implements size checking logic in two sync methods, blocking packages exceeding the limit unless whitelisted, and adds size information to sync logs
test/core/service/PackageSyncerService/executeTaskWithPackument.test.ts Adds duplicate import and two test cases covering block and allow scenarios for large packages
test/core/service/PackageSyncerService/executeTask.test.ts Adds duplicate import and two test cases covering block and allow scenarios for large packages

import { Task as TaskEntity } from '../../../../app/core/entity/Task.ts';
import { PackageManagerService } from '../../../../app/core/service/PackageManagerService.ts';
import { PackageSyncerService } from '../../../../app/core/service/PackageSyncerService.ts';
import { PackageVersionFileService } from '../../../../app/core/service/PackageVersionFileService.ts';
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

Duplicate import detected. The PackageVersionFileService is already imported at line 25 of this file. Adding it again at line 14 creates a duplicate import statement that should be removed.

Copilot uses AI. Check for mistakes.
import { Task as TaskEntity } from '../../../../app/core/entity/Task.ts';
import { PackageManagerService } from '../../../../app/core/service/PackageManagerService.ts';
import { PackageSyncerService } from '../../../../app/core/service/PackageSyncerService.ts';
import { PackageVersionFileService } from '../../../../app/core/service/PackageVersionFileService.ts';
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

Duplicate import detected. The PackageVersionFileService is already imported at line 25 of this file. Adding it again at line 14 creates a duplicate import statement that should be removed.

Copilot uses AI. Check for mistakes.
Comment on lines 116 to +118
this.#unpkgWhiteListAllowPackages = manifest.allowPackages ?? ({} as any);
// oxlint-disable-next-line typescript-eslint/no-explicit-any
this.#unpkgWhiteListAllowScopes = manifest.allowScopes ?? ([] as any);
this.#unpkgWhiteListAllowLargePackages = manifest.allowLargePackages ?? ({} as any);
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The oxlint-disable comments for no-explicit-any were removed from lines 116-117, but the code still uses as any type assertions. Either restore the oxlint-disable comments or fix the type assertions to avoid using any. Line 118 also uses as any without the disable comment, creating inconsistency.

Copilot uses AI. Check for mistakes.
*/
enableSyncUnpkgFilesWhiteList: boolean;
/**
* allow large package version size, default is MAX_SAFE_INTEGER
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The documentation comment is misleading. It says "allow large package version size" which sounds like a boolean flag, but it's actually the maximum allowed size in bytes. Consider rewording to "maximum allowed package version size in bytes, default is MAX_SAFE_INTEGER" to be more precise.

Suggested change
* allow large package version size, default is MAX_SAFE_INTEGER
* Maximum allowed package version size in bytes. Default is MAX_SAFE_INTEGER.

Copilot uses AI. Check for mistakes.
app.mockAgent().assertNoPendingInterceptors();
});

it('should mock large package version size block', async () => {
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The test name "should mock large package version size block" could be more descriptive. Consider renaming to "should block sync when package version size exceeds limit" to better describe the test's purpose and expected behavior.

Suggested change
it('should mock large package version size block', async () => {
it('should block sync when package version size exceeds limit', async () => {

Copilot uses AI. Check for mistakes.
if (!isAllowLargePackageVersion) {
lastErrorMessage = `large package version size: ${size}, allow size: ${this.config.cnpmcore.largePackageVersionSize}, see ${UNPKG_WHITE_LIST_URL}`;
logs.push(`[${isoNow()}] ❌ [${syncIndex}] Synced version ${version} fail, ${lastErrorMessage}`);
await this.taskService.appendTaskLog(task, logs.join('\n'));
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The log message reads awkwardly. Consider rephrasing to "size: ${size} exceeds limit but is whitelisted for sync" or "size: ${size} is too large but allowed by unpkg whitelist" for better clarity.

Copilot uses AI. Check for mistakes.
if (size && size > this.config.cnpmcore.largePackageVersionSize) {
const isAllowLargePackageVersion = await this.packageVersionFileService.isAllowLargePackageVersion(
scope,
name,
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The log message reads awkwardly. Consider rephrasing to "size: ${size} exceeds limit but is whitelisted for sync" or "size: ${size} is too large but allowed by unpkg whitelist" for better clarity.

Copilot uses AI. Check for mistakes.
res: {},
headers: {},
});
mock(app.config.cnpmcore, 'enableSyncUnpkgFilesWhiteList', true);
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The test enables the whitelist feature but relies on the implicit behavior that the package won't be in the whitelist. For better test clarity and explicitness, consider either: (1) removing line 2174 since the whitelist feature isn't needed for this test case, or (2) adding an explicit mock for isAllowLargePackageVersion to return false, similar to how the allow test mocks it to return true.

Suggested change
mock(app.config.cnpmcore, 'enableSyncUnpkgFilesWhiteList', true);

Copilot uses AI. Check for mistakes.
headers: {},
});
mock(app.config.cnpmcore, 'enableSyncUnpkgFilesWhiteList', true);
mock(app.config.cnpmcore, 'largePackageVersionSize', 100 * 1024 * 1024);
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The test enables the whitelist feature but relies on the implicit behavior that the package won't be in the whitelist. For better test clarity and explicitness, consider either: (1) removing line 2198 since the whitelist feature isn't needed for this test case, or (2) adding an explicit mock for isAllowLargePackageVersion to return false, similar to how the allow test mocks it to return true.

Suggested change
mock(app.config.cnpmcore, 'largePackageVersionSize', 100 * 1024 * 1024);
mock(app.config.cnpmcore, 'largePackageVersionSize', 100 * 1024 * 1024);
// Explicitly mock isAllowLargePackageVersion to return false for clarity
mock(PackageSyncerService.prototype, 'isAllowLargePackageVersion', async () => false);

Copilot uses AI. Check for mistakes.
);
}

async isAllowLargePackageVersion(pkgScope: string, pkgName: string, pkgVersion: string) {
Copy link

Copilot AI Dec 13, 2025

Choose a reason for hiding this comment

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

The method name reads awkwardly as "is allow large package version". Consider renaming to "isLargePackageVersionAllowed" which follows standard English grammar and is more consistent with naming conventions like "isPackageAllowed" vs "isAllowPackage".

Suggested change
async isAllowLargePackageVersion(pkgScope: string, pkgName: string, pkgVersion: string) {
async isLargePackageVersionAllowed(pkgScope: string, pkgName: string, pkgVersion: string) {

Copilot uses AI. Check for mistakes.
fengmk2 pushed a commit that referenced this pull request Dec 13, 2025
[skip ci]

## 4.16.0 (2025-12-13)

* feat: limit tgz file size through configuration (#926) ([a631fad](a631fad)), closes [#926](#926) [hi#level](https://github.com/hi/issues/level)
* chore: test on Node.js v20 (#925) ([deb3748](deb3748)), closes [#925](#925) [hi#level](https://github.com/hi/issues/level)
@github-actions
Copy link

🎉 This PR is included in version 4.16.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

fengmk2 added a commit to cnpm/unpkg-white-list that referenced this pull request Dec 13, 2025
fengmk2 added a commit to cnpm/unpkg-white-list that referenced this pull request Dec 13, 2025
cnpm/cnpmcore#926
cnpm/cnpmcore#926


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Introduced large-package and large-scope whitelisting capabilities for
improved dependency handling.

* **Documentation**
* Updated CLI usage examples and added workflow guidance for new
large-package and large-scope features.

* **Chores**
  * Configured allowances for specified large packages and scopes.

<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@codecov
Copy link

codecov bot commented Dec 13, 2025

Codecov Report

❌ Patch coverage is 96.00000% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 95.26%. Comparing base (deb3748) to head (0cc1765).
⚠️ Report is 4 commits behind head on master.

Files with missing lines Patch % Lines
app/core/service/PackageVersionFileService.ts 88.46% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master     #926      +/-   ##
==========================================
- Coverage   95.37%   95.26%   -0.12%     
==========================================
  Files         197      197              
  Lines       22139    22205      +66     
  Branches     2445     2450       +5     
==========================================
+ Hits        21116    21154      +38     
- Misses       1023     1051      +28     

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request released

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants