Skip to content

feat(core/formatters): support variable resolution in replace() first argument#793

Merged
Viren070 merged 6 commits intoViren070:mainfrom
kRYstall9:main
Mar 18, 2026
Merged

feat(core/formatters): support variable resolution in replace() first argument#793
Viren070 merged 6 commits intoViren070:mainfrom
kRYstall9:main

Conversation

@kRYstall9
Copy link
Copy Markdown
Contributor

@kRYstall9 kRYstall9 commented Mar 8, 2026

This feature makes the replace method work with any formatter variable, such as {stream.title}, {addon.name} etc...
This might be useful for any person who wants to take their custom formatter any step forward.

AS IS

filename: Movie.Title.2023.2160p.BluRay.HEVC.DV.TrueHD.Atmos.7.1.iTA.ENG-GROUP.mkv
{stream.filename::replace('.', ' ')::replace('{stream.title}', '')} replaces all the dots with a whitespace but it doesn't replace the stream title (Movie Title in this case) with an empty string

TO BE

filename: Movie.Title.2023.2160p.BluRay.HEVC.DV.TrueHD.Atmos.7.1.iTA.ENG-GROUP.mkv
{stream.filename::replace('.', ' ')::replace('{stream.title}', '')} replaces all the dots with a whitespace and it does replace the stream title (Movie Title in this case) with an empty string.
So it will result in 2023 2160p BluRay HEVC DV TrueHD Atmos 7 1 iTA ENG-GROUP mkv

Resolves #790

Summary by CodeRabbit

  • Improvements
    • Replace operations now resolve dynamic placeholders at runtime before performing replacements; errors or empty resolutions preserve the original placeholder to avoid unintended broad matches.
    • Modifier application carries runtime value-resolution context through the formatting pipeline, allowing multi-modifier chains to operate on resolved values.
    • No breaking public API changes.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 8, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b06fc4fa-f3ba-4075-b448-0b9d28ab0391

📥 Commits

Reviewing files that changed from the base of the PR and between 8025bc1 and 2b84426.

📒 Files selected for processing (1)
  • packages/core/src/formatters/base.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/src/formatters/base.ts

Walkthrough

This change makes replace(...) resolve inner {variable} expressions using parseModifiedVariable(parseValue) before replacing, and threads an optional parseValue through applySingleModifier to support modifier-aware resolution.

Changes

Cohort / File(s) Summary
Formatter core
packages/core/src/formatters/base.ts
Resolve {variable}-style keys inside replace(...) by parsing the inner variable with parseModifiedVariable(parseValue); if resolution is error/null/empty, keep original key. Extend internal applySingleModifier signature to accept optional parseValue and propagate it through modifier application calls.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested reviewers

  • Viren070

Poem

🐰 I hopped through strings and curly braces bright,
I chased the inner names until they came to light.
Replacements now follow the rabbit's trail,
No empty swaps, no accidental gale.
A nimble hop, a tidy file — all right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: enabling variable resolution in the replace() method's first argument, which directly aligns with the core functionality introduced in this PR.
Linked Issues check ✅ Passed The PR implementation fully satisfies issue #790 requirements: variable expressions are resolved before replacement, allowing dynamic substitution of metadata-derived substrings instead of only hardcoded strings.
Out of Scope Changes check ✅ Passed All changes remain focused on the replace() method variable resolution feature; the modification to applySingleModifier signature and parseValue propagation are necessary implementation details for this feature.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

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.

Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/formatters/base.ts`:
- Around line 899-917: The dynamic replace path can resolve a formatter variable
to an empty string and then call variable.replaceAll('', replaceKey), which
inserts replaceKey between every character; in the replace handling in base.ts
(the branch using shouldBeUndefined, key, replaceKey and
parseModifiedVariable/parseValue) add a guard after resolving resolvedKey: if
resolvedKey is an empty string, short-circuit and return the original variable
(no-op) instead of calling variable.replaceAll; keep existing behavior for
non-empty resolvedKey and preserve use of parseModifiedVariable/parseValue.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2c7bdc5b-b11e-4a3b-905c-54003377c1ea

📥 Commits

Reviewing files that changed from the base of the PR and between 2ce0b3a and fdddcc5.

📒 Files selected for processing (1)
  • packages/core/src/formatters/base.ts

Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/formatters/base.ts`:
- Around line 899-920: The code currently falls back to using the literal
"{...}" placeholder as the search key when parseModifiedVariable resolution
fails, which can silently become a no-op or corrupt strings; inside the branch
that handles key.startsWith('{') && key.endsWith('}') replace the current
swallowing logic with an explicit guard: after calling
this.parseModifiedVariable(innerVar, fullStringModifiers) and invoking
resolvedFn(parseValue), if resolved.error is present OR resolved.result == null
then return variable immediately (do not proceed to replaceAll); only set
resolvedKey = String(resolved.result) and continue if resolved.result is
non-null and non-empty, otherwise return variable to avoid empty-string
replacement. Ensure this change is applied where resolvedKey, resolved,
parseModifiedVariable, and variable.replaceAll are referenced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 47256978-f181-41b0-84c7-838f30e83fc1

📥 Commits

Reviewing files that changed from the base of the PR and between fdddcc5 and 4d69935.

📒 Files selected for processing (1)
  • packages/core/src/formatters/base.ts

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Copy link
Copy Markdown
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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/formatters/base.ts`:
- Around line 899-921: The guard allowing malformed splits should be tightened:
in the replace-argument handling (the block using variables key, replaceKey,
shouldBeUndefined inside the formatter method that calls
this.parseModifiedVariable and ultimately does variable.replaceAll), change the
condition from if (!shouldBeUndefined && key && replaceKey !== undefined) to
require shouldBeUndefined === undefined (or implement a small top-level scanner
to parse the two arguments instead of content.split), so that quoted/nested
commas (e.g., replace('{stream.title::replace('.', ' ')}', '')) do not slip
through and produce broken key/replaceKey fragments; ensure the rest of the
logic (resolving {var} via this.parseModifiedVariable, checking
resolved.error/result, and using resolvedKey.length check before
variable.replaceAll) remains the same.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 04e2e25d-f68a-4530-a7c6-055e8b10d840

📥 Commits

Reviewing files that changed from the base of the PR and between 4d69935 and 8025bc1.

📒 Files selected for processing (1)
  • packages/core/src/formatters/base.ts

Comment thread packages/core/src/formatters/base.ts Outdated
@kRYstall9
Copy link
Copy Markdown
Contributor Author

Hi @Viren070! I've addressed all the CodeRabbit suggestions. Could you take a look when you have a chance? Thanks!

@Viren070 Viren070 merged commit 0de87f1 into Viren070:main Mar 18, 2026
3 checks passed
@Viren070 Viren070 mentioned this pull request Mar 18, 2026
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.

feature request: Enhance replace method for formatters

2 participants