Skip to content

feat(keys-manager): support custom scope providers and wrapper services - #985

Open
HermannBjorgvin wants to merge 1 commit into
jsverse:masterfrom
HermannBjorgvin:feat/keys-manager-custom-providers
Open

feat(keys-manager): support custom scope providers and wrapper services#985
HermannBjorgvin wants to merge 1 commit into
jsverse:masterfrom
HermannBjorgvin:feat/keys-manager-custom-providers

Conversation

@HermannBjorgvin

@HermannBjorgvin HermannBjorgvin commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Adds two options to the keys manager so it can extract keys from projects that wrap the standard Transloco APIs in their own abstractions. Resubmission of jsverse/transloco-keys-manager#249, which was closed when that repository was archived. @shaharkazaz asked for it to be reopened here with a proper design pass.

In our Nx monorepo we wrap Transloco in a shared translations service to enforce conventions and keep future refactoring cheap. Without these options, TKM silently misses every key that flows through the wrapper, which makes find's missing/extra-key enforcement unusable.

What's included

scopeProviderFunctions (--scope-provider-functions) — additional function names treated like provideTranslocoScope when building the scopes map. Both the string form (provideScopedTranslations('todos')) and the object form (provideScopedTranslations({ scope: 'todos', alias: 'todosAlias' })) resolve, since the resolution reuses the same scope-def queries as the built-in provider. Lives in utils/update-scopes-map.ts, threaded from resolve-config.ts and the webpack plugin's incremental path.

serviceNames (--service-names) — additional service class names treated like TranslocoService by the service extractor, covering both constructor injection and inject(...) in property/variable declarations (keys-builder/typescript/service.extractor.ts). The option flows to extractors through ExtractorConfig rather than a separate argument, so the extractor pipeline shape is unchanged.

The TS extraction gate in keys-builder/typescript/index.ts also accounts for custom services: a file that injects TranslationsService but never imports from @jsverse/transloco (the wrapper lives behind its own import path) is still parsed and run through the service extractor, while the fast-path skip for unrelated files is preserved.

Config-file support — both options are also accepted under keysManager in transloco.config.ts (TranslocoGlobalConfig in @jsverse/transloco-utils), consistent with every other keys-manager option:

export default {
  keysManager: {
    scopeProviderFunctions: ["provideScopedTranslations"],
    serviceNames: ["TranslationsService"],
  },
} satisfies TranslocoGlobalConfig;

Tests — a new config-options/custom-providers suite covers custom scope provider resolution (string + object/alias forms) and custom service extraction via both injection styles, including a fixture with no transloco string anywhere in the file to lock in the import-gate behavior.

Design notes — input welcome

