Skip to content

fix: preserve decorator metadata in published bundles - #1412

Merged
kang-heewon merged 7 commits into
trunkfrom
fix/1338-preserve-decorator-metadata
Jul 18, 2026
Merged

fix: preserve decorator metadata in published bundles#1412
kang-heewon merged 7 commits into
trunkfrom
fix/1338-preserve-decorator-metadata

Conversation

@kang-heewon

@kang-heewon kang-heewon commented Jul 15, 2026

Copy link
Copy Markdown
Member

Outcome

Published Croco ESM and CJS bundles now retain decorator metadata for concrete constructor dependencies. Installed consumers can resolve representative services through Container.get, while trailing optional/default parameters keep their JavaScript defaults and explicit @Inject handlers remain authoritative.

The release smoke now fails when metadata is missing or when emitted trailing metadata is incorrectly injected.

Verification

  • pnpm check
  • pnpm build — 114/114 tasks
  • pnpm typecheck — 226/226 tasks
  • pnpm exec turbo test --concurrency=1 — 227/227 tasks
  • pnpm package-entrypoints:smoke — 110 packed packages; CJS/ESM metadata and DI checks for auth, PostHog features, and metering defaults
  • pnpm exec vitest run scripts/tests/package-entrypoint-smoke.spec.ts --config vitest.config.ts — 20/20 tests
  • pre-push test and typecheck gates — 227/227 and 226/226
  • independent adversarial review — no actionable findings

Review notes

  • Pins @swc/core in the shared build toolchain so tsup emits metadata instead of silently skipping the transformer.
  • Keeps constructor dependencies as runtime imports where emitted metadata needs concrete class identities.
  • Uses runtime constructor arity to omit uninjected trailing default slots; the real minified MeterRegistry CJS/ESM smoke validates that contract.
  • Includes patch changesets for metadata-bearing published packages and deterministic Problem-registry source-location updates.

Closes #1338

Summary by CodeRabbit

  • 새로운 기능

    • 배포된 ESM/CJS 번들에서 클래스 데코레이터 메타데이터가 보존되어 생성자 의존성 해석이 더 안정적입니다.
    • 환경 설정을 지연 초기화/일관된 동기화 방식으로 개선했습니다.
  • 버그 수정

    • DI 해석 시 범위 초과 파라미터로 인한 오류를 방지하고, 생성자 기본값과 명시적 주입 우선 순위를 정확히 유지합니다.
  • 테스트

    • 데코레이터 메타데이터+암시적 DI 스모크 및 컨테이너 주입 경로 검증을 강화했습니다.
  • 문서

    • 관련 출처/문제 레지스트리 표기와 타입 표기를 업데이트했습니다.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@kang-heewon, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 41 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 69512271-6cb9-497e-92c4-68bcb7108792

📥 Commits

Reviewing files that changed from the base of the PR and between 0f7b638 and 149e3ee.

⛔ Files ignored due to path filters (2)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (17)
  • docs/problem-code-registry.json
  • package.json
  • packages/auth-better-auth/src/libs/BetterAuthProvider.ts
  • packages/docs/src/content/docs/api/problems-core/src/variables/CROCO_PROBLEM_CODE_REGISTRY.md
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/framework-config/src/core.ts
  • packages/framework-config/src/tests/Core.spec.ts
  • packages/framework-context/src/libs/Container.ts
  • packages/framework-context/src/tests/CircularDependency.spec.ts
  • packages/framework-context/src/tests/FrameworkContext.spec.ts
  • packages/invitation-core/src/libs/DomainPolicyManager.ts
  • packages/invitation-drizzle/src/libs/DrizzleDomainPolicyStore.ts
  • packages/invitation-drizzle/src/libs/DrizzleInvitationStore.ts
  • packages/membership-drizzle/src/libs/DrizzleMembershipStore.ts
  • packages/notifications-core/src/libs/SendNotificationTask.ts
  • packages/onboarding-drizzle/src/libs/DrizzleOnboardingStore.ts
  • packages/transports-http/src/tests/ErrorHandler.spec.ts
📝 Walkthrough

Walkthrough

Changes

게시 번들 DI 메타데이터

