tyfigo 0.1.0-next.4294ee4.0 → 0.1.0-next.d1e2fdf.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/effect.d.mts +1 -1
- package/dist/{index-DqgkSYnb.d.mts → index-_5Tr2XH2.d.mts} +7 -3
- package/dist/index.d.mts +66 -2
- package/dist/index.mjs +111 -1
- package/dist/index.mjs.map +1 -0
- package/dist/resolve-Oj4qvq9_.d.mts +52 -0
- package/dist/resolve-wE3GPIQp.mjs +833 -0
- package/dist/resolve-wE3GPIQp.mjs.map +1 -0
- package/dist/runtime/index.d.mts +45 -0
- package/dist/runtime/index.mjs +98 -0
- package/dist/runtime/index.mjs.map +1 -0
- package/package.json +10 -2
package/dist/effect.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as Problem, c as Span, i as LocatedSpan, n as ResolvedConfig, o as ProblemCode, r as ResolvedLayer, s as Path, t as ResolveOptions } from "./index-
|
|
1
|
+
import { a as Problem, c as Span, i as LocatedSpan, n as ResolvedConfig, o as ProblemCode, r as ResolvedLayer, s as Path, t as ResolveOptions } from "./index-_5Tr2XH2.mjs";
|
|
2
2
|
export type { LocatedSpan, Path, Problem, ProblemCode, ResolveOptions, ResolvedConfig, ResolvedLayer, Span };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "effect";
|
|
1
|
+
import { Effect } from "effect";
|
|
2
2
|
/**
|
|
3
3
|
* A key path into a config value. Strings are object keys and numbers are array indices.
|
|
4
4
|
*/
|
|
@@ -19,7 +19,7 @@ interface Span {
|
|
|
19
19
|
* Spans keyed by {@link pathKey}.
|
|
20
20
|
*/
|
|
21
21
|
type PositionMap = ReadonlyMap<string, Span>;
|
|
22
|
-
type ProblemCode = 'parse-error' | 'duplicate-key' | 'file-not-found' | 'read-error' | 'unsupported-file' | 'missing-variable' | 'invalid-placeholder' | 'unknown-key' | 'type-mismatch';
|
|
22
|
+
type ProblemCode = 'parse-error' | 'duplicate-key' | 'file-not-found' | 'read-error' | 'unsupported-file' | 'missing-variable' | 'invalid-placeholder' | 'browser-placeholder' | 'unknown-key' | 'type-mismatch';
|
|
23
23
|
/**
|
|
24
24
|
* Something wrong with a config file. `start` and `length` are UTF-8 byte offsets, `line` and `column` are 1-based and
|
|
25
25
|
* `column` counts UTF-16 code units.
|
|
@@ -68,6 +68,10 @@ interface ResolveOptions {
|
|
|
68
68
|
* The environment name that picks `app.<environment>.config.yaml` and `.env.<environment>`. Defaults to `env.NODE_ENV`.
|
|
69
69
|
*/
|
|
70
70
|
readonly environment?: string | undefined;
|
|
71
|
+
/**
|
|
72
|
+
* The layer kinds to read. Defaults to all of them.
|
|
73
|
+
*/
|
|
74
|
+
readonly layers?: readonly LayerKind[] | undefined;
|
|
71
75
|
}
|
|
72
76
|
interface ResolvedLayer {
|
|
73
77
|
readonly file: string;
|
|
@@ -99,4 +103,4 @@ interface ResolvedConfig {
|
|
|
99
103
|
readonly problems: readonly Problem[];
|
|
100
104
|
}
|
|
101
105
|
export { Problem as a, Span as c, LocatedSpan as i, ResolvedConfig as n, ProblemCode as o, ResolvedLayer as r, Path as s, ResolveOptions as t };
|
|
102
|
-
//# sourceMappingURL=index-
|
|
106
|
+
//# sourceMappingURL=index-_5Tr2XH2.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,2 +1,66 @@
|
|
|
1
|
-
import { a as Problem, c as Span, i as LocatedSpan, n as ResolvedConfig, o as ProblemCode, r as ResolvedLayer, s as Path, t as ResolveOptions } from "./index-
|
|
2
|
-
|
|
1
|
+
import { a as Problem, c as Span, i as LocatedSpan, n as ResolvedConfig, o as ProblemCode, r as ResolvedLayer, s as Path, t as ResolveOptions } from "./index-_5Tr2XH2.mjs";
|
|
2
|
+
import { r as ConfigSource } from "./resolve-Oj4qvq9_.mjs";
|
|
3
|
+
import { Effect, Schema } from "effect";
|
|
4
|
+
import { StandardSchemaV1 } from "@standard-schema/spec";
|
|
5
|
+
/**
|
|
6
|
+
* A Standard Schema (Zod, Valibot, ArkType, …) or an Effect Schema without decoding services.
|
|
7
|
+
*/
|
|
8
|
+
type ConfigSchema = StandardSchemaV1 | Schema.ConstraintDecoder<unknown>;
|
|
9
|
+
type SchemaInput<S> = S extends StandardSchemaV1 ? StandardSchemaV1.InferInput<S> : S extends Schema.Top ? S['Encoded'] : never;
|
|
10
|
+
type SchemaOutput<S> = S extends StandardSchemaV1 ? StandardSchemaV1.InferOutput<S> : S extends Schema.Top ? S['Type'] : never;
|
|
11
|
+
/**
|
|
12
|
+
* A schema input with literals widened and everything readonly, so a schema-less config import is assignable to it.
|
|
13
|
+
*/
|
|
14
|
+
type LooseInput<T> = T extends string ? string : T extends number ? number : T extends boolean ? boolean : T extends readonly (infer U)[] ? readonly LooseInput<U>[] : T extends object ? { readonly [K in keyof T]: LooseInput<T[K]>; } : T;
|
|
15
|
+
interface ConfigIssue {
|
|
16
|
+
readonly path: readonly PropertyKey[];
|
|
17
|
+
readonly message: string;
|
|
18
|
+
/**
|
|
19
|
+
* `file:line:column` when the value came from a config import, or the file alone when the key has no position.
|
|
20
|
+
*/
|
|
21
|
+
readonly location?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
declare const ConfigValidationError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
24
|
+
readonly _tag: "ConfigValidationError";
|
|
25
|
+
} & Readonly<A>;
|
|
26
|
+
/**
|
|
27
|
+
* Thrown with every issue at once when a config or the environment does not match its schema.
|
|
28
|
+
*/
|
|
29
|
+
export declare class ConfigValidationError extends ConfigValidationError_base<{
|
|
30
|
+
readonly subject: string;
|
|
31
|
+
readonly issues: readonly ConfigIssue[];
|
|
32
|
+
}> {
|
|
33
|
+
get message(): string;
|
|
34
|
+
}
|
|
35
|
+
interface LoadEnvOptions extends ResolveOptions {
|
|
36
|
+
/**
|
|
37
|
+
* Where to start looking for `.env` files, which are searched there and then in the nearest directory with a
|
|
38
|
+
* `package.json`. Defaults to `process.cwd()`.
|
|
39
|
+
*/
|
|
40
|
+
readonly cwd?: string | undefined;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates a config import (or any value) with a Standard Schema or an Effect Schema and returns the schema's output.
|
|
44
|
+
*
|
|
45
|
+
* @throws {@link ConfigValidationError} listing every issue, with `file:line:column` when `config` is a config import.
|
|
46
|
+
* @throws TypeError when the schema validates asynchronously; use {@link loadConfigAsync} for those.
|
|
47
|
+
*/
|
|
48
|
+
export declare const loadConfig: <S extends ConfigSchema>(config: LooseInput<SchemaInput<S>>, schema: S) => SchemaOutput<S>;
|
|
49
|
+
/**
|
|
50
|
+
* {@link loadConfig} for schemas that may validate asynchronously.
|
|
51
|
+
*/
|
|
52
|
+
export declare const loadConfigAsync: <S extends ConfigSchema>(config: LooseInput<SchemaInput<S>>, schema: S) => Promise<SchemaOutput<S>>;
|
|
53
|
+
/**
|
|
54
|
+
* Validates `.env`, `.env.local`, `.env.<environment>` and `.env.<environment>.local` with the real environment on top.
|
|
55
|
+
* Never writes `process.env`.
|
|
56
|
+
*
|
|
57
|
+
* @throws {@link ConfigValidationError} listing every issue and every `.env` file that could not be read.
|
|
58
|
+
* @throws TypeError when the schema validates asynchronously; use {@link loadEnvAsync} for those.
|
|
59
|
+
*/
|
|
60
|
+
export declare const loadEnv: <S extends ConfigSchema>(schema: S, options?: LoadEnvOptions) => SchemaOutput<S>;
|
|
61
|
+
/**
|
|
62
|
+
* {@link loadEnv} for schemas that may validate asynchronously.
|
|
63
|
+
*/
|
|
64
|
+
export declare const loadEnvAsync: <S extends ConfigSchema>(schema: S, options?: LoadEnvOptions) => Promise<SchemaOutput<S>>;
|
|
65
|
+
export type { ConfigIssue, ConfigSchema, ConfigSource, LoadEnvOptions, LocatedSpan, LooseInput, Path, Problem, ProblemCode, ResolveOptions, ResolvedConfig, ResolvedLayer, SchemaInput, SchemaOutput, Span };
|
|
66
|
+
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1,111 @@
|
|
|
1
|
-
|
|
1
|
+
import { f as formatPath, g as readEnv, h as processEnv, i as getConfigSource } from "./resolve-wE3GPIQp.mjs";
|
|
2
|
+
import { Data, Effect, Schema } from "effect";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import process from "node:process";
|
|
5
|
+
// src/schema.ts
|
|
6
|
+
const formatIssue = (issue) => {
|
|
7
|
+
const path = formatPath(issue.path.map((segment) => typeof segment === "symbol" ? String(segment) : segment));
|
|
8
|
+
const text = path ? `${path}: ${issue.message}` : issue.message;
|
|
9
|
+
return issue.location ? `${issue.location} - ${text}` : text;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Thrown with every issue at once when a config or the environment does not match its schema.
|
|
13
|
+
*/
|
|
14
|
+
var ConfigValidationError = class extends Data.TaggedError("ConfigValidationError") {
|
|
15
|
+
get message() {
|
|
16
|
+
return [`Invalid ${this.subject}:`, ...this.issues.map((issue) => ` ${formatIssue(issue)}`)].join("\n");
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
const configSource = (config) => {
|
|
20
|
+
const source = getConfigSource(config);
|
|
21
|
+
return typeof source?.file === "string" && typeof source.position === "function" ? source : void 0;
|
|
22
|
+
};
|
|
23
|
+
const locateIssue = (source, path) => {
|
|
24
|
+
const end = path.findIndex((segment) => typeof segment === "symbol");
|
|
25
|
+
const keys = end === -1 ? path : path.slice(0, end);
|
|
26
|
+
const position = source.position(keys);
|
|
27
|
+
return position ? `${position.file}:${position.line}:${position.column}` : source.file;
|
|
28
|
+
};
|
|
29
|
+
const toStandardSchema = (schema) => Schema.isSchema(schema) ? Schema.toStandardSchemaV1(schema, { parseOptions: { errors: "all" } }) : schema;
|
|
30
|
+
const validate = Effect.fn("validate")(function* (schema, value, options) {
|
|
31
|
+
const pending = toStandardSchema(schema)["~standard"].validate(value);
|
|
32
|
+
let result;
|
|
33
|
+
if ("then" in pending) {
|
|
34
|
+
if (!options.async) {
|
|
35
|
+
pending.catch(() => void 0);
|
|
36
|
+
return yield* Effect.die(/* @__PURE__ */ new TypeError(`The schema for the ${options.subject} validates asynchronously; use loadConfigAsync or loadEnvAsync`));
|
|
37
|
+
}
|
|
38
|
+
result = yield* Effect.promise(async () => pending);
|
|
39
|
+
} else result = pending;
|
|
40
|
+
const issues = [...options.issues ?? [], ...(result.issues ?? []).map((issue) => {
|
|
41
|
+
const path = Array.from(issue.path ?? [], (segment) => typeof segment === "object" ? segment.key : segment);
|
|
42
|
+
return {
|
|
43
|
+
path,
|
|
44
|
+
message: issue.message,
|
|
45
|
+
location: options.source && locateIssue(options.source, path)
|
|
46
|
+
};
|
|
47
|
+
})];
|
|
48
|
+
if (issues.length > 0) return yield* new ConfigValidationError({
|
|
49
|
+
subject: options.subject,
|
|
50
|
+
issues
|
|
51
|
+
});
|
|
52
|
+
return result.value;
|
|
53
|
+
});
|
|
54
|
+
const decodeConfig = (config, schema, options) => {
|
|
55
|
+
const source = configSource(config);
|
|
56
|
+
return validate(schema, config, {
|
|
57
|
+
subject: source ? `config ${source.file}` : "config",
|
|
58
|
+
source,
|
|
59
|
+
async: options.async
|
|
60
|
+
});
|
|
61
|
+
};
|
|
62
|
+
const decodeEnv = Effect.fn("decodeEnv")(function* (schema, options) {
|
|
63
|
+
const env = options.env ?? processEnv();
|
|
64
|
+
const environment = options.environment ?? (env.NODE_ENV || void 0);
|
|
65
|
+
const result = yield* readEnv(join(options.cwd ?? process.cwd(), ".env"), {
|
|
66
|
+
environment,
|
|
67
|
+
env
|
|
68
|
+
});
|
|
69
|
+
return yield* validate(schema, result.variables, {
|
|
70
|
+
subject: "environment variables",
|
|
71
|
+
async: options.async,
|
|
72
|
+
issues: result.problems.map((problem) => ({
|
|
73
|
+
path: [],
|
|
74
|
+
message: problem.message,
|
|
75
|
+
location: `${problem.file}:${problem.line}:${problem.column}`
|
|
76
|
+
}))
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
// src/index.ts
|
|
80
|
+
/**
|
|
81
|
+
* Validates a config import (or any value) with a Standard Schema or an Effect Schema and returns the schema's output.
|
|
82
|
+
*
|
|
83
|
+
* @throws {@link ConfigValidationError} listing every issue, with `file:line:column` when `config` is a config import.
|
|
84
|
+
* @throws TypeError when the schema validates asynchronously; use {@link loadConfigAsync} for those.
|
|
85
|
+
*/
|
|
86
|
+
const loadConfig = (config, schema) => Effect.runSync(decodeConfig(config, schema, { async: false }));
|
|
87
|
+
/**
|
|
88
|
+
* {@link loadConfig} for schemas that may validate asynchronously.
|
|
89
|
+
*/
|
|
90
|
+
const loadConfigAsync = async (config, schema) => Effect.runPromise(decodeConfig(config, schema, { async: true }));
|
|
91
|
+
/**
|
|
92
|
+
* Validates `.env`, `.env.local`, `.env.<environment>` and `.env.<environment>.local` with the real environment on top.
|
|
93
|
+
* Never writes `process.env`.
|
|
94
|
+
*
|
|
95
|
+
* @throws {@link ConfigValidationError} listing every issue and every `.env` file that could not be read.
|
|
96
|
+
* @throws TypeError when the schema validates asynchronously; use {@link loadEnvAsync} for those.
|
|
97
|
+
*/
|
|
98
|
+
const loadEnv = (schema, options = {}) => Effect.runSync(decodeEnv(schema, {
|
|
99
|
+
...options,
|
|
100
|
+
async: false
|
|
101
|
+
}));
|
|
102
|
+
/**
|
|
103
|
+
* {@link loadEnv} for schemas that may validate asynchronously.
|
|
104
|
+
*/
|
|
105
|
+
const loadEnvAsync = async (schema, options = {}) => Effect.runPromise(decodeEnv(schema, {
|
|
106
|
+
...options,
|
|
107
|
+
async: true
|
|
108
|
+
}));
|
|
109
|
+
export { ConfigValidationError, loadConfig, loadConfigAsync, loadEnv, loadEnvAsync };
|
|
110
|
+
|
|
111
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/schema.ts","../src/index.ts"],"sourcesContent":["import { join } from 'node:path';\nimport process from 'node:process';\n\nimport { Data, Effect, Schema } from 'effect';\n\nimport { processEnv, readEnv } from './core/env.ts';\nimport { formatPath } from './core/positions.ts';\nimport { getConfigSource } from './runtime/resolve.ts';\n\nimport type { ResolveOptions } from './core/resolve.ts';\nimport type { ConfigSource } from './runtime/resolve.ts';\nimport type { StandardSchemaV1 } from '@standard-schema/spec';\n\n/**\n * A Standard Schema (Zod, Valibot, ArkType, …) or an Effect Schema without decoding services.\n */\nexport type ConfigSchema = StandardSchemaV1 | Schema.ConstraintDecoder<unknown>;\n\nexport type SchemaInput<S> = S extends StandardSchemaV1\n\t? StandardSchemaV1.InferInput<S>\n\t: S extends Schema.Top\n\t\t? S['Encoded']\n\t\t: never;\n\nexport type SchemaOutput<S> = S extends StandardSchemaV1\n\t? StandardSchemaV1.InferOutput<S>\n\t: S extends Schema.Top\n\t\t? S['Type']\n\t\t: never;\n\n/**\n * A schema input with literals widened and everything readonly, so a schema-less config import is assignable to it.\n */\nexport type LooseInput<T> = T extends string\n\t? string\n\t: T extends number\n\t\t? number\n\t\t: T extends boolean\n\t\t\t? boolean\n\t\t\t: T extends readonly (infer U)[]\n\t\t\t\t? readonly LooseInput<U>[]\n\t\t\t\t: T extends object\n\t\t\t\t\t? { readonly [K in keyof T]: LooseInput<T[K]> }\n\t\t\t\t\t: T;\n\nexport interface ConfigIssue {\n\treadonly path: readonly PropertyKey[];\n\treadonly message: string;\n\t/**\n\t * `file:line:column` when the value came from a config import, or the file alone when the key has no position.\n\t */\n\treadonly location?: string | undefined;\n}\n\nconst formatIssue = (issue: ConfigIssue): string => {\n\tconst path = formatPath(issue.path.map((segment) => (typeof segment === 'symbol' ? String(segment) : segment)));\n\tconst text = path ? `${path}: ${issue.message}` : issue.message;\n\treturn issue.location ? `${issue.location} - ${text}` : text;\n};\n\n/**\n * Thrown with every issue at once when a config or the environment does not match its schema.\n */\nexport class ConfigValidationError extends Data.TaggedError('ConfigValidationError')<{\n\treadonly subject: string;\n\treadonly issues: readonly ConfigIssue[];\n}> {\n\toverride get message(): string {\n\t\treturn [`Invalid ${this.subject}:`, ...this.issues.map((issue) => ` ${formatIssue(issue)}`)].join('\\n');\n\t}\n}\n\nexport type { ConfigSource } from './runtime/resolve.ts';\n\nexport const configSource = (config: unknown): ConfigSource | undefined => {\n\tconst source = getConfigSource(config);\n\treturn typeof source?.file === 'string' && typeof source.position === 'function' ? source : undefined;\n};\n\nconst locateIssue = (source: ConfigSource, path: readonly PropertyKey[]): string => {\n\tconst end = path.findIndex((segment) => typeof segment === 'symbol');\n\tconst keys = (end === -1 ? path : path.slice(0, end)) as readonly (string | number)[];\n\tconst position = source.position(keys);\n\treturn position ? `${position.file}:${position.line}:${position.column}` : source.file;\n};\n\nexport const toStandardSchema = (schema: ConfigSchema): StandardSchemaV1 =>\n\tSchema.isSchema(schema)\n\t\t? Schema.toStandardSchemaV1(schema as Schema.ConstraintDecoder<unknown>, { parseOptions: { errors: 'all' } })\n\t\t: (schema as StandardSchemaV1);\n\nexport interface ValidateOptions {\n\treadonly subject: string;\n\treadonly source?: ConfigSource | undefined;\n\t/**\n\t * Allow a schema that validates asynchronously. Without it, an async schema is a defect.\n\t */\n\treadonly async: boolean;\n\t/**\n\t * Issues found before validation, such as unreadable `.env` files. They fail validation even when the schema passes.\n\t */\n\treadonly issues?: readonly ConfigIssue[] | undefined;\n}\n\nexport const validate = Effect.fn('validate')(function* <S extends ConfigSchema>(\n\tschema: S,\n\tvalue: unknown,\n\toptions: ValidateOptions,\n) {\n\tconst pending = toStandardSchema(schema)['~standard'].validate(value);\n\tlet result: StandardSchemaV1.Result<unknown>;\n\tif ('then' in pending) {\n\t\tif (!options.async) {\n\t\t\tvoid pending.catch(() => undefined);\n\t\t\treturn yield* Effect.die(\n\t\t\t\tnew TypeError(\n\t\t\t\t\t`The schema for the ${options.subject} validates asynchronously; use loadConfigAsync or loadEnvAsync`,\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\tresult = yield* Effect.promise(async () => pending);\n\t} else {\n\t\tresult = pending;\n\t}\n\n\tconst issues = [\n\t\t...(options.issues ?? []),\n\t\t...(result.issues ?? []).map((issue): ConfigIssue => {\n\t\t\tconst path = Array.from(issue.path ?? [], (segment) =>\n\t\t\t\ttypeof segment === 'object' ? segment.key : segment,\n\t\t\t);\n\t\t\treturn {\n\t\t\t\tpath,\n\t\t\t\tmessage: issue.message,\n\t\t\t\tlocation: options.source && locateIssue(options.source, path),\n\t\t\t};\n\t\t}),\n\t];\n\tif (issues.length > 0) return yield* new ConfigValidationError({ subject: options.subject, issues });\n\treturn (result as StandardSchemaV1.SuccessResult<SchemaOutput<S>>).value;\n});\n\nexport const decodeConfig = <S extends ConfigSchema>(\n\tconfig: unknown,\n\tschema: S,\n\toptions: { readonly async: boolean },\n) => {\n\tconst source = configSource(config);\n\treturn validate(schema, config, {\n\t\tsubject: source ? `config ${source.file}` : 'config',\n\t\tsource,\n\t\tasync: options.async,\n\t});\n};\n\nexport interface LoadEnvOptions extends ResolveOptions {\n\t/**\n\t * Where to start looking for `.env` files, which are searched there and then in the nearest directory with a\n\t * `package.json`. Defaults to `process.cwd()`.\n\t */\n\treadonly cwd?: string | undefined;\n}\n\nexport const decodeEnv = Effect.fn('decodeEnv')(function* <S extends ConfigSchema>(\n\tschema: S,\n\toptions: LoadEnvOptions & { readonly async: boolean },\n) {\n\tconst env = options.env ?? processEnv();\n\tconst environment = options.environment ?? (env.NODE_ENV || undefined);\n\tconst result = yield* readEnv(join(options.cwd ?? process.cwd(), '.env'), { environment, env });\n\treturn yield* validate(schema, result.variables, {\n\t\tsubject: 'environment variables',\n\t\tasync: options.async,\n\t\tissues: result.problems.map((problem) => ({\n\t\t\tpath: [],\n\t\t\tmessage: problem.message,\n\t\t\tlocation: `${problem.file}:${problem.line}:${problem.column}`,\n\t\t})),\n\t});\n});\n","import { Effect } from 'effect';\n\nimport { decodeConfig, decodeEnv } from './schema.ts';\n\nimport type { ConfigSchema, LoadEnvOptions, LooseInput, SchemaInput, SchemaOutput } from './schema.ts';\n\nexport type {\n\tLocatedSpan,\n\tPath,\n\tProblem,\n\tProblemCode,\n\tResolvedConfig,\n\tResolvedLayer,\n\tResolveOptions,\n\tSpan,\n} from './core/index.ts';\nexport { ConfigValidationError } from './schema.ts';\nexport type {\n\tConfigIssue,\n\tConfigSchema,\n\tConfigSource,\n\tLoadEnvOptions,\n\tLooseInput,\n\tSchemaInput,\n\tSchemaOutput,\n} from './schema.ts';\n\n/**\n * Validates a config import (or any value) with a Standard Schema or an Effect Schema and returns the schema's output.\n *\n * @throws {@link ConfigValidationError} listing every issue, with `file:line:column` when `config` is a config import.\n * @throws TypeError when the schema validates asynchronously; use {@link loadConfigAsync} for those.\n */\nexport const loadConfig = <S extends ConfigSchema>(config: LooseInput<SchemaInput<S>>, schema: S): SchemaOutput<S> =>\n\tEffect.runSync(decodeConfig(config, schema, { async: false }));\n\n/**\n * {@link loadConfig} for schemas that may validate asynchronously.\n */\nexport const loadConfigAsync = async <S extends ConfigSchema>(\n\tconfig: LooseInput<SchemaInput<S>>,\n\tschema: S,\n): Promise<SchemaOutput<S>> => Effect.runPromise(decodeConfig(config, schema, { async: true }));\n\n/**\n * Validates `.env`, `.env.local`, `.env.<environment>` and `.env.<environment>.local` with the real environment on top.\n * Never writes `process.env`.\n *\n * @throws {@link ConfigValidationError} listing every issue and every `.env` file that could not be read.\n * @throws TypeError when the schema validates asynchronously; use {@link loadEnvAsync} for those.\n */\nexport const loadEnv = <S extends ConfigSchema>(schema: S, options: LoadEnvOptions = {}): SchemaOutput<S> =>\n\tEffect.runSync(decodeEnv(schema, { ...options, async: false }));\n\n/**\n * {@link loadEnv} for schemas that may validate asynchronously.\n */\nexport const loadEnvAsync = async <S extends ConfigSchema>(\n\tschema: S,\n\toptions: LoadEnvOptions = {},\n): Promise<SchemaOutput<S>> => Effect.runPromise(decodeEnv(schema, { ...options, async: true }));\n"],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { a as Problem, s as Path } from "./index-_5Tr2XH2.mjs";
|
|
2
|
+
/**
|
|
3
|
+
* The key of the non-enumerable {@link ConfigSource} on a config object exported by a generated server module.
|
|
4
|
+
*/
|
|
5
|
+
declare const configSource: unique symbol;
|
|
6
|
+
interface SourcePosition {
|
|
7
|
+
readonly file: string;
|
|
8
|
+
readonly line: number;
|
|
9
|
+
readonly column: number;
|
|
10
|
+
}
|
|
11
|
+
interface ConfigSource {
|
|
12
|
+
/**
|
|
13
|
+
* The base config file, as an absolute path.
|
|
14
|
+
*/
|
|
15
|
+
readonly file: string;
|
|
16
|
+
readonly environment: string | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* The layer files that were merged, in the order they apply.
|
|
19
|
+
*/
|
|
20
|
+
readonly layers: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* The `.env` files that were read, in the order they apply.
|
|
23
|
+
*/
|
|
24
|
+
readonly envFiles: readonly string[];
|
|
25
|
+
/**
|
|
26
|
+
* Where the value at `path` was set. A path the config does not have resolves to its nearest ancestor that it does have.
|
|
27
|
+
*/
|
|
28
|
+
readonly position: (path: Path) => SourcePosition | undefined;
|
|
29
|
+
}
|
|
30
|
+
declare const ConfigModuleError_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
|
|
31
|
+
readonly _tag: "ConfigModuleError";
|
|
32
|
+
} & Readonly<A>;
|
|
33
|
+
declare class ConfigModuleError extends ConfigModuleError_base<{
|
|
34
|
+
readonly message: string;
|
|
35
|
+
readonly file: string;
|
|
36
|
+
readonly problems: readonly Problem[];
|
|
37
|
+
}> {}
|
|
38
|
+
interface ConfigModuleOptions {
|
|
39
|
+
/**
|
|
40
|
+
* The environment name that picks `app.<environment>.config.yaml` and `.env.<environment>`. Defaults to `NODE_ENV`.
|
|
41
|
+
*/
|
|
42
|
+
readonly environment?: string | undefined;
|
|
43
|
+
}
|
|
44
|
+
declare const deepFreeze: <T>(value: T) => T;
|
|
45
|
+
declare const getConfigSource: (value: unknown) => ConfigSource | undefined;
|
|
46
|
+
/**
|
|
47
|
+
* Resolves a config file with its layers, `.env` files and placeholders, and returns the deep-frozen value. This is what a
|
|
48
|
+
* generated server module calls when it is evaluated. Throws a {@link ConfigModuleError} listing every problem.
|
|
49
|
+
*/
|
|
50
|
+
declare const resolveConfigModule: (file: string, options?: ConfigModuleOptions) => unknown;
|
|
51
|
+
export { configSource as a, resolveConfigModule as c, SourcePosition as i, ConfigModuleOptions as n, deepFreeze as o, ConfigSource as r, getConfigSource as s, ConfigModuleError as t };
|
|
52
|
+
//# sourceMappingURL=resolve-Oj4qvq9_.d.mts.map
|