feat(docs): refresh project documentation and migrate smartconfig tool configuration keys

This commit is contained in:
2026-03-24 19:57:20 +00:00
parent d82e98cfa1
commit 4971279a22
5 changed files with 242 additions and 403 deletions

View File

@@ -1,14 +1,10 @@
{ {
"npmci": {
"globalNpmTools": [],
"npmAccessLevel": "public"
},
"npmts": { "npmts": {
"testConfig": { "testConfig": {
"parallel": false "parallel": false
} }
}, },
"gitzone": { "@git.zone/cli": {
"projectType": "npm", "projectType": "npm",
"module": { "module": {
"githost": "code.foss.global", "githost": "code.foss.global",
@@ -34,9 +30,19 @@
"workflow improvement", "workflow improvement",
"persistent storage" "persistent storage"
] ]
},
"release": {
"registries": [
"https://verdaccio.lossless.digital",
"https://registry.npmjs.org"
],
"accessLevel": "public"
} }
}, },
"tsdoc": { "@git.zone/tsdoc": {
"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" "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"
},
"@ship.zone/szci": {
"globalNpmTools": []
} }
} }

View File

@@ -1,5 +1,12 @@
# Changelog # Changelog
## 2026-03-24 - 6.1.0 - feat(docs)
refresh project documentation and migrate smartconfig tool configuration keys
- rewrites the README with a clearer quick start, updated class documentation, and issue reporting guidance
- updates .smartconfig.json to use scoped tool configuration keys and adds release registry settings
- adds a standalone MIT license file to the repository
## 2025-08-16 - 5.3.3 - fix(appdata) ## 2025-08-16 - 5.3.3 - fix(appdata)
Redact sensitive values in AppData logs and add redaction tests Redact sensitive values in AppData logs and add redaction tests

21
license Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2025 Task Venture Capital GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

545
readme.md
View File

