Skip to content

chore: robustness & DX hardening (#13) - #24

Merged
timhettler merged 4 commits into
mainfrom
chore/robustness-dx-hardening
Aug 10, 2026
Merged

timhettler merged 4 commits into
mainfrom
chore/robustness-dx-hardening

Conversation

@timhettler

Copy link
Copy Markdown
Owner

Closes #13

Grab-bag of smaller robustness / DX items, each independent:

Item Fix
Invalid symbol IDs getSymbolId now validates an XML NCName (/^[A-Za-z_][A-Za-z0-9._-]*$/), rejecting names like foo! that break <use href="#foo!">. Test at create.spec.ts flipped from asserting foo! valid → asserting it throws.
Flat directory only Input dir is now walked recursively (sorted, deterministic). Symbol ids come from filenames, so a duplicate id across folders is rejected with a clear error.
Missing/empty viewBox Derived from width/height when possible; otherwise a warning is emitted and the attribute is omitted rather than written as invalid viewBox="".
Duplicate work Input dir read once and each file parsed once, reused for both the sprite and the id list (was read + parsed twice).
No watch mode Documented a chokidar-cli / concurrently recipe in the README (CLI stays a one-shot build step; no new dependency).
Node version undocumented Added engines to the published package and documented the floor.

Node floor (verified empirically)

The compiled CLI uses import … with { type: "json" }, so I ran the built dist across versions:

Node Result
18.20.4 ✅
20.9.0 ❌ SyntaxError: Unexpected token 'with'
20.17.0 ✅
22.13.1 ✅

→ engines.node: ">=18.20.0 <19 || >=20.10.0".

Verification

  • yarn test (package): 11 passing — incl. updated create.spec.ts (NCName + omitted viewBox) and new directory.spec.ts (nested folders + duplicate-id error).
  • tsc --noEmit green.
  • Regenerating the demo with the new CLI produces byte-identical output (no behavior change for the existing flat icon set).

🤖 Generated with Claude Code

timhettler and others added 4 commits August 10, 2026 10:47
Addresses the grab-bag of smaller robustness / DX items:

- Invalid symbol IDs: `getSymbolId` now validates against an XML NCName pattern,
  rejecting XML-invalid names like `foo!` that would break `<use href="#foo!">`
  (previously only leading digits / whitespace were caught).
- Nested folders: the input directory is walked recursively, so icons in
  sub-folders are included. Duplicate ids across folders (ids come from
  filenames) are rejected with a clear error.
- Missing/empty viewBox: derived from width/height when possible, otherwise a
  warning is emitted and the attribute is omitted rather than written as an
  invalid `viewBox=""`.
- Duplicate work: the input directory is read once and each file parsed once,
  then reused for both the sprite and the id list (was read/parsed twice).
- Watch mode: documented a `chokidar-cli` / `concurrently` recipe in the README.
- Node version: added an `engines` field to the published package and documented
  the minimum (Node >=18.20 or >=20.10 — the compiled CLI uses JSON import
  attributes, verified empirically that 20.0–20.9 fail).

Updates and adds tests (`create.spec.ts`, new `directory.spec.ts`).

Closes #13

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Review follow-up: with the default `-o` (output === input) or an output dir
nested under the input dir, the recursive walk would pick up a previously-written
`symbolstore.svg` on the next run and emit a bogus `symbolstore` symbol (or throw
a duplicate-id error). Exclude generated sprites (`symbolstore*.svg`) living in
the output dir from the input walk. Adds a test covering output === input.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Resolve the bin/symbol-store.ts conflict by combining this branch's recursive
icon walk + duplicate-id guard + single-parse with main's content hash (#8) and
accessible UseSvg template (#10):
- keep collectSvgFiles (recursive, already sorted) + the output-dir sprite guard
  + the single parse reused for both the sprite and SYMBOL_IDS (via getSvgSymbol),
- keep useHashSuffix and the content-hash filename,
- keep the accessible generated UseSvg (role=img / aria-hidden, title prop).
README auto-merged (node-version/watch/recursive notes alongside the
--hash and Accessibility sections).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@timhettler
timhettler merged commit 70a51af into main Aug 10, 2026
1 check passed
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.

Robustness & DX hardening (minor)

1 participant