Skip to content

bug(cli): reject unsupported output modes instead of silently succeeding #27

Description

@Hebilicious

Problem

cli.ts at 94bf4d8 accepts --mode as an arbitrary string and casts the assembled options to BuildOptions.

build() only writes files when the mode matches css, json, ts, or all. When a different string is supplied, all output branches are skipped and the function still returns { success: true }, provided the configuration import succeeds. The non-watch CLI then exits with code 0.

This lets a typo produce no output while CI reports success. Existing generated files can conceal the problem.

Reproduction to cover in an integration test

After building the package, create empty.config.mjs containing:

export default {};

Then invoke the built entry directly:

node packages/cssforge/dist/cli.js --config ./empty.config.mjs --mode typo

The source control flow predicts exit 0 and no output writes. Expected: a nonzero exit and an error naming the unsupported mode and accepted alternatives. This finding is source-confirmed; the full packaged CLI integration test was not run during filing.

Proposed fix

Define the accepted mode list once and reuse it for runtime validation, the TypeScript union, and help text. Validate before importing the configuration or starting a watcher. Also protect the exported build() API from invalid values supplied by JavaScript callers; a TypeScript cast does not validate runtime input.

Acceptance criteria

  • An unsupported mode produces a clear error and a nonzero non-watch CLI exit.
  • Invalid modes are rejected before writing outputs or starting watch mode.
  • JavaScript callers of build() receive the existing failure-result shape or another documented error contract.
  • Tests cover each supported mode, an invalid mode, default behavior, and the short -m form.
  • Invalid-mode tests assert that pre-existing output files remain unchanged.
  • Coordinate the shared mode list with the Style Dictionary mode in Add Style Dictionary token output #20; do not accidentally reject newly supported formats.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions