@config-bound/nestjs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +4 -0
- package/.turbo/turbo-format$colon$ci.log +6 -0
- package/.turbo/turbo-lint$colon$ci.log +4 -0
- package/.turbo/turbo-test.log +22 -0
- package/CHANGELOG.md +37 -0
- package/PUBLISHING.md +211 -0
- package/README.md +230 -0
- package/dist/config-bound.module.d.ts +10 -0
- package/dist/config-bound.module.d.ts.map +1 -0
- package/dist/config-bound.module.js +95 -0
- package/dist/config-bound.module.js.map +1 -0
- package/dist/config-bound.service.d.ts +22 -0
- package/dist/config-bound.service.d.ts.map +1 -0
- package/dist/config-bound.service.js +65 -0
- package/dist/config-bound.service.js.map +1 -0
- package/dist/config-bound.service.spec.d.ts.map +1 -0
- package/dist/config-bound.service.spec.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/config-bound-module-options.interface.d.ts +34 -0
- package/dist/interfaces/config-bound-module-options.interface.d.ts.map +1 -0
- package/dist/interfaces/config-bound-module-options.interface.js +6 -0
- package/dist/interfaces/config-bound-module-options.interface.js.map +1 -0
- package/eslint.config.mjs +3 -0
- package/jest.config.js +23 -0
- package/package.json +62 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
|
|
2
|
+
> @config-bound/nestjs@0.1.0 test
|
|
3
|
+
> jest
|
|
4
|
+
|
|
5
|
+
PASS src/config-bound.service.spec.ts (11.38 s)
|
|
6
|
+
ConfigBoundService
|
|
7
|
+
✓ should be defined (18 ms)
|
|
8
|
+
✓ should have a name (4 ms)
|
|
9
|
+
✓ should get default values (8 ms)
|
|
10
|
+
✓ should get database configuration (6 ms)
|
|
11
|
+
✓ should throw when getting non-existent value with getOrThrow (23 ms)
|
|
12
|
+
✓ should have sections (11 ms)
|
|
13
|
+
✓ should validate configuration (5 ms)
|
|
14
|
+
ConfigBoundModule - forRootAsync
|
|
15
|
+
✓ should be defined with async configuration (8 ms)
|
|
16
|
+
✓ should get values from async config (5 ms)
|
|
17
|
+
|
|
18
|
+
Test Suites: 1 passed, 1 total
|
|
19
|
+
Tests: 9 passed, 9 total
|
|
20
|
+
Snapshots: 0 total
|
|
21
|
+
Time: 11.776 s
|
|
22
|
+
Ran all test suites.
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# @config-bound/nestjs
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 3c2cf21: Add a CLI to export and interact with configuration schemas
|
|
8
|
+
- de1dc3b: Add @config-bound/nestjs package for NestJS integration
|
|
9
|
+
- Add ConfigBoundModule with forRoot() and forRootAsync() methods
|
|
10
|
+
- Add ConfigBoundService for dependency injection
|
|
11
|
+
- Support for both synchronous and asynchronous configuration
|
|
12
|
+
- Full TypeScript type safety and inference
|
|
13
|
+
- Integration with NestJS dependency injection system
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- dca5c72: Bumped various dependencies to latest.
|
|
18
|
+
- Updated dependencies [de1dc3b]
|
|
19
|
+
- Updated dependencies [3c2cf21]
|
|
20
|
+
- Updated dependencies [dca5c72]
|
|
21
|
+
- @config-bound/config-bound@0.1.0
|
|
22
|
+
|
|
23
|
+
## 1.0.0
|
|
24
|
+
|
|
25
|
+
### Minor Changes
|
|
26
|
+
|
|
27
|
+
- Add @config-bound/nestjs package for NestJS integration
|
|
28
|
+
- Add ConfigBoundModule with forRoot() and forRootAsync() methods
|
|
29
|
+
- Add ConfigBoundService for dependency injection
|
|
30
|
+
- Support for both synchronous and asynchronous configuration
|
|
31
|
+
- Full TypeScript type safety and inference
|
|
32
|
+
- Integration with NestJS dependency injection system
|
|
33
|
+
|
|
34
|
+
### Patch Changes
|
|
35
|
+
|
|
36
|
+
- Updated dependencies
|
|
37
|
+
- @config-bound/config-bound@1.0.0
|
package/PUBLISHING.md
ADDED
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
# Publishing @config-bound/nestjs
|
|
2
|
+
|
|
3
|
+
This document outlines the steps to publish the `@config-bound/nestjs` package to npm.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
1. npm account with access to the `@config-bound` scope
|
|
8
|
+
2. Authentication configured: `npm login`
|
|
9
|
+
3. Package built successfully: `npm run build`
|
|
10
|
+
|
|
11
|
+
## Pre-publish Checklist
|
|
12
|
+
|
|
13
|
+
- [ ] All tests pass
|
|
14
|
+
- [ ] Build succeeds without errors
|
|
15
|
+
- [ ] README.md is complete and accurate
|
|
16
|
+
- [ ] Version number is updated in package.json
|
|
17
|
+
- [ ] CHANGELOG.md is updated (if applicable)
|
|
18
|
+
- [ ] LICENSE file is present
|
|
19
|
+
- [ ] .npmignore is configured correctly
|
|
20
|
+
|
|
21
|
+
## Publishing Steps
|
|
22
|
+
|
|
23
|
+
### 1. Verify Package Contents
|
|
24
|
+
|
|
25
|
+
Preview what will be published:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
cd packages/nestjs
|
|
29
|
+
npm pack --dry-run
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This shows all files that will be included in the package.
|
|
33
|
+
|
|
34
|
+
### 2. Verify Package Configuration
|
|
35
|
+
|
|
36
|
+
Check the package.json exports:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
cat package.json | grep -A 10 "exports"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Should show:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
"exports": {
|
|
46
|
+
".": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"require": "./dist/index.js",
|
|
49
|
+
"import": "./dist/index.js"
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### 3. Test Installation Locally
|
|
55
|
+
|
|
56
|
+
Create a test package and install from local directory:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
mkdir /tmp/test-nestjs-package
|
|
60
|
+
cd /tmp/test-nestjs-package
|
|
61
|
+
npm init -y
|
|
62
|
+
npm install /path/to/configBound/packages/nestjs
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### 4. Update Version
|
|
66
|
+
|
|
67
|
+
Use semantic versioning:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
# For bug fixes
|
|
71
|
+
npm version patch
|
|
72
|
+
|
|
73
|
+
# For new features
|
|
74
|
+
npm version minor
|
|
75
|
+
|
|
76
|
+
# For breaking changes
|
|
77
|
+
npm version major
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Or manually update `package.json`:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"version": "0.0.2"
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### 5. Build the Package
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
npm run clean
|
|
92
|
+
npm run build
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 6. Publish to npm
|
|
96
|
+
|
|
97
|
+
For the first release:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
npm publish --access public
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
For subsequent releases:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npm publish
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### 7. Verify Publication
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm view @config-bound/nestjs
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### 8. Test Installation from npm
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
cd /tmp/test-install
|
|
119
|
+
npm init -y
|
|
120
|
+
npm install @config-bound/nestjs @config-bound/config-bound @nestjs/common @nestjs/core
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Publishing from CI/CD
|
|
124
|
+
|
|
125
|
+
If using GitHub Actions or similar:
|
|
126
|
+
|
|
127
|
+
```yaml
|
|
128
|
+
name: Publish Package
|
|
129
|
+
|
|
130
|
+
on:
|
|
131
|
+
push:
|
|
132
|
+
tags:
|
|
133
|
+
- 'nestjs-v*'
|
|
134
|
+
|
|
135
|
+
jobs:
|
|
136
|
+
publish:
|
|
137
|
+
runs-on: ubuntu-latest
|
|
138
|
+
steps:
|
|
139
|
+
- uses: actions/checkout@v3
|
|
140
|
+
|
|
141
|
+
- uses: actions/setup-node@v3
|
|
142
|
+
with:
|
|
143
|
+
node-version: '22'
|
|
144
|
+
registry-url: 'https://registry.npmjs.org'
|
|
145
|
+
|
|
146
|
+
- name: Install dependencies
|
|
147
|
+
run: npm ci
|
|
148
|
+
|
|
149
|
+
- name: Build
|
|
150
|
+
run: npm run build
|
|
151
|
+
|
|
152
|
+
- name: Publish to npm
|
|
153
|
+
working-directory: packages/nestjs
|
|
154
|
+
run: npm publish --access public
|
|
155
|
+
env:
|
|
156
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Post-publish
|
|
160
|
+
|
|
161
|
+
1. Create a GitHub release with the same version tag
|
|
162
|
+
2. Update documentation website (if applicable)
|
|
163
|
+
3. Announce on relevant channels
|
|
164
|
+
4. Update dependent packages to use new version
|
|
165
|
+
|
|
166
|
+
## Troubleshooting
|
|
167
|
+
|
|
168
|
+
### "Package already exists"
|
|
169
|
+
|
|
170
|
+
You cannot republish the same version. Bump the version and try again.
|
|
171
|
+
|
|
172
|
+
### "403 Forbidden"
|
|
173
|
+
|
|
174
|
+
Ensure you're logged in and have permission to publish to the `@config-bound` scope:
|
|
175
|
+
|
|
176
|
+
```bash
|
|
177
|
+
npm whoami
|
|
178
|
+
npm access list packages
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
### "EPERM: operation not permitted"
|
|
182
|
+
|
|
183
|
+
Make sure you have write permissions in the package directory.
|
|
184
|
+
|
|
185
|
+
### Type definitions not working
|
|
186
|
+
|
|
187
|
+
Verify that:
|
|
188
|
+
|
|
189
|
+
- `declaration: true` in tsconfig.json
|
|
190
|
+
- `types` field in package.json points to correct .d.ts file
|
|
191
|
+
- Build process generates .d.ts files
|
|
192
|
+
|
|
193
|
+
## Version History
|
|
194
|
+
|
|
195
|
+
- 0.0.1 - Initial release
|
|
196
|
+
|
|
197
|
+
## Related Commands
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
# View package info
|
|
201
|
+
npm view @config-bound/nestjs
|
|
202
|
+
|
|
203
|
+
# Download package tarball
|
|
204
|
+
npm pack
|
|
205
|
+
|
|
206
|
+
# Deprecate a version
|
|
207
|
+
npm deprecate @config-bound/nestjs@0.0.1 "Reason for deprecation"
|
|
208
|
+
|
|
209
|
+
# Unpublish (only within 72 hours)
|
|
210
|
+
npm unpublish @config-bound/nestjs@0.0.1
|
|
211
|
+
```
|
package/README.md
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
# @config-bound/nestjs
|
|
2
|
+
|
|
3
|
+
NestJS integration for the ConfigBound configuration library. This package provides a seamless way to integrate ConfigBound into your NestJS applications with full dependency injection support.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @config-bound/nestjs @config-bound/config-bound
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
### Basic Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { Module } from '@nestjs/common';
|
|
17
|
+
import { ConfigBoundModule } from '@config-bound/nestjs';
|
|
18
|
+
import { configItem, configSection } from '@config-bound/config-bound';
|
|
19
|
+
import { EnvVarBind } from '@config-bound/config-bound/bind/binds/envVar';
|
|
20
|
+
import Joi from 'joi';
|
|
21
|
+
|
|
22
|
+
const appConfig = {
|
|
23
|
+
port: configItem<number>({
|
|
24
|
+
default: 3000,
|
|
25
|
+
validator: Joi.number().port(),
|
|
26
|
+
description: 'Application port'
|
|
27
|
+
}),
|
|
28
|
+
database: configSection(
|
|
29
|
+
{
|
|
30
|
+
host: configItem<string>({
|
|
31
|
+
default: 'localhost',
|
|
32
|
+
validator: Joi.string(),
|
|
33
|
+
description: 'Database host'
|
|
34
|
+
}),
|
|
35
|
+
port: configItem<number>({
|
|
36
|
+
default: 5432,
|
|
37
|
+
validator: Joi.number().port(),
|
|
38
|
+
description: 'Database port'
|
|
39
|
+
})
|
|
40
|
+
},
|
|
41
|
+
'Database configuration'
|
|
42
|
+
)
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
@Module({
|
|
46
|
+
imports: [
|
|
47
|
+
ConfigBoundModule.forRoot({
|
|
48
|
+
schema: appConfig,
|
|
49
|
+
binds: [new EnvVarBind({ prefix: 'APP' })],
|
|
50
|
+
validateOnInit: true,
|
|
51
|
+
isGlobal: true
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
})
|
|
55
|
+
export class AppModule {}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### Using the Service
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { Injectable } from '@nestjs/common';
|
|
62
|
+
import { ConfigBoundService } from '@config-bound/nestjs';
|
|
63
|
+
|
|
64
|
+
@Injectable()
|
|
65
|
+
export class MyService {
|
|
66
|
+
constructor(private readonly config: ConfigBoundService) {}
|
|
67
|
+
|
|
68
|
+
getPort(): number {
|
|
69
|
+
return this.config.getOrThrow('app', 'port');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
getDatabaseUrl(): string {
|
|
73
|
+
const host = this.config.getOrThrow('database', 'host');
|
|
74
|
+
const port = this.config.getOrThrow('database', 'port');
|
|
75
|
+
return `postgresql://${host}:${port}`;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Async Configuration
|
|
81
|
+
|
|
82
|
+
For more complex scenarios where configuration depends on other services:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
import { Module } from '@nestjs/common';
|
|
86
|
+
import {
|
|
87
|
+
ConfigBoundModule,
|
|
88
|
+
ConfigBoundModuleOptions
|
|
89
|
+
} from '@config-bound/nestjs';
|
|
90
|
+
import { ConfigService } from '@nestjs/config';
|
|
91
|
+
|
|
92
|
+
@Module({
|
|
93
|
+
imports: [
|
|
94
|
+
ConfigBoundModule.forRootAsync({
|
|
95
|
+
imports: [ConfigModule],
|
|
96
|
+
useFactory: async (
|
|
97
|
+
configService: ConfigService
|
|
98
|
+
): Promise<ConfigBoundModuleOptions> => {
|
|
99
|
+
return {
|
|
100
|
+
schema: appConfig,
|
|
101
|
+
binds: [new EnvVarBind({ prefix: 'APP' })],
|
|
102
|
+
validateOnInit: true
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
inject: [ConfigService],
|
|
106
|
+
isGlobal: true
|
|
107
|
+
})
|
|
108
|
+
]
|
|
109
|
+
})
|
|
110
|
+
export class AppModule {}
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
### Using a Factory Class
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
import { Injectable } from '@nestjs/common';
|
|
117
|
+
import {
|
|
118
|
+
ConfigBoundOptionsFactory,
|
|
119
|
+
ConfigBoundModuleOptions
|
|
120
|
+
} from '@config-bound/nestjs';
|
|
121
|
+
|
|
122
|
+
@Injectable()
|
|
123
|
+
export class ConfigBoundConfigService implements ConfigBoundOptionsFactory {
|
|
124
|
+
createConfigBoundOptions(): ConfigBoundModuleOptions {
|
|
125
|
+
return {
|
|
126
|
+
schema: appConfig,
|
|
127
|
+
binds: [new EnvVarBind({ prefix: 'APP' })],
|
|
128
|
+
validateOnInit: true
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
@Module({
|
|
134
|
+
imports: [
|
|
135
|
+
ConfigBoundModule.forRootAsync({
|
|
136
|
+
useClass: ConfigBoundConfigService,
|
|
137
|
+
isGlobal: true
|
|
138
|
+
})
|
|
139
|
+
]
|
|
140
|
+
})
|
|
141
|
+
export class AppModule {}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
## API
|
|
145
|
+
|
|
146
|
+
### ConfigBoundModule
|
|
147
|
+
|
|
148
|
+
#### `forRoot(options: ConfigBoundModuleOptions): DynamicModule`
|
|
149
|
+
|
|
150
|
+
Register the module synchronously.
|
|
151
|
+
|
|
152
|
+
**Options:**
|
|
153
|
+
|
|
154
|
+
- `schema` (required): Your configuration schema. Top-level items (not in a `configSection`) are automatically placed in a section named after the `name` option (default: 'app')
|
|
155
|
+
- `name` (optional): Configuration name (default: 'app'). This is also the section name used for top-level config items
|
|
156
|
+
- `binds` (optional): Array of Bind instances for value resolution. For `EnvVarBind`, you can pass `{ prefix: "PREFIX" }` to prefix environment variable names
|
|
157
|
+
- `logger` (optional): Custom logger instance
|
|
158
|
+
- `validateOnInit` (optional): Validate configuration on module initialization (default: false)
|
|
159
|
+
- `isGlobal` (optional): Make the module global (default: false)
|
|
160
|
+
|
|
161
|
+
#### `forRootAsync(options: ConfigBoundModuleAsyncOptions): DynamicModule`
|
|
162
|
+
|
|
163
|
+
Register the module asynchronously.
|
|
164
|
+
|
|
165
|
+
**Options:**
|
|
166
|
+
|
|
167
|
+
- `imports` (optional): Modules to import
|
|
168
|
+
- `useFactory` (optional): Factory function to create options
|
|
169
|
+
- `useClass` (optional): Class to instantiate for options
|
|
170
|
+
- `useExisting` (optional): Existing provider to use
|
|
171
|
+
- `inject` (optional): Dependencies to inject into factory
|
|
172
|
+
- `isGlobal` (optional): Make the module global (default: false)
|
|
173
|
+
|
|
174
|
+
### ConfigBoundService
|
|
175
|
+
|
|
176
|
+
The service provides full type-safe access to your configuration:
|
|
177
|
+
|
|
178
|
+
**Methods:**
|
|
179
|
+
|
|
180
|
+
- `get(sectionName, elementName)`: Get a config value (returns undefined if not found)
|
|
181
|
+
- `getOrThrow(sectionName, elementName)`: Get a config value (throws if not found)
|
|
182
|
+
- `validate()`: Validate all configuration values
|
|
183
|
+
- `getValidationErrors()`: Get all validation errors without throwing
|
|
184
|
+
- `addBind(bind: Bind)`: Add a new bind at runtime
|
|
185
|
+
- `addSection(section: Section)`: Add a new section at runtime
|
|
186
|
+
- `getSections()`: Get all configuration sections
|
|
187
|
+
- `getTypedConfigBound()`: Get the underlying TypedConfigBound instance
|
|
188
|
+
|
|
189
|
+
**Properties:**
|
|
190
|
+
|
|
191
|
+
- `name`: The configuration name (string)
|
|
192
|
+
- `binds`: Array of Bind instances (Bind[])
|
|
193
|
+
- `sections`: Array of Section instances (Section[])
|
|
194
|
+
|
|
195
|
+
## Best Practices
|
|
196
|
+
|
|
197
|
+
1. **Use `isGlobal: true`** for application-wide configuration to avoid importing the module everywhere
|
|
198
|
+
2. **Enable `validateOnInit: true`** to catch configuration errors at startup
|
|
199
|
+
3. **Use `getOrThrow()`** for required configuration values
|
|
200
|
+
4. **Use `get()`** for optional configuration values with proper fallback handling
|
|
201
|
+
5. **Define your schema in a separate file** for reusability and better organization
|
|
202
|
+
6. **Use a prefix with `EnvVarBind`** to give a meaningful prefix to environment variable names (e.g., `new EnvVarBind({ prefix: "APP" })`)
|
|
203
|
+
7. **Remember top-level items go in the 'app' section**: Top-level `configItem` entries are automatically placed in a section named after the `name` option (default: 'app'), so access them with `config.getOrThrow("app", "port")`
|
|
204
|
+
|
|
205
|
+
## Type Safety
|
|
206
|
+
|
|
207
|
+
This package provides full TypeScript type inference from your configuration schema:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Schema definition
|
|
211
|
+
const appConfig = {
|
|
212
|
+
port: configItem<number>({ default: 3000 }),
|
|
213
|
+
apiKey: configItem<string>({ default: '' })
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
// Usage with full type safety
|
|
217
|
+
@Injectable()
|
|
218
|
+
export class MyService {
|
|
219
|
+
constructor(private readonly config: ConfigBoundService<typeof appConfig>) {}
|
|
220
|
+
|
|
221
|
+
initialize() {
|
|
222
|
+
const port = this.config.get('app', 'port'); // Type: number | undefined
|
|
223
|
+
const key = this.config.getOrThrow('app', 'apiKey'); // Type: string
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## License
|
|
229
|
+
|
|
230
|
+
MIT
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { ConfigSchema } from '@config-bound/config-bound';
|
|
3
|
+
import { ConfigBoundModuleOptions, ConfigBoundModuleAsyncOptions } from './interfaces/config-bound-module-options.interface';
|
|
4
|
+
export declare class ConfigBoundModule {
|
|
5
|
+
static forRoot<T extends ConfigSchema>(options: ConfigBoundModuleOptions<T>): DynamicModule;
|
|
6
|
+
static forRootAsync<T extends ConfigSchema>(options: ConfigBoundModuleAsyncOptions<T>): DynamicModule;
|
|
7
|
+
private static createAsyncProviders;
|
|
8
|
+
private static createAsyncOptionsProvider;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=config-bound.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.module.d.ts","sourceRoot":"","sources":["../src/config-bound.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAoB,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAEL,YAAY,EAEb,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAI9B,MAAM,oDAAoD,CAAC;AAE5D,qBACa,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,YAAY,EACnC,OAAO,EAAE,wBAAwB,CAAC,CAAC,CAAC,GACnC,aAAa;IAqBhB,MAAM,CAAC,YAAY,CAAC,CAAC,SAAS,YAAY,EACxC,OAAO,EAAE,6BAA6B,CAAC,CAAC,CAAC,GACxC,aAAa;IA2BhB,OAAO,CAAC,MAAM,CAAC,oBAAoB;IAoBnC,OAAO,CAAC,MAAM,CAAC,0BAA0B;CAyB1C"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var ConfigBoundModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.ConfigBoundModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const config_bound_1 = require("@config-bound/config-bound");
|
|
13
|
+
const config_bound_service_1 = require("./config-bound.service");
|
|
14
|
+
const config_bound_module_options_interface_1 = require("./interfaces/config-bound-module-options.interface");
|
|
15
|
+
let ConfigBoundModule = ConfigBoundModule_1 = class ConfigBoundModule {
|
|
16
|
+
static forRoot(options) {
|
|
17
|
+
const configBoundProvider = {
|
|
18
|
+
provide: config_bound_module_options_interface_1.CONFIG_BOUND_INSTANCE,
|
|
19
|
+
useFactory: () => {
|
|
20
|
+
return config_bound_1.ConfigBound.createConfig(options.schema, {
|
|
21
|
+
name: options.name,
|
|
22
|
+
binds: options.binds,
|
|
23
|
+
logger: options.logger,
|
|
24
|
+
validateOnInit: options.validateOnInit ?? false
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
return {
|
|
29
|
+
module: ConfigBoundModule_1,
|
|
30
|
+
global: options.isGlobal ?? false,
|
|
31
|
+
providers: [configBoundProvider, config_bound_service_1.ConfigBoundService],
|
|
32
|
+
exports: [config_bound_service_1.ConfigBoundService]
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
static forRootAsync(options) {
|
|
36
|
+
const configBoundProvider = {
|
|
37
|
+
provide: config_bound_module_options_interface_1.CONFIG_BOUND_INSTANCE,
|
|
38
|
+
useFactory: async (configOptions) => {
|
|
39
|
+
return config_bound_1.ConfigBound.createConfig(configOptions.schema, {
|
|
40
|
+
name: configOptions.name,
|
|
41
|
+
binds: configOptions.binds,
|
|
42
|
+
logger: configOptions.logger,
|
|
43
|
+
validateOnInit: configOptions.validateOnInit ?? false
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
inject: [config_bound_module_options_interface_1.CONFIG_BOUND_OPTIONS]
|
|
47
|
+
};
|
|
48
|
+
const asyncProviders = this.createAsyncProviders(options);
|
|
49
|
+
return {
|
|
50
|
+
module: ConfigBoundModule_1,
|
|
51
|
+
global: options.isGlobal ?? false,
|
|
52
|
+
imports: options.imports || [],
|
|
53
|
+
providers: [...asyncProviders, configBoundProvider, config_bound_service_1.ConfigBoundService],
|
|
54
|
+
exports: [config_bound_service_1.ConfigBoundService]
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
static createAsyncProviders(options) {
|
|
58
|
+
if (options.useExisting || options.useFactory) {
|
|
59
|
+
return [this.createAsyncOptionsProvider(options)];
|
|
60
|
+
}
|
|
61
|
+
if (options.useClass) {
|
|
62
|
+
return [
|
|
63
|
+
this.createAsyncOptionsProvider(options),
|
|
64
|
+
{
|
|
65
|
+
provide: options.useClass,
|
|
66
|
+
useClass: options.useClass
|
|
67
|
+
}
|
|
68
|
+
];
|
|
69
|
+
}
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
static createAsyncOptionsProvider(options) {
|
|
73
|
+
if (options.useFactory) {
|
|
74
|
+
return {
|
|
75
|
+
provide: config_bound_module_options_interface_1.CONFIG_BOUND_OPTIONS,
|
|
76
|
+
useFactory: options.useFactory,
|
|
77
|
+
inject: (options.inject || [])
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const inject = options.useExisting || options.useClass;
|
|
81
|
+
if (!inject) {
|
|
82
|
+
throw new Error('Invalid ConfigBoundModule async configuration: must provide useFactory, useClass, or useExisting');
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
provide: config_bound_module_options_interface_1.CONFIG_BOUND_OPTIONS,
|
|
86
|
+
useFactory: async (optionsFactory) => await optionsFactory.createConfigBoundOptions(),
|
|
87
|
+
inject: [inject]
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
exports.ConfigBoundModule = ConfigBoundModule;
|
|
92
|
+
exports.ConfigBoundModule = ConfigBoundModule = ConfigBoundModule_1 = __decorate([
|
|
93
|
+
(0, common_1.Module)({})
|
|
94
|
+
], ConfigBoundModule);
|
|
95
|
+
//# sourceMappingURL=config-bound.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.module.js","sourceRoot":"","sources":["../src/config-bound.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAiE;AACjE,6DAIoC;AACpC,iEAA4D;AAC5D,8GAM4D;AAGrD,IAAM,iBAAiB,yBAAvB,MAAM,iBAAiB;IAC5B,MAAM,CAAC,OAAO,CACZ,OAAoC;QAEpC,MAAM,mBAAmB,GAAa;YACpC,OAAO,EAAE,6DAAqB;YAC9B,UAAU,EAAE,GAAwB,EAAE;gBACpC,OAAO,0BAAW,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE;oBAC9C,IAAI,EAAE,OAAO,CAAC,IAAI;oBAClB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,MAAM,EAAE,OAAO,CAAC,MAAM;oBACtB,cAAc,EAAE,OAAO,CAAC,cAAc,IAAI,KAAK;iBAChD,CAAC,CAAC;YACL,CAAC;SACF,CAAC;QAEF,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,MAAM,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;YACjC,SAAS,EAAE,CAAC,mBAAmB,EAAE,yCAAkB,CAAC;YACpD,OAAO,EAAE,CAAC,yCAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,YAAY,CACjB,OAAyC;QAEzC,MAAM,mBAAmB,GAAa;YACpC,OAAO,EAAE,6DAAqB;YAC9B,UAAU,EAAE,KAAK,EACf,aAA0C,EACZ,EAAE;gBAChC,OAAO,0BAAW,CAAC,YAAY,CAAC,aAAa,CAAC,MAAM,EAAE;oBACpD,IAAI,EAAE,aAAa,CAAC,IAAI;oBACxB,KAAK,EAAE,aAAa,CAAC,KAAK;oBAC1B,MAAM,EAAE,aAAa,CAAC,MAAM;oBAC5B,cAAc,EAAE,aAAa,CAAC,cAAc,IAAI,KAAK;iBACtD,CAAC,CAAC;YACL,CAAC;YACD,MAAM,EAAE,CAAC,4DAAoB,CAAC;SAC/B,CAAC;QAEF,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QAE1D,OAAO;YACL,MAAM,EAAE,mBAAiB;YACzB,MAAM,EAAE,OAAO,CAAC,QAAQ,IAAI,KAAK;YACjC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE;YAC9B,SAAS,EAAE,CAAC,GAAG,cAAc,EAAE,mBAAmB,EAAE,yCAAkB,CAAC;YACvE,OAAO,EAAE,CAAC,yCAAkB,CAAC;SAC9B,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,oBAAoB,CACjC,OAAyC;QAEzC,IAAI,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YAC9C,OAAO,CAAC,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACrB,OAAO;gBACL,IAAI,CAAC,0BAA0B,CAAC,OAAO,CAAC;gBACxC;oBACE,OAAO,EAAE,OAAO,CAAC,QAAQ;oBACzB,QAAQ,EAAE,OAAO,CAAC,QAAQ;iBAC3B;aACF,CAAC;QACJ,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,MAAM,CAAC,0BAA0B,CACvC,OAAyC;QAEzC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,4DAAoB;gBAC7B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAY;aAC1C,CAAC;QACJ,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CACb,kGAAkG,CACnG,CAAC;QACJ,CAAC;QAED,OAAO;YACL,OAAO,EAAE,4DAAoB;YAC7B,UAAU,EAAE,KAAK,EAAE,cAA4C,EAAE,EAAE,CACjE,MAAM,cAAc,CAAC,wBAAwB,EAAE;YACjD,MAAM,EAAE,CAAC,MAAM,CAAC;SACjB,CAAC;IACJ,CAAC;CACF,CAAA;AAlGY,8CAAiB;4BAAjB,iBAAiB;IAD7B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,iBAAiB,CAkG7B"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { ConfigSchema, TypedConfigBound, InferConfigType } from '@config-bound/config-bound';
|
|
2
|
+
import { Bind } from '@config-bound/config-bound/bind';
|
|
3
|
+
import { Section } from '@config-bound/config-bound/section';
|
|
4
|
+
export declare class ConfigBoundService<T extends ConfigSchema = ConfigSchema> {
|
|
5
|
+
private readonly configBound;
|
|
6
|
+
constructor(configBound: TypedConfigBound<T>);
|
|
7
|
+
getTypedConfigBound(): TypedConfigBound<T>;
|
|
8
|
+
get name(): string;
|
|
9
|
+
get binds(): Bind[];
|
|
10
|
+
get sections(): Section[];
|
|
11
|
+
addBind(bind: Bind): void;
|
|
12
|
+
addSection(section: Section): void;
|
|
13
|
+
getSections(): Section[];
|
|
14
|
+
get<K extends keyof InferConfigType<T>, E extends keyof InferConfigType<T>[K]>(sectionName: K, elementName: E): InferConfigType<T>[K][E] | undefined;
|
|
15
|
+
getOrThrow<K extends keyof InferConfigType<T>, E extends keyof InferConfigType<T>[K]>(sectionName: K, elementName: E): InferConfigType<T>[K][E];
|
|
16
|
+
validate(): void;
|
|
17
|
+
getValidationErrors(): Array<{
|
|
18
|
+
path: string;
|
|
19
|
+
message: string;
|
|
20
|
+
}>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=config-bound.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.service.d.ts","sourceRoot":"","sources":["../src/config-bound.service.ts"],"names":[],"mappings":"AACA,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,eAAe,EAChB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAG7D,qBACa,kBAAkB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY;IAGjE,OAAO,CAAC,QAAQ,CAAC,WAAW;gBAAX,WAAW,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAInD,mBAAmB,IAAI,gBAAgB,CAAC,CAAC,CAAC;IAI1C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,IAAI,KAAK,IAAI,IAAI,EAAE,CAElB;IAED,IAAI,QAAQ,IAAI,OAAO,EAAE,CAExB;IAED,OAAO,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI;IAIzB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,WAAW,IAAI,OAAO,EAAE;IAIxB,GAAG,CACD,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,EAClC,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrC,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,SAAS;IAIvE,UAAU,CACR,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,EAClC,CAAC,SAAS,MAAM,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACrC,WAAW,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAI3D,QAAQ,IAAI,IAAI;IAIhB,mBAAmB,IAAI,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;CAGhE"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.ConfigBoundService = void 0;
|
|
16
|
+
const common_1 = require("@nestjs/common");
|
|
17
|
+
const config_bound_1 = require("@config-bound/config-bound");
|
|
18
|
+
const config_bound_module_options_interface_1 = require("./interfaces/config-bound-module-options.interface");
|
|
19
|
+
let ConfigBoundService = class ConfigBoundService {
|
|
20
|
+
configBound;
|
|
21
|
+
constructor(configBound) {
|
|
22
|
+
this.configBound = configBound;
|
|
23
|
+
}
|
|
24
|
+
// Type-safe access to the underlying config bound
|
|
25
|
+
getTypedConfigBound() {
|
|
26
|
+
return this.configBound;
|
|
27
|
+
}
|
|
28
|
+
get name() {
|
|
29
|
+
return this.configBound.name;
|
|
30
|
+
}
|
|
31
|
+
get binds() {
|
|
32
|
+
return this.configBound.binds;
|
|
33
|
+
}
|
|
34
|
+
get sections() {
|
|
35
|
+
return this.configBound.sections;
|
|
36
|
+
}
|
|
37
|
+
addBind(bind) {
|
|
38
|
+
this.configBound.addBind(bind);
|
|
39
|
+
}
|
|
40
|
+
addSection(section) {
|
|
41
|
+
this.configBound.addSection(section);
|
|
42
|
+
}
|
|
43
|
+
getSections() {
|
|
44
|
+
return this.configBound.getSections();
|
|
45
|
+
}
|
|
46
|
+
get(sectionName, elementName) {
|
|
47
|
+
return this.configBound.get(sectionName, elementName);
|
|
48
|
+
}
|
|
49
|
+
getOrThrow(sectionName, elementName) {
|
|
50
|
+
return this.configBound.getOrThrow(sectionName, elementName);
|
|
51
|
+
}
|
|
52
|
+
validate() {
|
|
53
|
+
this.configBound.validate();
|
|
54
|
+
}
|
|
55
|
+
getValidationErrors() {
|
|
56
|
+
return this.configBound.getValidationErrors();
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
exports.ConfigBoundService = ConfigBoundService;
|
|
60
|
+
exports.ConfigBoundService = ConfigBoundService = __decorate([
|
|
61
|
+
(0, common_1.Injectable)(),
|
|
62
|
+
__param(0, (0, common_1.Inject)(config_bound_module_options_interface_1.CONFIG_BOUND_INSTANCE)),
|
|
63
|
+
__metadata("design:paramtypes", [config_bound_1.TypedConfigBound])
|
|
64
|
+
], ConfigBoundService);
|
|
65
|
+
//# sourceMappingURL=config-bound.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.service.js","sourceRoot":"","sources":["../src/config-bound.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;AAAA,2CAAoD;AACpD,6DAIoC;AAGpC,8GAA2F;AAGpF,IAAM,kBAAkB,GAAxB,MAAM,kBAAkB;IAGV;IAFnB,YAEmB,WAAgC;QAAhC,gBAAW,GAAX,WAAW,CAAqB;IAChD,CAAC;IAEJ,kDAAkD;IAClD,mBAAmB;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IAC/B,CAAC;IAED,IAAI,KAAK;QACP,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC;IAChC,CAAC;IAED,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,IAAU;QAChB,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAED,UAAU,CAAC,OAAgB;QACzB,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,WAAW;QACT,OAAO,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC;IACxC,CAAC;IAED,GAAG,CAGD,WAAc,EAAE,WAAc;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IACxD,CAAC;IAED,UAAU,CAGR,WAAc,EAAE,WAAc;QAC9B,OAAO,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAC/D,CAAC;IAED,QAAQ;QACN,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;IAC9B,CAAC;IAED,mBAAmB;QACjB,OAAO,IAAI,CAAC,WAAW,CAAC,mBAAmB,EAAE,CAAC;IAChD,CAAC;CACF,CAAA;AAxDY,gDAAkB;6BAAlB,kBAAkB;IAD9B,IAAA,mBAAU,GAAE;IAGR,WAAA,IAAA,eAAM,EAAC,6DAAqB,CAAC,CAAA;qCACA,+BAAgB;GAHrC,kBAAkB,CAwD9B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.service.spec.d.ts","sourceRoot":"","sources":["../src/config-bound.service.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound.service.spec.js","sourceRoot":"","sources":["../src/config-bound.service.spec.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { ConfigBoundModule } from './config-bound.module';
|
|
2
|
+
export { ConfigBoundService } from './config-bound.service';
|
|
3
|
+
export { ConfigBoundModuleOptions, ConfigBoundModuleAsyncOptions, ConfigBoundOptionsFactory } from './interfaces/config-bound-module-options.interface';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,OAAO,EACL,wBAAwB,EACxB,6BAA6B,EAC7B,yBAAyB,EAC1B,MAAM,oDAAoD,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ConfigBoundService = exports.ConfigBoundModule = void 0;
|
|
4
|
+
var config_bound_module_1 = require("./config-bound.module");
|
|
5
|
+
Object.defineProperty(exports, "ConfigBoundModule", { enumerable: true, get: function () { return config_bound_module_1.ConfigBoundModule; } });
|
|
6
|
+
var config_bound_service_1 = require("./config-bound.service");
|
|
7
|
+
Object.defineProperty(exports, "ConfigBoundService", { enumerable: true, get: function () { return config_bound_service_1.ConfigBoundService; } });
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,6DAA0D;AAAjD,wHAAA,iBAAiB,OAAA;AAC1B,+DAA4D;AAAnD,0HAAA,kBAAkB,OAAA"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ModuleMetadata, Type } from '@nestjs/common';
|
|
2
|
+
import { ConfigSchema } from '@config-bound/config-bound';
|
|
3
|
+
import { Bind } from '@config-bound/config-bound/bind';
|
|
4
|
+
export type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
5
|
+
export interface Logger {
|
|
6
|
+
logLevels: LogLevel[];
|
|
7
|
+
trace?(message: string, ...meta: unknown[]): void;
|
|
8
|
+
debug(message: string, ...meta: unknown[]): void;
|
|
9
|
+
info(message: string, ...meta: unknown[]): void;
|
|
10
|
+
warn(message: string, ...meta: unknown[]): void;
|
|
11
|
+
error(message: string, ...meta: unknown[]): void;
|
|
12
|
+
silent?(message: string, ...meta: unknown[]): void;
|
|
13
|
+
}
|
|
14
|
+
export interface ConfigBoundModuleOptions<T extends ConfigSchema = ConfigSchema> {
|
|
15
|
+
schema: T;
|
|
16
|
+
name?: string;
|
|
17
|
+
binds?: Bind[];
|
|
18
|
+
logger?: Logger;
|
|
19
|
+
validateOnInit?: boolean;
|
|
20
|
+
isGlobal?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export interface ConfigBoundOptionsFactory<T extends ConfigSchema = ConfigSchema> {
|
|
23
|
+
createConfigBoundOptions(): Promise<ConfigBoundModuleOptions<T>> | ConfigBoundModuleOptions<T>;
|
|
24
|
+
}
|
|
25
|
+
export interface ConfigBoundModuleAsyncOptions<T extends ConfigSchema = ConfigSchema> extends Pick<ModuleMetadata, 'imports'> {
|
|
26
|
+
isGlobal?: boolean;
|
|
27
|
+
useExisting?: Type<ConfigBoundOptionsFactory<T>>;
|
|
28
|
+
useClass?: Type<ConfigBoundOptionsFactory<T>>;
|
|
29
|
+
useFactory?: (...args: unknown[]) => Promise<ConfigBoundModuleOptions<T>> | ConfigBoundModuleOptions<T>;
|
|
30
|
+
inject?: unknown[];
|
|
31
|
+
}
|
|
32
|
+
export declare const CONFIG_BOUND_OPTIONS = "CONFIG_BOUND_OPTIONS";
|
|
33
|
+
export declare const CONFIG_BOUND_INSTANCE = "CONFIG_BOUND_INSTANCE";
|
|
34
|
+
//# sourceMappingURL=config-bound-module-options.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound-module-options.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/config-bound-module-options.interface.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC1D,OAAO,EAAE,IAAI,EAAE,MAAM,iCAAiC,CAAC;AAEvD,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,QAAQ,CAAC;AAEhF,MAAM,WAAW,MAAM;IACrB,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,KAAK,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAClD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAChD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjD,MAAM,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CACpD;AAED,MAAM,WAAW,wBAAwB,CACvC,CAAC,SAAS,YAAY,GAAG,YAAY;IAErC,MAAM,EAAE,CAAC,CAAC;IACV,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB,CACxC,CAAC,SAAS,YAAY,GAAG,YAAY;IAErC,wBAAwB,IACpB,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,GACpC,wBAAwB,CAAC,CAAC,CAAC,CAAC;CACjC;AAED,MAAM,WAAW,6BAA6B,CAC5C,CAAC,SAAS,YAAY,GAAG,YAAY,CACrC,SAAQ,IAAI,CAAC,cAAc,EAAE,SAAS,CAAC;IACvC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,EAAE,IAAI,CAAC,yBAAyB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,UAAU,CAAC,EAAE,CACX,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,OAAO,CAAC,wBAAwB,CAAC,CAAC,CAAC,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED,eAAO,MAAM,oBAAoB,yBAAyB,CAAC;AAC3D,eAAO,MAAM,qBAAqB,0BAA0B,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CONFIG_BOUND_INSTANCE = exports.CONFIG_BOUND_OPTIONS = void 0;
|
|
4
|
+
exports.CONFIG_BOUND_OPTIONS = 'CONFIG_BOUND_OPTIONS';
|
|
5
|
+
exports.CONFIG_BOUND_INSTANCE = 'CONFIG_BOUND_INSTANCE';
|
|
6
|
+
//# sourceMappingURL=config-bound-module-options.interface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-bound-module-options.interface.js","sourceRoot":"","sources":["../../src/interfaces/config-bound-module-options.interface.ts"],"names":[],"mappings":";;;AA+Ca,QAAA,oBAAoB,GAAG,sBAAsB,CAAC;AAC9C,QAAA,qBAAqB,GAAG,uBAAuB,CAAC"}
|
package/jest.config.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
2
|
+
|
|
3
|
+
/** @type {import('ts-jest').JestConfigWithTsJest} **/
|
|
4
|
+
module.exports = {
|
|
5
|
+
testEnvironment: 'node',
|
|
6
|
+
rootDir: './src',
|
|
7
|
+
testMatch: ['**/*.spec.ts'],
|
|
8
|
+
transform: {
|
|
9
|
+
'^.+\\.tsx?$': [
|
|
10
|
+
'ts-jest',
|
|
11
|
+
{
|
|
12
|
+
tsconfig: {
|
|
13
|
+
experimentalDecorators: true,
|
|
14
|
+
emitDecoratorMetadata: true,
|
|
15
|
+
isolatedModules: false
|
|
16
|
+
},
|
|
17
|
+
diagnostics: {
|
|
18
|
+
ignoreCodes: [151002]
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@config-bound/nestjs",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "NestJS integration for ConfigBound configuration library",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"require": "./dist/index.js",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"build": "tsc",
|
|
16
|
+
"clean": "rimraf dist",
|
|
17
|
+
"test": "jest",
|
|
18
|
+
"lint": "eslint src/**/*.ts --fix",
|
|
19
|
+
"lint:ci": "eslint src/**/*.ts",
|
|
20
|
+
"format": "prettier --write --config ../../.config/.prettierrc --ignore-path ../../.config/.prettierignore src/**/*.ts",
|
|
21
|
+
"format:ci": "prettier --check --config ../../.config/.prettierrc --ignore-path ../../.config/.prettierignore src/**/*.ts"
|
|
22
|
+
},
|
|
23
|
+
"keywords": [
|
|
24
|
+
"nestjs",
|
|
25
|
+
"config",
|
|
26
|
+
"configuration",
|
|
27
|
+
"environment",
|
|
28
|
+
"settings"
|
|
29
|
+
],
|
|
30
|
+
"author": "Robert Keyser",
|
|
31
|
+
"license": "MIT",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@config-bound/config-bound": "0.1.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@nestjs/common": "^10.0.0 || ^11.0.0",
|
|
37
|
+
"@nestjs/core": "^10.0.0 || ^11.0.0",
|
|
38
|
+
"reflect-metadata": "^0.1.13 || ^0.2.0",
|
|
39
|
+
"rxjs": "^7.0.0"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@config-bound/eslint-config": "*",
|
|
43
|
+
"@nestjs/common": "^11.1.8",
|
|
44
|
+
"@nestjs/core": "^11.1.8",
|
|
45
|
+
"@nestjs/testing": "^11.1.8",
|
|
46
|
+
"@types/jest": "^30.0.0",
|
|
47
|
+
"@types/node": "^24.10.0",
|
|
48
|
+
"eslint": "^9.39.1",
|
|
49
|
+
"jest": "^30.2.0",
|
|
50
|
+
"rimraf": "^6.1.0",
|
|
51
|
+
"ts-jest": "^29.4.5",
|
|
52
|
+
"typescript": "^5.9.3"
|
|
53
|
+
},
|
|
54
|
+
"publishConfig": {
|
|
55
|
+
"access": "public",
|
|
56
|
+
"registry": "https://registry.npmjs.org"
|
|
57
|
+
},
|
|
58
|
+
"repository": {
|
|
59
|
+
"type": "git",
|
|
60
|
+
"url": "https://github.com/notr-ai/ConfigBound"
|
|
61
|
+
}
|
|
62
|
+
}
|