-
-
Notifications
You must be signed in to change notification settings - Fork 167
Fix VALUE variables from scripts reaching templates #1060
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
WalkthroughThis PR fixes a bug where variables set in user scripts were not being passed to the template phase. It introduces key resolution logic to handle variable lookups, treats null values as concrete (non-prompting) variables, adds snapshot/restore functionality for variable state, and integrates these changes across the formatter, preflight, and API layers. Changes
Sequence DiagramsequenceDiagram
participant Script as User Script
participant QA as QuickAddApi
participant Fmt as Formatter
participant VS as Value Syntax
participant Template as Templater
Script->>QA: Set variables (e.g., title, backdrop)
QA->>QA: Snapshot variables (if shouldClearVariables)
QA->>Fmt: format(template, variables)
Fmt->>Fmt: Process {{VALUE:*}} tokens
Fmt->>VS: resolveExistingVariableKey(variables, key)
VS->>VS: Check exact match
alt No exact match
VS->>VS: Derive base key, try case-insensitive
end
VS-->>Fmt: Return resolved key (or null)
alt Resolved key found
Fmt->>Fmt: Use resolved key for lookup
Fmt->>Fmt: hasConcreteVariable (null = concrete)
Fmt-->>QA: Substituted value (no prompt)
else No resolved key
Fmt-->>QA: Prompt user
end
alt shouldClearVariables was true
QA->>QA: Restore from snapshot
end
QA-->>Template: Fully formatted template
Template->>Template: Render note
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this 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
🧹 Nitpick comments (1)
src/utils/valueSyntax.ts (1)
50-70: Key resolution function correctly implements the described lookup order.The implementation follows the PR's resolution strategy:
- Exact key match (with non-undefined value)
- Base key fallback for label-scoped tokens
- Case-insensitive unique match
The guard for empty
variableKeyat line 54 prevents unnecessary processing.Minor: Consider caching the Map.get() result
Line 61 calls both
vars.has(candidate)andvars.get(candidate), resulting in two lookups. You could slightly optimize by using onlyget()and checking againstundefined:for (const candidate of candidates) { - if (vars.has(candidate) && vars.get(candidate) !== undefined) { + const value = vars.get(candidate); + if (value !== undefined) { return candidate; }This is a minor optimization and the current code is perfectly correct.
📜 Review details
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
src/formatters/formatter-issue929-integration.test.ts(1 hunks)src/formatters/formatter.test.ts(3 hunks)src/formatters/formatter.ts(6 hunks)src/preflight/runOnePagePreflight.ts(2 hunks)src/quickAddApi.ts(3 hunks)src/utils/valueSyntax.test.ts(2 hunks)src/utils/valueSyntax.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (5)
**/*.{ts,tsx,mts,mjs,js,json}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,mts,mjs,js,json}: Use tab indentation with width 2 in TypeScript and configuration files (enforced by Biome).
Follow an 80-character line guide (enforced by Biome).
Files:
src/quickAddApi.tssrc/utils/valueSyntax.test.tssrc/preflight/runOnePagePreflight.tssrc/formatters/formatter.tssrc/utils/valueSyntax.tssrc/formatters/formatter-issue929-integration.test.tssrc/formatters/formatter.test.ts
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Use camelCase for variables and functions in TypeScript.
Prefer type-only imports in TypeScript.
Files:
src/quickAddApi.tssrc/utils/valueSyntax.test.tssrc/preflight/runOnePagePreflight.tssrc/formatters/formatter.tssrc/utils/valueSyntax.tssrc/formatters/formatter-issue929-integration.test.tssrc/formatters/formatter.test.ts
**/*.{ts,tsx,svelte}
📄 CodeRabbit inference engine (AGENTS.md)
Use PascalCase for classes and Svelte components.
Files:
src/quickAddApi.tssrc/utils/valueSyntax.test.tssrc/preflight/runOnePagePreflight.tssrc/formatters/formatter.tssrc/utils/valueSyntax.tssrc/formatters/formatter-issue929-integration.test.tssrc/formatters/formatter.test.ts
src/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Route logging through the
loggerutilities for consistent output.
Files:
src/quickAddApi.tssrc/utils/valueSyntax.test.tssrc/preflight/runOnePagePreflight.tssrc/formatters/formatter.tssrc/utils/valueSyntax.tssrc/formatters/formatter-issue929-integration.test.tssrc/formatters/formatter.test.ts
src/{engine,services,utils}/**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
Structure production code so Obsidian dependencies are injected behind interfaces to enable unit testing without loading real Obsidian modules.
Files:
src/utils/valueSyntax.test.tssrc/utils/valueSyntax.ts
🧬 Code graph analysis (3)
src/utils/valueSyntax.test.ts (1)
src/utils/valueSyntax.ts (2)
resolveExistingVariableKey(50-70)buildValueVariableKey(17-25)
src/preflight/runOnePagePreflight.ts (2)
src/preflight/RequirementCollector.ts (1)
FieldRequirement(18-35)src/utils/valueSyntax.ts (1)
resolveExistingVariableKey(50-70)
src/formatters/formatter.ts (1)
src/utils/valueSyntax.ts (1)
resolveExistingVariableKey(50-70)
🔇 Additional comments (16)
src/formatters/formatter-issue929-integration.test.ts (1)
172-187: Test expectations correctly reflect the new null-handling semantics.The updated test properly validates the behavioral change where:
nullis treated as an explicit value → converts to empty string, no promptundefinedtriggers fallback behavior → prompts and uses file basenameThis aligns with the PR objective distinguishing
null(intentional) fromundefined(missing).src/preflight/runOnePagePreflight.ts (2)
28-28: LGTM!Import added for the new centralized key resolution utility.
238-244: Unresolved input detection now uses centralized key resolution.The updated filter correctly leverages
resolveExistingVariableKeyto determine which inputs are already satisfied. This ensures:
- Exact key matches are recognized
- Base keys for label-scoped tokens are checked
- Case-insensitive unique matches are honored
The negation logic (
!resolveExistingVariableKey(...)) properly identifies truly unresolved inputs that need prompting.src/quickAddApi.ts (2)
34-48: Snapshot/restore helpers correctly preserve variable state.The implementation properly:
- Creates a shallow copy of Map entries for snapshot
- Clears and repopulates the Map on restore, maintaining the original reference
This approach ensures format-local variables are cleaned up while preserving pre-existing script values.
230-248: Variable restoration logic correctly fixes the clearing issue.The snapshot-restore pattern ensures that when
shouldClearVariablesis true:
- Pre-existing variables are captured before formatting
- Formatting proceeds normally (may add temporary variables)
- Original state is restored afterward
This preserves script-provided variables across formatting calls, fixing the core issue where
quickAddApi.format()was clearing the shared variables map.src/formatters/formatter.test.ts (2)
13-18:hasConcreteVariablelogic correctly updated for new semantics.The updated implementation properly distinguishes:
undefined→ not concrete (triggers prompt)null→ concrete (intentional empty value, no prompt)The comment accurately documents this behavior change.
174-179: Test correctly reflects null as a concrete value.The test now validates that:
- Setting a variable to
nulldoes not trigger a prompt- The result is an empty string (null coerced to "")
This is consistent with the PR's behavioral change where
nullis treated as an explicit value.src/utils/valueSyntax.test.ts (1)
47-84: Comprehensive test coverage forresolveExistingVariableKey.The test suite covers all key resolution scenarios:
- Exact key matches
- Base key fallback for label-scoped tokens
- Case-insensitive unique matches
- Ambiguous case-insensitive matches returning
null- Distinction between
undefined(missing) andnull(present)These tests validate the resolution order described in the PR: exact key → base key → case-insensitive unique match.
src/utils/valueSyntax.ts (1)
33-48: Case-insensitive matching helper is well-implemented.The function correctly:
- Performs lowercase comparison for case-insensitivity
- Skips
undefinedvalues (treating them as missing)- Returns
nullfor ambiguous matches (multiple keys differ only by case)- Returns the actual key (preserving original casing) when a unique match is found
src/formatters/formatter.ts (7)
29-32: LGTM! Import additions support key resolution logic.The new imports are used correctly throughout the file to enable variable key resolution with label-scope and case-insensitive matching.
63-68: LGTM! Null is correctly treated as a concrete value.The updated logic ensures that only
undefinedis considered missing, whilenull, empty strings, and other falsy values are treated as intentional. This aligns with the PR objective to honor explicit null values without prompting.
153-156: LGTM! Null-to-empty-string conversion is appropriate.The special handling for the reserved
valuevariable correctly treats null as an explicit (non-prompting) value while converting it to an empty string for template replacement. This ensures string operations work correctly.
299-327: LGTM! Conditional prompting prevents re-asking for existing variables.The logic correctly skips prompting when a resolved key is found, which preserves script-provided variables. When prompting is necessary, setting the value under the original
variableKeyensures future lookups work correctly.
329-332: LGTM! Effective key pattern ensures correct variable lookups.The effectiveKey correctly prioritizes the resolved key (for case/label-scoped matches) while falling back to the original key when needed. This enables consistent variable access throughout the replacement logic.
345-346: LGTM! Replacement uses the effective key consistently.The replacement value is correctly retrieved using
effectiveKey, maintaining consistency with the rawValue lookup and ensuring script-provided variables are used regardless of key casing or label-scope differences.
293-296: LGTM! Variable resolution logic correctly handles key matching.The resolution call enables finding variables set by scripts even when keys differ by label-scope or case. For each candidate key (exact first, then base key if labeled), the function tries an exact match with undefined check, then falls back to a case-insensitive match. This properly handles edge cases: ambiguous case-insensitive matches return null, undefined values are treated as missing, and null values are allowed as valid variables.
Summary
Problem
Scripts can set QuickAdd.variables/params.variables correctly, but subsequent Template steps still prompt for {{VALUE:...}} placeholders. Two failure modes were observed:
Fix
Behavior changes / Notes
Test Plan
Issue
Fixes #1059
Summary by CodeRabbit
Bug Fixes
Tests
✏️ Tip: You can customize this high-level summary in your review settings.