The Problem

The repository lacks an automated CI/CD gate, so every merge lands without a verified build or test run. Across a fleet of 49 source files this means changes can introduce regressions that go undetected until manual inspection, and the Dockerfile can drift from its intended base image without validation.

What This Does

svg-path-editor is a browser‑based editor for creating and manipulating SVG path data. The core library lives in src/lib/ and exposes types and transformation functions (optimizePath, reversePath, svg.ts — 60 functions, 16 type definitions). The Angular app in src/app/ wires the library UI: app.component.ts boots the module, canvas/canvas.component.ts handles pointer events and viewBox movement, export/export.component.ts can download the edited path, and storage.service.ts persists paths in local storage. User actions flow through a small set of shared utilities—refreshAbsolutePositions, targetLocation, getType—that are called from dozens of call sites, making the svg.ts module a high‑blast‑radius hub (15 importers, instability 0.12). Two modules, optimize-path.ts and reverse-path.ts, participate in a circular import dependency that complicates changes.

How It Is Wired

Execution starts at src/main.ts which bootstraps the Angular app defined in src/app/app.module.ts. The component hierarchy then routes events:

  • app.component.ts (45 functions) listens for global shortcuts and forwards them to keyboard-navigable.directive.ts.
  • canvas/canvas.component.ts (39 functions) captures drag events, calls eventToLocation and targetLocation (called from 11 places) to compute snap positions, and invokes refreshAbsolutePositions (14 callers) to recompute the viewBox.
  • Path‑editing commands (optimizePath, reversePath, Make) are defined in src/lib/ and called from the UI components; optimizePath and reversePath each appear in the circular dependency (optimize-path ↔ reverse-path).
  • export/export.component.ts (10 functions) reads the current path and either copies to clipboard or triggers a file download—this is the sole function that reads/writes files outside the repo.

The import graph contains 49 modules and 85 edges; the most connected are src/lib/svg (Ca 15, Ce 2, instability 0.12) and src/app/app.module (Ca 2, Ce 13, instability 0.87), indicating that modifications to the SVG module ripple widely, while the module graph shows two cycles that must be broken when adding new logic.

How To Use It

# Clone the repository
git clone https://github.com/moses-y/svg-path-editor

# Install dependencies
npm install

# Start development server (http://localhost:4200/)
npm start

# Build production artifacts
npm run build

# Run unit tests (Karma)
npm test

Docker is also supported; docker-compose up builds and runs the container defined in Dockerfile and docker-compose.yml.

Real‑World Use

A UI designer receives an SVG path string from a design system and needs to trim unnecessary points before publishing. They open the editor, paste the raw path into the path field, click Optimize (which calls optimizePath from src/lib/optimize-path.ts), review the simplified geometry, and export the cleaned path via the Download button (export/export.component.ts). The resulting path can be dropped back into the design system’s component library, preserving the original viewBox settings.

Code Health & Issues

Measured static‑analysis findings (9 total):

  • HIGH / soundness – Import cycle member: src/lib/optimize-path.ts and src/lib/reverse-path.ts mutually import each other, creating a circular dependency.
  • MEDIUM / cognitive_load – Oversized file: src/lib/svg.ts contains 622 lines, making it hard to hold in one mental model; a change ripples to 15 importers.
  • MEDIUM / cognitive_load – Deep nesting: src/lib/path-parser.ts reaches a maximum indentation depth of 6, obscuring control flow.
  • MEDIUM / clarity – Hub module: src/lib/svg.ts is depended on by 15 other modules; churn here has high‑blast‑radius impact.
  • MEDIUM / cognitive_load – High branching density (58 branch points over 162 lines) in src/lib/optimize-path.ts, src/app/keyboard-navigable/keyboard-navigable.directive.ts, and src/lib/change-path-origin.ts.
  • MEDIUM / clarity – Duplicated code blocks: 4 × 6‑line repeats across src/lib/change-path-origin.ts and src/lib/reverse-path.ts.
  • MEDIUM / cognitive_load – Deep nesting in src/lib/path-parser.ts (already listed).

SDLC hygiene observations (from file‑structure audit):

  • No CI pipeline configured – no automated build/test gate.
  • Dockerfile uses mutable base image node:current; no digest pinning.
  • No USER directive in the Dockerfile, meaning the container runs as root.
  • Dependabot/Renovate not configured; two manifest files (package.json, src/lib/package.json) have no automated update bot.
  • License file present, lockfile committed, no committed secrets detected.

The Bottom Line

The project delivers a functional, client‑side SVG editor with a solid library backbone and a rich feature set for path editing, transformation, and export. However, the absence of CI/CD, circular imports in core utilities, and several high‑impact code‑health smells make ongoing maintenance risky. Teams that need a quick, browser‑based path editor and are willing to address the identified hygiene items will find it usable; others requiring strict test coverage and automated deployment pipelines should plan refactor effort up front.