feat: template-based editor url paths#1115
feat: template-based editor url paths#1115briantstephan wants to merge 11 commits into2026-custom-components-templatesfrom
Conversation
commit: |
32d23b5 to
0e32dad
Compare
WalkthroughThis pull request adds dynamic editor template routing and configuration naming to the visual-editor Vite plugin. It introduces a new Sequence DiagramsequenceDiagram
participant Plugin as Vite Plugin (plugin.ts)
participant RegistryGen as Registry Generator
participant EditorRoute as Editor Route Utils
participant EditTemplate as Edit Template
Plugin->>RegistryGen: generateRegistryTemplateFiles()
RegistryGen->>RegistryGen: collect registry templates
RegistryGen->>RegistryGen: updateTemplateManifest() -> availableTemplates
RegistryGen->>EditorRoute: getEditorTemplateInfoFromTemplateNames(availableTemplates)
EditorRoute->>EditorRoute: classify templates (legacy, shared, custom)
EditorRoute-->>RegistryGen: { path, configName }
RegistryGen->>EditTemplate: read edit.tsx content
RegistryGen->>EditorRoute: injectEditorTemplateInfo(content, info)
EditorRoute->>EditorRoute: replace placeholders or apply regex patches
EditorRoute-->>RegistryGen: updated content
RegistryGen->>EditTemplate: write updated edit.tsx
Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 2✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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.
Actionable comments posted: 2
🤖 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/visual-editor/src/vite-plugin/editorRoute.ts`:
- Around line 88-100: The current injection only handles EDIT_PATH_PLACEHOLDER
and EDIT_PATH_DECLARATION_PATTERN and throws if neither is found; add a
migration step that detects the legacy getPath form (match the getPath function
definition / return expression in updatedContent) and replace it with the modern
declaration form (e.g. `const editPath = "<editorTemplateInfo.path>"` or swap in
EDIT_PATH_PLACEHOLDER then replace) before throwing, so updatedContent is
upgraded in place; update the logic around EDIT_PATH_PLACEHOLDER,
EDIT_PATH_DECLARATION_PATTERN and the throw to first test for and transform the
legacy getPath shape (using the same editorTemplateInfo.path) and add a
regression test that runs the plugin against an older src/templates/edit.tsx
containing getPath to ensure the file is migrated and build no longer fails.
In `@packages/visual-editor/src/vite-plugin/registryTemplateGenerator.ts`:
- Around line 949-962: The getAvailableTemplateNames function currently builds
available templates from PRESERVED_EDIT_REGISTRY_KEYS and the manifest but can
omit an on-disk src/templates/main.tsx; update getAvailableTemplateNames to also
detect and include the physical main template by checking
fs.existsSync(path.join(rootDir, "src", "templates", "main.tsx")) (or
equivalent) and ensure "main" is included in the returned set alongside
builtInTemplateNames and manifestTemplateNames so generateRegistryTemplateFiles
and the initial resolver see the same available template list; reference the
getAvailableTemplateNames function, PRESERVED_EDIT_REGISTRY_KEYS,
manifestTemplateNames, and generateRegistryTemplateFiles when making this
change.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 54f6a37f-6fdb-4103-87b0-254568c876da
📒 Files selected for processing (6)
packages/visual-editor/src/vite-plugin/editorRoute.test.tspackages/visual-editor/src/vite-plugin/editorRoute.tspackages/visual-editor/src/vite-plugin/plugin.tspackages/visual-editor/src/vite-plugin/registryTemplateGenerator.test.tspackages/visual-editor/src/vite-plugin/registryTemplateGenerator.tspackages/visual-editor/src/vite-plugin/templates/edit.tsx
There was a problem hiding this comment.
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/visual-editor/src/vite-plugin/editorRoute.ts`:
- Around line 7-15: The current regex constants (EDIT_PATH_DECLARATION_PATTERN,
LEGACY_GET_PATH_BLOCK_PATTERN, LEGACY_GET_PATH_EXPRESSION_PATTERN,
EDIT_TEMPLATE_NAME_DECLARATION_PATTERN, EDIT_CONFIG_NAME_PROPERTY_PATTERN) only
match double-quoted literals and require a trailing comma; update these patterns
to accept both single and double quotes (e.g. ["']) and make the comma after the
name property optional so reinjection won't break when formatters change quotes
or remove trailing commas; apply the same relaxed patterns to the other
occurrences referenced (lines ~97–135 and ~139–166) or alternatively replace
this string-based approach with an AST-based reinjection using ts-morph
consistent with registryTemplateGenerator.ts.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: b0a10a39-64e5-46dd-9527-2c1998f18696
📒 Files selected for processing (4)
packages/visual-editor/src/vite-plugin/editorRoute.test.tspackages/visual-editor/src/vite-plugin/editorRoute.tspackages/visual-editor/src/vite-plugin/registryTemplateGenerator.test.tspackages/visual-editor/src/vite-plugin/registryTemplateGenerator.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- packages/visual-editor/src/vite-plugin/editorRoute.test.ts
- packages/visual-editor/src/vite-plugin/registryTemplateGenerator.test.ts
- packages/visual-editor/src/vite-plugin/registryTemplateGenerator.ts
| const EDIT_PATH_DECLARATION_PATTERN = /const editPath = ".*?";/; | ||
| const LEGACY_GET_PATH_BLOCK_PATTERN = | ||
| /export const getPath:\s*GetPath<TemplateProps>\s*=\s*\(\)\s*=>\s*\{\s*return\s+(".*?");\s*\};/; | ||
| const LEGACY_GET_PATH_EXPRESSION_PATTERN = | ||
| /export const getPath:\s*GetPath<TemplateProps>\s*=\s*\(\)\s*=>\s*(".*?");/; | ||
| const EDIT_TEMPLATE_NAME_DECLARATION_PATTERN = | ||
| /const editTemplateName = ".*?";/; | ||
| const EDIT_CONFIG_NAME_PROPERTY_PATTERN = | ||
| /(export const config:\s*TemplateConfig\s*=\s*\{[\s\S]*?\bname:\s*)(".*?"|editTemplateName)(,)/; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
python - <<'PY'
import re
patterns = {
"EDIT_PATH_DECLARATION_PATTERN": re.compile(r'const editPath = ".*?";'),
"LEGACY_GET_PATH_BLOCK_PATTERN": re.compile(
r'export const getPath:\s*GetPath<TemplateProps>\s*=\s*\(\)\s*=>\s*\{\s*return\s+(".*?");\s*\};'
),
"LEGACY_GET_PATH_EXPRESSION_PATTERN": re.compile(
r'export const getPath:\s*GetPath<TemplateProps>\s*=\s*\(\)\s*=>\s*(".*?");'
),
"EDIT_TEMPLATE_NAME_DECLARATION_PATTERN": re.compile(
r'const editTemplateName = ".*?";'
),
"EDIT_CONFIG_NAME_PROPERTY_PATTERN": re.compile(
r'(export const config:\s*TemplateConfig\s*=\s*\{[\s\S]*?\bname:\s*)(".*?"|editTemplateName)(,)'
),
}
samples = {
"double_quote_path": 'const editPath = "edit/foo";',
"single_quote_path": "const editPath = 'edit/foo';",
"double_quote_legacy_getPath": 'export const getPath: GetPath<TemplateProps> = () => "edit/foo";',
"single_quote_legacy_getPath": "export const getPath: GetPath<TemplateProps> = () => 'edit/foo';",
"double_quote_template_name": 'const editTemplateName = "edit-foo";',
"single_quote_template_name": "const editTemplateName = 'edit-foo';",
"config_name_with_comma": 'export const config: TemplateConfig = {\n name: "edit-foo",\n}',
"config_name_without_comma": 'export const config: TemplateConfig = {\n name: "edit-foo"\n}',
}
for sample_name, sample in samples.items():
matched = [name for name, pattern in patterns.items() if pattern.search(sample)]
print(f"{sample_name}: {matched}")
PYRepository: yext/visual-editor
Length of output: 430
Broaden the reinjection patterns to accept both quote styles and optional trailing commas.
The regex patterns in lines 7–15 only match double-quoted string literals, and EDIT_CONFIG_NAME_PROPERTY_PATTERN requires a trailing comma after name. Since plugin.ts rereads src/templates/edit.tsx from disk on every build, a formatter rewriting this file to single quotes or removing the trailing comma will cause injectEditorTemplateInfo() to fail to find its injection placeholders, even though the file is valid TypeScript. This leads to silent build failures for formatting-only changes.
Either update the patterns to accept both quote styles and optional trailing commas, or switch to AST-based reinjection (using ts-morph, similar to registryTemplateGenerator.ts).
Also applies to: 97–135, 139–166
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@packages/visual-editor/src/vite-plugin/editorRoute.ts` around lines 7 - 15,
The current regex constants (EDIT_PATH_DECLARATION_PATTERN,
LEGACY_GET_PATH_BLOCK_PATTERN, LEGACY_GET_PATH_EXPRESSION_PATTERN,
EDIT_TEMPLATE_NAME_DECLARATION_PATTERN, EDIT_CONFIG_NAME_PROPERTY_PATTERN) only
match double-quoted literals and require a trailing comma; update these patterns
to accept both single and double quotes (e.g. ["']) and make the comma after the
name property optional so reinjection won't break when formatters change quotes
or remove trailing commas; apply the same relaxed patterns to the other
occurrences referenced (lines ~97–135 and ~139–166) or alternatively replace
this string-based approach with an AST-based reinjection using ts-morph
consistent with registryTemplateGenerator.ts.
This sets the editor URL path to
/edit/{templateId}when nomaintemplate is present, or the default/editwhen there is amaintemplate.Tested with other changes in platform and confirmed that editors were served at the correct paths and worked as expected.