-
Notifications
You must be signed in to change notification settings - Fork 2
[WIP] chore(api): create modular config interface #1352
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Note Reviews pausedUse the following commands to manage reviews:
WalkthroughThis pull request introduces a new configuration variable, Changes
Sequence Diagram(s)sequenceDiagram
participant App as Application Startup
participant FS as File System (mkdirSync)
participant Env as Environment Module
App->>Env: Retrieve CONFIG_MODULES_HOME value
Env-->>App: Returns path value
App->>FS: Call mkdirSync(<CONFIG_MODULES_HOME>, {recursive: true})
FS-->>App: Directory created (if not exists)
sequenceDiagram
participant Main as Main App
participant Reg as ApiStateConfigModule.register()
participant Conf as ApiStateConfig Instance
participant Prov as Providers (ConfigProvider & PersistenceProvider)
participant Scheduler as ScheduledConfigPersistence
Main->>Reg: Call register(options)
Reg->>Conf: Instantiate ApiStateConfig with default settings
Reg->>Prov: Setup ConfigProvider and PersistenceProvider
Prov->>Scheduler: Initialize scheduled persistence
Scheduler-->>Prov: Scheduled task ready
Reg-->>Main: Return DynamicModule with providers
Suggested reviewers
Poem
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
@coderabbitai pause |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (9)
api/src/index.ts (2)
6-6
: Fix import order according to linting rulesThe static analysis is flagging an ordering issue with the imports.
-import { unlinkSync, mkdirSync } from 'fs'; +import { mkdirSync, unlinkSync } from 'fs';🧰 Tools
🪛 GitHub Check: Build API
[failure] 6-6:
ReplaceunlinkSync,·mkdir
withmkdirSync,·unlink
🪛 GitHub Check: Test API
[failure] 6-6:
ReplaceunlinkSync,·mkdir
withmkdirSync,·unlink
17-17
: Fix import order according to linting rulesThe static analysis is flagging an ordering issue with the environment imports.
-import { environment, PORT, CONFIG_MODULES_HOME } from '@app/environment.js'; +import { CONFIG_MODULES_HOME, environment, PORT } from '@app/environment.js';🧰 Tools
🪛 GitHub Check: Build API
[failure] 17-17:
Replaceenvironment,·PORT,·CONFIG_MODULES_HOME
withCONFIG_MODULES_HOME,·environment,·PORT
🪛 GitHub Check: Test API
[failure] 17-17:
Replaceenvironment,·PORT,·CONFIG_MODULES_HOME
withCONFIG_MODULES_HOME,·environment,·PORT
api/src/unraid-api/config/config.interface.ts (1)
1-9
: Consider the static analysis suggestion about empty interfaceWhile the empty
ConfigFeatures
interface serves as a container for type extensions, the static analyzer flags it as suspicious. Since it's meant to be extended, keeping it as an interface is justified, but you could add documentation to clarify this for static analyzers./** * Container record of config names to their types. Used for type completion on registered configs. * Config authors should redeclare/merge this interface with their config names as the keys * and implementation models as the types. + * + * @remarks This is intentionally an empty interface to be extended by other modules. */ export interface ConfigFeatures {};🧰 Tools
🪛 Biome (1.9.4)
[error] 8-8: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
api/src/unraid-api/config/config.registry.ts (1)
14-30
: Consider refactoring the static-only classThe static analysis tool flags this class for having only static members. While functionally correct, consider these alternatives:
- Use the class name instead of
this
in static methods- Convert to a namespace or module-level object with exported functions
Option 1: Use class name instead of
this
:export class ConfigRegistry { /** A map of config names to their implementation models. */ private static configTypes = new Map<string, string>(); static register(configName: string, configType: string) { - this.configTypes.set(configName, configType); + ConfigRegistry.configTypes.set(configName, configType); } static getConfigType(configName: string) { - return this.configTypes.get(configName); + return ConfigRegistry.configTypes.get(configName); } static getConfigToken(configName: string) { const configType = ConfigRegistry.getConfigType(configName) ?? ''; return makeConfigToken(configName, configType); } }Option 2: Convert to module-level functions:
/** A map of config names to their implementation models. */ const configTypes = new Map<string, string>(); export function registerConfig(configName: string, configType: string) { configTypes.set(configName, configType); } export function getConfigType(configName: string) { return configTypes.get(configName); } export function getConfigToken(configName: string) { const configType = getConfigType(configName) ?? ''; return makeConfigToken(configName, configType); }🧰 Tools
🪛 Biome (1.9.4)
[error] 14-30: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 19-19: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.(lint/complexity/noThisInStatic)
[error] 23-23: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.(lint/complexity/noThisInStatic)
api/src/unraid-api/config/api-state.service.ts (2)
4-5
: Consider using absolute import paths.Static analysis flags these relative imports. If your style guide requires absolute paths, consider updating these imports accordingly.
- import type { ApiStateConfig } from './api-state.model.js'; - import { makeConfigToken } from './config.registry.js'; + import type { ApiStateConfig } from '@app/unraid-api/config/api-state.model.js'; + import { makeConfigToken } from '@app/unraid-api/config/config.registry.js';🧰 Tools
🪛 GitHub Check: Build API
[failure] 4-4:
import statements should have an absolute path🪛 GitHub Check: Test API
[failure] 4-4:
import statements should have an absolute path
57-70
: Consider handling multiple invocations of setup().If this method is called more than once, multiple intervals could be registered for the same token, leading to unexpected behavior. An optional improvement is to guard against re-initializing.
setup() { if (this.schedulerRegistry.doesExists('interval', this.token)) { + this.logger.warn(`Persistence already set up for token ${this.token}. Skipping re-initialization.`); return; } ... }
api/src/unraid-api/config/api-state.register.ts (2)
4-7
: Consider using absolute import paths.Your build pipeline reports warnings for relative paths. Converting them to absolute paths may align with your import style guidelines.
- import type { ApiStateConfigOptions } from './api-state.model.js'; - import type { ApiStateConfigPersistenceOptions } from './api-state.service.js'; - import { ApiStateConfig } from './api-state.model.js'; - import { ScheduledConfigPersistence } from './api-state.service.js'; + import type { ApiStateConfigOptions } from '@app/unraid-api/config/api-state.model.js'; + import type { ApiStateConfigPersistenceOptions } from '@app/unraid-api/config/api-state.service.js'; + import { ApiStateConfig } from '@app/unraid-api/config/api-state.model.js'; + import { ScheduledConfigPersistence } from '@app/unraid-api/config/api-state.service.js';🧰 Tools
🪛 GitHub Check: Build API
[failure] 4-4:
import statements should have an absolute path
[failure] 5-5:
import statements should have an absolute path
[failure] 6-6:
import statements should have an absolute path
[failure] 7-7:
import statements should have an absolute path🪛 GitHub Check: Test API
[failure] 4-4:
import statements should have an absolute path
[failure] 5-5:
import statements should have an absolute path
[failure] 6-6:
import statements should have an absolute path
[failure] 7-7:
import statements should have an absolute path
13-45
: Consider refactoring to a plain function rather than a static-only class.A lint rule warns about classes containing only static methods. If instance state is unnecessary, a simpler function can suffice. Alternatively, keep the class if you anticipate adding instance functionality later.
-export class ApiStateConfigModule { - private static readonly logger = new Logger(ApiStateConfigModule.name); - - static async register<ConfigType>( - options: ApiStateRegisterOptions<ConfigType> - ): Promise<DynamicModule> { - ... - return { - module: ApiStateConfigModule, - providers: [ConfigProvider, PersistenceProvider], - exports: [ConfigProvider], - }; - } -} + +export async function registerApiStateConfigModule<ConfigType>( + options: ApiStateRegisterOptions<ConfigType> +): Promise<DynamicModule> { + const logger = new Logger('ApiStateConfigModule'); + ... + return { + module: class {}, + providers: [ConfigProvider, PersistenceProvider], + exports: [ConfigProvider], + }; +}🧰 Tools
🪛 Biome (1.9.4)
[error] 13-45: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
api/src/unraid-api/config/api-state.model.ts (1)
10-10
: Consider using absolute import paths.Static analysis warns about these imports. Converting them to absolute references could satisfy your project’s build checks.
- import { ConfigRegistry } from './config.registry.js'; + import { ConfigRegistry } from '@app/unraid-api/config/config.registry.js';🧰 Tools
🪛 GitHub Check: Build API
[failure] 10-10:
import statements should have an absolute path🪛 GitHub Check: Test API
[failure] 10-10:
import statements should have an absolute path
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (12)
api/.env.development
(1 hunks)api/.env.production
(1 hunks)api/.env.staging
(1 hunks)api/.env.test
(1 hunks)api/src/environment.ts
(1 hunks)api/src/index.ts
(3 hunks)api/src/unraid-api/config/api-state.model.ts
(1 hunks)api/src/unraid-api/config/api-state.register.ts
(1 hunks)api/src/unraid-api/config/api-state.service.ts
(1 hunks)api/src/unraid-api/config/config.injection.ts
(1 hunks)api/src/unraid-api/config/config.interface.ts
(1 hunks)api/src/unraid-api/config/config.registry.ts
(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (6)
api/src/unraid-api/config/config.injection.ts (2)
api/src/unraid-api/config/config.interface.ts (1)
ConfigFeatures
(8-8)api/src/unraid-api/config/config.registry.ts (1)
ConfigRegistry
(14-30)
api/src/index.ts (1)
api/src/environment.ts (1)
CONFIG_MODULES_HOME
(89-89)
api/src/unraid-api/config/api-state.register.ts (2)
api/src/unraid-api/config/api-state.model.ts (2)
ApiStateConfigOptions
(12-17)ApiStateConfig
(19-103)api/src/unraid-api/config/api-state.service.ts (2)
ApiStateConfigPersistenceOptions
(7-16)ScheduledConfigPersistence
(18-74)
api/src/unraid-api/config/api-state.service.ts (2)
api/src/unraid-api/config/api-state.model.ts (1)
ApiStateConfig
(19-103)api/src/unraid-api/config/config.registry.ts (1)
makeConfigToken
(10-12)
api/src/unraid-api/config/api-state.model.ts (2)
api/src/unraid-api/config/config.registry.ts (1)
ConfigRegistry
(14-30)api/src/environment.ts (1)
CONFIG_MODULES_HOME
(89-89)
api/src/unraid-api/config/config.registry.ts (1)
api/src/unraid-api/config/api-state.service.ts (1)
configName
(34-36)
🪛 GitHub Check: Build API
api/src/environment.ts
[failure] 89-89:
Insert ⏎
[failure] 89-89:
Newline required at end of file but not found
api/src/index.ts
[failure] 6-6:
Replace unlinkSync,·mkdir
with mkdirSync,·unlink
[failure] 17-17:
Replace environment,·PORT,·CONFIG_MODULES_HOME
with CONFIG_MODULES_HOME,·environment,·PORT
api/src/unraid-api/config/api-state.register.ts
[failure] 4-4:
import statements should have an absolute path
[failure] 5-5:
import statements should have an absolute path
[failure] 6-6:
import statements should have an absolute path
[failure] 7-7:
import statements should have an absolute path
api/src/unraid-api/config/api-state.service.ts
[failure] 4-4:
import statements should have an absolute path
api/src/unraid-api/config/api-state.model.ts
[failure] 10-10:
import statements should have an absolute path
🪛 GitHub Check: Test API
api/src/environment.ts
[failure] 89-89:
Insert ⏎
[failure] 89-89:
Newline required at end of file but not found
api/src/index.ts
[failure] 6-6:
Replace unlinkSync,·mkdir
with mkdirSync,·unlink
[failure] 17-17:
Replace environment,·PORT,·CONFIG_MODULES_HOME
with CONFIG_MODULES_HOME,·environment,·PORT
api/src/unraid-api/config/api-state.register.ts
[failure] 4-4:
import statements should have an absolute path
[failure] 5-5:
import statements should have an absolute path
[failure] 6-6:
import statements should have an absolute path
[failure] 7-7:
import statements should have an absolute path
api/src/unraid-api/config/api-state.service.ts
[failure] 4-4:
import statements should have an absolute path
api/src/unraid-api/config/api-state.model.ts
[failure] 10-10:
import statements should have an absolute path
🪛 Biome (1.9.4)
api/src/unraid-api/config/config.interface.ts
[error] 8-8: An empty interface is equivalent to {}.
Safe fix: Use a type alias instead.
(lint/suspicious/noEmptyInterface)
api/src/unraid-api/config/api-state.register.ts
[error] 13-45: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
api/src/unraid-api/config/config.registry.ts
[error] 14-30: Avoid classes that contain only static members.
Prefer using simple functions instead of classes with only static members.
(lint/complexity/noStaticOnlyClass)
[error] 19-19: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
[error] 23-23: Using this in a static context can be confusing.
this refers to the class.
Unsafe fix: Use the class name instead.
(lint/complexity/noThisInStatic)
⏰ Context from checks skipped due to timeout of 90000ms (2)
- GitHub Check: Build Web App
- GitHub Check: Cloudflare Pages
🔇 Additional comments (9)
api/.env.test (1)
12-12
: Looks good - new config variable added consistently.The CONFIG_MODULES_HOME variable has been added with a development-appropriate relative path that matches the pattern of other configuration paths in this file.
api/.env.development (1)
12-12
: Looks good - new config variable added consistently.The CONFIG_MODULES_HOME variable has been added with a development-appropriate relative path that matches the pattern of other configuration paths in this file.
api/.env.production (1)
5-5
: Looks good - new config variable added with production path.The CONFIG_MODULES_HOME variable has been added with an appropriate absolute path for the production environment.
api/.env.staging (1)
5-5
: Looks good - new config variable added with staging path.The CONFIG_MODULES_HOME variable has been added with an appropriate absolute path for the staging environment, matching the production path for environment parity.
api/src/unraid-api/config/config.injection.ts (1)
1-13
: Well-designed custom decorator for configuration injectionThe
InjectConfig
decorator provides a clean abstraction over NestJS's dependency injection system for configuration settings. Good use of generics to ensure type safety by constraining the feature parameter to keys of theConfigFeatures
interface.api/src/index.ts (1)
47-48
: Good practice ensuring the config directory existsCreating the config modules directory at startup with recursive option is a good practice to prevent file operation errors later in the application lifecycle.
api/src/unraid-api/config/config.interface.ts (1)
11-20
: Good interface design for configuration metadataThe
ConfigMetadata
interface provides a clear structure for configuration metadata with well-documented properties. The use of Zod for schema validation is a good practice for runtime type checking.api/src/unraid-api/config/config.registry.ts (1)
10-12
: Clean implementation of token creationThe
makeConfigToken
function is a simple and effective way to generate unique tokens for configurations.api/src/unraid-api/config/api-state.model.ts (1)
19-29
: Nice design for managing default config immutability and logging.Registering the config before assigning a new logger ensures the token is always recognized, and the
structuredClone
usage effectively prevents accidental mutations tooptions.defaultConfig
.
api/src/environment.ts
Outdated
@@ -86,3 +86,4 @@ | |||
: 'https://mothership.unraid.net/ws'; | |||
|
|||
export const PM2_HOME = process.env.PM2_HOME ?? join(homedir(), '.pm2'); | |||
export const CONFIG_MODULES_HOME = process.env.CONFIG_MODULES_HOME!; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add fallback value and fix missing newline.
Two issues to address:
- The non-null assertion (
!
) assumes CONFIG_MODULES_HOME will always be defined. Consider adding a fallback value to prevent potential runtime errors. - Static analysis indicates a missing newline at the end of the file.
-export const CONFIG_MODULES_HOME = process.env.CONFIG_MODULES_HOME!;
+export const CONFIG_MODULES_HOME = process.env.CONFIG_MODULES_HOME ?? './configs';
+
📝 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.
export const CONFIG_MODULES_HOME = process.env.CONFIG_MODULES_HOME!; | |
export const CONFIG_MODULES_HOME = process.env.CONFIG_MODULES_HOME ?? './configs'; | |
🧰 Tools
🪛 GitHub Check: Build API
[failure] 89-89:
Insert ⏎
[failure] 89-89:
Newline required at end of file but not found
🪛 GitHub Check: Test API
[failure] 89-89:
Insert ⏎
[failure] 89-89:
Newline required at end of file but not found
✅ Actions performedReviews paused. |
7c6525e
to
86cd4b4
Compare
This plugin has been deployed to Cloudflare R2 and is available for testing.
|
Summary by CodeRabbit