fix: translation service issue and ng-packagr issues#21296
Open
npapp-dev002 wants to merge 4 commits intodevelopfrom
Open
fix: translation service issue and ng-packagr issues#21296npapp-dev002 wants to merge 4 commits intodevelopfrom
npapp-dev002 wants to merge 4 commits intodevelopfrom
Conversation
- Fix greedy regex in declarationMergingPostStep: change from /declare module '([^\@spartacus].+)'/g to /declare module '([^'@][^']*)'/g to prevent matching across multiple declare module statements on one line - Add repairNgPackagrCorruptions() function to fix 10 known ng-packagr bundler corruptions in dist/core/types/spartacus-core.d.ts ng-packagr bug (ng-packagr/ng-packagr#3085): When bundling .d.ts files, ng-packagr uses a greedy match for 'declare module "path" { body }' blocks which consumes surrounding code, embedding inline '"./spartacus-core"' fragments in declarations for: - GlobalMessageConfig (declare module header) - ProductScope enum (MULTI_DIMENSIONAL_AVAILABILITY + LoadingScopes) - AnonymousConsentsConfig (showAnonymousConsents property) - I18nConfig (debug logging JSDoc comment) - FeaturesConfig (lazy-loading JSDoc comment) - FeatureModuleConfig (dependencies + cmsComponents + CmsConfig) - CmsStructureConfig (JSDoc + class declaration) - CmsService (refreshComponent JSDoc + method signature) - HTTP_TIMEOUT_CONFIG (JSDoc + constant declaration) - UsersSelectors (getPreferencesLoaderState export) The repair function runs before AND after propagateDeclarationMerging to handle both the raw ng-packagr output and post-propagation variants.
The repair pattern for AnonymousConsentsConfig.consentManagementPage
was only replacing the corrupted line with the property declaration,
but was missing the JSDoc comment body and closing '*/'.
The ng-packagr corruption consumed:
'* Show all anonymous consents on the consent management page.\n*/\nshowAnonymousConsents?: boolean;'
leaving an unclosed '/**' opener in the output, which caused TypeScript
to treat 'showAnonymousConsents?: boolean;' as part of the block comment,
making the property invisible to type checking.
Fixes: TS2339 Property 'showAnonymousConsents' does not exist on type
'{ hideConsents?: string[] | undefined; }'
Contributor
Merge Checks Failed |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a chain of TypeScript compilation errors caused by two independent bugs: a type mismatch in the i18next translation service, and a long-standing issue with ng-packagr's
.d.tsbundler corrupting the builtdist/coretype declarations.Problems Fixed
1.
TS2345— i18next translation service type errorFile:
projects/core/src/i18n/i18next/i18next-translation.service.ts:72The call to
this.i18next.t(namespacedKeys, options as TOptions)caused aTS2345error because theTOptionstype is not compatible with the overloaded signatures ofi18next.t()in newer versions ofi18next.Fix: Changed
options as TOptions→options as anyand removed the unusedTOptionsimport.2.
TS2339— Missing properties/methods on types from@spartacus/coreMultiple builds (
storefrontlib,smartedit, and others) failed withTS2339errors such as:Property 'showAnonymousConsents' does not exist on type '{ hideConsents?: string[] | undefined; }'Property 'clearComponentState' does not exist on type 'CmsService'CmsStructureConfig,HTTP_TIMEOUT_CONFIG,PageMetaConfignot foundRoot cause: ng-packagr has a known bug (ng-packagr#3085) where its
.d.tsbundler uses a greedy regex to replacedeclare module "path" { body }augmentation blocks. When multiple such blocks appear near each other, the greedy match consumes surrounding code and replaces it with an inline"./spartacus-core"fragment, corrupting the surrounding type declarations indist/core/types/spartacus-core.d.ts.This affected 10 locations in the bundled type file, silently dropping or garbling declarations for:
GlobalMessageConfigmodule headerdeclare moduleblockProductScope.MULTI_DIMENSIONAL_AVAILABILITYenum valueLoadingScopesmodule blockAnonymousConsentsConfig.consentManagementPage.showAnonymousConsentsTS2339in consent-management componentI18nConfigdebug logging JSDocFeaturesConfiglazy-loading JSDocFeatureModuleConfig.dependencies+cmsComponents+CmsConfigclassCmsStructureConfigclass declarationTS2339CmsService.refreshComponent+clearComponentStateTS2339in smarteditHTTP_TIMEOUT_CONFIGconstant declarationTS2339UsersSelectors.getPreferencesLoaderStateexportA secondary bug was also found in the custom
declarationMergingPostStepNx builder (tools/build-lib/declaration-merging/index.ts): its regex/declare module '([^\@spartacus].+)'/gused a greedy.+which could itself match across multipledeclare modulestatements on the same line, compounding the corruption.Fix: Two changes were made to
tools/build-lib/declaration-merging/index.ts:Fixed the greedy regex — changed from
/declare module '([^\@spartacus].+)'/gto/declare module '([^'@][^']*)'/g(non-greedy, stops at the first closing quote).Added
repairNgPackagrCorruptions()— a new function that applies targeted string repairs for all 10 known corruption patterns. It runs both before and afterpropagateDeclarationMergingto handle the raw ng-packagr output and the post-propagation variants. Each repair replaces the garbled fragment with the correct TypeScript content derived from the original source files.Files Changed
projects/core/src/i18n/i18next/i18next-translation.service.tsoptions as TOptions→options as anytools/build-lib/declaration-merging/index.tsrepairNgPackagrCorruptions()tools/build-lib/declaration-merging/index.jstools/build-lib/augmented-types/index.jsnx.json"analytics": false) added automatically by Nx CLITesting
npx nx build core --skip-nx-cache→ ✅ All 10 ng-packagr corruptions repaired on every buildnpx nx build storefrontlib --skip-nx-cache→ ✅ No TypeScript errorsnpx nx build smartedit --skip-nx-cache→ ✅ No TypeScript errorsWhat broke and when
The build started failing on March 27, 2026, when commit
5517dfe90cmergedorigin/release/221121.9.xintodevelop. That merge brought in apackage-lock.jsonupdate that bumped two packages:ng-packagr21.2.021.2.2rollup-plugin-dts6.2.36.4.1The
ng-packagrbump itself is cosmetic — the real breaking change isrollup-plugin-dtsgoing from 6.2.3 → 6.4.1.What
rollup-plugin-dtsdoesrollup-plugin-dtsis the engine ng-packagr uses to bundle all individual compiled.d.tsfiles into a singlespartacus-core.d.ts. Among other things, it must rewritedeclare module "some/relative/path" { ... }augmentation blocks so they all point to the single output file instead of relative paths.What changed in 6.4.1
Version 6.2.3 handled augmentation blocks only in the
renderChunkphase. Version 6.4.1 introduced a completely new two-phase approach:Phase 1 —
transform()(per-file, before bundling):Phase 2 —
ModuleDeclarationFixerinrenderChunk()(after bundling):The intention is sound: embed absolute path markers before bundling, then resolve them after. However, the implementation has a bug.
The bug in
ModuleDeclarationFixerAfter rollup bundles all the files, multiple augmentation blocks from different source files end up concatenated in a single
.d.ts. Each one has the/*dts-resolved:...*/marker comment embedded inline:ModuleDeclarationFixer.fix()callsparse(chunk.fileName, code.toString())to re-parse the bundled output as TypeScript, then walksthis.source.statements. The/*dts-resolved:...*/comment is embedded in the source betweennode.name.getEnd()andnode.body.getStart().The bug: TypeScript's parser computes
node.body.getStart()including leading trivia (whitespace and comments). When the/*dts-resolved:...*/marker is a block comment sitting between the module name and the opening{, TypeScript considers that comment as leading trivia of the body. Depending on what other content is between the twodeclare moduleblocks, the trivia boundary may extend further than expected — causingnode.body.getStart()to point past the opening{of the next block.The
overwrite(node.name.getStart(), node.body.getStart(), ...)call then replaces a range that spans across multiple declarations, consuming the code between them and replacing it with just"./spartacus-core". This is the corruption:Why it didn't break before (6.2.3)
In 6.2.3, the
renderChunkpipeline ended withTypeOnlyFixer— there was noModuleDeclarationFixerand noencodeResolvedModule. Augmentation block path rewriting was handled differently (by a simpler namespace-aware string manipulation that did not involve embedded marker comments). The/*dts-resolved:...*/mechanism is entirely new in 6.4.x.Why
clearComponentStatewas also affectedCommit
3814342cae(January 27, 2026) addedclearComponentState()toCmsService. This new method was introduced long before the ng-packagr bump. However, it sits adjacent torefreshComponent()in the source, which is declared in an augmentation block context. When the 6.4.1 bug consumedrefreshComponent's JSDoc, it swept pastclearComponentStatetoo — dropping it entirely from the bundled output. The method was never missing from the source; it was silently erased by the bundler bug.Complete timeline
Recommended follow-up
Report upstream: File a bug against
rollup-plugin-dts≥ 6.3.x at https://github.com/Swatinem/rollup-plugin-dts with the specific/*dts-resolved:*/+ adjacent augmentation blocks reproduction case.Pin the version: Until the upstream fix lands, consider pinning
rollup-plugin-dtsto6.2.3inpackage.jsonto avoid the regression on fresh installs:Remove the workaround: Once the upstream bug is fixed and a patched version of
rollup-plugin-dtsis available, therepairNgPackagrCorruptions()function intools/build-lib/declaration-merging/index.tsshould be removed.