@push.rocks/smartconfig 6.0.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/dist_ts/00_commitinfo_data.d.ts +8 -0
- package/dist_ts/00_commitinfo_data.js +9 -0
- package/dist_ts/classes.appdata.d.ts +72 -0
- package/dist_ts/classes.appdata.js +454 -0
- package/dist_ts/classes.keyvaluestore.d.ts +63 -0
- package/dist_ts/classes.keyvaluestore.js +169 -0
- package/dist_ts/classes.smartconfig.d.ts +29 -0
- package/dist_ts/classes.smartconfig.js +67 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +4 -0
- package/dist_ts/paths.d.ts +8 -0
- package/dist_ts/paths.js +15 -0
- package/dist_ts/plugins.d.ts +12 -0
- package/dist_ts/plugins.js +13 -0
- package/package.json +73 -0
- package/readme.hints.md +0 -0
- package/readme.md +517 -0
- package/readme.plan.md +225 -0
- package/smartconfig.json +42 -0
- package/ts/00_commitinfo_data.ts +8 -0
- package/ts/classes.appdata.ts +548 -0
- package/ts/classes.keyvaluestore.ts +222 -0
- package/ts/classes.smartconfig.ts +79 -0
- package/ts/index.ts +3 -0
- package/ts/paths.ts +22 -0
- package/ts/plugins.ts +25 -0
package/readme.plan.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# AppData Refactoring Plan
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
Refactor the AppData class to improve elegance, maintainability, and extensibility while maintaining 100% backward compatibility.
|
|
5
|
+
|
|
6
|
+
## Current Issues
|
|
7
|
+
- 100+ lines of nested switch statements in processEnvMapping
|
|
8
|
+
- Static helpers recreate Qenv instances on every call
|
|
9
|
+
- Complex boolean conversion logic scattered across multiple places
|
|
10
|
+
- Typo: "ephermal" should be "ephemeral"
|
|
11
|
+
- Difficult to test and extend with new transformations
|
|
12
|
+
|
|
13
|
+
## Architecture Improvements
|
|
14
|
+
|
|
15
|
+
### 1. Singleton Qenv Provider
|
|
16
|
+
Create a shared Qenv instance to avoid repeated instantiation:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
let sharedQenv: plugins.qenv.Qenv | undefined;
|
|
20
|
+
|
|
21
|
+
function getQenv(): plugins.qenv.Qenv {
|
|
22
|
+
if (!sharedQenv) {
|
|
23
|
+
sharedQenv = new plugins.qenv.Qenv(
|
|
24
|
+
process.cwd(),
|
|
25
|
+
plugins.path.join(process.cwd(), '.nogit')
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return sharedQenv;
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Centralized Type Converters
|
|
33
|
+
Extract all conversion logic into pure utility functions:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
function toBoolean(value: unknown): boolean {
|
|
37
|
+
if (typeof value === 'boolean') return value;
|
|
38
|
+
if (value == null) return false;
|
|
39
|
+
const s = String(value).toLowerCase();
|
|
40
|
+
return s === 'true';
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function toJson<T>(value: unknown): T | undefined {
|
|
44
|
+
if (typeof value === 'string') {
|
|
45
|
+
try {
|
|
46
|
+
return JSON.parse(value);
|
|
47
|
+
} catch {
|
|
48
|
+
return undefined;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return value as T;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function fromBase64(value: unknown): string {
|
|
55
|
+
if (value == null) return '';
|
|
56
|
+
return Buffer.from(String(value), 'base64').toString('utf8');
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function toNumber(value: unknown): number | undefined {
|
|
60
|
+
if (value == null) return undefined;
|
|
61
|
+
const num = Number(value);
|
|
62
|
+
return Number.isNaN(num) ? undefined : num;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function toString(value: unknown): string | undefined {
|
|
66
|
+
if (value == null) return undefined;
|
|
67
|
+
return String(value);
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. Declarative Pipeline Architecture
|
|
72
|
+
|
|
73
|
+
Replace the giant switch statement with a composable pipeline:
|
|
74
|
+
|
|
75
|
+
#### Data Structures
|
|
76
|
+
```typescript
|
|
77
|
+
type MappingSpec = {
|
|
78
|
+
source:
|
|
79
|
+
| { type: 'env', key: string }
|
|
80
|
+
| { type: 'hard', value: string };
|
|
81
|
+
transforms: Transform[];
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
type Transform = 'boolean' | 'json' | 'base64' | 'number';
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
#### Pipeline Functions
|
|
88
|
+
```typescript
|
|
89
|
+
// Parse mapping string into spec
|
|
90
|
+
function parseMappingSpec(input: string): MappingSpec
|
|
91
|
+
|
|
92
|
+
// Resolve the source value
|
|
93
|
+
async function resolveSource(source: MappingSpec['source']): Promise<unknown>
|
|
94
|
+
|
|
95
|
+
// Apply transformations
|
|
96
|
+
function applyTransforms(value: unknown, transforms: Transform[]): unknown
|
|
97
|
+
|
|
98
|
+
// Complete pipeline
|
|
99
|
+
async function processMappingValue(mappingString: string): Promise<unknown>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### 4. Transform Registry
|
|
103
|
+
Enable easy extension with new transforms:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
const transformRegistry: Record<string, (v: unknown) => unknown> = {
|
|
107
|
+
boolean: toBoolean,
|
|
108
|
+
json: toJson,
|
|
109
|
+
base64: fromBase64,
|
|
110
|
+
number: toNumber,
|
|
111
|
+
};
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### 5. Simplified processEnvMapping
|
|
115
|
+
Build pure object tree first, then write to kvStore:
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
async function evaluateMappingValue(mappingValue: any): Promise<any> {
|
|
119
|
+
if (typeof mappingValue === 'string') {
|
|
120
|
+
return processMappingValue(mappingValue);
|
|
121
|
+
}
|
|
122
|
+
if (mappingValue && typeof mappingValue === 'object') {
|
|
123
|
+
const out: any = {};
|
|
124
|
+
for (const [k, v] of Object.entries(mappingValue)) {
|
|
125
|
+
out[k] = await evaluateMappingValue(v);
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Main loop becomes:
|
|
133
|
+
for (const key in this.options.envMapping) {
|
|
134
|
+
const evaluated = await evaluateMappingValue(this.options.envMapping[key]);
|
|
135
|
+
if (evaluated !== undefined) {
|
|
136
|
+
await this.kvStore.writeKey(key as keyof T, evaluated);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Backward Compatibility
|
|
142
|
+
|
|
143
|
+
### Supported Prefixes (Maintained)
|
|
144
|
+
- `hard:` - Hardcoded value
|
|
145
|
+
- `hard_boolean:` - Hardcoded boolean
|
|
146
|
+
- `hard_json:` - Hardcoded JSON
|
|
147
|
+
- `hard_base64:` - Hardcoded base64
|
|
148
|
+
- `boolean:` - Environment variable as boolean
|
|
149
|
+
- `json:` - Environment variable as JSON
|
|
150
|
+
- `base64:` - Environment variable as base64
|
|
151
|
+
|
|
152
|
+
### Supported Suffixes (Maintained)
|
|
153
|
+
- `_JSON` - Auto-parse as JSON
|
|
154
|
+
- `_BASE64` - Auto-decode from base64
|
|
155
|
+
|
|
156
|
+
### Typo Fix Strategy
|
|
157
|
+
- Add `ephemeral` option to interface
|
|
158
|
+
- Keep reading `ephermal` for backward compatibility
|
|
159
|
+
- Log deprecation warning when old spelling is used
|
|
160
|
+
|
|
161
|
+
## Implementation Steps
|
|
162
|
+
|
|
163
|
+
1. **Add utility functions** at the top of the file
|
|
164
|
+
2. **Implement pipeline functions** (parseMappingSpec, resolveSource, applyTransforms)
|
|
165
|
+
3. **Refactor processEnvMapping** to use the pipeline
|
|
166
|
+
4. **Update static helpers** to use shared utilities
|
|
167
|
+
5. **Fix typo** with compatibility shim
|
|
168
|
+
6. **Add error boundaries** for better error reporting
|
|
169
|
+
7. **Test** to ensure backward compatibility
|
|
170
|
+
|
|
171
|
+
## Benefits
|
|
172
|
+
|
|
173
|
+
### Code Quality
|
|
174
|
+
- **70% reduction** in processEnvMapping complexity
|
|
175
|
+
- **Better separation** of concerns
|
|
176
|
+
- **Easier testing** - each function is pure and testable
|
|
177
|
+
- **Cleaner error handling** with boundaries
|
|
178
|
+
|
|
179
|
+
### Performance
|
|
180
|
+
- **Shared Qenv instance** reduces allocations
|
|
181
|
+
- **Optional parallelization** with Promise.all
|
|
182
|
+
- **Fewer repeated operations**
|
|
183
|
+
|
|
184
|
+
### Maintainability
|
|
185
|
+
- **Extensible** - Easy to add new transforms
|
|
186
|
+
- **Readable** - Clear pipeline flow
|
|
187
|
+
- **Debuggable** - Each step can be logged
|
|
188
|
+
- **Type-safe** - Better TypeScript support
|
|
189
|
+
|
|
190
|
+
## Testing Strategy
|
|
191
|
+
|
|
192
|
+
1. **Unit tests** for each utility function
|
|
193
|
+
2. **Integration tests** for the full pipeline
|
|
194
|
+
3. **Backward compatibility tests** for all existing prefixes/suffixes
|
|
195
|
+
4. **Edge case tests** for error conditions
|
|
196
|
+
|
|
197
|
+
## Future Extensions
|
|
198
|
+
|
|
199
|
+
With the transform registry, adding new features becomes trivial:
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
// Add YAML support
|
|
203
|
+
transformRegistry['yaml'] = (v) => YAML.parse(String(v));
|
|
204
|
+
|
|
205
|
+
// Add integer parsing
|
|
206
|
+
transformRegistry['int'] = (v) => parseInt(String(v), 10);
|
|
207
|
+
|
|
208
|
+
// Add custom transformers
|
|
209
|
+
transformRegistry['uppercase'] = (v) => String(v).toUpperCase();
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Migration Path
|
|
213
|
+
|
|
214
|
+
1. Implement new architecture alongside existing code
|
|
215
|
+
2. Gradually migrate internal usage
|
|
216
|
+
3. Mark old patterns as deprecated (with warnings)
|
|
217
|
+
4. Remove deprecated code in next major version
|
|
218
|
+
|
|
219
|
+
## Success Metrics
|
|
220
|
+
|
|
221
|
+
- All existing tests pass
|
|
222
|
+
- No breaking changes for users
|
|
223
|
+
- Reduced code complexity (measurable via cyclomatic complexity)
|
|
224
|
+
- Improved test coverage
|
|
225
|
+
- Better performance (fewer allocations, optional parallelization)
|
package/smartconfig.json
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
{
|
|
2
|
+
"npmci": {
|
|
3
|
+
"globalNpmTools": [],
|
|
4
|
+
"npmAccessLevel": "public"
|
|
5
|
+
},
|
|
6
|
+
"npmts": {
|
|
7
|
+
"testConfig": {
|
|
8
|
+
"parallel": false
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"gitzone": {
|
|
12
|
+
"projectType": "npm",
|
|
13
|
+
"module": {
|
|
14
|
+
"githost": "code.foss.global",
|
|
15
|
+
"gitscope": "push.rocks",
|
|
16
|
+
"gitrepo": "smartconfig",
|
|
17
|
+
"description": "A comprehensive configuration management library providing key-value storage, environment variable mapping, and tool configuration.",
|
|
18
|
+
"npmPackagename": "@push.rocks/smartconfig",
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"keywords": [
|
|
21
|
+
"npm",
|
|
22
|
+
"configuration management",
|
|
23
|
+
"tool management",
|
|
24
|
+
"key-value store",
|
|
25
|
+
"project setup",
|
|
26
|
+
"typescript",
|
|
27
|
+
"environment setup",
|
|
28
|
+
"dependencies management",
|
|
29
|
+
"npm package enhancement",
|
|
30
|
+
"automation",
|
|
31
|
+
"async operations",
|
|
32
|
+
"app configuration",
|
|
33
|
+
"smart file handling",
|
|
34
|
+
"workflow improvement",
|
|
35
|
+
"persistent storage"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
"tsdoc": {
|
|
40
|
+
"legal": "\n## License and Legal Information\n\nThis repository contains open-source code that is licensed under the MIT License. A copy of the MIT License can be found in the [license](license) file within this repository. \n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH and are not included within the scope of the MIT license granted herein. Use of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines, and any usage must be approved in writing by Task Venture Capital GmbH.\n\n### Company Information\n\nTask Venture Capital GmbH \nRegistered at District court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or if you require further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* autocreated commitinfo by @push.rocks/commitinfo
|
|
3
|
+
*/
|
|
4
|
+
export const commitinfo = {
|
|
5
|
+
name: '@push.rocks/smartconfig',
|
|
6
|
+
version: '6.0.0',
|
|
7
|
+
description: 'A comprehensive configuration management library providing key-value storage, environment variable mapping, and tool configuration.'
|
|
8
|
+
}
|