@@ -1,517 +1,322 @@
# @push.rocks/smartconfig 🚀 # @push.rocks/smartconfig 🚀
**Supercharge your npm projects with powerful configuration management, tool orchestration, and persistent key-value storage.** A comprehensive TypeScript configuration management library providing centralized tool configs, persistent key-value storage, and powerful environment variable mapping with automatic type conversions.
## Issue Reporting and Security
For reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.
## Install 📦 ## Install 📦
```bash ```bash
# Using npm
npm install @push.rocks/smartconfig --save npm install @push.rocks/smartconfig --save
# or
# Using pnpm (recommended)
pnpm add @push.rocks/smartconfig pnpm add @push.rocks/smartconfig
``` ```
## Overview 🎯 ## Quick Start ⚡
`@push.rocks/smartconfig` is your Swiss Army knife for npm project configuration. It eliminates configuration sprawl by centralizing tool settings, providing intelligent key-value storage, and offering powerful environment variable mapping with automatic type conversions. ```typescript
import { Smartconfig, AppData, KeyValueStore } from '@push.rocks/smartconfig';
### Why smartconfig? // 1. Read tool config from .smartconfig.json
const sc = new Smartconfig();
const eslintOpts = sc.dataFor('eslint', { extends: 'standard' });
- **🎛️ Centralized Configuration**: Manage all your tool configs in one `.smartconfig.json` file // 2. Map env vars to typed config (with auto-conversion)
- **💾 Persistent Storage**: Smart key-value store with multiple storage strategies const appData = await AppData.createAndInit<{ port: number; debug: boolean }>({
- **🔐 Environment Mapping**: Sophisticated env var handling with automatic type conversion envMapping: {
- **🏗️ TypeScript First**: Full type safety and IntelliSense support port: 'PORT',
- **⚡ Zero Config**: Works out of the box with sensible defaults debug: 'boolean:DEBUG',
- **🔄 Reactive**: Built-in change detection and observables },
});
## Core Concepts 🏗️ // 3. Persist data between runs
const kv = new KeyValueStore({ typeArg: 'userHomeDir', identityArg: 'myapp' });
await kv.writeKey('lastRun', Date.now());
```
### 1. Smartconfig Configuration Management ## Three Core Classes 🏗️
Stop scattering configuration across dozens of files. Centralize everything in `.smartconfig.json`: ### 1. `Smartconfig` — Centralized Tool Configuration
Reads a `.smartconfig.json` file from a project directory and merges its contents with your defaults. One file, every tool.
```typescript ```typescript
import { Smartconfig } from '@push.rocks/smartconfig'; import { Smartconfig } from '@push.rocks/smartconfig';
// Initialize with current directory const sc = new Smartconfig(); // uses cwd
const smartconfig = new Smartconfig(); const sc2 = new Smartconfig('/my/project'); // or specify a path
// Or specify a custom path const prettierConfig = sc.dataFor<PrettierConfig>('prettier', {
const smartconfig = new Smartconfig('/path/to/project'); semi: false,
singleQuote: true,
// Get merged configuration for any tool
const eslintConfig = smartconfig.dataFor<EslintConfig>('eslint', {
// Default values if not in .smartconfig.json
extends: 'standard',
rules: {}
}); });
``` ```
**.smartconfig.json example:** **`.smartconfig.json`** example:
```json ```json
{ {
"eslint": {
"extends": "@company/eslint-config",
"rules": {
"no-console": "warn"
}
},
"prettier": { "prettier": {
"semi": false, "semi": true,
"singleQuote": true "printWidth": 120
},
"eslint": {
"extends": "@company/eslint-config"
} }
} }
``` ```
### 2. KeyValueStore - Persistent Data Storage Values from the file override the defaults you pass in. Missing keys fall back to your defaults.
A flexible key-value store that persists data between script executions: **Properties:**
- `smartconfigJsonExists: boolean` — whether `.smartconfig.json` was found
- `smartconfigJsonData: any` — the parsed JSON contents
**Methods:**
- `dataFor<T>(toolName: string, defaults: T): T` — returns merged config
---
### 2. `KeyValueStore<T>` — Persistent Data Storage
A generic, typed key-value store that persists JSON to disk (or stays in-memory for tests). Supports change detection via RxJS observables.
```typescript ```typescript
import { KeyValueStore } from '@push.rocks/smartconfig'; import { KeyValueStore } from '@push.rocks/smartconfig';
interface UserSettings { interface Settings {
username: string; username: string;
apiKey: string;
preferences: {
theme: 'light' | 'dark'; theme: 'light' | 'dark';
notifications: boolean;
};
} }
// Different storage strategies // Store in ~/.smartconfig/kv/
const kvStore = new KeyValueStore<UserSettings>({ const kv = new KeyValueStore<Settings>({
typeArg: 'userHomeDir', // Store in user's home directory typeArg: 'userHomeDir',
identityArg: 'myApp', identityArg: 'myApp',
mandatoryKeys: ['username', 'apiKey'] mandatoryKeys: ['username'],
}); });
// Write operations await kv.writeKey('username', 'jane');
await kvStore.writeKey('username', 'john_doe'); await kv.writeKey('theme', 'dark');
await kvStore.writeKey('preferences', {
theme: 'dark',
notifications: true
});
// Read operations const user = await kv.readKey('username'); // 'jane'
const username = await kvStore.readKey('username'); const all = await kv.readAll(); // { username: 'jane', theme: 'dark' }
const allData = await kvStore.readAll();
// Check for missing mandatory keys // React to changes
const missingKeys = await kvStore.getMissingMandatoryKeys(); kv.changeSubject.subscribe((data) => console.log('changed:', data));
if (missingKeys.length > 0) {
console.log('Missing required configuration:', missingKeys);
}
// Wait for keys to be present
await kvStore.waitForKeysPresent(['apiKey']);
``` ```
**Storage Types:** **Storage types:**
- `userHomeDir`: Store in user's home directory
- `custom`: Specify your own path
- `ephemeral`: In-memory only (perfect for testing)
### 3. AppData - Advanced Environment Management 🌟 | `typeArg` | Where it goes | Use case |
|-----------|--------------|----------|
| `'userHomeDir'` | `~/.smartconfig/kv/<identity>.json` | CLI tools, per-user state |
| `'custom'` | Your path (file or directory) | App data, project-local state |
| `'ephemeral'` | Memory only — nothing on disk | Tests |
The crown jewel of smartconfig - sophisticated environment variable mapping with automatic type conversion: **Methods:**
| Method | Description |
|--------|------------|
| `readKey(key)` | Read a single value |
| `writeKey(key, value)` | Write a single value |
| `readAll()` | Read everything |
| `writeAll(obj)` | Merge an object into the store |
| `deleteKey(key)` | Remove a key |
| `reset()` | Wipe all keys (synced to disk) |
| `wipe()` | Delete the backing file entirely |
| `getMissingMandatoryKeys()` | Returns keys declared mandatory but not yet set |
| `waitForKeysPresent(keys)` | Returns a Promise that resolves once all listed keys exist |
| `waitForAndGetKey(key)` | Waits for a key, then returns its value |
---
### 3. `AppData<T>` — Environment Variable Mapping 🌟
The flagship class. Maps environment variables (or hardcoded values) into a typed config object with automatic type conversions, nested object support, and smart storage path selection.
```typescript ```typescript
import { AppData } from '@push.rocks/smartconfig'; import { AppData } from '@push.rocks/smartconfig';
interface AppConfig { interface Config {
apiUrl: string; apiUrl: string;
apiKey: string; apiKey: string;
port: number;
features: { features: {
analytics: boolean; analytics: boolean;
payment: boolean; payment: boolean;
}; };
cache: {
ttl: number;
redis: { redis: {
host: string; host: string;
password: string; password: string;
}; };
};
} }
const appData = await AppData.createAndInit<AppConfig>({ const appData = await AppData.createAndInit<Config>({
dirPath: '/app/config', // Optional: defaults to smart path selection requiredKeys: ['apiKey'],
requiredKeys: ['apiKey', 'apiUrl'],
envMapping: { envMapping: {
apiUrl: 'API_URL', // Simple mapping apiUrl: 'API_URL', // plain env var
apiKey: 'hard:development-key-123', // Hardcoded value apiKey: 'hard:dev-key-123', // hardcoded fallback
port: 'hard:3000', // Hardcoded number
features: { features: {
analytics: 'boolean:ENABLE_ANALYTICS', // Force boolean conversion analytics: 'boolean:ENABLE_ANALYTICS', // converts "true"/"false" → boolean
payment: 'hard_boolean:true' // Hardcoded boolean payment: 'hard_boolean:true', // hardcoded boolean
}, },
cache: {
ttl: 'json:CACHE_CONFIG', // Parse JSON from env var
redis: { redis: {
host: 'REDIS_HOST', host: 'REDIS_HOST',
password: 'base64:REDIS_PASSWORD_B64' // Decode base64 password: 'base64:REDIS_PASSWORD_B64', // base64-decode at load time
} },
}
}, },
overwriteObject: { overwriteObject: {
// Force these values regardless of env vars apiUrl: 'http://localhost:3000', // force override after env mapping
port: 8080 },
}
}); });
const store = await appData.getKvStore(); const store = await appData.getKvStore();
const apiUrl = await store.readKey('apiUrl'); const url = await store.readKey('apiUrl');
``` ```
## AppData Special Cases & Conversions 🎯 #### Mapping Prefixes
### Environment Variable Prefixes | Prefix | What it does | Example mapping | Result |
|--------|-------------|-----------------|--------|
| *(none)* | Raw env var as string | `'MY_VAR'` | `process.env.MY_VAR` |
| `hard:` | Hardcoded string | `'hard:hello'` | `"hello"` |
| `boolean:` | Env var → `true`/`false` | `'boolean:FLAG'` | `true` or `false` |
| `json:` | Env var → `JSON.parse()` | `'json:CONFIG'` | parsed object |
| `base64:` | Env var → base64 decode | `'base64:SECRET'` | decoded string |
| `hard_boolean:` | Hardcoded boolean | `'hard_boolean:false'` | `false` |
| `hard_json:` | Hardcoded JSON | `'hard_json:{"a":1}'` | `{ a: 1 }` |
| `hard_base64:` | Hardcoded base64 | `'hard_base64:SGVsbG8='` | `"Hello"` |
AppData supports sophisticated type conversion through prefixes: Suffix detection also works: a mapping ending in `_JSON` or `_BASE64` triggers the corresponding transform automatically.
| Prefix | Description | Example | Result | #### Boolean Conversion Rules
|--------|-------------|---------|--------|
| `hard:` | Hardcoded value | `hard:myvalue` | `"myvalue"` |
| `hard_boolean:` | Hardcoded boolean | `hard_boolean:true` | `true` |
| `hard_json:` | Hardcoded JSON | `hard_json:{"key":"value"}` | `{key: "value"}` |
| `hard_base64:` | Hardcoded base64 | `hard_base64:SGVsbG8=` | `"Hello"` |
| `boolean:` | Env var as boolean | `boolean:FEATURE_FLAG` | `true/false` |
| `json:` | Parse env var as JSON | `json:CONFIG_JSON` | Parsed object |
| `base64:` | Decode env var from base64 | `base64:SECRET_B64` | Decoded string |
### Automatic Suffix Detection The `boolean:` prefix (and `hard_boolean:`) recognizes:
Variables ending with certain suffixes get automatic conversion: - **true**: `"true"`, `"1"`, `"yes"`, `"y"`, `"on"` (case-insensitive)
- **false**: `"false"`, `"0"`, `"no"`, `"n"`, `"off"` (case-insensitive)
#### Nested Objects
Mapping values can be objects — they are resolved recursively:
```typescript ```typescript
{
envMapping: { envMapping: {
// Automatically parsed as JSON if MY_CONFIG_JSON="{"enabled":true}"
config: 'MY_CONFIG_JSON',
// Automatically decoded from base64 if SECRET_KEY_BASE64="SGVsbG8="
secret: 'SECRET_KEY_BASE64'
}
}
```
### Complex Examples
```typescript
const appData = await AppData.createAndInit({
envMapping: {
// Simple environment variable
apiUrl: 'API_URL',
// Hardcoded values with type conversion
debugMode: 'hard_boolean:false',
maxRetries: 'hard:5',
defaultConfig: 'hard_json:{"timeout":30,"retries":3}',
// Environment variables with conversion
features: 'json:FEATURE_FLAGS', // Expects: {"feature1":true,"feature2":false}
isProduction: 'boolean:IS_PROD', // Expects: "true" or "false"
apiSecret: 'base64:API_SECRET', // Expects: base64 encoded string
// Nested structures
database: { database: {
host: 'DB_HOST', host: 'DB_HOST',
port: 'hard:5432', port: 'hard:5432',
credentials: { credentials: {
user: 'DB_USER', user: 'DB_USER',
password: 'base64:DB_PASSWORD_ENCODED', password: 'base64:DB_PASS_B64',
ssl: 'boolean:DB_USE_SSL' ssl: 'boolean:DB_SSL',
} },
}
}, },
// Override any env mappings
overwriteObject: {
debugMode: true, // Force debug mode regardless of env
database: {
host: 'localhost' // Force localhost for development
}
}
});
```
### Boolean Conversion Rules
AppData intelligently handles boolean conversions:
1. **String "true"/"false"**: Converted to boolean
2. **With `boolean:` prefix**: Any env var value is converted (`"true"``true`, anything else → `false`)
3. **With `hard_boolean:` prefix**: Hardcoded boolean value
4. **Regular env vars**: Strings remain strings unless prefixed
```typescript
// Environment: FEATURE_A="true", FEATURE_B="yes", FEATURE_C="1"
{
envMapping: {
featureA: 'FEATURE_A', // Result: "true" (string)
featureB: 'boolean:FEATURE_B', // Result: false (only "true" → true)
featureC: 'boolean:FEATURE_C', // Result: false (only "true" → true)
featureD: 'hard_boolean:true' // Result: true (hardcoded)
}
} }
``` ```
### Static Helper Functions #### Smart Storage Path
AppData provides convenient static methods for directly accessing and converting environment variables without creating an instance: When no `dirPath` is specified, AppData auto-selects:
1. `/app/data` — if it exists (containers)
2. `/data` — if it exists (alternate container path)
3. `.nogit/appdata` — local dev fallback
Or pass `ephemeral: true` for zero disk I/O (great for tests).
#### Static Helpers
Quick one-shot env var reads without creating an AppData instance:
```typescript ```typescript
import { AppData } from '@push.rocks/smartconfig'; const isEnabled = await AppData.valueAsBoolean('FEATURE_FLAG');
const config = await AppData.valueAsJson<MyType>('CONFIG_JSON');
// Get environment variable as boolean
const isEnabled = await AppData.valueAsBoolean('FEATURE_ENABLED');
// Returns: true if "true", false otherwise
// Get environment variable as parsed JSON
interface Config {
timeout: number;
retries: number;
}
const config = await AppData.valueAsJson<Config>('SERVICE_CONFIG');
// Returns: Parsed object or undefined
// Get environment variable as base64 decoded string
const secret = await AppData.valueAsBase64('ENCODED_SECRET'); const secret = await AppData.valueAsBase64('ENCODED_SECRET');
// Returns: Decoded string or undefined const url = await AppData.valueAsString('API_URL');
// Get environment variable as string
const apiUrl = await AppData.valueAsString('API_URL');
// Returns: String value or undefined
// Get environment variable as number
const port = await AppData.valueAsNumber('PORT'); const port = await AppData.valueAsNumber('PORT');
// Returns: Number value or undefined
``` ```
These static methods are perfect for: #### Instance Methods
- Quick environment variable access without setup
- Simple type conversions in utility functions
- One-off configuration checks
- Scenarios where you don't need the full AppData instance
## Advanced Patterns 🎨 | Method | Description |
|--------|------------|
| `getKvStore()` | Returns the underlying `KeyValueStore<T>` |
| `logMissingKeys()` | Logs and returns any required keys that are missing |
| `waitForAndGetKey(key)` | Blocks until a key is present, then returns it |
### Reactive Configuration ---
Subscribe to configuration changes: ## Security 🔐
```typescript AppData automatically redacts sensitive values in its console logs. Keys matching patterns like `secret`, `token`, `password`, `api`, `auth`, `jwt`, etc. are truncated. JWT tokens (starting with `eyJ`) are also detected and shortened. Your actual stored values are never modified — only log output is redacted.
const kvStore = new KeyValueStore<Config>({
typeArg: 'custom',
identityArg: 'myApp'
});
// Subscribe to changes ---
kvStore.changeSubject.subscribe((newData) => {
console.log('Configuration changed:', newData);
});
// Changes trigger notifications
await kvStore.writeKey('theme', 'dark');
```
### Testing with Ephemeral Storage
Perfect for unit tests - no file system pollution:
```typescript
const testStore = new KeyValueStore<TestData>({
typeArg: 'ephemeral',
identityArg: 'test'
});
// All operations work normally, but nothing persists to disk
await testStore.writeKey('testKey', 'testValue');
```
### Smart Path Resolution
AppData automatically selects the best storage location:
1. Checks for `/app/data` (containerized environments)
2. Falls back to `/data` (alternate container path)
3. Uses `.nogit/appdata` (local development)
```typescript
// Automatic path selection
const appData = await AppData.createAndInit({
// No dirPath specified - smart detection
requiredKeys: ['apiKey']
});
// Or force ephemeral for testing
const testData = await AppData.createAndInit({
ephemeral: true, // No disk persistence
requiredKeys: ['testKey']
});
```
### Waiting for Configuration
Block until required configuration is available:
```typescript
const appData = await AppData.createAndInit<Config>({
requiredKeys: ['apiKey', 'apiUrl']
});
// Wait for specific key
const apiKey = await appData.waitForAndGetKey('apiKey');
// Check missing keys
const missingKeys = await appData.logMissingKeys();
// Logs: "The following mandatory keys are missing in the appdata:
// -> apiKey,
// -> apiUrl"
```
## Real-World Example 🌍 ## Real-World Example 🌍
Here's a complete example of a CLI tool using smartconfig:
```typescript ```typescript
import { Smartconfig, AppData, KeyValueStore } from '@push.rocks/smartconfig'; import { Smartconfig, AppData, KeyValueStore } from '@push.rocks/smartconfig';
interface CliConfig { interface CliConfig {
githubToken: string; githubToken: string;
openaiKey: string;
model: 'gpt-3' | 'gpt-4'; model: 'gpt-3' | 'gpt-4';
cache: { cache: { enabled: boolean; ttl: number };
enabled: boolean;
ttl: number;
};
} }
class MyCLI { // Tool-level config from .smartconfig.json
private smartconfig: Smartconfig; const sc = new Smartconfig();
private appData: AppData<CliConfig>; const toolDefaults = sc.dataFor('mycli', { defaultModel: 'gpt-3' });
private cache: KeyValueStore<{[key: string]: any}>;
async initialize() { // Env-mapped runtime config
// Load tool configuration const appData = await AppData.createAndInit<CliConfig>({
this.smartconfig = new Smartconfig(); requiredKeys: ['githubToken'],
const config = this.smartconfig.dataFor<any>('mycli', {
defaultModel: 'gpt-3'
});
// Setup app data with env mapping
this.appData = await AppData.createAndInit<CliConfig>({
requiredKeys: ['githubToken', 'openaiKey'],
envMapping: { envMapping: {
githubToken: 'GITHUB_TOKEN', githubToken: 'GITHUB_TOKEN',
openaiKey: 'base64:OPENAI_KEY_ENCODED',
model: 'hard:gpt-4', model: 'hard:gpt-4',
cache: { cache: {
enabled: 'boolean:ENABLE_CACHE', enabled: 'boolean:ENABLE_CACHE',
ttl: 'hard:3600' ttl: 'hard:3600',
} },
} },
}); });
// Initialize cache // Persistent user-level cache
this.cache = new KeyValueStore({ const cache = new KeyValueStore({
typeArg: 'userHomeDir', typeArg: 'userHomeDir',
identityArg: 'mycli-cache' identityArg: 'mycli-cache',
}); });
// Check for missing configuration // Check mandatory keys
const missingKeys = await this.appData.logMissingKeys(); const missing = await appData.logMissingKeys();
if (missingKeys.length > 0) { if (missing.length > 0) {
console.error('Please configure the missing keys'); console.error('Missing config — set these env vars and retry.');
process.exit(1); process.exit(1);
} }
}
async run() { const store = await appData.getKvStore();
await this.initialize(); const settings = await store.readAll();
console.log(`Model: ${settings.model}, Cache: ${settings.cache.enabled}`);
const config = await this.appData.getKvStore();
const settings = await config.readAll();
console.log(`Using model: ${settings.model}`);
console.log(`Cache enabled: ${settings.cache.enabled}`);
// Use the configuration...
}
}
// Run the CLI
const cli = new MyCLI();
cli.run();
``` ```
## API Reference 📚
### Smartconfig Class
```typescript
new Smartconfig(cwdArg?: string)
```
- `cwdArg`: Optional working directory path
**Methods:**
- `dataFor<T>(toolName: string, defaultOptions: T): T` - Get merged configuration
### KeyValueStore Class
```typescript
new KeyValueStore<T>(options: {
typeArg: 'custom' | 'userHomeDir' | 'ephemeral';
identityArg: string;
customPath?: string;
mandatoryKeys?: Array<keyof T>;
})
```
**Methods:**
- `readKey(key: string): Promise<T>` - Read single value
- `writeKey(key: string, value: T): Promise<void>` - Write single value
- `readAll(): Promise<T>` - Read all values
- `writeAll(data: T): Promise<void>` - Write all values
- `deleteKey(key: string): Promise<void>` - Delete a key
- `getMissingMandatoryKeys(): Promise<string[]>` - Check missing required keys
- `waitForKeysPresent(keys: string[]): Promise<void>` - Wait for keys
### AppData Class
```typescript
await AppData.createAndInit<T>(options: {
dirPath?: string;
requiredKeys?: Array<keyof T>;
ephemeral?: boolean;
envMapping?: PartialDeep<T>;
overwriteObject?: PartialDeep<T>;
})
```
**Methods:**
- `getKvStore(): Promise<KeyValueStore<T>>` - Get underlying store
- `logMissingKeys(): Promise<Array<keyof T>>` - Log and return missing keys
- `waitForAndGetKey<K>(key: K): Promise<T[K]>` - Wait for and retrieve key
## License and Legal Information ## License and Legal Information
This 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. This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
**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. **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.
### Trademarks ### Trademarks
This 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. This 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 or third parties, 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 or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.
### Company Information ### Company Information
Task Venture Capital GmbH Task Venture Capital GmbH
Registered at District court Bremen HRB 35230 HB, Germany Registered at District Court Bremen HRB 35230 HB, Germany
For any legal inquiries or if you require further information, please contact us via email at hello@task.vc. For any legal inquiries or further information, please contact us via email at hello@task.vc.
By 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. By 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.

View File

@@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@push.rocks/smartconfig', name: '@push.rocks/smartconfig',
version: '6.0.1', version: '6.1.0',
description: 'A comprehensive configuration management library providing key-value storage, environment variable mapping, and tool configuration.' description: 'A comprehensive configuration management library providing key-value storage, environment variable mapping, and tool configuration.'
} }