feat(typed-config): new package combining cosmiconfig+toml+xdg+standard-schema#297
feat(typed-config): new package combining cosmiconfig+toml+xdg+standard-schema#297stephansama wants to merge 1 commit into
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (7)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
There was a problem hiding this comment.
Code Review
This pull request introduces @stephansama/typed-config, a new configuration loader that integrates cosmiconfig, smol-toml, and xdg-app-paths with validation via Standard Schema V1. The feedback highlights a missing root-level TOML search path, potential issues with shallow merging of default values for nested schemas, and performance concerns regarding the inclusion of absolute XDG paths in the cosmiconfig search sequence.
| const base = [ | ||
| ...getDefaultSearchPlaces(name), | ||
| `.config/.${name}rc.json`, | ||
| `.config/.${name}rc.yaml`, | ||
| `.config/.${name}rc.yml`, | ||
| `.config/.${name}rc.toml`, | ||
| `.config/.${name}rc`, | ||
| ]; |
There was a problem hiding this comment.
The buildSearchPlaces function is missing .${name}rc.toml in the root search places. While it is included for the .config/ subdirectory, the PR description and README state that standard discovery should include .<name>rc.toml at the project root. Since cosmiconfig's getDefaultSearchPlaces does not include TOML by default, it should be explicitly added here to ensure consistency with the documentation.
| const base = [ | |
| ...getDefaultSearchPlaces(name), | |
| `.config/.${name}rc.json`, | |
| `.config/.${name}rc.yaml`, | |
| `.config/.${name}rc.yml`, | |
| `.config/.${name}rc.toml`, | |
| `.config/.${name}rc`, | |
| ]; | |
| const base = [ | |
| ...getDefaultSearchPlaces(name), | |
| `.${name}rc.toml`, | |
| `.config/.${name}rc.json`, | |
| `.config/.${name}rc.yaml`, | |
| `.config/.${name}rc.yml`, | |
| `.config/.${name}rc.toml`, | |
| `.config/.${name}rc`, | |
| ]; |
| const found = await explorer.search(); | ||
| const raw = found?.config as Partial<T> | undefined; | ||
|
|
||
| const merged: unknown = { ...defaults, ...raw }; |
There was a problem hiding this comment.
The merge between defaults and the loaded config (raw) is a shallow merge. If the configuration schema contains nested objects, any values provided in the config file for a nested key will completely overwrite the corresponding nested object in defaults, rather than merging them. This might be unexpected for users providing complex default configurations. Consider using a deep merge approach if nested support is intended.
| const xdgDirectory = path.join(xdgAppPaths(name).config(), "config"); | ||
| return [ | ||
| ...base, | ||
| `${xdgDirectory}.json`, | ||
| `${xdgDirectory}.yaml`, | ||
| `${xdgDirectory}.yml`, | ||
| `${xdgDirectory}.toml`, | ||
| ]; |
There was a problem hiding this comment.
Including absolute XDG paths in searchPlaces causes cosmiconfig to check these same absolute paths repeatedly at every level of the directory tree as it climbs upwards from the current working directory. This results in redundant disk I/O. A more efficient approach would be to handle XDG paths as a separate fallback step after the project-local search is completed.
Closes STE-40
New
@stephansama/typed-configpackage. OnecreateConfig({ name, schema, xdg?, defaults? })call wraps cosmiconfig + smol-toml + xdg-app-paths and validates the result through any Standard-Schema-V1 validator (zod / valibot / arktype).Search order
.<name>rc{,.json,.yaml,.yml,.toml},package.json#<name>)..config/.<name>rc.{json,yaml,yml,toml}under the project root.xdg: true)$XDG_CONFIG_HOME/<name>/config.{json,yaml,yml,toml}(fallback~/.config/<name>/).Explicit
defaultsmerge underneath the loaded file before validation. TOML loader registered automatically viasmol-toml.Tests
5 cases in
src/index.test.tscover defaults, JSON loading, TOML loading, defaults+file merge, and validation-error throw path.Acceptance criteria
createConfig(schema, { name })loads + validates via cosmiconfigxdg: trueCreateConfigOptions<T>,ConfigResult<T>