@perkos/util-config 1.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/README.md +192 -0
- package/dist/index.d.mts +118 -0
- package/dist/index.d.ts +118 -0
- package/dist/index.js +214 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +176 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# @perkos/util-config
|
|
2
|
+
|
|
3
|
+
Configuration management utilities for PerkOS services.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @perkos/util-config
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Basic Environment Variables
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import {
|
|
17
|
+
getEnv,
|
|
18
|
+
getRequiredEnv,
|
|
19
|
+
getEnvNumber,
|
|
20
|
+
getEnvBoolean,
|
|
21
|
+
getEnvJson,
|
|
22
|
+
} from "@perkos/util-config";
|
|
23
|
+
|
|
24
|
+
// Get optional env var with default
|
|
25
|
+
const apiUrl = getEnv("API_URL", "http://localhost:3000");
|
|
26
|
+
|
|
27
|
+
// Get required env var (throws if missing)
|
|
28
|
+
const apiKey = getRequiredEnv("API_KEY");
|
|
29
|
+
|
|
30
|
+
// Get as number
|
|
31
|
+
const port = getEnvNumber("PORT", 3000);
|
|
32
|
+
|
|
33
|
+
// Get as boolean
|
|
34
|
+
const debug = getEnvBoolean("DEBUG", false);
|
|
35
|
+
|
|
36
|
+
// Get as parsed JSON
|
|
37
|
+
const config = getEnvJson<{ key: string }>("CONFIG_JSON");
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Typed Configuration Builder
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
import { createConfig, validateConfig } from "@perkos/util-config";
|
|
44
|
+
|
|
45
|
+
// Define configuration schema
|
|
46
|
+
const config = createConfig({
|
|
47
|
+
prefix: "APP",
|
|
48
|
+
strict: true,
|
|
49
|
+
vars: {
|
|
50
|
+
API_KEY: { required: true, type: "string" },
|
|
51
|
+
PORT: { type: "number", default: 3000 },
|
|
52
|
+
DEBUG: { type: "boolean", default: false },
|
|
53
|
+
SETTINGS: { type: "json", default: {} },
|
|
54
|
+
NETWORK: {
|
|
55
|
+
required: true,
|
|
56
|
+
validator: (v) => ["mainnet", "testnet"].includes(v),
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// config is typed: { API_KEY: string, PORT: number, DEBUG: boolean, ... }
|
|
62
|
+
|
|
63
|
+
// Validate without creating
|
|
64
|
+
const result = validateConfig({
|
|
65
|
+
prefix: "APP",
|
|
66
|
+
vars: {
|
|
67
|
+
API_KEY: { required: true },
|
|
68
|
+
PORT: { type: "number" },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (!result.valid) {
|
|
73
|
+
console.error("Config errors:", result.errors);
|
|
74
|
+
console.warn("Warnings:", result.warnings);
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Price Configuration
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
import { parsePrice, createPriceConfig, createRouteMapping } from "@perkos/util-config";
|
|
82
|
+
|
|
83
|
+
// Parse single price
|
|
84
|
+
const price = parsePrice(process.env.PRICE_USD, 0.01);
|
|
85
|
+
|
|
86
|
+
// Create price config from env
|
|
87
|
+
const prices = createPriceConfig({
|
|
88
|
+
analyze: { envKey: "AI_ANALYZE_PRICE_USD", default: 0.05 },
|
|
89
|
+
generate: { envKey: "AI_GENERATE_PRICE_USD", default: 0.15 },
|
|
90
|
+
transcribe: { envKey: "AI_TRANSCRIBE_PRICE_USD", default: 0.04 },
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// Create route mappings
|
|
94
|
+
const routes = createRouteMapping(
|
|
95
|
+
[
|
|
96
|
+
{ path: "/api/ai/analyze", priceKey: "analyze" },
|
|
97
|
+
{ path: "/api/ai/generate", priceKey: "generate" },
|
|
98
|
+
{ path: "/api/ai/transcribe", priceKey: "transcribe" },
|
|
99
|
+
],
|
|
100
|
+
prices
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
// Get price for route
|
|
104
|
+
import { getRoutePrice } from "@perkos/util-config";
|
|
105
|
+
const price = getRoutePrice(routes, "/api/ai/analyze"); // 0.05
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Service Discovery
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
import { createServiceInfo } from "@perkos/util-config";
|
|
112
|
+
|
|
113
|
+
const serviceInfo = createServiceInfo({
|
|
114
|
+
name: "My AI Service",
|
|
115
|
+
version: "1.0.0",
|
|
116
|
+
description: "AI-powered services with micropayments",
|
|
117
|
+
capabilities: [
|
|
118
|
+
"image-analysis",
|
|
119
|
+
"image-generation",
|
|
120
|
+
"text-summarization",
|
|
121
|
+
],
|
|
122
|
+
endpoints: {
|
|
123
|
+
analyze: {
|
|
124
|
+
path: "/api/ai/analyze",
|
|
125
|
+
method: "POST",
|
|
126
|
+
description: "Analyze images",
|
|
127
|
+
price: 0.05,
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Feature Flags
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
import { createFeatureFlags, isFeatureEnabled } from "@perkos/util-config";
|
|
137
|
+
|
|
138
|
+
const flags = createFeatureFlags({
|
|
139
|
+
newUI: { envKey: "FEATURE_NEW_UI", default: false },
|
|
140
|
+
betaAPI: { envKey: "FEATURE_BETA_API", default: false },
|
|
141
|
+
analytics: { envKey: "FEATURE_ANALYTICS", default: true },
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
if (isFeatureEnabled(flags, "newUI")) {
|
|
145
|
+
// Show new UI
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## API Reference
|
|
150
|
+
|
|
151
|
+
### Environment Utilities
|
|
152
|
+
|
|
153
|
+
| Function | Description |
|
|
154
|
+
|----------|-------------|
|
|
155
|
+
| `getEnv(key, default?)` | Get env var with optional default |
|
|
156
|
+
| `getRequiredEnv(key)` | Get required env var (throws if missing) |
|
|
157
|
+
| `getEnvNumber(key, default?)` | Get env var as number |
|
|
158
|
+
| `getEnvBoolean(key, default?)` | Get env var as boolean |
|
|
159
|
+
| `getEnvJson(key, default?)` | Get env var as parsed JSON |
|
|
160
|
+
|
|
161
|
+
### Configuration Builder
|
|
162
|
+
|
|
163
|
+
| Function | Description |
|
|
164
|
+
|----------|-------------|
|
|
165
|
+
| `createConfig(config)` | Create typed config from env vars |
|
|
166
|
+
| `validateConfig(config)` | Validate config without creating |
|
|
167
|
+
|
|
168
|
+
### Price Configuration
|
|
169
|
+
|
|
170
|
+
| Function | Description |
|
|
171
|
+
|----------|-------------|
|
|
172
|
+
| `parsePrice(envVar, fallback)` | Parse price with fallback |
|
|
173
|
+
| `createPriceConfig(priceMap)` | Create price config from env |
|
|
174
|
+
| `createRouteMapping(routes, prices)` | Map routes to prices |
|
|
175
|
+
| `getRoutePrice(routes, path)` | Get price for route |
|
|
176
|
+
|
|
177
|
+
### Service Discovery
|
|
178
|
+
|
|
179
|
+
| Function | Description |
|
|
180
|
+
|----------|-------------|
|
|
181
|
+
| `createServiceInfo(info)` | Create service discovery info |
|
|
182
|
+
|
|
183
|
+
### Feature Flags
|
|
184
|
+
|
|
185
|
+
| Function | Description |
|
|
186
|
+
|----------|-------------|
|
|
187
|
+
| `createFeatureFlags(flags)` | Create feature flags from env |
|
|
188
|
+
| `isFeatureEnabled(flags, feature)` | Check if feature is enabled |
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @perkos/config
|
|
3
|
+
* Configuration management utilities for PerkOS services
|
|
4
|
+
*/
|
|
5
|
+
interface EnvConfig<T extends Record<string, EnvVarConfig>> {
|
|
6
|
+
vars: T;
|
|
7
|
+
prefix?: string;
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface EnvVarConfig {
|
|
11
|
+
required?: boolean;
|
|
12
|
+
default?: string | number | boolean;
|
|
13
|
+
type?: "string" | "number" | "boolean" | "json";
|
|
14
|
+
validator?: (value: string) => boolean;
|
|
15
|
+
transform?: (value: string) => unknown;
|
|
16
|
+
}
|
|
17
|
+
type ParsedConfig<T extends Record<string, EnvVarConfig>> = {
|
|
18
|
+
[K in keyof T]: T[K]["type"] extends "number" ? number : T[K]["type"] extends "boolean" ? boolean : T[K]["type"] extends "json" ? unknown : string;
|
|
19
|
+
};
|
|
20
|
+
interface ConfigValidationResult {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
errors: string[];
|
|
23
|
+
warnings: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get environment variable with optional default
|
|
27
|
+
*/
|
|
28
|
+
declare function getEnv(key: string, defaultValue?: string): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get required environment variable (throws if missing)
|
|
31
|
+
*/
|
|
32
|
+
declare function getRequiredEnv(key: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Get environment variable as number
|
|
35
|
+
*/
|
|
36
|
+
declare function getEnvNumber(key: string, defaultValue?: number): number | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Get environment variable as boolean
|
|
39
|
+
*/
|
|
40
|
+
declare function getEnvBoolean(key: string, defaultValue?: boolean): boolean | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Get environment variable as JSON
|
|
43
|
+
*/
|
|
44
|
+
declare function getEnvJson<T>(key: string, defaultValue?: T): T | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Create a typed configuration from environment variables
|
|
47
|
+
*/
|
|
48
|
+
declare function createConfig<T extends Record<string, EnvVarConfig>>(config: EnvConfig<T>): ParsedConfig<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Validate configuration without creating it
|
|
51
|
+
*/
|
|
52
|
+
declare function validateConfig<T extends Record<string, EnvVarConfig>>(config: EnvConfig<T>): ConfigValidationResult;
|
|
53
|
+
interface ServiceInfo {
|
|
54
|
+
name: string;
|
|
55
|
+
version: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
capabilities?: string[];
|
|
58
|
+
endpoints?: Record<string, EndpointInfo>;
|
|
59
|
+
}
|
|
60
|
+
interface EndpointInfo {
|
|
61
|
+
path: string;
|
|
62
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
63
|
+
description?: string;
|
|
64
|
+
price?: number;
|
|
65
|
+
rateLimit?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create service discovery info
|
|
69
|
+
*/
|
|
70
|
+
declare function createServiceInfo(info: ServiceInfo): ServiceInfo;
|
|
71
|
+
interface PriceConfig {
|
|
72
|
+
[key: string]: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Parse price from environment variable with fallback
|
|
76
|
+
*/
|
|
77
|
+
declare function parsePrice(envVar: string | undefined, fallback: number): number;
|
|
78
|
+
/**
|
|
79
|
+
* Create price configuration from environment
|
|
80
|
+
*/
|
|
81
|
+
declare function createPriceConfig(priceMap: Record<string, {
|
|
82
|
+
envKey: string;
|
|
83
|
+
default: number;
|
|
84
|
+
}>): PriceConfig;
|
|
85
|
+
interface RouteConfig {
|
|
86
|
+
path: string;
|
|
87
|
+
price: number;
|
|
88
|
+
description?: string;
|
|
89
|
+
rateLimit?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create route price mapping from price config
|
|
93
|
+
*/
|
|
94
|
+
declare function createRouteMapping(routes: Array<{
|
|
95
|
+
path: string;
|
|
96
|
+
priceKey: string;
|
|
97
|
+
description?: string;
|
|
98
|
+
}>, prices: PriceConfig): Record<string, RouteConfig>;
|
|
99
|
+
/**
|
|
100
|
+
* Get price for a route path
|
|
101
|
+
*/
|
|
102
|
+
declare function getRoutePrice(routes: Record<string, RouteConfig>, path: string): number | undefined;
|
|
103
|
+
interface FeatureFlags {
|
|
104
|
+
[key: string]: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create feature flags from environment
|
|
108
|
+
*/
|
|
109
|
+
declare function createFeatureFlags(flags: Record<string, {
|
|
110
|
+
envKey: string;
|
|
111
|
+
default: boolean;
|
|
112
|
+
}>): FeatureFlags;
|
|
113
|
+
/**
|
|
114
|
+
* Check if a feature is enabled
|
|
115
|
+
*/
|
|
116
|
+
declare function isFeatureEnabled(flags: FeatureFlags, feature: string): boolean;
|
|
117
|
+
|
|
118
|
+
export { type ConfigValidationResult, type EndpointInfo, type EnvConfig, type EnvVarConfig, type FeatureFlags, type ParsedConfig, type PriceConfig, type RouteConfig, type ServiceInfo, createConfig, createFeatureFlags, createPriceConfig, createRouteMapping, createServiceInfo, getEnv, getEnvBoolean, getEnvJson, getEnvNumber, getRequiredEnv, getRoutePrice, isFeatureEnabled, parsePrice, validateConfig };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @perkos/config
|
|
3
|
+
* Configuration management utilities for PerkOS services
|
|
4
|
+
*/
|
|
5
|
+
interface EnvConfig<T extends Record<string, EnvVarConfig>> {
|
|
6
|
+
vars: T;
|
|
7
|
+
prefix?: string;
|
|
8
|
+
strict?: boolean;
|
|
9
|
+
}
|
|
10
|
+
interface EnvVarConfig {
|
|
11
|
+
required?: boolean;
|
|
12
|
+
default?: string | number | boolean;
|
|
13
|
+
type?: "string" | "number" | "boolean" | "json";
|
|
14
|
+
validator?: (value: string) => boolean;
|
|
15
|
+
transform?: (value: string) => unknown;
|
|
16
|
+
}
|
|
17
|
+
type ParsedConfig<T extends Record<string, EnvVarConfig>> = {
|
|
18
|
+
[K in keyof T]: T[K]["type"] extends "number" ? number : T[K]["type"] extends "boolean" ? boolean : T[K]["type"] extends "json" ? unknown : string;
|
|
19
|
+
};
|
|
20
|
+
interface ConfigValidationResult {
|
|
21
|
+
valid: boolean;
|
|
22
|
+
errors: string[];
|
|
23
|
+
warnings: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get environment variable with optional default
|
|
27
|
+
*/
|
|
28
|
+
declare function getEnv(key: string, defaultValue?: string): string | undefined;
|
|
29
|
+
/**
|
|
30
|
+
* Get required environment variable (throws if missing)
|
|
31
|
+
*/
|
|
32
|
+
declare function getRequiredEnv(key: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Get environment variable as number
|
|
35
|
+
*/
|
|
36
|
+
declare function getEnvNumber(key: string, defaultValue?: number): number | undefined;
|
|
37
|
+
/**
|
|
38
|
+
* Get environment variable as boolean
|
|
39
|
+
*/
|
|
40
|
+
declare function getEnvBoolean(key: string, defaultValue?: boolean): boolean | undefined;
|
|
41
|
+
/**
|
|
42
|
+
* Get environment variable as JSON
|
|
43
|
+
*/
|
|
44
|
+
declare function getEnvJson<T>(key: string, defaultValue?: T): T | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Create a typed configuration from environment variables
|
|
47
|
+
*/
|
|
48
|
+
declare function createConfig<T extends Record<string, EnvVarConfig>>(config: EnvConfig<T>): ParsedConfig<T>;
|
|
49
|
+
/**
|
|
50
|
+
* Validate configuration without creating it
|
|
51
|
+
*/
|
|
52
|
+
declare function validateConfig<T extends Record<string, EnvVarConfig>>(config: EnvConfig<T>): ConfigValidationResult;
|
|
53
|
+
interface ServiceInfo {
|
|
54
|
+
name: string;
|
|
55
|
+
version: string;
|
|
56
|
+
description?: string;
|
|
57
|
+
capabilities?: string[];
|
|
58
|
+
endpoints?: Record<string, EndpointInfo>;
|
|
59
|
+
}
|
|
60
|
+
interface EndpointInfo {
|
|
61
|
+
path: string;
|
|
62
|
+
method: "GET" | "POST" | "PUT" | "DELETE" | "PATCH";
|
|
63
|
+
description?: string;
|
|
64
|
+
price?: number;
|
|
65
|
+
rateLimit?: number;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Create service discovery info
|
|
69
|
+
*/
|
|
70
|
+
declare function createServiceInfo(info: ServiceInfo): ServiceInfo;
|
|
71
|
+
interface PriceConfig {
|
|
72
|
+
[key: string]: number;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Parse price from environment variable with fallback
|
|
76
|
+
*/
|
|
77
|
+
declare function parsePrice(envVar: string | undefined, fallback: number): number;
|
|
78
|
+
/**
|
|
79
|
+
* Create price configuration from environment
|
|
80
|
+
*/
|
|
81
|
+
declare function createPriceConfig(priceMap: Record<string, {
|
|
82
|
+
envKey: string;
|
|
83
|
+
default: number;
|
|
84
|
+
}>): PriceConfig;
|
|
85
|
+
interface RouteConfig {
|
|
86
|
+
path: string;
|
|
87
|
+
price: number;
|
|
88
|
+
description?: string;
|
|
89
|
+
rateLimit?: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Create route price mapping from price config
|
|
93
|
+
*/
|
|
94
|
+
declare function createRouteMapping(routes: Array<{
|
|
95
|
+
path: string;
|
|
96
|
+
priceKey: string;
|
|
97
|
+
description?: string;
|
|
98
|
+
}>, prices: PriceConfig): Record<string, RouteConfig>;
|
|
99
|
+
/**
|
|
100
|
+
* Get price for a route path
|
|
101
|
+
*/
|
|
102
|
+
declare function getRoutePrice(routes: Record<string, RouteConfig>, path: string): number | undefined;
|
|
103
|
+
interface FeatureFlags {
|
|
104
|
+
[key: string]: boolean;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Create feature flags from environment
|
|
108
|
+
*/
|
|
109
|
+
declare function createFeatureFlags(flags: Record<string, {
|
|
110
|
+
envKey: string;
|
|
111
|
+
default: boolean;
|
|
112
|
+
}>): FeatureFlags;
|
|
113
|
+
/**
|
|
114
|
+
* Check if a feature is enabled
|
|
115
|
+
*/
|
|
116
|
+
declare function isFeatureEnabled(flags: FeatureFlags, feature: string): boolean;
|
|
117
|
+
|
|
118
|
+
export { type ConfigValidationResult, type EndpointInfo, type EnvConfig, type EnvVarConfig, type FeatureFlags, type ParsedConfig, type PriceConfig, type RouteConfig, type ServiceInfo, createConfig, createFeatureFlags, createPriceConfig, createRouteMapping, createServiceInfo, getEnv, getEnvBoolean, getEnvJson, getEnvNumber, getRequiredEnv, getRoutePrice, isFeatureEnabled, parsePrice, validateConfig };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createConfig: () => createConfig,
|
|
24
|
+
createFeatureFlags: () => createFeatureFlags,
|
|
25
|
+
createPriceConfig: () => createPriceConfig,
|
|
26
|
+
createRouteMapping: () => createRouteMapping,
|
|
27
|
+
createServiceInfo: () => createServiceInfo,
|
|
28
|
+
getEnv: () => getEnv,
|
|
29
|
+
getEnvBoolean: () => getEnvBoolean,
|
|
30
|
+
getEnvJson: () => getEnvJson,
|
|
31
|
+
getEnvNumber: () => getEnvNumber,
|
|
32
|
+
getRequiredEnv: () => getRequiredEnv,
|
|
33
|
+
getRoutePrice: () => getRoutePrice,
|
|
34
|
+
isFeatureEnabled: () => isFeatureEnabled,
|
|
35
|
+
parsePrice: () => parsePrice,
|
|
36
|
+
validateConfig: () => validateConfig
|
|
37
|
+
});
|
|
38
|
+
module.exports = __toCommonJS(index_exports);
|
|
39
|
+
function getEnv(key, defaultValue) {
|
|
40
|
+
return process.env[key] ?? defaultValue;
|
|
41
|
+
}
|
|
42
|
+
function getRequiredEnv(key) {
|
|
43
|
+
const value = process.env[key];
|
|
44
|
+
if (value === void 0 || value === "") {
|
|
45
|
+
throw new Error(`Required environment variable ${key} is not set`);
|
|
46
|
+
}
|
|
47
|
+
return value;
|
|
48
|
+
}
|
|
49
|
+
function getEnvNumber(key, defaultValue) {
|
|
50
|
+
const value = process.env[key];
|
|
51
|
+
if (value === void 0) return defaultValue;
|
|
52
|
+
const parsed = parseFloat(value);
|
|
53
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
54
|
+
}
|
|
55
|
+
function getEnvBoolean(key, defaultValue) {
|
|
56
|
+
const value = process.env[key];
|
|
57
|
+
if (value === void 0) return defaultValue;
|
|
58
|
+
return value.toLowerCase() === "true" || value === "1";
|
|
59
|
+
}
|
|
60
|
+
function getEnvJson(key, defaultValue) {
|
|
61
|
+
const value = process.env[key];
|
|
62
|
+
if (value === void 0) return defaultValue;
|
|
63
|
+
try {
|
|
64
|
+
return JSON.parse(value);
|
|
65
|
+
} catch {
|
|
66
|
+
return defaultValue;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
function createConfig(config) {
|
|
70
|
+
const result = {};
|
|
71
|
+
const prefix = config.prefix ? `${config.prefix}_` : "";
|
|
72
|
+
for (const [key, varConfig] of Object.entries(config.vars)) {
|
|
73
|
+
const envKey = `${prefix}${key}`;
|
|
74
|
+
const rawValue = process.env[envKey];
|
|
75
|
+
if (rawValue === void 0 || rawValue === "") {
|
|
76
|
+
if (varConfig.required && config.strict !== false) {
|
|
77
|
+
throw new Error(`Required environment variable ${envKey} is not set`);
|
|
78
|
+
}
|
|
79
|
+
if (varConfig.default !== void 0) {
|
|
80
|
+
result[key] = varConfig.default;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
result[key] = void 0;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (varConfig.validator && !varConfig.validator(rawValue)) {
|
|
87
|
+
throw new Error(`Invalid value for environment variable ${envKey}`);
|
|
88
|
+
}
|
|
89
|
+
if (varConfig.transform) {
|
|
90
|
+
result[key] = varConfig.transform(rawValue);
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
switch (varConfig.type) {
|
|
94
|
+
case "number":
|
|
95
|
+
const num = parseFloat(rawValue);
|
|
96
|
+
if (isNaN(num)) {
|
|
97
|
+
throw new Error(`Invalid number for environment variable ${envKey}`);
|
|
98
|
+
}
|
|
99
|
+
result[key] = num;
|
|
100
|
+
break;
|
|
101
|
+
case "boolean":
|
|
102
|
+
result[key] = rawValue.toLowerCase() === "true" || rawValue === "1";
|
|
103
|
+
break;
|
|
104
|
+
case "json":
|
|
105
|
+
try {
|
|
106
|
+
result[key] = JSON.parse(rawValue);
|
|
107
|
+
} catch {
|
|
108
|
+
throw new Error(`Invalid JSON for environment variable ${envKey}`);
|
|
109
|
+
}
|
|
110
|
+
break;
|
|
111
|
+
default:
|
|
112
|
+
result[key] = rawValue;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
function validateConfig(config) {
|
|
118
|
+
const errors = [];
|
|
119
|
+
const warnings = [];
|
|
120
|
+
const prefix = config.prefix ? `${config.prefix}_` : "";
|
|
121
|
+
for (const [key, varConfig] of Object.entries(config.vars)) {
|
|
122
|
+
const envKey = `${prefix}${key}`;
|
|
123
|
+
const rawValue = process.env[envKey];
|
|
124
|
+
if (rawValue === void 0 || rawValue === "") {
|
|
125
|
+
if (varConfig.required) {
|
|
126
|
+
errors.push(`Missing required: ${envKey}`);
|
|
127
|
+
} else if (varConfig.default === void 0) {
|
|
128
|
+
warnings.push(`Optional not set: ${envKey}`);
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (varConfig.validator && !varConfig.validator(rawValue)) {
|
|
133
|
+
errors.push(`Invalid value: ${envKey}`);
|
|
134
|
+
}
|
|
135
|
+
if (varConfig.type === "number" && isNaN(parseFloat(rawValue))) {
|
|
136
|
+
errors.push(`Invalid number: ${envKey}`);
|
|
137
|
+
}
|
|
138
|
+
if (varConfig.type === "json") {
|
|
139
|
+
try {
|
|
140
|
+
JSON.parse(rawValue);
|
|
141
|
+
} catch {
|
|
142
|
+
errors.push(`Invalid JSON: ${envKey}`);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
valid: errors.length === 0,
|
|
148
|
+
errors,
|
|
149
|
+
warnings
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
function createServiceInfo(info) {
|
|
153
|
+
return {
|
|
154
|
+
...info,
|
|
155
|
+
capabilities: info.capabilities || [],
|
|
156
|
+
endpoints: info.endpoints || {}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
function parsePrice(envVar, fallback) {
|
|
160
|
+
if (!envVar) return fallback;
|
|
161
|
+
const parsed = parseFloat(envVar);
|
|
162
|
+
return isNaN(parsed) ? fallback : parsed;
|
|
163
|
+
}
|
|
164
|
+
function createPriceConfig(priceMap) {
|
|
165
|
+
const result = {};
|
|
166
|
+
for (const [key, config] of Object.entries(priceMap)) {
|
|
167
|
+
result[key] = parsePrice(process.env[config.envKey], config.default);
|
|
168
|
+
}
|
|
169
|
+
return result;
|
|
170
|
+
}
|
|
171
|
+
function createRouteMapping(routes, prices) {
|
|
172
|
+
const result = {};
|
|
173
|
+
for (const route of routes) {
|
|
174
|
+
result[route.path] = {
|
|
175
|
+
path: route.path,
|
|
176
|
+
price: prices[route.priceKey] || 0,
|
|
177
|
+
description: route.description
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
function getRoutePrice(routes, path) {
|
|
183
|
+
const route = routes[path];
|
|
184
|
+
return route?.price;
|
|
185
|
+
}
|
|
186
|
+
function createFeatureFlags(flags) {
|
|
187
|
+
const result = {};
|
|
188
|
+
for (const [key, config] of Object.entries(flags)) {
|
|
189
|
+
const value = process.env[config.envKey];
|
|
190
|
+
result[key] = value !== void 0 ? value.toLowerCase() === "true" || value === "1" : config.default;
|
|
191
|
+
}
|
|
192
|
+
return result;
|
|
193
|
+
}
|
|
194
|
+
function isFeatureEnabled(flags, feature) {
|
|
195
|
+
return flags[feature] ?? false;
|
|
196
|
+
}
|
|
197
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
198
|
+
0 && (module.exports = {
|
|
199
|
+
createConfig,
|
|
200
|
+
createFeatureFlags,
|
|
201
|
+
createPriceConfig,
|
|
202
|
+
createRouteMapping,
|
|
203
|
+
createServiceInfo,
|
|
204
|
+
getEnv,
|
|
205
|
+
getEnvBoolean,
|
|
206
|
+
getEnvJson,
|
|
207
|
+
getEnvNumber,
|
|
208
|
+
getRequiredEnv,
|
|
209
|
+
getRoutePrice,
|
|
210
|
+
isFeatureEnabled,
|
|
211
|
+
parsePrice,
|
|
212
|
+
validateConfig
|
|
213
|
+
});
|
|
214
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @perkos/config\n * Configuration management utilities for PerkOS services\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface EnvConfig<T extends Record<string, EnvVarConfig>> {\n vars: T;\n prefix?: string;\n strict?: boolean;\n}\n\nexport interface EnvVarConfig {\n required?: boolean;\n default?: string | number | boolean;\n type?: \"string\" | \"number\" | \"boolean\" | \"json\";\n validator?: (value: string) => boolean;\n transform?: (value: string) => unknown;\n}\n\nexport type ParsedConfig<T extends Record<string, EnvVarConfig>> = {\n [K in keyof T]: T[K][\"type\"] extends \"number\"\n ? number\n : T[K][\"type\"] extends \"boolean\"\n ? boolean\n : T[K][\"type\"] extends \"json\"\n ? unknown\n : string;\n};\n\nexport interface ConfigValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n// ============================================================================\n// Environment Variable Utilities\n// ============================================================================\n\n/**\n * Get environment variable with optional default\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n return process.env[key] ?? defaultValue;\n}\n\n/**\n * Get required environment variable (throws if missing)\n */\nexport function getRequiredEnv(key: string): string {\n const value = process.env[key];\n if (value === undefined || value === \"\") {\n throw new Error(`Required environment variable ${key} is not set`);\n }\n return value;\n}\n\n/**\n * Get environment variable as number\n */\nexport function getEnvNumber(key: string, defaultValue?: number): number | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get environment variable as boolean\n */\nexport function getEnvBoolean(key: string, defaultValue?: boolean): boolean | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n return value.toLowerCase() === \"true\" || value === \"1\";\n}\n\n/**\n * Get environment variable as JSON\n */\nexport function getEnvJson<T>(key: string, defaultValue?: T): T | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n// ============================================================================\n// Configuration Builder\n// ============================================================================\n\n/**\n * Create a typed configuration from environment variables\n */\nexport function createConfig<T extends Record<string, EnvVarConfig>>(\n config: EnvConfig<T>\n): ParsedConfig<T> {\n const result: Record<string, unknown> = {};\n const prefix = config.prefix ? `${config.prefix}_` : \"\";\n\n for (const [key, varConfig] of Object.entries(config.vars)) {\n const envKey = `${prefix}${key}`;\n const rawValue = process.env[envKey];\n\n // Handle missing values\n if (rawValue === undefined || rawValue === \"\") {\n if (varConfig.required && config.strict !== false) {\n throw new Error(`Required environment variable ${envKey} is not set`);\n }\n if (varConfig.default !== undefined) {\n result[key] = varConfig.default;\n continue;\n }\n result[key] = undefined;\n continue;\n }\n\n // Validate\n if (varConfig.validator && !varConfig.validator(rawValue)) {\n throw new Error(`Invalid value for environment variable ${envKey}`);\n }\n\n // Transform or parse by type\n if (varConfig.transform) {\n result[key] = varConfig.transform(rawValue);\n continue;\n }\n\n switch (varConfig.type) {\n case \"number\":\n const num = parseFloat(rawValue);\n if (isNaN(num)) {\n throw new Error(`Invalid number for environment variable ${envKey}`);\n }\n result[key] = num;\n break;\n case \"boolean\":\n result[key] = rawValue.toLowerCase() === \"true\" || rawValue === \"1\";\n break;\n case \"json\":\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n throw new Error(`Invalid JSON for environment variable ${envKey}`);\n }\n break;\n default:\n result[key] = rawValue;\n }\n }\n\n return result as ParsedConfig<T>;\n}\n\n/**\n * Validate configuration without creating it\n */\nexport function validateConfig<T extends Record<string, EnvVarConfig>>(\n config: EnvConfig<T>\n): ConfigValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n const prefix = config.prefix ? `${config.prefix}_` : \"\";\n\n for (const [key, varConfig] of Object.entries(config.vars)) {\n const envKey = `${prefix}${key}`;\n const rawValue = process.env[envKey];\n\n if (rawValue === undefined || rawValue === \"\") {\n if (varConfig.required) {\n errors.push(`Missing required: ${envKey}`);\n } else if (varConfig.default === undefined) {\n warnings.push(`Optional not set: ${envKey}`);\n }\n continue;\n }\n\n if (varConfig.validator && !varConfig.validator(rawValue)) {\n errors.push(`Invalid value: ${envKey}`);\n }\n\n if (varConfig.type === \"number\" && isNaN(parseFloat(rawValue))) {\n errors.push(`Invalid number: ${envKey}`);\n }\n\n if (varConfig.type === \"json\") {\n try {\n JSON.parse(rawValue);\n } catch {\n errors.push(`Invalid JSON: ${envKey}`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n// ============================================================================\n// Service Discovery Configuration\n// ============================================================================\n\nexport interface ServiceInfo {\n name: string;\n version: string;\n description?: string;\n capabilities?: string[];\n endpoints?: Record<string, EndpointInfo>;\n}\n\nexport interface EndpointInfo {\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n description?: string;\n price?: number;\n rateLimit?: number;\n}\n\n/**\n * Create service discovery info\n */\nexport function createServiceInfo(info: ServiceInfo): ServiceInfo {\n return {\n ...info,\n capabilities: info.capabilities || [],\n endpoints: info.endpoints || {},\n };\n}\n\n// ============================================================================\n// Price Configuration\n// ============================================================================\n\nexport interface PriceConfig {\n [key: string]: number;\n}\n\n/**\n * Parse price from environment variable with fallback\n */\nexport function parsePrice(envVar: string | undefined, fallback: number): number {\n if (!envVar) return fallback;\n const parsed = parseFloat(envVar);\n return isNaN(parsed) ? fallback : parsed;\n}\n\n/**\n * Create price configuration from environment\n */\nexport function createPriceConfig(\n priceMap: Record<string, { envKey: string; default: number }>\n): PriceConfig {\n const result: PriceConfig = {};\n for (const [key, config] of Object.entries(priceMap)) {\n result[key] = parsePrice(process.env[config.envKey], config.default);\n }\n return result;\n}\n\n// ============================================================================\n// Route Configuration\n// ============================================================================\n\nexport interface RouteConfig {\n path: string;\n price: number;\n description?: string;\n rateLimit?: number;\n}\n\n/**\n * Create route price mapping from price config\n */\nexport function createRouteMapping(\n routes: Array<{ path: string; priceKey: string; description?: string }>,\n prices: PriceConfig\n): Record<string, RouteConfig> {\n const result: Record<string, RouteConfig> = {};\n for (const route of routes) {\n result[route.path] = {\n path: route.path,\n price: prices[route.priceKey] || 0,\n description: route.description,\n };\n }\n return result;\n}\n\n/**\n * Get price for a route path\n */\nexport function getRoutePrice(\n routes: Record<string, RouteConfig>,\n path: string\n): number | undefined {\n const route = routes[path];\n return route?.price;\n}\n\n// ============================================================================\n// Feature Flags\n// ============================================================================\n\nexport interface FeatureFlags {\n [key: string]: boolean;\n}\n\n/**\n * Create feature flags from environment\n */\nexport function createFeatureFlags(\n flags: Record<string, { envKey: string; default: boolean }>\n): FeatureFlags {\n const result: FeatureFlags = {};\n for (const [key, config] of Object.entries(flags)) {\n const value = process.env[config.envKey];\n result[key] =\n value !== undefined\n ? value.toLowerCase() === \"true\" || value === \"1\"\n : config.default;\n }\n return result;\n}\n\n/**\n * Check if a feature is enabled\n */\nexport function isFeatureEnabled(\n flags: FeatureFlags,\n feature: string\n): boolean {\n return flags[feature] ?? false;\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
function getEnv(key, defaultValue) {
|
|
3
|
+
return process.env[key] ?? defaultValue;
|
|
4
|
+
}
|
|
5
|
+
function getRequiredEnv(key) {
|
|
6
|
+
const value = process.env[key];
|
|
7
|
+
if (value === void 0 || value === "") {
|
|
8
|
+
throw new Error(`Required environment variable ${key} is not set`);
|
|
9
|
+
}
|
|
10
|
+
return value;
|
|
11
|
+
}
|
|
12
|
+
function getEnvNumber(key, defaultValue) {
|
|
13
|
+
const value = process.env[key];
|
|
14
|
+
if (value === void 0) return defaultValue;
|
|
15
|
+
const parsed = parseFloat(value);
|
|
16
|
+
return isNaN(parsed) ? defaultValue : parsed;
|
|
17
|
+
}
|
|
18
|
+
function getEnvBoolean(key, defaultValue) {
|
|
19
|
+
const value = process.env[key];
|
|
20
|
+
if (value === void 0) return defaultValue;
|
|
21
|
+
return value.toLowerCase() === "true" || value === "1";
|
|
22
|
+
}
|
|
23
|
+
function getEnvJson(key, defaultValue) {
|
|
24
|
+
const value = process.env[key];
|
|
25
|
+
if (value === void 0) return defaultValue;
|
|
26
|
+
try {
|
|
27
|
+
return JSON.parse(value);
|
|
28
|
+
} catch {
|
|
29
|
+
return defaultValue;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function createConfig(config) {
|
|
33
|
+
const result = {};
|
|
34
|
+
const prefix = config.prefix ? `${config.prefix}_` : "";
|
|
35
|
+
for (const [key, varConfig] of Object.entries(config.vars)) {
|
|
36
|
+
const envKey = `${prefix}${key}`;
|
|
37
|
+
const rawValue = process.env[envKey];
|
|
38
|
+
if (rawValue === void 0 || rawValue === "") {
|
|
39
|
+
if (varConfig.required && config.strict !== false) {
|
|
40
|
+
throw new Error(`Required environment variable ${envKey} is not set`);
|
|
41
|
+
}
|
|
42
|
+
if (varConfig.default !== void 0) {
|
|
43
|
+
result[key] = varConfig.default;
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
result[key] = void 0;
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (varConfig.validator && !varConfig.validator(rawValue)) {
|
|
50
|
+
throw new Error(`Invalid value for environment variable ${envKey}`);
|
|
51
|
+
}
|
|
52
|
+
if (varConfig.transform) {
|
|
53
|
+
result[key] = varConfig.transform(rawValue);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
switch (varConfig.type) {
|
|
57
|
+
case "number":
|
|
58
|
+
const num = parseFloat(rawValue);
|
|
59
|
+
if (isNaN(num)) {
|
|
60
|
+
throw new Error(`Invalid number for environment variable ${envKey}`);
|
|
61
|
+
}
|
|
62
|
+
result[key] = num;
|
|
63
|
+
break;
|
|
64
|
+
case "boolean":
|
|
65
|
+
result[key] = rawValue.toLowerCase() === "true" || rawValue === "1";
|
|
66
|
+
break;
|
|
67
|
+
case "json":
|
|
68
|
+
try {
|
|
69
|
+
result[key] = JSON.parse(rawValue);
|
|
70
|
+
} catch {
|
|
71
|
+
throw new Error(`Invalid JSON for environment variable ${envKey}`);
|
|
72
|
+
}
|
|
73
|
+
break;
|
|
74
|
+
default:
|
|
75
|
+
result[key] = rawValue;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return result;
|
|
79
|
+
}
|
|
80
|
+
function validateConfig(config) {
|
|
81
|
+
const errors = [];
|
|
82
|
+
const warnings = [];
|
|
83
|
+
const prefix = config.prefix ? `${config.prefix}_` : "";
|
|
84
|
+
for (const [key, varConfig] of Object.entries(config.vars)) {
|
|
85
|
+
const envKey = `${prefix}${key}`;
|
|
86
|
+
const rawValue = process.env[envKey];
|
|
87
|
+
if (rawValue === void 0 || rawValue === "") {
|
|
88
|
+
if (varConfig.required) {
|
|
89
|
+
errors.push(`Missing required: ${envKey}`);
|
|
90
|
+
} else if (varConfig.default === void 0) {
|
|
91
|
+
warnings.push(`Optional not set: ${envKey}`);
|
|
92
|
+
}
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
if (varConfig.validator && !varConfig.validator(rawValue)) {
|
|
96
|
+
errors.push(`Invalid value: ${envKey}`);
|
|
97
|
+
}
|
|
98
|
+
if (varConfig.type === "number" && isNaN(parseFloat(rawValue))) {
|
|
99
|
+
errors.push(`Invalid number: ${envKey}`);
|
|
100
|
+
}
|
|
101
|
+
if (varConfig.type === "json") {
|
|
102
|
+
try {
|
|
103
|
+
JSON.parse(rawValue);
|
|
104
|
+
} catch {
|
|
105
|
+
errors.push(`Invalid JSON: ${envKey}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
valid: errors.length === 0,
|
|
111
|
+
errors,
|
|
112
|
+
warnings
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function createServiceInfo(info) {
|
|
116
|
+
return {
|
|
117
|
+
...info,
|
|
118
|
+
capabilities: info.capabilities || [],
|
|
119
|
+
endpoints: info.endpoints || {}
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
function parsePrice(envVar, fallback) {
|
|
123
|
+
if (!envVar) return fallback;
|
|
124
|
+
const parsed = parseFloat(envVar);
|
|
125
|
+
return isNaN(parsed) ? fallback : parsed;
|
|
126
|
+
}
|
|
127
|
+
function createPriceConfig(priceMap) {
|
|
128
|
+
const result = {};
|
|
129
|
+
for (const [key, config] of Object.entries(priceMap)) {
|
|
130
|
+
result[key] = parsePrice(process.env[config.envKey], config.default);
|
|
131
|
+
}
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
function createRouteMapping(routes, prices) {
|
|
135
|
+
const result = {};
|
|
136
|
+
for (const route of routes) {
|
|
137
|
+
result[route.path] = {
|
|
138
|
+
path: route.path,
|
|
139
|
+
price: prices[route.priceKey] || 0,
|
|
140
|
+
description: route.description
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
function getRoutePrice(routes, path) {
|
|
146
|
+
const route = routes[path];
|
|
147
|
+
return route?.price;
|
|
148
|
+
}
|
|
149
|
+
function createFeatureFlags(flags) {
|
|
150
|
+
const result = {};
|
|
151
|
+
for (const [key, config] of Object.entries(flags)) {
|
|
152
|
+
const value = process.env[config.envKey];
|
|
153
|
+
result[key] = value !== void 0 ? value.toLowerCase() === "true" || value === "1" : config.default;
|
|
154
|
+
}
|
|
155
|
+
return result;
|
|
156
|
+
}
|
|
157
|
+
function isFeatureEnabled(flags, feature) {
|
|
158
|
+
return flags[feature] ?? false;
|
|
159
|
+
}
|
|
160
|
+
export {
|
|
161
|
+
createConfig,
|
|
162
|
+
createFeatureFlags,
|
|
163
|
+
createPriceConfig,
|
|
164
|
+
createRouteMapping,
|
|
165
|
+
createServiceInfo,
|
|
166
|
+
getEnv,
|
|
167
|
+
getEnvBoolean,
|
|
168
|
+
getEnvJson,
|
|
169
|
+
getEnvNumber,
|
|
170
|
+
getRequiredEnv,
|
|
171
|
+
getRoutePrice,
|
|
172
|
+
isFeatureEnabled,
|
|
173
|
+
parsePrice,
|
|
174
|
+
validateConfig
|
|
175
|
+
};
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @perkos/config\n * Configuration management utilities for PerkOS services\n */\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface EnvConfig<T extends Record<string, EnvVarConfig>> {\n vars: T;\n prefix?: string;\n strict?: boolean;\n}\n\nexport interface EnvVarConfig {\n required?: boolean;\n default?: string | number | boolean;\n type?: \"string\" | \"number\" | \"boolean\" | \"json\";\n validator?: (value: string) => boolean;\n transform?: (value: string) => unknown;\n}\n\nexport type ParsedConfig<T extends Record<string, EnvVarConfig>> = {\n [K in keyof T]: T[K][\"type\"] extends \"number\"\n ? number\n : T[K][\"type\"] extends \"boolean\"\n ? boolean\n : T[K][\"type\"] extends \"json\"\n ? unknown\n : string;\n};\n\nexport interface ConfigValidationResult {\n valid: boolean;\n errors: string[];\n warnings: string[];\n}\n\n// ============================================================================\n// Environment Variable Utilities\n// ============================================================================\n\n/**\n * Get environment variable with optional default\n */\nexport function getEnv(key: string, defaultValue?: string): string | undefined {\n return process.env[key] ?? defaultValue;\n}\n\n/**\n * Get required environment variable (throws if missing)\n */\nexport function getRequiredEnv(key: string): string {\n const value = process.env[key];\n if (value === undefined || value === \"\") {\n throw new Error(`Required environment variable ${key} is not set`);\n }\n return value;\n}\n\n/**\n * Get environment variable as number\n */\nexport function getEnvNumber(key: string, defaultValue?: number): number | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? defaultValue : parsed;\n}\n\n/**\n * Get environment variable as boolean\n */\nexport function getEnvBoolean(key: string, defaultValue?: boolean): boolean | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n return value.toLowerCase() === \"true\" || value === \"1\";\n}\n\n/**\n * Get environment variable as JSON\n */\nexport function getEnvJson<T>(key: string, defaultValue?: T): T | undefined {\n const value = process.env[key];\n if (value === undefined) return defaultValue;\n try {\n return JSON.parse(value) as T;\n } catch {\n return defaultValue;\n }\n}\n\n// ============================================================================\n// Configuration Builder\n// ============================================================================\n\n/**\n * Create a typed configuration from environment variables\n */\nexport function createConfig<T extends Record<string, EnvVarConfig>>(\n config: EnvConfig<T>\n): ParsedConfig<T> {\n const result: Record<string, unknown> = {};\n const prefix = config.prefix ? `${config.prefix}_` : \"\";\n\n for (const [key, varConfig] of Object.entries(config.vars)) {\n const envKey = `${prefix}${key}`;\n const rawValue = process.env[envKey];\n\n // Handle missing values\n if (rawValue === undefined || rawValue === \"\") {\n if (varConfig.required && config.strict !== false) {\n throw new Error(`Required environment variable ${envKey} is not set`);\n }\n if (varConfig.default !== undefined) {\n result[key] = varConfig.default;\n continue;\n }\n result[key] = undefined;\n continue;\n }\n\n // Validate\n if (varConfig.validator && !varConfig.validator(rawValue)) {\n throw new Error(`Invalid value for environment variable ${envKey}`);\n }\n\n // Transform or parse by type\n if (varConfig.transform) {\n result[key] = varConfig.transform(rawValue);\n continue;\n }\n\n switch (varConfig.type) {\n case \"number\":\n const num = parseFloat(rawValue);\n if (isNaN(num)) {\n throw new Error(`Invalid number for environment variable ${envKey}`);\n }\n result[key] = num;\n break;\n case \"boolean\":\n result[key] = rawValue.toLowerCase() === \"true\" || rawValue === \"1\";\n break;\n case \"json\":\n try {\n result[key] = JSON.parse(rawValue);\n } catch {\n throw new Error(`Invalid JSON for environment variable ${envKey}`);\n }\n break;\n default:\n result[key] = rawValue;\n }\n }\n\n return result as ParsedConfig<T>;\n}\n\n/**\n * Validate configuration without creating it\n */\nexport function validateConfig<T extends Record<string, EnvVarConfig>>(\n config: EnvConfig<T>\n): ConfigValidationResult {\n const errors: string[] = [];\n const warnings: string[] = [];\n const prefix = config.prefix ? `${config.prefix}_` : \"\";\n\n for (const [key, varConfig] of Object.entries(config.vars)) {\n const envKey = `${prefix}${key}`;\n const rawValue = process.env[envKey];\n\n if (rawValue === undefined || rawValue === \"\") {\n if (varConfig.required) {\n errors.push(`Missing required: ${envKey}`);\n } else if (varConfig.default === undefined) {\n warnings.push(`Optional not set: ${envKey}`);\n }\n continue;\n }\n\n if (varConfig.validator && !varConfig.validator(rawValue)) {\n errors.push(`Invalid value: ${envKey}`);\n }\n\n if (varConfig.type === \"number\" && isNaN(parseFloat(rawValue))) {\n errors.push(`Invalid number: ${envKey}`);\n }\n\n if (varConfig.type === \"json\") {\n try {\n JSON.parse(rawValue);\n } catch {\n errors.push(`Invalid JSON: ${envKey}`);\n }\n }\n }\n\n return {\n valid: errors.length === 0,\n errors,\n warnings,\n };\n}\n\n// ============================================================================\n// Service Discovery Configuration\n// ============================================================================\n\nexport interface ServiceInfo {\n name: string;\n version: string;\n description?: string;\n capabilities?: string[];\n endpoints?: Record<string, EndpointInfo>;\n}\n\nexport interface EndpointInfo {\n path: string;\n method: \"GET\" | \"POST\" | \"PUT\" | \"DELETE\" | \"PATCH\";\n description?: string;\n price?: number;\n rateLimit?: number;\n}\n\n/**\n * Create service discovery info\n */\nexport function createServiceInfo(info: ServiceInfo): ServiceInfo {\n return {\n ...info,\n capabilities: info.capabilities || [],\n endpoints: info.endpoints || {},\n };\n}\n\n// ============================================================================\n// Price Configuration\n// ============================================================================\n\nexport interface PriceConfig {\n [key: string]: number;\n}\n\n/**\n * Parse price from environment variable with fallback\n */\nexport function parsePrice(envVar: string | undefined, fallback: number): number {\n if (!envVar) return fallback;\n const parsed = parseFloat(envVar);\n return isNaN(parsed) ? fallback : parsed;\n}\n\n/**\n * Create price configuration from environment\n */\nexport function createPriceConfig(\n priceMap: Record<string, { envKey: string; default: number }>\n): PriceConfig {\n const result: PriceConfig = {};\n for (const [key, config] of Object.entries(priceMap)) {\n result[key] = parsePrice(process.env[config.envKey], config.default);\n }\n return result;\n}\n\n// ============================================================================\n// Route Configuration\n// ============================================================================\n\nexport interface RouteConfig {\n path: string;\n price: number;\n description?: string;\n rateLimit?: number;\n}\n\n/**\n * Create route price mapping from price config\n */\nexport function createRouteMapping(\n routes: Array<{ path: string; priceKey: string; description?: string }>,\n prices: PriceConfig\n): Record<string, RouteConfig> {\n const result: Record<string, RouteConfig> = {};\n for (const route of routes) {\n result[route.path] = {\n path: route.path,\n price: prices[route.priceKey] || 0,\n description: route.description,\n };\n }\n return result;\n}\n\n/**\n * Get price for a route path\n */\nexport function getRoutePrice(\n routes: Record<string, RouteConfig>,\n path: string\n): number | undefined {\n const route = routes[path];\n return route?.price;\n}\n\n// ============================================================================\n// Feature Flags\n// ============================================================================\n\nexport interface FeatureFlags {\n [key: string]: boolean;\n}\n\n/**\n * Create feature flags from environment\n */\nexport function createFeatureFlags(\n flags: Record<string, { envKey: string; default: boolean }>\n): FeatureFlags {\n const result: FeatureFlags = {};\n for (const [key, config] of Object.entries(flags)) {\n const value = process.env[config.envKey];\n result[key] =\n value !== undefined\n ? value.toLowerCase() === \"true\" || value === \"1\"\n : config.default;\n }\n return result;\n}\n\n/**\n * Check if a feature is enabled\n */\nexport function isFeatureEnabled(\n flags: FeatureFlags,\n feature: string\n): boolean {\n return flags[feature] ?? false;\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@perkos/util-config",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Configuration management utilities for PerkOS services",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"scripts": {
|
|
19
|
+
"build": "tsup",
|
|
20
|
+
"dev": "tsup --watch",
|
|
21
|
+
"lint": "tsc --noEmit",
|
|
22
|
+
"test": "vitest run",
|
|
23
|
+
"clean": "rm -rf dist",
|
|
24
|
+
"prepublishOnly": "npm run build"
|
|
25
|
+
},
|
|
26
|
+
"keywords": [
|
|
27
|
+
"config",
|
|
28
|
+
"configuration",
|
|
29
|
+
"environment",
|
|
30
|
+
"perkos",
|
|
31
|
+
"x402"
|
|
32
|
+
],
|
|
33
|
+
"author": "PerkOS",
|
|
34
|
+
"license": "MIT",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/PerkOS-xyz/pkg-util-config.git"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.10.0",
|
|
41
|
+
"tsup": "^8.0.1",
|
|
42
|
+
"typescript": "^5.3.3",
|
|
43
|
+
"vitest": "^1.2.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"node": ">=18.0.0"
|
|
47
|
+
}
|
|
48
|
+
}
|