Analysis of commit ce8c743
Assignee: @copilot
Summary
The three new story file template generator functions in code/core/src/core-server/utils/new-story-templates/ contain near-identical import resolution and args serialization logic that is duplicated across all template variants. This is copy-paste duplication introduced as part of the recent PR adding new-story template helpers.
Duplication Details
Pattern: Component Import Resolution Logic
- Severity: Medium
- Occurrences: 3 identical or near-identical blocks
- Locations:
code/core/src/core-server/utils/new-story-templates/javascript.ts (lines 17–22)
code/core/src/core-server/utils/new-story-templates/typescript.ts (lines 19–24)
code/core/src/core-server/utils/new-story-templates/csf-factory-template.ts (lines 19–24)
- Code Sample:
const importName = data.componentIsDefaultExport
? await getComponentVariableName(data.basenameWithoutExtension)
: data.componentExportName;
const importStatement = data.componentIsDefaultExport
? `import \$\{importName} from './\$\{data.basenameWithoutExtension}';`
: `import { \$\{importName} } from './\$\{data.basenameWithoutExtension}';`;
Pattern: hasArgs / argsString Serialization Logic
- Severity: Low–Medium
- Occurrences: 2 identical blocks
- Locations:
code/core/src/core-server/utils/new-story-templates/javascript.ts (lines 24–25)
code/core/src/core-server/utils/new-story-templates/typescript.ts (lines 26–27)
- Code Sample:
const hasArgs = Boolean(data.args && Object.keys(data.args).length > 0);
const argsString = hasArgs ? `args: \$\{JSON.stringify(data.args, null, 2)},` : '';
Pattern: Shared Interface Fields
All three template data interfaces (JavaScriptTemplateData, TypeScriptTemplateData, CsfFactoryTemplateData) declare the same five fields:
basenameWithoutExtension: string;
componentExportName: string;
componentIsDefaultExport: boolean;
exportedStoryName: string;
args?: Record(string, any);
Impact Analysis
- Maintainability: Any change to import generation logic (e.g., supporting
import type, ESM extensions, or path aliases) must be applied in three separate files. This has already caused a subtle inconsistency: the TypeScript template omits the trailing semicolon on the import statement (line 23 of typescript.ts) while the other two templates include it.
- Bug Risk: High — a fix to one template (e.g., correcting the
argsString format or escaping) will silently miss the other two if not applied consistently.
- Code Bloat: ~18 lines of duplicated import-resolution code across the three template files.
Refactoring Recommendations
-
Extract resolveComponentImport() helper
- Create:
code/core/src/core-server/utils/new-story-templates/helpers.ts
- Signature:
export async function resolveComponentImport(
data: Pick(BaseTemplateData, 'componentIsDefaultExport' | 'componentExportName' | 'basenameWithoutExtension'),
trailingSemicolon = true
): Promise<{ importName: string; importStatement: string }>;
- Estimated effort: ~1 hour
- Benefits: Single place to update import logic; fixes existing inconsistency around trailing semicolons
-
Extract BaseTemplateData interface
- Define the five shared fields in a
BaseTemplateData interface in helpers.ts and have each template interface extend it:
export interface BaseTemplateData {
basenameWithoutExtension: string;
componentExportName: string;
componentIsDefaultExport: boolean;
exportedStoryName: string;
args?: Record(string, any);
}
- Estimated effort: ~30 minutes
- Benefits: Single source of truth for shared template input shape
-
Extract serializeArgs() helper (optional)
- Consolidate the
hasArgs/argsString pattern used in JS and TS templates
- Estimated effort: ~30 minutes
Implementation Checklist
Analysis Metadata
- Analyzed Files: 3 (
javascript.ts, typescript.ts, csf-factory-template.ts)
- Detection Method: Serena semantic code analysis + pattern search
- Commit: ce8c743
- Analysis Date: 2026-04-03
Generated by Duplicate Code Detector · ◷
To install this agentic workflow, run
gh aw add github/gh-aw/.github/workflows/duplicate-code-detector.md@852cb06ad52958b402ed982b69957ffc57ca0619
Analysis of commit ce8c743
Assignee:
@copilotSummary
The three new story file template generator functions in
code/core/src/core-server/utils/new-story-templates/contain near-identical import resolution and args serialization logic that is duplicated across all template variants. This is copy-paste duplication introduced as part of the recent PR adding new-story template helpers.Duplication Details
Pattern: Component Import Resolution Logic
code/core/src/core-server/utils/new-story-templates/javascript.ts(lines 17–22)code/core/src/core-server/utils/new-story-templates/typescript.ts(lines 19–24)code/core/src/core-server/utils/new-story-templates/csf-factory-template.ts(lines 19–24)Pattern:
hasArgs/argsStringSerialization Logiccode/core/src/core-server/utils/new-story-templates/javascript.ts(lines 24–25)code/core/src/core-server/utils/new-story-templates/typescript.ts(lines 26–27)Pattern: Shared Interface Fields
All three template data interfaces (
JavaScriptTemplateData,TypeScriptTemplateData,CsfFactoryTemplateData) declare the same five fields:Impact Analysis
import type, ESM extensions, or path aliases) must be applied in three separate files. This has already caused a subtle inconsistency: the TypeScript template omits the trailing semicolon on the import statement (line 23 oftypescript.ts) while the other two templates include it.argsStringformat or escaping) will silently miss the other two if not applied consistently.Refactoring Recommendations
Extract
resolveComponentImport()helpercode/core/src/core-server/utils/new-story-templates/helpers.tsExtract
BaseTemplateDatainterfaceBaseTemplateDatainterface inhelpers.tsand have each template interface extend it:Extract
serializeArgs()helper (optional)hasArgs/argsStringpattern used in JS and TS templatesImplementation Checklist
code/core/src/core-server/utils/new-story-templates/helpers.tswithBaseTemplateDataandresolveComponentImport()javascript.ts,typescript.ts, andcsf-factory-template.tsto use shared helpers*.test.tsfiles alongside each templateAnalysis Metadata
javascript.ts,typescript.ts,csf-factory-template.ts)