Skip to content

refactor: migrate ucd-store to use utils#59

Merged
luxass merged 12 commits intomainfrom
luxass/06-14-refactor-migrate-ucd-store-to-use-utils
Jun 15, 2025
Merged

refactor: migrate ucd-store to use utils#59
luxass merged 12 commits intomainfrom
luxass/06-14-refactor-migrate-ucd-store-to-use-utils

Conversation

@luxass
Copy link
Member

@luxass luxass commented Jun 14, 2025

This PR refactors the ucd-store implementation to use the ucd-files functions from the utils package.

resolves #54

Summary by CodeRabbit

  • Refactor
    • Updated internal implementations to use shared utility packages for improved consistency and maintainability.
    • Replaced custom filesystem and download logic with unified adapters and utilities.
  • New Features
    • Added new utilities for flattening file paths and repairing Unicode data files.
  • Bug Fixes
    • Removed the unsupported "download" command from the CLI tool.
  • Chores
    • Updated dependencies and TypeScript path aliases.
  • Tests
    • Added and removed tests to align with the new utilities and removed commands.

@changeset-bot
Copy link

changeset-bot bot commented Jun 14, 2025

🦋 Changeset detected

Latest commit: fa61a58

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
@ucdjs/ucd-store Minor
@ucdjs/utils Minor
@ucdjs/cli Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jun 14, 2025

Walkthrough

This change refactors the @ucdjs/ucd-store package to remove its internal download, validation, and filesystem abstraction logic, migrating these responsibilities to the @ucdjs/utils package. Related CLI commands and tests for downloading Unicode data are removed, and new utilities for file path flattening and repair are introduced and exported from @ucdjs/utils.

Changes

File(s) Change Summary
packages/ucd-store/src/download.ts, packages/ucd-store/src/fs-interface.ts Deleted internal download, validation, repair logic, and custom filesystem interface.
packages/ucd-store/src/index.ts Removed exports for deleted download and filesystem modules.
packages/ucd-store/src/local.ts, packages/ucd-store/src/remote.ts Refactored to use @ucdjs/utils for filesystem and file path handling; disabled in-package repair logic.
packages/cli/src/cli-utils.ts, packages/cli/src/cmd/download.ts Removed CLI "download" command implementation and related command handling.
packages/cli/test/cli-utils.test.ts, packages/cli/test/cmd/download.test.ts Removed or commented out tests for the CLI "download" command.
packages/ucd-store/test/download.fs.test.ts, packages/ucd-store/test/fs-interface.test.ts Deleted tests for internal download and filesystem logic.
packages/utils/src/ucd-files.ts, packages/utils/src/ucd-files/helpers.ts Added and exported flattenFilePaths utility; reorganized and extended exports for repair and validation.
packages/utils/src/ucd-files/internal.ts Replaced local file path flattening with external helper import.
packages/utils/src/ucd-files/validate.ts Added repairUCDFiles function and types; switched to external flattening helper.
packages/utils/test/ucd-files/dump._test.ts, packages/utils/test/ucd-files/fs-adapter.test.ts Added new or extended tests for repair and filesystem adapter utilities (some tests commented out).
.changeset/happy-banks-happen.md Added changeset for minor version update and migration summary.
pnpm-workspace.yaml Updated "@luxass/unicode-utils-new" dependency version.
tooling/tsconfig/base.json Added TypeScript path aliases for new utility modules.

Sequence Diagram(s)

sequenceDiagram
    participant LocalUCDStore
    participant utils/ucd-files
    participant FSAdapter

    LocalUCDStore->>utils/ucd-files: mirrorUCDFiles(options)
    utils/ucd-files->>FSAdapter: createDefaultFSAdapter()
    utils/ucd-files->>FSAdapter: write/read/exists operations
    utils/ucd-files-->>LocalUCDStore: Result (mirrored files, errors)
Loading

Assessment against linked issues