Layer / File(s) Summary
런타임 생성자 메타데이터 유지
.changeset/*, package.json, pnpm-workspace.yaml, packages/*/src/libs/*, packages/docs/content/docs/api/*
생성자 의존성을 런타임 import로 유지하고 선택적 인자를 명시적 undefined 기본값으로 표현했으며, SWC 빌드 허용과 관련 문서를 갱신했습니다.
소스 모드 DI 바인딩
packages/transports-http/src/libs/ErrorHandler.ts, packages/transports-http/src/tests/*
ErrorHandlerLOGGER_TOKEN 주입을 런타임에 적용하고 컨테이너 해석 테스트를 추가했습니다.
컨테이너 기본값 및 범위 가드
packages/framework-context/src/libs/Container.ts, packages/framework-context/src/tests/*, docs/*
메타데이터 범위를 벗어난 매개변수 해석을 건너뛰고 후행 기본값 및 명시적 @Inject 동작을 검증하도록 변경했습니다.
패키지 메타데이터 스모크 검증
scripts/package-entrypoint-smoke.mts, scripts/tests/package-entrypoint-smoke.spec.ts
패킹된 ESM/CJS 번들의 design:paramtypes, 암시적 DI, 기본값을 검증하는 성공 및 실패 스모크를 추가했습니다.

지연 초기화 런타임 환경

Layer / File(s) Summary
환경 Proxy 및 동기화
packages/framework-config/src/core.ts
환경 설정을 지연 생성하고 Proxy 트랩을 통해 런타임 환경과 대상 객체를 동기화하도록 변경했습니다.
환경 지연 검증 테스트
packages/framework-config/src/tests/Core.spec.ts
검증 지연, 클라이언트 접근 제한, process.env identity 보존, 키와 디스크립터 동기화를 테스트합니다.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PackedPackage
  participant SmokeScript
  participant Container
  PackedPackage->>SmokeScript: ESM/CJS 서비스와 design:paramtypes 로드
  SmokeScript->>Container: 서비스 해석 요청
  Container-->>SmokeScript: 의존성 주입 및 기본값 보존 결과
  SmokeScript-->>PackedPackage: 성공 또는 메타데이터 오류 보고
Loading

Possibly related PRs

  • croco-dev/framework#634: 패키지 엔트리포인트 스모크 인프라와 게시 번들 검증에 연결됩니다.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning framework-config의 Proxy 기반 env 리팩터는 데코레이터 메타데이터 보존과 직접 관련이 없어 범위를 벗어납니다. 해당 env 리팩터를 별도 PR로 분리하거나, 메타데이터 보존에 꼭 필요한 최소 변경만 남기세요.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 게시된 번들에서 데코레이터 메타데이터를 보존한다는 핵심 변경을 정확히 요약합니다.
Linked Issues check ✅ Passed SWC 의존성 추가, 런타임 import 전환, packed smoke 검증과 Container 기본값/Inject 동작 보강으로 #1338의 핵심 요구를 충족합니다.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/1338-preserve-decorator-metadata

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.

@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown

📊 Benchmark Results

✅ All benchmarks passed

Benchmark p75 Threshold Baseline vs Baseline Status Notes
CrocoApp constructor 8.9μs 30.0ms 8.2μs +8.7% -
CrocoApp lambdaHandler (10 controllers) 380.9μs 50.0ms 258.4μs +47.4% -
Lambda cold-start simulation 438.8μs 80.0ms 418.1μs +5.0% -
Lambda cold-start with headers 392.2μs 80.0ms 369.7μs +6.1% -
Lambda cold-start with binary body 376.4μs 80.0ms 339.1μs +11.0% -
Lambda cold-start with query params 324.1μs 80.0ms 301.3μs +7.6% -
Lambda cold-start with authorizer context 318.6μs 80.0ms 299.8μs +6.3% -
Lambda cold-start realistic scenario 317.6μs 80.0ms 299.2μs +6.2% -
EventBusConfig.start (10 handlers) 1.5μs 10.0ms 1.4μs +5.6% -
EventPublisher.publishNow single event 1.8μs 2.0ms 1.7μs +5.3% -
DefaultHandlerResolver.resolve × 10 0.1μs 5.0ms 0.1μs -11.2% -
Container.get singleton (cold) 75.6μs 5.0ms 70.3μs +7.5% -
Container.register × 50 components 3.5ms 10.0ms 3.2ms +7.0% -
Container.validate (50 components) 3.9ms 20.0ms 3.4ms +15.0% -
Container.get singleton (warm) 1.7μs 500.0μs 1.6μs +1.2% -
TelemetryRuntime.init (lambda preset) 2.1μs 200.0ms 1.1ms -99.8% -
lambdaPreset config creation 1.4μs 2.0ms 1.4μs -0.6% -

Updated: 2026-07-18T04:24:42.648Z · Commit: 80f5388

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/auth-better-auth/src/libs/BetterAuthProvider.ts`:
- Around line 1-5: Replace each file-wide consistent-type-imports suppression
with a localized suppression on the required runtime DI import only:
BetterAuthFactory in packages/auth-better-auth/src/libs/BetterAuthProvider.ts
(lines 1-5), TxManager in
packages/membership-drizzle/src/libs/DrizzleMembershipStore.ts (lines 1-10),
NotificationProviderRegistry in
packages/notifications-core/src/libs/SendNotificationTask.ts (lines 1-7), and
TxManager in packages/onboarding-drizzle/src/libs/DrizzleOnboardingStore.ts
(lines 1-5). Remove the file-level directives while preserving the runtime
imports needed for emitted DI metadata.

In `@packages/framework-config/src/core.ts`:
- Line 29: Defer evaluation of SKIP_ENV_VALIDATION in the framework
configuration flow instead of initializing skipValidation at module import time.
Read and parse process.env.SKIP_ENV_VALIDATION on the first env access, ensuring
later environment changes are observed and invalid boolean values throw at that
access rather than during import.

In `@packages/framework-context/src/libs/Container.ts`:
- Around line 294-298: Update buildDependencyGraph’s dependency filter to
consult getParameterInjectionToken when parameterIndex is beyond node.length,
retaining explicitly `@Inject-declared` dependencies in the static graph while
excluding only parameters without an explicit injection token. Keep the existing
constructor-function and nodeSet checks for included dependencies.

In `@packages/invitation-core/src/libs/DomainPolicyManager.ts`:
- Around line 1-12: Separate only the pure type imports while preserving runtime
imports required for constructor injection: in
packages/invitation-core/src/libs/DomainPolicyManager.ts, move Membership and
MembershipRole to import type; in
packages/invitation-drizzle/src/libs/DrizzleDomainPolicyStore.ts, move
DomainPolicy to import type; and in
packages/invitation-drizzle/src/libs/DrizzleInvitationStore.ts, move Invitation
and InvitationStatus to import type. Keep EventPublisher, MembershipManager,
DomainPolicyStore, and other runtime dependencies unchanged.

In `@packages/transports-http/src/tests/ErrorHandler.spec.ts`:
- Around line 61-66: Update the ErrorHandler container-construction test to
verify the resolved ErrorHandler instance actually contains the logger
registered under LOGGER_TOKEN, rather than only asserting its ErrorHandler type.
Preserve the existing Container.register and Container.set setup while asserting
the injected logger matches mockLogger.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 343b5a35-ca6a-4c5e-9fe8-a8dbd532609a

📥 Commits

Reviewing files that changed from the base of the PR and between 63af081 and 3d98f89.

⛔ Files ignored due to path filters (2)
  • packages/problems-core/src/generated/problem-code-registry.ts is excluded by !**/generated/**
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • .changeset/preserve-decorator-metadata.md
  • docs/problem-code-registry.json
  • package.json
  • packages/analytics-posthog/src/libs/PostHogAnalyticsManager.ts
  • packages/auth-better-auth/src/libs/BetterAuthProvider.ts
  • packages/docs/src/content/docs/en/reference/problem-recovery-cookbook.md
  • packages/features-posthog/src/libs/PostHogFeatureManager.ts
  • packages/framework-config/src/core.ts
  • packages/framework-config/src/tests/Core.spec.ts
  • packages/framework-context/src/libs/Container.ts
  • packages/framework-context/src/tests/FrameworkContext.spec.ts
  • packages/framework-logger/src/Logger.ts
  • packages/invitation-core/src/libs/DomainPolicyManager.ts
  • packages/invitation-core/src/libs/InvitationManager.ts
  • packages/invitation-core/src/libs/RateLimitedInvitationService.ts
  • packages/invitation-drizzle/src/libs/DrizzleDomainPolicyStore.ts
  • packages/invitation-drizzle/src/libs/DrizzleInvitationStore.ts
  • packages/membership-core/src/libs/MembershipManager.ts
  • packages/membership-core/src/libs/MembershipService.ts
  • packages/membership-drizzle/src/libs/DrizzleMembershipStore.ts
  • packages/metering-core/src/libs/MeterRegistry.ts
  • packages/metrics-billing/src/libs/BillingEventHandler.ts
  • packages/notifications-core/src/libs/NotificationService.ts
  • packages/notifications-core/src/libs/SendNotificationTask.ts
  • packages/onboarding-core/src/libs/OnboardingManager.ts
  • packages/onboarding-drizzle/src/libs/DrizzleOnboardingStore.ts
  • packages/search-core/src/libs/sync/SearchAutoSync.ts
  • packages/storage-r2/src/libs/R2StorageProvider.ts
  • packages/transports-http/src/libs/ErrorHandler.ts
  • packages/transports-http/src/tests/ErrorHandler.spec.ts
  • pnpm-workspace.yaml
  • scripts/package-entrypoint-smoke.mts
  • scripts/tests/package-entrypoint-smoke.spec.ts

Comment thread packages/auth-better-auth/src/libs/BetterAuthProvider.ts Outdated
Comment thread packages/framework-config/src/core.ts Outdated
Comment thread packages/framework-context/src/libs/Container.ts Outdated
Comment thread packages/invitation-core/src/libs/DomainPolicyManager.ts Outdated
Comment thread packages/transports-http/src/tests/ErrorHandler.spec.ts
…corator-metadata

# Conflicts:
#	packages/docs/src/content/docs/api/problems-core/src/variables/CROCO_PROBLEM_CODE_REGISTRY.md
@kang-heewon
kang-heewon merged commit 1c843a5 into trunk Jul 18, 2026
8 of 9 checks passed
@kang-heewon
kang-heewon deleted the fix/1338-preserve-decorator-metadata branch July 18, 2026 04:55
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.

[build] Preserve decorator metadata in published package bundles

1 participant