{"id":17652415,"url":"https://github.com/bashleigh/nestjs-config-v2-prototype","last_synced_at":"2025-05-07T07:34:18.020Z","repository":{"id":41798284,"uuid":"172731042","full_name":"bashleigh/nestjs-config-v2-prototype","owner":"bashleigh","description":"An example/prototype of v2 for nestjs-config","archived":false,"fork":false,"pushed_at":"2023-01-03T16:53:21.000Z","size":289,"stargazers_count":7,"open_issues_count":15,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-31T07:41:34.088Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bashleigh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-02-26T14:48:13.000Z","updated_at":"2023-03-10T08:05:28.000Z","dependencies_parsed_at":"2023-02-01T08:01:23.028Z","dependency_job_id":null,"html_url":"https://github.com/bashleigh/nestjs-config-v2-prototype","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fnestjs-config-v2-prototype","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fnestjs-config-v2-prototype/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fnestjs-config-v2-prototype/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bashleigh%2Fnestjs-config-v2-prototype/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bashleigh","download_url":"https://codeload.github.com/bashleigh/nestjs-config-v2-prototype/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252834049,"owners_count":21811300,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-23T11:46:54.552Z","updated_at":"2025-05-07T07:34:17.993Z","avatar_url":"https://github.com/bashleigh.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Nestjs-config v2 prototype\n\nAfter creating this [proposal](https://github.com/nestjs-community/nestjs-config/issues/54) I decided to create this prototype before attempting to modify the existing code base. This also enables me to create a fresh scenario to test my logic and new implementation of features etc.\n\n## Testing\n\n```bash\n$ yarn test\n```\n\nThis prototype will hopefully enable a better solution to using the nestjs-config module and be more of a 'nest' implementation of the existing module and utilise more of the nestjs container instead of 'bunging' everyrthing into one provider thus providing a better usage of nestjs and the config module.\n\n## Examples\n\n### Injecting\n\nInjecting will move away from a singular module inject and enable more freely injectable providers as such\n\n#### Inject via token\n\nBasic objects can be injected using a token\n\n```typescript\n// config/my_config.ts\nexport default {\n  test: string = 'hello';\n}\n```\n\n```typescript\nimport {InjectConfig} from 'nestjs-config';\nimport {Controller} from '@nestjs/common';\n\n@Controller()\nexport class ExampleController {\n  constructor(private readonly @InjectConfig('my_config') config) {}\n\n  someMethod(): string {\n    return this.config.test;\n  }\n\n  anotherMethod(): string {\n    return this.config.get\u003cstring\u003e('not.defined', 'default value');\n  }\n}\n```\n\nIn the above example you'll notice that there is a method `get` on the injected config parameter. That's because all object configs are 'wrapped' in a `Config` class which provides such lodash get functionality like in the previous version of `nestjs-config`. Except now it has a Type Parameter (**Thanks @natc ;)**).\n\n#### Inject via Type\n\nTyped classes etc can be used to inject your config. \n\nIn this example the class used does not come with the `get` functionality although you could extend the config class if you so wished `export default class MyConfigClass extends Config {}`.\n\nAll 'types' are used as `ClassProvider`s. So they are technically injectables?\n\n```typescript\n// config/my.config.class.ts\nexport default class MyConfigClass {\n  public static test: string = 'hello';\n}\n```\n\n```typescript\n\n@Module({\n  imports: [\n    ConfigModule.forRootAsync(path.resolve(__dirname, 'config', '**', '*(!.d).{ts,js}')),\n    SomeModle.forRootAsync({\n      useFactory: (conifg: MyConfigClass) =\u003e config,\n      inject: [MyConfigClass],\n    }),\n  ],\n})\nexport class ExampleModule {}\n```\n\nThe below will not work as ConfigProviders are created asynchronously via the ConfigModule.\n\n```typescript\nimport { MyConfigClass } from './config/my.config.class';\nimport { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class ExampleProvider {\n  constructor(private readonly config: MyConfigClass) {}\n}\n```\n\n#### Defined tokens injection\n\nThe token used can be manipulated as such\n\n```typescript\n// config/my.defined.provide.ts\nexport default {\n  __provide: 'my_custom_token',\n};\n```\n\n```typescript\nimport {Injectable} from '@nestjs/common';\n\nInjectable()\nexport class ExampleProvider {\n\tconstructor(private readonly @InjectConfig('my_custom_token') config) {}\n}\n```\n\nAgain the above should work with Provider types such as\n\n```typescript\n// config/database.ts\n\nexport default class DatabaseConfig implements TypeOrmModuleOptions {\n  public static type: string = 'mysql';\n  public static host: process.env.TYPEORM_HOST,\n  public static port: process.env.TYPEORM_PORT,\n  public static username: process.env.TYPEORM_USERNAME,\n  public static password: process.env.TYPEORM_PASSWORD,\n}\n```\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { ConfigModule } from 'nestjs-config';\nimport { TypeOrmModule } from '@nestjs/typeorm';\nimport DatabaseConfig from './config/database';\n\n@Module({\n  imports: [\n    ConfigModule.forRootAsync('config/**/*(!.d).{ts,js}'),\n    TypeOrmModule.forRootAsync({\n      useFactory: (config: DatabaseConfig) =\u003e config,\n      injects: [DatabaseConfig],\n    }),\n  ],\n})\nexport class ExampleModule {}\n```\n\nAlternatively using no class/type\n\n```typescript\n// config/database.ts\nexport default {\n  type: 'mysql',\n  host: process.env.TYPEORM_HOST,\n  ...\n}\n```\n\n```typescript\nimport { Module } from '@nestjs/common';\nimport { ConfigModule, configToken } from 'nestjs-config';\nimport { TypeOrmModule } from '@nestjs/typeorm';\n\n@Module({\n  imports: [\n    ConfigModule.forRootAsync('config/**/*(!.d).{ts,js}'),\n    TypeOrmModule.forRootAsync({\n      useFactory: config =\u003e config,\n      injects: [configToken('database')],\n    }),\n  ],\n})\nexport class ExampleModule {}\n```\n\nBy default the file name is used for the token if no `__provide` key is specified.\n\n### Using the ConfigService\n\nIn my proposal I wasn't sure if the ConfigService still had a role within the config module. However I've managed to maintain some of the v1 functionality by utiling the moduleRef and keeping local references of the `__name`,`__provide` or file name of the provider's token being created. I'm not sure I like this functionality as it is; as a provider currently cannot be found using a ClassProvider token which is kinda sad. Would be nice but not quite sure how it would really work? Plus using the moduleRef seems a little hacky and kind of defeats the purpose of types before runtime. \n\n```typescript\nimport {Injectable} from '@nestjs/common';\nimport {ConfigService} from 'nestjs-config';\n\n@Injectable()\nexport class ExampleProvider {\n  constructor(private readonly configService: ConfigService) {}\n\n  someMethod(): string {\n    return this.configService.get\u003cstring\u003e('my_config.test', 'something that doesn\\'t say hello');\n  }\n}\n```\n\n## Merge \n\nMerge has been remove in v2, the prefered method is to use `ConfigModule.forRootAsync` in your module.\n\n## Renaming method\n\nThe renaming method has been removed as of v2. The perfered method now is to define your name/provide token using the `__name` or `__provide` keys defined in `DefinedConfigProvider`.\n\n\n## TODO\n\n- [x] forRoot method\n- [x] ~~merging for modules~~ (Might as well use comfigModule.forRootAsync?)\n- [x] dotenv loading\n- [x] resolveRootPath\n- [x] documentation comments\n- [ ] throw exception on no default export from file? Or consider what to do if multiple exports\n- [ ] throw exception on no defined config provider\n- [x] throw exception when no reference token is found\n- [ ] validating config types etc with different package/drivers\n- [x] add configService back into configModule and resolve names with references of their token \n- [x] ~~add rename method etc (do I still need this with __name || __provide?)~~\n- [x] add configModuleOptions back in\n- [x] ~~attempt static property setting with decorator~~ don't need it \n- [x] ~~attempt better parameter decorator setter~~ don't need it \n- [ ] consider replacing loadash.get with ts-get\n- [x] ~~make sure injection via type works correctly~~ Won't work because the token doesn't exist before injectable is instanced\n- [x] make a 'toString' or 'toObject' method for when calling as `config` as the tokens would require `useFactory: (config: Config) =\u003e config.config)` bit annoying. Maybe just define to Config instead of Config.config ","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashleigh%2Fnestjs-config-v2-prototype","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbashleigh%2Fnestjs-config-v2-prototype","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbashleigh%2Fnestjs-config-v2-prototype/lists"}