Objective (Issue #) Addressed Explanation
Migrate ucd-store to using utils package (#54)

Assessment against linked issues: Out-of-scope changes

Code Change (file_path) Explanation

Possibly related PRs

Suggested labels

pkg: ucd-store

Poem

A bunny with code on its mind,
Hopped from store to utils, leaving old bits behind.
No more custom downloads, no more fs fight—
Now helpers and mirrors make everything right!
With a twitch of a nose and a refactor so neat,
Unicode data is fetched in a single, quick leap.
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

packages/cli/src/cli-utils.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

packages/ucd-store/src/local.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

packages/cli/test/cli-utils.test.ts

Oops! Something went wrong! :(

ESLint: 9.28.0

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

https://eslint.org/docs/latest/use/configure/migration-guide

If you still have problems after following the migration guide, please stop by
https://eslint.org/chat/help to chat with the team.

  • 7 others
✨ Finishing Touches
  • 📝 Generate Docstrings

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the pkg: utils Changes related to the Utils package. label Jun 14, 2025
Copy link
Member Author

luxass commented Jun 14, 2025

This stack of pull requests is managed by Graphite. Learn more about stacking.

@codecov
Copy link

codecov bot commented Jun 14, 2025

Codecov Report

Attention: Patch coverage is 24.77064% with 82 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
packages/utils/src/ucd-files/validate.ts 3.84% 75 Missing ⚠️
packages/ucd-store/src/local.ts 30.00% 7 Missing ⚠️

📢 Thoughts on this report? Let us know!

@luxass luxass marked this pull request as ready for review June 14, 2025 06:48
@github-actions github-actions bot added pkg: cli Changes related to the CLI package. pkg: ucd-store Changes related to the UCD Store package. labels Jun 14, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🔭 Outside diff range comments (1)
packages/cli/src/cli-utils.ts (1)

170-173: ⚠️ Potential issue

Help text still advertises removed download command

download no longer exists, yet it’s still listed in the help table:

["download", "Download Unicode data files."],

This will confuse users and should be removed (or the command reinstated).

-            ["download", "Download Unicode data files."],
🧹 Nitpick comments (10)
.changeset/happy-banks-happen.md (1)

1-8: Changeset summary is too terse for external consumers

The entry only repeats the commit title. Consumers reading release notes won’t know what moved from ucd-store into utils, or that the CLI download command was removed.
Consider adding one or two bullet points under the header to spell out:

  • ucd-store now delegates file IO / validation to @ucdjs/utils.
  • CLI: download command deprecated (will be replaced by store).

Helps users anticipate behavioural changes without digging through PRs.

packages/utils/test/ucd-files/fs-adapter.test.ts (1)

37-47: Great ↑ coverage, but add explicit assertion count & restore spy

Nice addition! Two tiny test-hygiene tweaks:

   it("should write file successfully", async () => {
+    expect.assertions(1);          // guards against false positives
     const { writeFile } = await import("node:fs/promises");
@@
-    await fs.writeFile("/test.txt", "file content");
-
-    expect(writeFile).toHaveBeenCalledWith("/test.txt", "file content", "utf-8");
+    await fs.writeFile("/test.txt", "file content");
+    expect(writeFile).toHaveBeenCalledWith(
+      "/test.txt",
+      "file content",
+      "utf-8",
+    );
+    vi.restoreAllMocks();          // defensive cleanup for later tests
   });

The extra expect.assertions(1) ensures the spy expectation actually runs; restoring mocks keeps isolation if more tests are appended later.

packages/cli/test/cli-utils.test.ts (3)

6-7: Don’t leave commented-out mocks

Dead code clutters the test file and can easily drift out of date. If the mock will return with the upcoming store command, re-add it when that change lands.
For now, delete the line or annotate with a TODO including a ticket/PR reference.


14-17: Prefer test.skip over commented-out blocks

Vitest supports skipping while retaining visibility in the test report:

-// it("should return the command from the third positional argument if it is supported", () => {
-//   const flags: Arguments = { _: ["", "", "download"], version: false };
-//   expect(resolveCommand(flags)).toBe("download");
-// });
+it.skip("should return the command from the third positional argument if it is supported (download deprecated)", () => {
+  const flags: Arguments = { _: ["", "", "download"], version: false };
+  expect(resolveCommand(flags)).toBe("download");
+});

This keeps CI noise low yet reminds maintainers that coverage is intentionally paused.


80-95: Same for the integration test—use it.skip

Commenting removes the test from reporters entirely and risks accidental loss.
Convert to a skipped test or delete until the replacement command is implemented.

packages/cli/src/cli-utils.ts (1)

20-22: Minor: expose all supported commands in SUPPORTED_COMMANDS

SUPPORTED_COMMANDS now only contains "codegen".
Including "help" (and perhaps "version") would make ucd help resolve via the primary branch instead of the fallback route, improving clarity.

Optional tweak:

-const SUPPORTED_COMMANDS = new Set<CLICommand>(["codegen"]);
+const SUPPORTED_COMMANDS = new Set<CLICommand>(["help", "version", "codegen"]);
packages/utils/test/ucd-files/dump._test.ts (1)

1-210: All tests are commented out – either enable or delete

Keeping a .ts test file with 100 % commented content adds noise and may confuse tooling.
If these tests are WIP, rename the file to .test.todo.ts or move to a draft branch; otherwise delete it.

packages/ucd-store/src/local.ts (2)

100-101: Specify text encoding when reading the manifest

Relying on the adapter’s default may return a Buffer instead of a UTF-8 string for some implementations.

-const manifestContent = await this.#fs.readFile(storeManifestPath);
+const manifestContent = await this.#fs.readFile(storeManifestPath, "utf8");
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 100-100: packages/ucd-store/src/local.ts#L100
Added line #L100 was not covered by tests


143-144: Write manifest with explicit encoding

Same rationale as above; be explicit.

-await this.#fs.writeFile(storeManifestPath, JSON.stringify(manifestData, null, 2));
+await this.#fs.writeFile(
+  storeManifestPath,
+  JSON.stringify(manifestData, null, 2),
+  "utf8",
+);
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 143-143: packages/ucd-store/src/local.ts#L143
Added line #L143 was not covered by tests

packages/utils/src/ucd-files/validate.ts (1)

223-245: Unbounded Promise.all may overwhelm the proxy

Downloading hundreds of files concurrently can exhaust sockets or throttle the proxy.
Introduce a small pool (e.g. p-limit) or chunk with for..of + await to keep concurrency sane.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 223-225: packages/utils/src/ucd-files/validate.ts#L223-L225
Added lines #L223 - L225 were not covered by tests


[warning] 228-228: packages/utils/src/ucd-files/validate.ts#L228
Added line #L228 was not covered by tests


[warning] 231-231: packages/utils/src/ucd-files/validate.ts#L231
Added line #L231 was not covered by tests


[warning] 233-233: packages/utils/src/ucd-files/validate.ts#L233
Added line #L233 was not covered by tests


[warning] 235-241: packages/utils/src/ucd-files/validate.ts#L235-L241
Added lines #L235 - L241 were not covered by tests

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3292668 and fa61a58.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (20)
  • .changeset/happy-banks-happen.md (1 hunks)
  • packages/cli/src/cli-utils.ts (1 hunks)
  • packages/cli/src/cmd/download.ts (0 hunks)
  • packages/cli/test/cli-utils.test.ts (2 hunks)
  • packages/cli/test/cmd/download.test.ts (0 hunks)
  • packages/ucd-store/src/download.ts (0 hunks)
  • packages/ucd-store/src/fs-interface.ts (0 hunks)
  • packages/ucd-store/src/index.ts (0 hunks)
  • packages/ucd-store/src/local.ts (8 hunks)
  • packages/ucd-store/src/remote.ts (3 hunks)
  • packages/ucd-store/test/download.fs.test.ts (0 hunks)
  • packages/ucd-store/test/fs-interface.test.ts (0 hunks)
  • packages/utils/src/ucd-files.ts (1 hunks)
  • packages/utils/src/ucd-files/helpers.ts (1 hunks)
  • packages/utils/src/ucd-files/internal.ts (2 hunks)
  • packages/utils/src/ucd-files/validate.ts (3 hunks)
  • packages/utils/test/ucd-files/dump._test.ts (1 hunks)
  • packages/utils/test/ucd-files/fs-adapter.test.ts (1 hunks)
  • pnpm-workspace.yaml (1 hunks)
  • tooling/tsconfig/base.json (1 hunks)
💤 Files with no reviewable changes (7)
  • packages/ucd-store/src/index.ts
  • packages/cli/test/cmd/download.test.ts
  • packages/cli/src/cmd/download.ts
  • packages/ucd-store/src/fs-interface.ts
  • packages/ucd-store/test/fs-interface.test.ts
  • packages/ucd-store/test/download.fs.test.ts
  • packages/ucd-store/src/download.ts
🧰 Additional context used
🧬 Code Graph Analysis (3)
packages/utils/test/ucd-files/fs-adapter.test.ts (1)
packages/utils/src/ucd-files/fs-adapter.ts (2)
  • writeFile (33-35)
  • createDefaultFSAdapter (13-58)
packages/cli/test/cli-utils.test.ts (1)
packages/cli/src/cli-utils.ts (1)
  • resolveCommand (46-56)
packages/utils/src/ucd-files/internal.ts (1)
packages/utils/src/ucd-files.ts (1)
  • flattenFilePaths (5-5)
🪛 GitHub Check: codecov/patch
packages/ucd-store/src/local.ts

[warning] 72-72: packages/ucd-store/src/local.ts#L72
Added line #L72 was not covered by tests


[warning] 76-76: packages/ucd-store/src/local.ts#L76
Added line #L76 was not covered by tests


[warning] 100-100: packages/ucd-store/src/local.ts#L100
Added line #L100 was not covered by tests


[warning] 119-119: packages/ucd-store/src/local.ts#L119
Added line #L119 was not covered by tests


[warning] 143-143: packages/ucd-store/src/local.ts#L143
Added line #L143 was not covered by tests


[warning] 152-153: packages/ucd-store/src/local.ts#L152-L153
Added lines #L152 - L153 were not covered by tests

packages/utils/src/ucd-files/validate.ts

[warning] 183-196: packages/utils/src/ucd-files/validate.ts#L183-L196
Added lines #L183 - L196 were not covered by tests


[warning] 198-204: packages/utils/src/ucd-files/validate.ts#L198-L204
Added lines #L198 - L204 were not covered by tests


[warning] 206-212: packages/utils/src/ucd-files/validate.ts#L206-L212
Added lines #L206 - L212 were not covered by tests


[warning] 214-216: packages/utils/src/ucd-files/validate.ts#L214-L216
Added lines #L214 - L216 were not covered by tests


[warning] 218-218: packages/utils/src/ucd-files/validate.ts#L218
Added line #L218 was not covered by tests


[warning] 220-220: packages/utils/src/ucd-files/validate.ts#L220
Added line #L220 was not covered by tests


[warning] 223-225: packages/utils/src/ucd-files/validate.ts#L223-L225
Added lines #L223 - L225 were not covered by tests


[warning] 228-228: packages/utils/src/ucd-files/validate.ts#L228
Added line #L228 was not covered by tests


[warning] 231-231: packages/utils/src/ucd-files/validate.ts#L231
Added line #L231 was not covered by tests


[warning] 233-233: packages/utils/src/ucd-files/validate.ts#L233
Added line #L233 was not covered by tests


[warning] 235-241: packages/utils/src/ucd-files/validate.ts#L235-L241
Added lines #L235 - L241 were not covered by tests


[warning] 243-252: packages/utils/src/ucd-files/validate.ts#L243-L252
Added lines #L243 - L252 were not covered by tests


[warning] 254-254: packages/utils/src/ucd-files/validate.ts#L254
Added line #L254 was not covered by tests


[warning] 256-273: packages/utils/src/ucd-files/validate.ts#L256-L273
Added lines #L256 - L273 were not covered by tests

🔇 Additional comments (6)
pnpm-workspace.yaml (1)

24-24:

Details

✅ Verification successful

Confirm the new unicode-utils version is published

The alias for @luxass/unicode-utils-new was bumped to npm:@luxass/unicode-utils@0.12.0-beta.8. Ensure this version exists on the registry and matches the utilities your refactor now depends on.


🏁 Script executed:

#!/bin/bash
# Verify the published version of unicode-utils
npm view @luxass/unicode-utils@0.12.0-beta.8 version

Length of output: 68


✅ Verified: @luxass/unicode-utils@0.12.0-beta.8 is published

Running

npm view @luxass/unicode-utils@0.12.0-beta.8 version

returned 0.12.0-beta.8, confirming the package exists on the registry. No further action needed.

packages/utils/src/ucd-files/helpers.ts (1)

3-17:

Details

❓ Verification inconclusive

Edge-case: folders that also carry content are skipped

flattenFilePaths omits the path when an entry has children, assuming it’s purely a directory.
If the UnicodeVersionFile model ever allows both children and file data (e.g. an index file inside a folder), that file will be lost.

Consider:

-    if (file.children) {
-      paths.push(...flattenFilePaths(file.children, fullPath));
-    } else {
-      paths.push(fullPath);
-    }
+    if (file.children?.length) {
+      paths.push(...flattenFilePaths(file.children, fullPath));
+    }
+    // Push the node itself when it represents a real file (i.e., has no children OR can coexist with children)
+    if (!file.children || file.children.length === 0 || file.isFile) {
+      paths.push(fullPath);
+    }

If the data model guarantees “folder OR file” exclusivity, at least document that contract via a JSDoc comment to make the intention explicit.


🏁 Script executed:

#!/bin/bash
# Locate the UnicodeVersionFile type definition to verify its shape
rg -n "UnicodeVersionFile" -A5 packages/utils/src/ucd-files

Length of output: 2478


Clarify flattenFilePaths Assumptions

  • The current implementation treats any node with a defined children array—even an empty one—as a folder and never pushes its own path.
  • Please confirm the contract of UnicodeVersionFile.children:
    • Is it only ever defined on directories (and always undefined on leaf files)?
    • Or can a file node have both children and its own data (or an empty children array)?
  • If it’s truly “folder OR file” exclusive, document that in a JSDoc on flattenFilePaths (or on the type) to make the invariant explicit.
  • Otherwise, update the code to only recurse when there are actual children and always push the node’s path:
-  if (file.children) {
-    paths.push(...flattenFilePaths(file.children, fullPath));
-  } else {
-    paths.push(fullPath);
-  }
+  if (file.children?.length) {
+    paths.push(...flattenFilePaths(file.children, fullPath));
+  }
+  paths.push(fullPath);

Please verify and adjust accordingly.

packages/utils/src/ucd-files/internal.ts (1)

58-62: Verify flattenFilePaths prefix – risk of path mismatch

flattenFilePaths(filteredEntries, \${version}`)omits theucd/segment that may exist on disk (seeurlPathabove). IfflattenFilePathsdoesn't internally prepend that folder,locatedFiles` will contain paths that cannot be resolved later.

Please double-check the helper’s expected prefix and, if necessary, pass the full urlPath:

-    locatedFiles.push(...flattenFilePaths(filteredEntries, `${version}`));
+    locatedFiles.push(...flattenFilePaths(filteredEntries, urlPath.replace(/^\//, "")));
packages/ucd-store/src/remote.ts (1)

93-99: Good swap to buildUCDPath

Using the shared helper simplifies the URL construction and removes the earlier duplicated logic.
Looks correct and keeps the proxy handling intact.

packages/utils/src/ucd-files.ts (1)

5-11: Public surface LGTM

Re-exporting flattenFilePaths, mirrorUCDFiles, repairUCDFiles, and companions provides a clean, central API.
No issues spotted.

packages/utils/src/ucd-files/validate.ts (1)

104-104: flattenFilePaths may return absolute segments – normalise before comparing

If any required path is absolute, the subsequent files.includes(file) check will fail.
Consider path.relative or ensure flattenFilePaths always yields paths relative to the version root.

Comment on lines +10 to +11
"@ucdjs/utils/ucd-files": ["./packages/utils/src/ucd-files.ts"],
"@ucdjs/utils/types": ["./packages/utils/src/types.ts"],
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Avoid hard-coding .ts extensions in path aliases

Pointing a path alias directly at a .ts source file can bite you at runtime if anything consumes the compiled JS without the TypeScript path-mapping (e.g. tests executed with plain node, downstream packages, build artefacts published to npm).
Prefer aliasing a module directory (or the public entry file emitted to dist) instead:

-      "@ucdjs/utils/ucd-files": ["./packages/utils/src/ucd-files.ts"],
-      "@ucdjs/utils/types": ["./packages/utils/src/types.ts"],
+      "@ucdjs/utils/ucd-files": ["./packages/utils/src/ucd-files"],
+      "@ucdjs/utils/types": ["./packages/utils/src/types"],

This leaves resolution to TypeScript during dev while keeping the import specifier extension-agnostic for consumers.
Double-check any IDE/TS-Server errors after the change and ensure the emitted declaration maps stay intact.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"@ucdjs/utils/ucd-files": ["./packages/utils/src/ucd-files.ts"],
"@ucdjs/utils/types": ["./packages/utils/src/types.ts"],
"@ucdjs/utils/ucd-files": ["./packages/utils/src/ucd-files"],
"@ucdjs/utils/types": ["./packages/utils/src/types"],
🤖 Prompt for AI Agents
In tooling/tsconfig/base.json around lines 10 to 11, the path aliases currently
point directly to .ts source files, which can cause runtime issues for consumers
not using TypeScript path mapping. To fix this, change the aliases to point to
the module directories or the public entry files (e.g., the folder or the
compiled output location) instead of specific .ts files. After updating, verify
that IDE/TS-Server does not report errors and that emitted declaration files
maintain correct mappings.

Comment on lines 112 to 114
const fileStructure = await this.getFileTree(version);
return this.flattenFilePaths(fileStructure);
return flattenFilePaths(fileStructure);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Possible type / runtime issue when flattening the tree

flattenFilePaths(fileStructure) is called without the optional prefix that other callers supply.
That’s fine only if the second parameter is optional and defaults to "". If not, this will be a TS compile-time error.

Additionally, fileStructure may contain null children because processFileStructure filters only the top level.
flattenFilePaths should defensively skip falsy children to avoid runtime errors.

return flattenFilePaths(
-  fileStructure
+  fileStructure.filter(Boolean),         // ensure no nulls
+  ""                                     // explicit empty prefix clarifies intent
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const fileStructure = await this.getFileTree(version);
return this.flattenFilePaths(fileStructure);
return flattenFilePaths(fileStructure);
}
const fileStructure = await this.getFileTree(version);
return flattenFilePaths(
fileStructure.filter(Boolean), // ensure no nulls
"" // explicit empty prefix clarifies intent
);
}
🤖 Prompt for AI Agents
In packages/ucd-store/src/remote.ts around lines 112 to 114, ensure that when
calling flattenFilePaths(fileStructure), you provide the optional prefix
parameter if it is not defaulted to an empty string to avoid TypeScript errors.
Also, update flattenFilePaths to defensively check for and skip any falsy or
null children in fileStructure to prevent runtime errors caused by null entries
in the tree.

Comment on lines +152 to 154
throw new Error(
`[ucd-store]: Validation and repair functionality is not implemented yet. Please implement the _validateAndRepairStore method.`,
);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Unimplemented _validateAndRepairStore blocks shipping code

Throwing here prevents any existing store from booting, effectively breaking consumers. Either:

  1. Wire this to the new validateUCDFiles / repairUCDFiles utilities now, or
  2. Mark the entire class as experimental and guard usage upstream.

Leaving a hard throw in production code is unsafe.

Need help integrating the new utilities? Happy to sketch the implementation.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 152-153: packages/ucd-store/src/local.ts#L152-L153
Added lines #L152 - L153 were not covered by tests

🤖 Prompt for AI Agents
In packages/ucd-store/src/local.ts around lines 152 to 154, the current code
throws an error because the _validateAndRepairStore method is unimplemented,
which blocks the store from booting and breaks consumers. To fix this, replace
the throw statement by integrating the new validateUCDFiles and repairUCDFiles
utilities within the _validateAndRepairStore method to perform validation and
repair as intended. Alternatively, if immediate integration is not feasible,
mark the class as experimental and add guards upstream to prevent usage in
production until the method is implemented.

Comment on lines +72 to 73
this.#fs = this.#fs || (await createDefaultFSAdapter());

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Guard createDefaultFSAdapter() only once

Because the constructor already sets #fs, the bootstrap assignment will never execute unless #fs is falsy (now null). The current pattern works but favour a single initialisation site to avoid subtle state bugs; e.g. move the fallback logic to the constructor and drop this line.

🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 72-72: packages/ucd-store/src/local.ts#L72
Added line #L72 was not covered by tests

🤖 Prompt for AI Agents
In packages/ucd-store/src/local.ts at lines 72-73, the fallback initialization
of #fs using createDefaultFSAdapter() should be removed from bootstrap since the
constructor already sets #fs. Move the fallback logic entirely to the
constructor to ensure #fs is initialized in one place only, then delete the
conditional assignment in bootstrap to avoid redundant or conflicting state
initialization.

Comment on lines +65 to 67
// TODO: fix this!
this.#fs = options.fs!;
this.#filter = createPathFilter(filters);
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid unsafe non-null assertion on options.fs

options.fs! will crash if the caller omits the adapter – precisely the scenario the default path is meant to cover. Either make fs mandatory in the public type or fall back immediately.

-// TODO: fix this!
-this.#fs = options.fs!;
+this.#fs = options.fs ?? null; // initialised later in bootstrap

(Remove the non-null assertion and treat the field as possibly null until bootstrap assigns the default.)

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// TODO: fix this!
this.#fs = options.fs!;
this.#filter = createPathFilter(filters);
this.#fs = options.fs ?? null; // initialised later in bootstrap
this.#filter = createPathFilter(filters);
🤖 Prompt for AI Agents
In packages/ucd-store/src/local.ts around lines 65 to 67, remove the non-null
assertion on options.fs to avoid potential crashes if fs is omitted. Instead,
treat this.#fs as possibly null or undefined initially, and ensure it falls back
to a default adapter during bootstrap or initialization. Adjust the code to
safely handle the absence of fs without assuming it is always provided.

Comment on lines +218 to +221
try {
// ensure the version directory exists
await fs.mkdir(versionOutputDir, { recursive: true });

Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Use ensureDir instead of mkdir for adapter portability

FSAdapter does not guarantee a low-level mkdir method, but it does expose ensureDir (already used below). Stick to the higher-level helper for consistency.

-// ensure the version directory exists
-await fs.mkdir(versionOutputDir, { recursive: true });
+// ensure the version directory exists
+await fs.ensureDir(versionOutputDir);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
try {
// ensure the version directory exists
await fs.mkdir(versionOutputDir, { recursive: true });
try {
// ensure the version directory exists
await fs.ensureDir(versionOutputDir);
🧰 Tools
🪛 GitHub Check: codecov/patch

[warning] 218-218: packages/utils/src/ucd-files/validate.ts#L218
Added line #L218 was not covered by tests


[warning] 220-220: packages/utils/src/ucd-files/validate.ts#L220
Added line #L220 was not covered by tests

🤖 Prompt for AI Agents
In packages/utils/src/ucd-files/validate.ts around lines 218 to 221, replace the
use of fs.mkdir with fs.ensureDir to create the version directory. This change
ensures compatibility with the FSAdapter, which may not support mkdir but does
provide ensureDir. Update the code to call await fs.ensureDir(versionOutputDir,
{ recursive: true }) instead of mkdir for consistent and portable directory
creation.

Copy link
Member Author

luxass commented Jun 15, 2025

Merge activity

  • Jun 15, 2:11 PM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jun 15, 2:11 PM UTC: @luxass merged this pull request with Graphite.

@luxass luxass merged commit 115abdd into main Jun 15, 2025
5 of 6 checks passed
@luxass luxass deleted the luxass/06-14-refactor-migrate-ucd-store-to-use-utils branch June 15, 2025 14:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pkg: cli Changes related to the CLI package. pkg: ucd-store Changes related to the UCD Store package. pkg: utils Changes related to the Utils package.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

migrate ucd-store to using utils package

1 participant