@outfitter/config 0.3.0 → 0.3.2
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/env.d.ts +2 -0
- package/dist/env.js +18 -0
- package/dist/environment.d.ts +2 -0
- package/dist/environment.js +10 -0
- package/dist/index.js +6 -1137
- package/dist/shared/@outfitter/config-3n1xvxce.js +5 -0
- package/dist/shared/@outfitter/config-443pb6p2.js +34 -0
- package/dist/shared/@outfitter/config-a6g8nmxw.d.ts +90 -0
- package/dist/shared/@outfitter/config-veqxf02x.d.ts +143 -0
- package/dist/shared/@outfitter/config-w3pwcpr2.js +36 -0
- package/package.json +9 -9
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/config/src/env.ts
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
var portSchema = z.string().regex(/^\d+$/).transform(Number).pipe(z.number().int().positive().max(65535));
|
|
5
|
+
var booleanSchema = z.enum(["true", "false", "1", "0", ""]).transform((val) => val === "true" || val === "1");
|
|
6
|
+
var optionalBooleanSchema = z.string().optional().transform((val) => {
|
|
7
|
+
if (val === undefined || val === "")
|
|
8
|
+
return;
|
|
9
|
+
return val === "true" || val === "1";
|
|
10
|
+
});
|
|
11
|
+
function parseEnv(schema, envObj = process.env) {
|
|
12
|
+
return schema.parse(envObj);
|
|
13
|
+
}
|
|
14
|
+
var appEnvSchema = z.object({
|
|
15
|
+
NODE_ENV: z.enum(["development", "test", "production"]).default("development"),
|
|
16
|
+
NO_COLOR: optionalBooleanSchema,
|
|
17
|
+
FORCE_COLOR: optionalBooleanSchema,
|
|
18
|
+
CI: optionalBooleanSchema,
|
|
19
|
+
TERM: z.string().optional(),
|
|
20
|
+
XDG_CONFIG_HOME: z.string().optional(),
|
|
21
|
+
XDG_DATA_HOME: z.string().optional(),
|
|
22
|
+
XDG_STATE_HOME: z.string().optional(),
|
|
23
|
+
XDG_CACHE_HOME: z.string().optional(),
|
|
24
|
+
HOME: z.string().optional()
|
|
25
|
+
});
|
|
26
|
+
var env = parseEnv(appEnvSchema);
|
|
27
|
+
function getEnvBoolean(key) {
|
|
28
|
+
const value = process.env[key];
|
|
29
|
+
if (value === undefined || value === "")
|
|
30
|
+
return;
|
|
31
|
+
return value === "true" || value === "1";
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export { portSchema, booleanSchema, optionalBooleanSchema, parseEnv, env, getEnvBoolean };
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified environment profiles for Outfitter packages.
|
|
3
|
+
*
|
|
4
|
+
* Provides a shared "environment" concept that cascades defaults
|
|
5
|
+
* across all Outfitter packages. The environment is determined by
|
|
6
|
+
* the `OUTFITTER_ENV` environment variable, falling back to
|
|
7
|
+
* `"production"` when unset or invalid.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```typescript
|
|
11
|
+
* import { getEnvironment, getEnvironmentDefaults } from "@outfitter/config";
|
|
12
|
+
*
|
|
13
|
+
* const env = getEnvironment(); // "development" | "production" | "test"
|
|
14
|
+
* const defaults = getEnvironmentDefaults(env);
|
|
15
|
+
*
|
|
16
|
+
* if (defaults.verbose) {
|
|
17
|
+
* console.log("Verbose mode enabled");
|
|
18
|
+
* }
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* Valid Outfitter environment names.
|
|
25
|
+
*
|
|
26
|
+
* - `"development"` — Local development with verbose output and debug logging
|
|
27
|
+
* - `"production"` — Production deployments with minimal output
|
|
28
|
+
* - `"test"` — Test runs with full error detail but no logging
|
|
29
|
+
*/
|
|
30
|
+
type OutfitterEnv = "development" | "production" | "test";
|
|
31
|
+
/**
|
|
32
|
+
* Profile-specific defaults for an environment.
|
|
33
|
+
*
|
|
34
|
+
* These defaults provide sensible starting values that individual
|
|
35
|
+
* packages can override or extend.
|
|
36
|
+
*/
|
|
37
|
+
interface EnvironmentDefaults {
|
|
38
|
+
/** Default log level. `null` means logging is disabled by default. */
|
|
39
|
+
logLevel: "debug" | "info" | "warn" | "error" | null;
|
|
40
|
+
/** Whether verbose output is enabled by default. */
|
|
41
|
+
verbose: boolean;
|
|
42
|
+
/** How much error detail to include in output. */
|
|
43
|
+
errorDetail: "full" | "message";
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Determine the current Outfitter environment.
|
|
47
|
+
*
|
|
48
|
+
* Reads the `OUTFITTER_ENV` environment variable. If set to a valid
|
|
49
|
+
* value (`"development"`, `"production"`, or `"test"`), returns that
|
|
50
|
+
* value. Otherwise falls back to `"production"`.
|
|
51
|
+
*
|
|
52
|
+
* @returns The current environment
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```typescript
|
|
56
|
+
* // With OUTFITTER_ENV=development
|
|
57
|
+
* getEnvironment(); // "development"
|
|
58
|
+
*
|
|
59
|
+
* // With OUTFITTER_ENV unset or invalid
|
|
60
|
+
* getEnvironment(); // "production"
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
declare function getEnvironment(): OutfitterEnv;
|
|
64
|
+
/**
|
|
65
|
+
* Get the default settings for an environment profile.
|
|
66
|
+
*
|
|
67
|
+
* Returns a shallow copy of the defaults for the given environment.
|
|
68
|
+
* These defaults are intended as starting values that individual
|
|
69
|
+
* packages can override via their own configuration.
|
|
70
|
+
*
|
|
71
|
+
* | Setting | `development` | `production` | `test` |
|
|
72
|
+
* |---------|--------------|-------------|--------|
|
|
73
|
+
* | logLevel | `"debug"` | `null` | `null` |
|
|
74
|
+
* | verbose | `true` | `false` | `false` |
|
|
75
|
+
* | errorDetail | `"full"` | `"message"` | `"full"` |
|
|
76
|
+
*
|
|
77
|
+
* @param env - The environment to get defaults for
|
|
78
|
+
* @returns Profile-specific default settings
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const defaults = getEnvironmentDefaults("development");
|
|
83
|
+
* // { logLevel: "debug", verbose: true, errorDetail: "full" }
|
|
84
|
+
*
|
|
85
|
+
* const prodDefaults = getEnvironmentDefaults("production");
|
|
86
|
+
* // { logLevel: null, verbose: false, errorDetail: "message" }
|
|
87
|
+
* ```
|
|
88
|
+
*/
|
|
89
|
+
declare function getEnvironmentDefaults(env: OutfitterEnv): EnvironmentDefaults;
|
|
90
|
+
export { OutfitterEnv, EnvironmentDefaults, getEnvironment, getEnvironmentDefaults };
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* Port number schema (1-65535) with string-to-number coercion.
|
|
4
|
+
*
|
|
5
|
+
* Validates that a string contains only digits, then transforms
|
|
6
|
+
* to a number and validates the port range.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* const schema = z.object({ PORT: portSchema });
|
|
11
|
+
* schema.parse({ PORT: "3000" }); // { PORT: 3000 }
|
|
12
|
+
* schema.parse({ PORT: "invalid" }); // throws
|
|
13
|
+
* schema.parse({ PORT: "99999" }); // throws (out of range)
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
declare const portSchema: z.ZodType<number, string>;
|
|
17
|
+
/**
|
|
18
|
+
* Boolean schema with proper string coercion.
|
|
19
|
+
*
|
|
20
|
+
* Accepts: "true", "false", "1", "0", ""
|
|
21
|
+
* - "true" or "1" -> true
|
|
22
|
+
* - "false", "0", or "" -> false
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const schema = z.object({ DEBUG: booleanSchema });
|
|
27
|
+
* schema.parse({ DEBUG: "true" }); // { DEBUG: true }
|
|
28
|
+
* schema.parse({ DEBUG: "1" }); // { DEBUG: true }
|
|
29
|
+
* schema.parse({ DEBUG: "false" }); // { DEBUG: false }
|
|
30
|
+
* schema.parse({ DEBUG: "" }); // { DEBUG: false }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
declare const booleanSchema: z.ZodType<boolean, string>;
|
|
34
|
+
/**
|
|
35
|
+
* Optional boolean schema - returns undefined if not set.
|
|
36
|
+
*
|
|
37
|
+
* Unlike `booleanSchema`, this returns `undefined` for missing
|
|
38
|
+
* or empty values, allowing callers to distinguish between
|
|
39
|
+
* "explicitly set to false" and "not set".
|
|
40
|
+
*
|
|
41
|
+
* @example
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const schema = z.object({ NO_COLOR: optionalBooleanSchema });
|
|
44
|
+
* schema.parse({ NO_COLOR: "true" }); // { NO_COLOR: true }
|
|
45
|
+
* schema.parse({ NO_COLOR: "" }); // { NO_COLOR: undefined }
|
|
46
|
+
* schema.parse({ NO_COLOR: undefined }); // { NO_COLOR: undefined }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
declare const optionalBooleanSchema: z.ZodType<boolean | undefined, string | undefined>;
|
|
50
|
+
/**
|
|
51
|
+
* Parse and validate environment variables against a Zod schema.
|
|
52
|
+
*
|
|
53
|
+
* By default reads from `process.env`, but accepts a custom env
|
|
54
|
+
* object for testing.
|
|
55
|
+
*
|
|
56
|
+
* @typeParam T - The Zod schema shape
|
|
57
|
+
* @param schema - Zod object schema to validate against
|
|
58
|
+
* @param envObj - Environment object (defaults to process.env)
|
|
59
|
+
* @returns Validated and transformed environment object
|
|
60
|
+
* @throws {z.ZodError} When validation fails
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* const AppEnv = z.object({
|
|
65
|
+
* PORT: portSchema,
|
|
66
|
+
* DEBUG: booleanSchema,
|
|
67
|
+
* });
|
|
68
|
+
*
|
|
69
|
+
* const env = parseEnv(AppEnv);
|
|
70
|
+
* console.log(env.PORT); // number
|
|
71
|
+
* console.log(env.DEBUG); // boolean
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
declare function parseEnv<T extends z.ZodRawShape>(schema: z.ZodObject<T>, envObj?: Record<string, string | undefined>): z.infer<z.ZodObject<T>>;
|
|
75
|
+
type AppEnvShape = {
|
|
76
|
+
NODE_ENV: z.ZodDefault<z.ZodEnum<{
|
|
77
|
+
development: "development";
|
|
78
|
+
test: "test";
|
|
79
|
+
production: "production";
|
|
80
|
+
}>>;
|
|
81
|
+
NO_COLOR: typeof optionalBooleanSchema;
|
|
82
|
+
FORCE_COLOR: typeof optionalBooleanSchema;
|
|
83
|
+
CI: typeof optionalBooleanSchema;
|
|
84
|
+
TERM: z.ZodOptional<z.ZodString>;
|
|
85
|
+
XDG_CONFIG_HOME: z.ZodOptional<z.ZodString>;
|
|
86
|
+
XDG_DATA_HOME: z.ZodOptional<z.ZodString>;
|
|
87
|
+
XDG_STATE_HOME: z.ZodOptional<z.ZodString>;
|
|
88
|
+
XDG_CACHE_HOME: z.ZodOptional<z.ZodString>;
|
|
89
|
+
HOME: z.ZodOptional<z.ZodString>;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Schema for common application environment variables.
|
|
93
|
+
*/
|
|
94
|
+
declare const appEnvSchema: z.ZodObject<AppEnvShape>;
|
|
95
|
+
/**
|
|
96
|
+
* Type for the pre-parsed application environment.
|
|
97
|
+
*/
|
|
98
|
+
type Env = z.infer<typeof appEnvSchema>;
|
|
99
|
+
/**
|
|
100
|
+
* Pre-parsed application environment.
|
|
101
|
+
*
|
|
102
|
+
* Access common environment variables with proper typing:
|
|
103
|
+
* - `env.NODE_ENV`: "development" | "test" | "production"
|
|
104
|
+
* - `env.NO_COLOR`: boolean | undefined
|
|
105
|
+
* - `env.FORCE_COLOR`: boolean | undefined
|
|
106
|
+
* - `env.CI`: boolean | undefined
|
|
107
|
+
* - `env.TERM`: string | undefined
|
|
108
|
+
* - `env.XDG_*`: string | undefined
|
|
109
|
+
* - `env.HOME`: string | undefined
|
|
110
|
+
*
|
|
111
|
+
* @example
|
|
112
|
+
* ```typescript
|
|
113
|
+
* import { env } from "@outfitter/config";
|
|
114
|
+
*
|
|
115
|
+
* if (env.CI) {
|
|
116
|
+
* console.log("Running in CI environment");
|
|
117
|
+
* }
|
|
118
|
+
*
|
|
119
|
+
* if (env.NO_COLOR) {
|
|
120
|
+
* // Disable color output
|
|
121
|
+
* }
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare const env: Env;
|
|
125
|
+
/**
|
|
126
|
+
* Reads an optional boolean from process.env at call time.
|
|
127
|
+
*
|
|
128
|
+
* Unlike `env.NO_COLOR` (which is static), this reads dynamically
|
|
129
|
+
* for use cases where env vars may change at runtime (e.g., tests).
|
|
130
|
+
*
|
|
131
|
+
* @param key - The environment variable name to read
|
|
132
|
+
* @returns `true` if "true"/"1", `false` if "false"/"0", `undefined` otherwise
|
|
133
|
+
*
|
|
134
|
+
* @example
|
|
135
|
+
* ```typescript
|
|
136
|
+
* // For terminal detection that needs dynamic behavior
|
|
137
|
+
* if (getEnvBoolean("NO_COLOR")) {
|
|
138
|
+
* // colors disabled
|
|
139
|
+
* }
|
|
140
|
+
* ```
|
|
141
|
+
*/
|
|
142
|
+
declare function getEnvBoolean(key: "NO_COLOR" | "FORCE_COLOR" | "CI"): boolean | undefined;
|
|
143
|
+
export { portSchema, booleanSchema, optionalBooleanSchema, parseEnv, Env, env, getEnvBoolean };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// @bun
|
|
2
|
+
// packages/config/src/environment.ts
|
|
3
|
+
var VALID_ENVIRONMENTS = new Set([
|
|
4
|
+
"development",
|
|
5
|
+
"production",
|
|
6
|
+
"test"
|
|
7
|
+
]);
|
|
8
|
+
var ENVIRONMENT_DEFAULTS = {
|
|
9
|
+
development: {
|
|
10
|
+
logLevel: "debug",
|
|
11
|
+
verbose: true,
|
|
12
|
+
errorDetail: "full"
|
|
13
|
+
},
|
|
14
|
+
production: {
|
|
15
|
+
logLevel: null,
|
|
16
|
+
verbose: false,
|
|
17
|
+
errorDetail: "message"
|
|
18
|
+
},
|
|
19
|
+
test: {
|
|
20
|
+
logLevel: null,
|
|
21
|
+
verbose: false,
|
|
22
|
+
errorDetail: "full"
|
|
23
|
+
}
|
|
24
|
+
};
|
|
25
|
+
function getEnvironment() {
|
|
26
|
+
const value = process.env["OUTFITTER_ENV"];
|
|
27
|
+
if (value !== undefined && VALID_ENVIRONMENTS.has(value)) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
return "production";
|
|
31
|
+
}
|
|
32
|
+
function getEnvironmentDefaults(env) {
|
|
33
|
+
return { ...ENVIRONMENT_DEFAULTS[env] };
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export { getEnvironment, getEnvironmentDefaults };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@outfitter/config",
|
|
3
3
|
"description": "XDG-compliant config loading with schema validation for Outfitter",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
@@ -9,12 +9,6 @@
|
|
|
9
9
|
"module": "./dist/index.js",
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"exports": {
|
|
12
|
-
"./environment": {
|
|
13
|
-
"import": {
|
|
14
|
-
"types": "./dist/environment.d.ts",
|
|
15
|
-
"default": "./dist/environment.js"
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
12
|
".": {
|
|
19
13
|
"import": {
|
|
20
14
|
"types": "./dist/index.d.ts",
|
|
@@ -27,6 +21,12 @@
|
|
|
27
21
|
"default": "./dist/env.js"
|
|
28
22
|
}
|
|
29
23
|
},
|
|
24
|
+
"./environment": {
|
|
25
|
+
"import": {
|
|
26
|
+
"types": "./dist/environment.d.ts",
|
|
27
|
+
"default": "./dist/environment.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
30
|
"./package.json": "./package.json"
|
|
31
31
|
},
|
|
32
32
|
"sideEffects": false,
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
"clean": "rm -rf dist"
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@outfitter/contracts": "0.
|
|
43
|
-
"@outfitter/types": "0.2.
|
|
42
|
+
"@outfitter/contracts": "0.4.0",
|
|
43
|
+
"@outfitter/types": "0.2.2",
|
|
44
44
|
"zod": "^4.3.5"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|