Per the discussion on the original PR, flagging the open design questions rather than treating the old diff as settled:

  • Option naming: scopeProviderFunctions / serviceNames are carried over from the original PR. Happy to rename — e.g. customScopeProviders / customServiceNames if you'd rather the names signal they extend rather than replace the built-ins.
  • Config-file support is included (answering the open question from Problem with setting translocoConfig using httpcall in factory, when TranslocoService as dependency anywhere #249 with "yes") — for monorepos this belongs in transloco.config.ts next to the rest of the keys-manager config rather than on every CLI invocation.
  • Matching is name-based, same as the existing provideTranslocoScope/TranslocoService detection — TKM's extraction is syntactic throughout, so the custom names follow the same convention rather than introducing import-path resolution.

PR Checklist

PR Type

  • Feature

What is the current behavior?

Only provideTranslocoScope, TRANSLOCO_SCOPE, and TranslocoService are recognized for scope detection and service key extraction. Keys used through custom wrappers are not extracted, and find reports them as extra/missing incorrectly.

Issue Number: N/A (resubmission of jsverse/transloco-keys-manager#249)

What is the new behavior?

Custom scope provider function names and custom service class names can be registered via CLI flags or transloco.config.ts, and are treated exactly like their built-in counterparts during extraction.

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

Docs for the two new options still need a home — I couldn't find the keys-manager options reference in this repo, so pointers welcome on where to add them (hence the unchecked docs box).

Summary by CodeRabbit

  • New Features

    • Added configuration options for custom translation-scope provider functions.
    • Added support for custom translation service names when extracting translation keys.
    • Custom services are now recognized even without a direct Transloco import.
    • Added support for custom provider and service settings in global configuration and Webpack processing.
  • Tests

    • Added coverage for custom services, scoped translations, and supported configuration formats.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The keys manager now accepts configurable scope-provider functions and wrapper service names. TypeScript extraction detects custom services, and scope mapping detects custom providers. Tests cover custom services and scoped translations. Fun fact: “i18n” abbreviates “internationalization.”

Changes

Custom provider and service support

Layer / File(s) Summary
Configuration contracts and propagation
libs/transloco-keys-manager/src/lib/cli-options.ts, libs/transloco-keys-manager/src/lib/types.ts, libs/transloco-utils/src/lib/transloco-utils.types.ts, libs/transloco-keys-manager/src/lib/keys-builder/utils/extract-keys.ts
Adds repeatable CLI options and configuration fields for custom scope-provider functions and service names. Passes service names to extractors.
Custom service detection
libs/transloco-keys-manager/src/lib/keys-builder/typescript/index.ts, libs/transloco-keys-manager/src/lib/keys-builder/typescript/service.extractor.ts
Detects configured wrapper services without a direct TranslocoService import and extracts their translation calls.
Configurable scope-provider detection
libs/transloco-keys-manager/src/lib/utils/update-scopes-map.ts, libs/transloco-keys-manager/src/lib/utils/resolve-config.ts, libs/transloco-keys-manager/src/lib/webpack-plugin/webpack-plugin.ts
Builds scope-provider queries and detection patterns from the default and configured provider names.
Custom provider and service tests
libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/config-options/custom-providers/*, libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/buildTranslationFiles.spec.ts, libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/build-translation-utils.ts, libs/transloco-keys-manager/src/lib/tests/warn-unsupported-options.spec.ts
Tests custom service extraction, aliased scopes, both file formats, and shared CLI option handling.

Possibly related issues

Possibly related PRs

  • jsverse/transloco#943 — Modifies the same CLI and TypeScript extraction infrastructure used by this change.

Suggested reviewers: shaharkazaz

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ 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%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes support for custom scope providers and wrapper services in the keys manager.
Description check ✅ Passed The description follows the template, explains the behavior and design, identifies tests, and clearly notes that documentation remains pending.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install timed out. The project may have too many dependencies for the sandbox.


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.

@pkg-pr-new

pkg-pr-new Bot commented Aug 12, 2026

Copy link
Copy Markdown

Open in StackBlitz

@jsverse/transloco

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco@985

@jsverse/transloco-keys-manager

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-keys-manager@985

@jsverse/transloco-locale

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-locale@985

@jsverse/transloco-messageformat

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-messageformat@985

@jsverse/transloco-optimize

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-optimize@985

@jsverse/transloco-persist-lang

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-persist-lang@985

@jsverse/transloco-persist-translations

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-persist-translations@985

@jsverse/transloco-preload-langs

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-preload-langs@985

@jsverse/transloco-schematics

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-schematics@985

@jsverse/transloco-scoped-libs

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-scoped-libs@985

@jsverse/transloco-utils

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-utils@985

@jsverse/transloco-validator

npm i https://pkg.pr.new/jsverse/transloco/@jsverse/transloco-validator@985

commit: c5cdd86

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

🧹 Nitpick comments (1)
libs/transloco-keys-manager/src/lib/utils/update-scopes-map.ts (1)

30-43: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Validate custom provider names before interpolation.

scopeProviderFunctions is inserted directly into a tsquery selector and a RegExp. An empty or malformed name can break selector parsing, broaden the pre-scan to unrelated files, or cause excessive backtracking while TypeScript files are scanned. Restrict each value to a valid TypeScript identifier and escape values used in the regular expression. Add tests for rejected names.

Verify that the CLI and configuration normalization apply the same validation. This is a local and CI robustness issue, not a remote-user injection path.

Fun fact: i18n is a numeronym with 18 letters between i and n.

Static analysis flags the dynamic regular-expression construction.

Also applies to: 94-105

🤖 Prompt for 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.

In `@libs/transloco-keys-manager/src/lib/utils/update-scopes-map.ts` around lines
30 - 43, Validate scopeProviderFunctions entries as non-empty valid TypeScript
identifiers during shared CLI/config normalization, rejecting invalid names
consistently before they reach these helpers. In buildFunctionProviderQuery,
only interpolate validated identifiers into selectors; in buildProviderRegex,
escape each name before constructing the regex while preserving the built-in
provider names. Add tests covering rejected names and the normalized validation
path.

Source: Linters/SAST tools

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

Nitpick comments:
In `@libs/transloco-keys-manager/src/lib/utils/update-scopes-map.ts`:
- Around line 30-43: Validate scopeProviderFunctions entries as non-empty valid
TypeScript identifiers during shared CLI/config normalization, rejecting invalid
names consistently before they reach these helpers. In
buildFunctionProviderQuery, only interpolate validated identifiers into
selectors; in buildProviderRegex, escape each name before constructing the regex
while preserving the built-in provider names. Add tests covering rejected names
and the normalized validation path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c5a7ed05-f7e8-47d4-b089-730b530e8d31

📥 Commits

Reviewing files that changed from the base of the PR and between 3f1cd86 and c5cdd86.

📒 Files selected for processing (16)
  • libs/transloco-keys-manager/src/lib/cli-options.ts
  • libs/transloco-keys-manager/src/lib/keys-builder/typescript/index.ts
  • libs/transloco-keys-manager/src/lib/keys-builder/typescript/service.extractor.ts
  • libs/transloco-keys-manager/src/lib/keys-builder/utils/extract-keys.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/build-translation-utils.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/buildTranslationFiles.spec.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/config-options/custom-providers/custom-providers-spec.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/config-options/custom-providers/src/custom-scope-provider.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/config-options/custom-providers/src/custom-service-constructor.ts
  • libs/transloco-keys-manager/src/lib/tests/buildTranslationFiles/config-options/custom-providers/src/custom-service-inject.ts
  • libs/transloco-keys-manager/src/lib/tests/warn-unsupported-options.spec.ts
  • libs/transloco-keys-manager/src/lib/types.ts
  • libs/transloco-keys-manager/src/lib/utils/resolve-config.ts
  • libs/transloco-keys-manager/src/lib/utils/update-scopes-map.ts
  • libs/transloco-keys-manager/src/lib/webpack-plugin/webpack-plugin.ts
  • libs/transloco-utils/src/lib/transloco-utils.types.ts

@HermannBjorgvin

Copy link
Copy Markdown
Contributor Author

@shaharkazaz holding off on responding to the code-rabbit reviews until everyone is happy with the design/approach to this feature.

@medbenmakhlouf medbenmakhlouf added enhancement New feature or request keys-manager Related to the @jsverse/transloco-keys-manager package area: scope Scope resolution, lazy-loaded scopes, TRANSLOCO_SCOPE labels Sep 2, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: scope Scope resolution, lazy-loaded scopes, TRANSLOCO_SCOPE enhancement New feature or request keys-manager Related to the @jsverse/transloco-keys-manager package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants