Skip to content

feat: ng icons manager v2 - #281

Merged
Dafnik merged 9 commits into
mainfrom
feature/icons-manager-v2
Jun 25, 2026
Merged

Dafnik merged 9 commits into
mainfrom
feature/icons-manager-v2

Conversation

@Dafnik

@Dafnik Dafnik commented Jun 25, 2026 •

Copy link
Copy Markdown
Owner

add config support
add multiple projects support

Summary by CodeRabbit

  • New Features

    • Introduced a configuration-based workflow with named jobs, per-job input/output directories, and updated icon loading paths.
    • Added watch mode and improved CLI job selection, with clearer validation and error handling.
  • Bug Fixes

    • Improved handling of missing, ambiguous, and conflicting icons.
    • Added safer directory validation to avoid accidental overwrites and invalid paths.
  • Documentation

    • Updated setup, configuration, CLI, and package support guidance to match the new workflow.

Dafnik added 2 commits June 25, 2026 09:22
add config support
add multiple projects support
add config support
add multiple projects support
@coderabbitai

coderabbitai Bot commented Jun 25, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@Dafnik, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 55 minutes and 55 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 824312dd-177c-41d1-95a9-78d248cffd39

📥 Commits

Reviewing files that changed from the base of the PR and between 2f6743c and f8874d5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (36)
  • .github/workflows/dev.yml
  • .github/workflows/release.yml
  • eslint.config.mjs
  • jest.config.ts
  • jest.preset.js
  • libs/dfts-helper/jest.config.ts
  • libs/dfts-helper/project.json
  • libs/dfts-helper/tsconfig.lib.json
  • libs/dfts-helper/tsconfig.spec.json
  • libs/dfts-helper/vitest.config.ts
  • libs/dfts-qrcode/jest.config.ts
  • libs/dfts-qrcode/project.json
  • libs/dfts-qrcode/tsconfig.lib.json
  • libs/dfts-qrcode/tsconfig.spec.json
  • libs/dfts-qrcode/vitest.config.ts
  • libs/ng-icons-manager/README.md
  • libs/ng-icons-manager/jest.config.ts
  • libs/ng-icons-manager/project.json
  • libs/ng-icons-manager/src/internal/cli/cli-application.ts
  • libs/ng-icons-manager/src/internal/cli/cli-options.ts
  • libs/ng-icons-manager/src/internal/cli/setup-command.ts
  • libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts
  • libs/ng-icons-manager/src/internal/core/icon-parser.ts
  • libs/ng-icons-manager/src/internal/infrastructure/chokidar-watcher.ts
  • libs/ng-icons-manager/src/internal/infrastructure/create-cli-application.ts
  • libs/ng-icons-manager/src/test/cli.spec.ts
  • libs/ng-icons-manager/src/test/fakes.ts
  • libs/ng-icons-manager/src/test/integration/cli.integration.spec.ts
  • libs/ng-icons-manager/src/test/integration/test-utils.ts
  • libs/ng-icons-manager/src/test/setup-command.spec.ts
  • libs/ng-icons-manager/src/test/watch.spec.ts
  • libs/ng-icons-manager/tsconfig.lib.json
  • libs/ng-icons-manager/tsconfig.spec.json
  • libs/ng-icons-manager/vitest.config.ts
  • nx.json
  • package.json
📝 Walkthrough

Walkthrough

The PR converts ng-icons-manager to an ESM-only, config-driven job runner with new config validation, icon resolution/output logic, CLI/watch orchestration, and updated docs and tests.

Changes

ng-icons-manager rewrite

Layer / File(s) Summary
Public surface and packaging
libs/ng-icons-manager/src/index.ts, libs/ng-icons-manager/src/config/index.ts, libs/ng-icons-manager/src/core/index.ts, libs/ng-icons-manager/package.json, libs/ng-icons-manager/project.json, libs/ng-icons-manager/jest.config.ts, libs/ng-icons-manager/tsconfig.lib.json, libs/ng-icons-manager/README.md
ng-icons-manager becomes ESM-first, exports the new config types and defineConfig, and updates the README to match the job-based workflow.
Shared test harness
libs/ng-icons-manager/src/test/fakes.ts, libs/ng-icons-manager/src/test/integration/test-utils.ts
In-memory fakes and CLI helpers provide filesystem, module import, logging, watcher, and execFile behavior for the new tests.
Config loading and validation
libs/ng-icons-manager/src/internal/core/issues.ts, libs/ng-icons-manager/src/internal/core/ports.ts, libs/ng-icons-manager/src/internal/config/*, libs/ng-icons-manager/src/test/config.spec.ts
Configuration loading validates .mjs configs, resolves job paths, enforces output safety, and returns structured config/read issues with unit coverage.
Icon processing pipeline
libs/ng-icons-manager/src/internal/core/icon-*.ts, libs/ng-icons-manager/src/internal/core/icon-manager.ts, libs/ng-icons-manager/src/test/icon-resolver.spec.ts, libs/ng-icons-manager/src/test/scanner-and-runner.spec.ts
Icon parsing, registry lookup, resolution, output synchronization, and job orchestration are rebuilt around the job model and covered by parser/resolver/scanner tests.
CLI runtime and wiring
libs/ng-icons-manager/bin/cli.js, libs/ng-icons-manager/src/internal/cli/*, libs/ng-icons-manager/src/internal/infrastructure/*, libs/ng-icons-manager/src/test/cli.spec.ts, libs/ng-icons-manager/src/test/integration/cli.integration.spec.ts
The CLI now parses the new flags, builds the application from Node-based infrastructure, and updates argument and integration tests around the ESM entrypoint.
Watch coordination
libs/ng-icons-manager/src/internal/cli/serial-job-watcher.ts, libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts, libs/ng-icons-manager/src/test/watch.spec.ts
Watch mode now serializes reruns, reloads configs on change, and closes watcher handles during shutdown and invalid reloads.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

Possibly related PRs

  • Dafnik/dfts-common#251: Adds the earlier config-driven ng-icons-manager loading and scanner changes that this PR replaces with the new job model.
  • Dafnik/dfts-common#252: Touches the same ng-icons-manager integration tests and helpers that are rewritten here for the ESM CLI flow.

Poem

Hop, hop! I sifted globs through moonlit hay,
and wrote the chosen SVGs on their way.
Jobs now dance in ESM shine,
config.mjs and icons align.
Thump-thump—my paws approve the springtime play. 🐇

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title is related to the library, but it is too generic to convey the main change in this PR. Use a more specific title that mentions the config-driven multi-job rewrite, such as 'feat: add config-driven multi-job ng-icons-manager'.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/icons-manager-v2

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (3)
libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts (1)

37-37: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant selected() call.

Line 37 calls this.selected(this.config, selectedJobs) only for early validation and discards the result; apply() (Line 51) validates again. You can drop Line 37 and rely on apply()'s validation, or keep a comment clarifying it is an intentional pre-watch validation gate.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts` at line 37, The
WatchCoordinator flow has a redundant selected() validation call that discards
its result before apply() validates again. Remove the early
this.selected(this.config, selectedJobs) call in watch-coordinator’s setup path,
or if you keep it, add a clear comment that it is an intentional pre-watch
validation gate; use the selected() and apply() methods in WatchCoordinator to
locate the fix.
libs/ng-icons-manager/src/internal/cli/cli-application.ts (1)

26-30: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant jobs() resolution on the non-watch path.

Line 26 resolves+validates the job list and discards it, then once() (Line 39) resolves it again. Consider computing once and passing the resolved jobs down to avoid the double lookup and keep validation in a single place.

♻️ Possible simplification
-      const config = await this.configs.load(configPath);
-      this.jobs(config, options.jobs);
-
-      if (options.verbose) this.logger.info(`Loaded config from ${config.configPath}`);
-      if (options.watch) return this.watch.run(config, options.jobs, options.verbose, signal);
-      return this.once(config, options);
+      const config = await this.configs.load(configPath);
+      const jobs = this.jobs(config, options.jobs);
+
+      if (options.verbose) this.logger.info(`Loaded config from ${config.configPath}`);
+      if (options.watch) return this.watch.run(config, options.jobs, options.verbose, signal);
+      return this.once(jobs, options);

(adjust once() signature accordingly)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/ng-icons-manager/src/internal/cli/cli-application.ts` around lines 26 -
30, The CLI flow in `CLIApplication` resolves `jobs()` twice on the non-watch
path, once before branching and again inside `once()`. Compute the resolved jobs
a single time in `run()` and pass them through to `once()` (and keep
`watch.run()` consistent if needed), then update `once()`’s signature to accept
the already-resolved jobs so validation happens in one place only.
libs/ng-icons-manager/src/internal/infrastructure/native-config-importer.ts (1)

6-9: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Cache-busting query string leaks modules across watch reloads.

Appending a unique ?t=${Date.now()} makes the ESM loader treat each reload as a new module and retain it in the registry for the process lifetime. In a long-lived --watch session that reloads config on every change, memory grows unbounded. There's no built-in eviction for the ESM cache, so this is inherent to the approach—worth confirming the watch reload frequency is low enough that this is acceptable, or documenting the tradeoff.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@libs/ng-icons-manager/src/internal/infrastructure/native-config-importer.ts`
around lines 6 - 9, The dynamic import in native-config-importer.importFile uses
a cache-busting query string that causes each watch reload to register a new ESM
module and leak memory over time. Update importFile to avoid unbounded module
growth in long-lived watch sessions by removing or gating the timestamp-based
busting logic, and either reuse stable module URLs or document/confirm the watch
reload tradeoff where importFile is called.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@libs/ng-icons-manager/src/internal/cli/cli-options.ts`:
- Around line 27-29: The CLI option parsing in cli-options.ts must keep the
explicit duplicate --config validation because util.parseArgs with strict mode
will otherwise silently accept repeated non-multiple options and use the last
value. Preserve or restore the tokens.filter check in the option-parsing logic
that counts 'config' occurrences, and ensure it throws the existing error when
more than one --config is provided so duplicate config input is rejected instead
of overwritten.

In `@libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts`:
- Around line 34-67: The abort path in watch coordination can leave a
SerialJobWatcher registered after cleanup has already started. In
WatchCoordinator.apply, after awaiting watcher.start(), guard against
this.finished before calling this.jobWatchers.set so a watcher is not added once
finish(0) has already run. Use the existing finish/closeJobs flow and the
this.finished flag in watch-coordinator.ts to skip registration when shutdown is
in progress.

In `@libs/ng-icons-manager/src/internal/core/icon-parser.ts`:
- Around line 13-24: commentHints currently only extracts hints from HTML and
block comments, so it misses `//` line comments used by the spec template.
Update the comment parsing in `commentHints` within `icon-parser.ts` to also
scan single-line comment content for `i(...)` patterns, alongside the existing
`commentHints` regex handling for `<!-- -->` and `/* */`, so names like
`matAlarm` are collected.

In `@libs/ng-icons-manager/src/internal/infrastructure/chokidar-watcher.ts`:
- Around line 18-34: The readyPromise in ChokidarWatcher only resolves on the
watcher’s ready event, so ready() can hang forever if FSWatcher emits error
first; update the ChokidarWatcher constructor and ready() flow so the promise
settles on the first error as well, and make sure the same error path is wired
through onError and any internal handlers to either reject or otherwise unblock
callers waiting on ready().

---

Nitpick comments:
In `@libs/ng-icons-manager/src/internal/cli/cli-application.ts`:
- Around line 26-30: The CLI flow in `CLIApplication` resolves `jobs()` twice on
the non-watch path, once before branching and again inside `once()`. Compute the
resolved jobs a single time in `run()` and pass them through to `once()` (and
keep `watch.run()` consistent if needed), then update `once()`’s signature to
accept the already-resolved jobs so validation happens in one place only.

In `@libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts`:
- Line 37: The WatchCoordinator flow has a redundant selected() validation call
that discards its result before apply() validates again. Remove the early
this.selected(this.config, selectedJobs) call in watch-coordinator’s setup path,
or if you keep it, add a clear comment that it is an intentional pre-watch
validation gate; use the selected() and apply() methods in WatchCoordinator to
locate the fix.

In `@libs/ng-icons-manager/src/internal/infrastructure/native-config-importer.ts`:
- Around line 6-9: The dynamic import in native-config-importer.importFile uses
a cache-busting query string that causes each watch reload to register a new ESM
module and leak memory over time. Update importFile to avoid unbounded module
growth in long-lived watch sessions by removing or gating the timestamp-based
busting logic, and either reuse stable module URLs or document/confirm the watch
reload tradeoff where importFile is called.
🪄 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: c087b362-efd0-439f-ad23-8d7726e05f99

📥 Commits

Reviewing files that changed from the base of the PR and between c61b809 and 2f6743c.

📒 Files selected for processing (52)
  • libs/ng-icons-manager/README.md
  • libs/ng-icons-manager/bin/cli.js
  • libs/ng-icons-manager/jest.config.ts
  • libs/ng-icons-manager/package.json
  • libs/ng-icons-manager/project.json
  • libs/ng-icons-manager/src/adapters/console-logger.ts
  • libs/ng-icons-manager/src/adapters/fs-adapter.ts
  • libs/ng-icons-manager/src/adapters/index.ts
  • libs/ng-icons-manager/src/adapters/module-resolver.ts
  • libs/ng-icons-manager/src/config/defaults.ts
  • libs/ng-icons-manager/src/config/icon-map.ts
  • libs/ng-icons-manager/src/config/index.ts
  • libs/ng-icons-manager/src/core/cache.service.ts
  • libs/ng-icons-manager/src/core/icon-scanner.ts
  • libs/ng-icons-manager/src/core/index.ts
  • libs/ng-icons-manager/src/core/scanner.facade.ts
  • libs/ng-icons-manager/src/index.ts
  • libs/ng-icons-manager/src/internal/cli/cli-application.ts
  • libs/ng-icons-manager/src/internal/cli/cli-options.ts
  • libs/ng-icons-manager/src/internal/cli/cli-reporter.ts
  • libs/ng-icons-manager/src/internal/cli/serial-job-watcher.ts
  • libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts
  • libs/ng-icons-manager/src/internal/config/config-loader.ts
  • libs/ng-icons-manager/src/internal/config/config-validator.ts
  • libs/ng-icons-manager/src/internal/config/models.ts
  • libs/ng-icons-manager/src/internal/config/output-path-policy.ts
  • libs/ng-icons-manager/src/internal/core/icon-manager.ts
  • libs/ng-icons-manager/src/internal/core/icon-output.ts
  • libs/ng-icons-manager/src/internal/core/icon-parser.ts
  • libs/ng-icons-manager/src/internal/core/icon-registry.ts
  • libs/ng-icons-manager/src/internal/core/icon-resolver.ts
  • libs/ng-icons-manager/src/internal/core/icon-scanner.ts
  • libs/ng-icons-manager/src/internal/core/issues.ts
  • libs/ng-icons-manager/src/internal/core/ports.ts
  • libs/ng-icons-manager/src/internal/infrastructure/chokidar-watcher.ts
  • libs/ng-icons-manager/src/internal/infrastructure/console-logger.ts
  • libs/ng-icons-manager/src/internal/infrastructure/create-cli-application.ts
  • libs/ng-icons-manager/src/internal/infrastructure/native-config-importer.ts
  • libs/ng-icons-manager/src/internal/infrastructure/node-file-system.ts
  • libs/ng-icons-manager/src/internal/infrastructure/node-module-loader.ts
  • libs/ng-icons-manager/src/test/cli.spec.ts
  • libs/ng-icons-manager/src/test/config.spec.ts
  • libs/ng-icons-manager/src/test/fakes.ts
  • libs/ng-icons-manager/src/test/icon-resolver.spec.ts
  • libs/ng-icons-manager/src/test/icon-scanner.spec.ts
  • libs/ng-icons-manager/src/test/integration/cli.integration.spec.ts
  • libs/ng-icons-manager/src/test/integration/test-utils.ts
  • libs/ng-icons-manager/src/test/mock.spec.ts
  • libs/ng-icons-manager/src/test/scanner-and-runner.spec.ts
  • libs/ng-icons-manager/src/test/watch.spec.ts
  • libs/ng-icons-manager/src/types.ts
  • libs/ng-icons-manager/tsconfig.lib.json
💤 Files with no reviewable changes (14)
  • libs/ng-icons-manager/src/adapters/console-logger.ts
  • libs/ng-icons-manager/src/config/icon-map.ts
  • libs/ng-icons-manager/src/adapters/module-resolver.ts
  • libs/ng-icons-manager/src/adapters/fs-adapter.ts
  • libs/ng-icons-manager/src/core/icon-scanner.ts
  • libs/ng-icons-manager/src/types.ts
  • libs/ng-icons-manager/src/core/cache.service.ts
  • libs/ng-icons-manager/src/config/defaults.ts
  • libs/ng-icons-manager/src/adapters/index.ts
  • libs/ng-icons-manager/src/test/mock.spec.ts
  • libs/ng-icons-manager/src/core/index.ts
  • libs/ng-icons-manager/src/test/icon-scanner.spec.ts
  • libs/ng-icons-manager/src/core/scanner.facade.ts
  • libs/ng-icons-manager/src/config/index.ts

Comment thread libs/ng-icons-manager/src/internal/cli/cli-options.ts Outdated
Comment thread libs/ng-icons-manager/src/internal/cli/watch-coordinator.ts
Comment thread libs/ng-icons-manager/src/internal/core/icon-parser.ts
@github-actions

Copy link
Copy Markdown

Code Coverage

Package Line Rate Branch Rate Complexity Health
helper 33% 100% 0 ❌
helper.array 100% 100% 0 ✔
helper.array.chunk 100% 100% 0 ✔
helper.array.contains-duplicates 100% 100% 0 ✔
helper.array.for-each-if-absent 100% 100% 0 ✔
helper.array.for-each-if-present 100% 100% 0 ✔
helper.array.hash 100% 100% 0 ✔
helper.array.push-if-absent 100% 100% 0 ✔
helper.array.remove 64% 40% 0 ➖
helper.boolean.from 100% 100% 0 ✔
helper.boolean.from-storage 100% 100% 0 ✔
helper.boolean.is 100% 100% 0 ✔
helper.date.from-storage 100% 100% 0 ✔
helper.date.is 100% 100% 0 ✔
helper.number 100% 83% 0 ✔
helper.number.from 100% 100% 0 ✔
helper.number.from-storage 100% 100% 0 ✔
helper.number.generator 100% 100% 0 ✔
helper.number.is 100% 100% 0 ✔
helper.number.is-numeric 100% 100% 0 ✔
helper.object.from-storage 100% 100% 0 ✔
helper.object.is 100% 100% 0 ✔
helper.stopwatch 67% 84% 0 ➖
helper.storage 96% 93% 0 ✔
helper.string 100% 50% 0 ✔
helper.string.chunk 100% 100% 0 ✔
helper.string.count-words 100% 100% 0 ✔
helper.string.cut 100% 100% 0 ✔
helper.string.email 100% 50% 0 ✔
helper.string.from 100% 100% 0 ✔
helper.string.from-storage 100% 100% 0 ✔
helper.string.generator 91% 82% 0 ✔
helper.string.imploder 81% 61% 0 ✔
helper.string.read-time 100% 100% 0 ✔
helper.string.transformer 75% 50% 0 ✔
helper.string.truncate 100% 100% 0 ✔
helper.string.url 100% 50% 0 ✔
Summary 89% (244 / 275) 82% (173 / 210) 0 ✔

@Dafnik
Dafnik merged commit 743799e into main Jun 25, 2026
14 checks passed
@Dafnik
Dafnik deleted the feature/icons-manager-v2 branch June 25, 2026 09:42
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.

1 participant