@konfig.ts/core 0.0.1

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.
@@ -0,0 +1,63 @@
1
+ declare const RenderError_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 & {
2
+ readonly _tag: "RenderError";
3
+ } & Readonly<A>;
4
+ export declare class RenderError extends RenderError_base<{
5
+ readonly message: string;
6
+ readonly cause?: unknown;
7
+ }> {
8
+ }
9
+ declare const EmbedYamlReadError_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 & {
10
+ readonly _tag: "EmbedYamlReadError";
11
+ } & Readonly<A>;
12
+ export declare class EmbedYamlReadError extends EmbedYamlReadError_base<{
13
+ readonly path: string;
14
+ readonly cause: unknown;
15
+ }> {
16
+ }
17
+ declare const BoundaryDecodeError_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 & {
18
+ readonly _tag: "BoundaryDecodeError";
19
+ } & Readonly<A>;
20
+ export declare class BoundaryDecodeError extends BoundaryDecodeError_base<{
21
+ readonly schema: string;
22
+ readonly cause: unknown;
23
+ }> {
24
+ }
25
+ declare const HelmVersionTooLow_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 & {
26
+ readonly _tag: "HelmVersionTooLow";
27
+ } & Readonly<A>;
28
+ export declare class HelmVersionTooLow extends HelmVersionTooLow_base<{
29
+ readonly required: string;
30
+ readonly found: string;
31
+ }> {
32
+ get message(): string;
33
+ }
34
+ declare const HelmRenderError_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 & {
35
+ readonly _tag: "HelmRenderError";
36
+ } & Readonly<A>;
37
+ export declare class HelmRenderError extends HelmRenderError_base<{
38
+ readonly chart: string;
39
+ readonly version: string;
40
+ readonly cause: unknown;
41
+ }> {
42
+ }
43
+ declare const HelmDigestMismatch_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 & {
44
+ readonly _tag: "HelmDigestMismatch";
45
+ } & Readonly<A>;
46
+ export declare class HelmDigestMismatch extends HelmDigestMismatch_base<{
47
+ readonly chart: string;
48
+ readonly version: string;
49
+ readonly expected: string;
50
+ readonly actual: string;
51
+ }> {
52
+ get message(): string;
53
+ }
54
+ declare const CrdExtractError_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 & {
55
+ readonly _tag: "CrdExtractError";
56
+ } & Readonly<A>;
57
+ export declare class CrdExtractError extends CrdExtractError_base<{
58
+ readonly chart: string;
59
+ readonly cause: unknown;
60
+ }> {
61
+ }
62
+ export type AnyRenderError = RenderError | EmbedYamlReadError | BoundaryDecodeError | HelmVersionTooLow | HelmRenderError | HelmDigestMismatch | CrdExtractError;
63
+ export {};
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Nominal-typing primitive — attach a phantom brand to a string value.
3
+ * Used by `Dep.*Ref` constructors and the like. Safe by construction:
4
+ * the brand is a type-only label that the caller stamps on themselves.
5
+ */
6
+ export declare const brand: <T>(value: string) => T;
7
+ /**
8
+ * Unsafe escape hatch — claim a value has type `T` without runtime
9
+ * proof. Every call site MUST pass a one-line `reason` explaining why
10
+ * the cast is sound (e.g. "variance erasure", "runtime narrowed via
11
+ * _tag check", "Object.keys is string[]"). Audit by grepping for
12
+ * `unsafeCoerce(` and reading the reasons.
13
+ *
14
+ * For values crossing a trust boundary (external command output, file
15
+ * contents, network payloads), prefer `boundary` from
16
+ * `@konfig.ts/core/boundary` — it produces a `BoundaryDecodeError`
17
+ * instead of silently accepting the claim.
18
+ *
19
+ * The `reason` parameter is intentionally not used at runtime; it
20
+ * documents intent for readers and audits.
21
+ */
22
+ export declare const unsafeCoerce: <T>(value: unknown, _reason: string) => T;
@@ -0,0 +1,2 @@
1
+ export { ChildProcess } from "effect/unstable/process";
2
+ export { ChildProcessSpawner, type ChildProcessSpawner as ChildProcessSpawnerType, } from "effect/unstable/process/ChildProcessSpawner";
@@ -0,0 +1,7 @@
1
+ import { Effect, Schema } from "effect";
2
+ import { BoundaryDecodeError } from "./RenderError";
3
+ export interface BoundaryInput<S extends Schema.Top> {
4
+ readonly schema: S;
5
+ readonly label?: string;
6
+ }
7
+ export declare const boundary: <S extends Schema.Top>(input: BoundaryInput<S>) => (value: unknown) => Effect.Effect<S["Type"], BoundaryDecodeError, S["DecodingServices"]>;
package/dist/deps.d.ts ADDED
@@ -0,0 +1,126 @@
1
+ import { Context, Layer, type Redacted } from "effect";
2
+ declare const NeedBrand: unique symbol;
3
+ export interface Need<K extends string, N extends string> {
4
+ readonly [NeedBrand]: {
5
+ readonly kind: K;
6
+ readonly name: N;
7
+ };
8
+ }
9
+ export type Provide<K extends string, N extends string> = Need<K, N>;
10
+ declare const SecretRefBrand: unique symbol;
11
+ declare const ConfigMapRefBrand: unique symbol;
12
+ declare const ServiceAccountRefBrand: unique symbol;
13
+ declare const PvcRefBrand: unique symbol;
14
+ declare const BuiltImageRefBrand: unique symbol;
15
+ /**
16
+ * Nominal reference to a named Secret. `N` brands the secret's metadata
17
+ * name; `K` (defaults to `string`) brands the union of declared data
18
+ * keys, so consumers like `secretEnv({ ref, key })` can constrain `key`
19
+ * to keys that actually exist; `Ns` (defaults to `string`) brands the
20
+ * secret's owning namespace, so pod-context consumers (like
21
+ * `secretEnvForPod`) can reject refs from a different namespace at
22
+ * compile time — eliminating the runtime "secret not found across
23
+ * namespaces" failure mode.
24
+ */
25
+ export type SecretRef<N extends string, K extends string = string, Ns extends string = string> = string & {
26
+ readonly [SecretRefBrand]: {
27
+ readonly name: N;
28
+ readonly keys: K;
29
+ readonly namespace: Ns;
30
+ };
31
+ };
32
+ /**
33
+ * Nominal reference to a named ConfigMap. `N` brands the metadata name;
34
+ * `K` (defaults to `string`) brands the union of declared data keys, so
35
+ * `configMapEnv({ ref, key })` can constrain `key` to keys that actually
36
+ * exist on the map. Producers (e.g. `ConfigMap.make`) populate `K` from
37
+ * the literal `data` (or `binaryData`) record keys.
38
+ */
39
+ export type ConfigMapRef<N extends string, K extends string = string> = string & {
40
+ readonly [ConfigMapRefBrand]: {
41
+ readonly name: N;
42
+ readonly keys: K;
43
+ };
44
+ };
45
+ export type ServiceAccountRef<N extends string> = string & {
46
+ readonly [ServiceAccountRefBrand]: N;
47
+ };
48
+ export type PvcRef<N extends string> = string & {
49
+ readonly [PvcRefBrand]: N;
50
+ };
51
+ /**
52
+ * Nominal reference to a container image built in-tree. Runtime value
53
+ * is the full image ref (`registry/app:tag`) — a string, so K8s YAML
54
+ * serializes it directly. The phantom `App` brand carries the literal
55
+ * app name and ties the ref to the dep graph via `Dep.Image`.
56
+ *
57
+ * Container `image` fields accept either a raw string (escape hatch
58
+ * for vendor images: `ghcr.io/bitnami/postgresql:16.0.0`) or
59
+ * `BuiltImageRef<App>`. The branded path catches a workload whose
60
+ * build module is missing from the composition at `AppOfApps.entrypoint`.
61
+ */
62
+ export type BuiltImageRef<App extends string> = string & {
63
+ readonly [BuiltImageRefBrand]: App;
64
+ };
65
+ export type BuiltImageRefApp<R> = R extends BuiltImageRef<infer App> ? App : never;
66
+ export type SecretRefName<R> = R extends SecretRef<infer N, infer _K, infer _Ns> ? N : never;
67
+ export type SecretRefKeys<R> = R extends SecretRef<infer _N, infer K, infer _Ns> ? K : never;
68
+ export type SecretRefNamespace<R> = R extends SecretRef<infer _N, infer _K, infer Ns> ? Ns : never;
69
+ export type ConfigMapRefName<R> = R extends ConfigMapRef<infer N, infer _K> ? N : never;
70
+ export type ConfigMapRefKeys<R> = R extends ConfigMapRef<infer _N, infer K> ? K : never;
71
+ export type PvcRefName<R> = R extends PvcRef<infer N> ? N : never;
72
+ export declare const Secret: <N extends string, K extends string = string, Ns extends string = string>(name: N) => Context.Service<Need<"Secret", N>, SecretRef<N, K, Ns>>;
73
+ export type SecretValuesRecord<K extends string> = {
74
+ readonly [P in K]: Redacted.Redacted<string>;
75
+ };
76
+ export declare const SecretValues: <N extends string, K extends string = string>(name: N) => Context.Service<Need<"SecretValues", N>, SecretValuesRecord<K>>;
77
+ export declare const ConfigMap: <N extends string, K extends string = string>(name: N) => Context.Service<Need<"ConfigMap", N>, ConfigMapRef<N, K>>;
78
+ export declare const Namespace: <N extends string>(name: N) => Context.Service<Need<"Namespace", N>, N>;
79
+ export declare const ServiceAccount: <N extends string>(name: N) => Context.Service<Need<"ServiceAccount", N>, ServiceAccountRef<N>>;
80
+ export declare const Application: <N extends string>(name: N) => Context.Service<Need<"Application", N>, N>;
81
+ export declare const Pvc: <N extends string>(name: N) => Context.Service<Need<"Pvc", N>, PvcRef<N>>;
82
+ export declare const App: <N extends string, S = unknown>(name: N) => Context.Service<Need<"App", N>, S>;
83
+ /**
84
+ * Context.Service tag for a `BuiltImageRef<App>`. Modules that build an
85
+ * image emit a Layer providing this service; modules that deploy a
86
+ * container yield `Dep.Image(app)` to receive the typed ref. The
87
+ * dep-graph residual at `AppOfApps.entrypoint` catches a missing
88
+ * provider exactly like for `Dep.Secret`.
89
+ */
90
+ export declare const Image: <N extends string>(name: N) => Context.Service<Need<"Image", N>, BuiltImageRef<N>>;
91
+ interface _ImageRefInput<App extends string> {
92
+ readonly app: App;
93
+ readonly registry: string;
94
+ readonly tag: string;
95
+ }
96
+ /**
97
+ * `BuiltImageRef` value namespace.
98
+ *
99
+ * const apiImage = BuiltImageRef.of({
100
+ * app: "api",
101
+ * registry: "ghcr.io/example",
102
+ * tag: "1.0.0",
103
+ * });
104
+ *
105
+ * `BuiltImageRef.of` constructs the brand from registry + app + tag.
106
+ * The literal `app` is captured in the brand so a workload's
107
+ * `Dep.Need<"Image", App>` matches only the build module that
108
+ * provides this exact app.
109
+ */
110
+ export declare const BuiltImageRef: {
111
+ of: <const App extends string>(input: _ImageRefInput<App>) => BuiltImageRef<App>;
112
+ };
113
+ /**
114
+ * Layer providing `Dep.Image(App)` for downstream consumers. Combine
115
+ * with `Application.define` / `Module.fixedNs`'s `provides` slot to
116
+ * have a build module surface its image to sibling workload modules
117
+ * in the composition.
118
+ */
119
+ export declare const provideImage: <const App extends string>(input: _ImageRefInput<App>) => Layer.Layer<Provide<"Image", App>>;
120
+ export declare const provideSecret: <const N extends string, const K extends string = string, const Ns extends string = string>(name: N) => Layer.Layer<Provide<"Secret", N>>;
121
+ export declare const provideConfigMap: <const N extends string, const K extends string = string>(name: N) => Layer.Layer<Provide<"ConfigMap", N>>;
122
+ export declare const provideNamespace: <const N extends string>(name: N) => Layer.Layer<Provide<"Namespace", N>>;
123
+ export declare const provideServiceAccount: <const N extends string>(name: N) => Layer.Layer<Provide<"ServiceAccount", N>>;
124
+ export declare const provideApplication: <const N extends string>(name: N) => Layer.Layer<Provide<"Application", N>>;
125
+ export declare const providePvc: <const N extends string>(name: N) => Layer.Layer<Provide<"Pvc", N>>;
126
+ export {};
package/dist/diff.d.ts ADDED
@@ -0,0 +1,96 @@
1
+ export interface RedactOptions {
2
+ /**
3
+ * Normalize numeric strings: `"1.0"` compares equal to `1`,
4
+ * `"true"` stays a string (only numerics are normalized). Useful for
5
+ * Helm-templated manifests where some fields get stringified.
6
+ */
7
+ readonly normalizeNumerics?: boolean;
8
+ }
9
+ export interface RedactInput {
10
+ readonly value: unknown;
11
+ readonly parentKey?: string | null;
12
+ readonly options?: RedactOptions;
13
+ }
14
+ /**
15
+ * Canonicalize a parsed YAML/JSON value for structural comparison,
16
+ * applying two normalizations:
17
+ *
18
+ * 1. **Null/undefined keys are dropped.** Any object key whose value is
19
+ * `null` or `undefined` is omitted from the redacted output. This is
20
+ * deliberate: it makes an *explicit* `field: null` compare equal to
21
+ * an *absent* `field`, which is what we want when diffing manifests
22
+ * where one side spells out a null default the other side simply
23
+ * omits. The trade-off is that a genuine "field was set to null vs.
24
+ * field removed" distinction is intentionally invisible to the diff.
25
+ * 2. **Numeric normalization** (opt-in via
26
+ * {@link RedactOptions.normalizeNumerics}) — see that field.
27
+ *
28
+ * Helm metadata redaction (dropping chart-churn labels/annotations) is
29
+ * layered on top when a `labels`/`annotations` map appears under
30
+ * `metadata`.
31
+ */
32
+ export declare const redact: (input: RedactInput) => unknown;
33
+ export interface DeepEqualInput {
34
+ readonly a: unknown;
35
+ readonly b: unknown;
36
+ }
37
+ export declare const deepEqual: (input: DeepEqualInput) => boolean;
38
+ export declare const parseYaml: (text: string) => unknown;
39
+ /**
40
+ * Parse a multi-doc YAML file into an ordered list of documents. Each
41
+ * document's parsed structure is preserved as-is. Empty / whitespace-only
42
+ * segments are dropped, but their position is *not* preserved — only
43
+ * present documents are returned. Use the returned index to identify
44
+ * documents inside one file (alongside the filename) when reporting.
45
+ */
46
+ export declare const parseYamlAll: (text: string) => ReadonlyArray<unknown>;
47
+ export type DocDiff = {
48
+ readonly _tag: "Same";
49
+ readonly key: string;
50
+ } | {
51
+ readonly _tag: "MissingLeft";
52
+ readonly key: string;
53
+ readonly right: unknown;
54
+ } | {
55
+ readonly _tag: "MissingRight";
56
+ readonly key: string;
57
+ readonly left: unknown;
58
+ } | {
59
+ readonly _tag: "Changed";
60
+ readonly key: string;
61
+ readonly left: unknown;
62
+ readonly right: unknown;
63
+ };
64
+ export type FileDiff = {
65
+ readonly _tag: "Same";
66
+ readonly file: string;
67
+ } | {
68
+ readonly _tag: "MissingLeft";
69
+ readonly file: string;
70
+ } | {
71
+ readonly _tag: "MissingRight";
72
+ readonly file: string;
73
+ } | {
74
+ readonly _tag: "Changed";
75
+ readonly file: string;
76
+ readonly left: unknown;
77
+ readonly right: unknown;
78
+ /** Per-document breakdown if the file holds a multi-doc YAML stream. */
79
+ readonly docs?: ReadonlyArray<DocDiff>;
80
+ };
81
+ export interface DiffResult {
82
+ readonly entries: ReadonlyArray<FileDiff>;
83
+ }
84
+ export interface DiffFilesInput {
85
+ readonly left: Readonly<Record<string, string>>;
86
+ readonly right: Readonly<Record<string, string>>;
87
+ readonly options?: RedactOptions;
88
+ }
89
+ export declare const diffFiles: (input: DiffFilesInput) => DiffResult;
90
+ export declare const hasDifferences: (result: DiffResult) => boolean;
91
+ export type DiffFormat = "summary" | "detail" | "json";
92
+ export interface FormatDiffInput {
93
+ readonly result: DiffResult;
94
+ readonly format?: DiffFormat;
95
+ }
96
+ export declare const formatDiff: (input: FormatDiffInput) => string;
@@ -0,0 +1,44 @@
1
+ import { Effect, Schema } from "effect";
2
+ export declare const EnvImages: Schema.$Record<Schema.String, Schema.String>;
3
+ export type EnvImages = typeof EnvImages.Type;
4
+ export declare const ImagesConfig: Schema.Struct<{
5
+ readonly envs: Schema.$Record<Schema.String, Schema.$Record<Schema.String, Schema.String>>;
6
+ }>;
7
+ export type ImagesConfig = typeof ImagesConfig.Type;
8
+ export declare const decodeImagesSync: (input: unknown) => ImagesConfig;
9
+ export declare const decodeImagesEffect: (input: unknown) => Effect.Effect<{
10
+ readonly envs: {
11
+ readonly [x: string]: {
12
+ readonly [x: string]: string;
13
+ };
14
+ };
15
+ }, Schema.SchemaError, never>;
16
+ declare const ImagesEnvMissing_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 & {
17
+ readonly _tag: "ImagesEnvMissing";
18
+ } & Readonly<A>;
19
+ export declare class ImagesEnvMissing extends ImagesEnvMissing_base<{
20
+ readonly env: string;
21
+ }> {
22
+ }
23
+ export interface LookupEnvInput {
24
+ readonly cfg: ImagesConfig;
25
+ readonly env: string;
26
+ }
27
+ export declare const lookupEnv: (input: LookupEnvInput) => EnvImages | undefined;
28
+ export declare const lookupEnvEffect: (input: LookupEnvInput) => Effect.Effect<EnvImages, ImagesEnvMissing>;
29
+ export declare const imagesFor: (input: LookupEnvInput) => EnvImages;
30
+ declare const ImagesAppMissing_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: "ImagesAppMissing";
32
+ } & Readonly<A>;
33
+ export declare class ImagesAppMissing extends ImagesAppMissing_base<{
34
+ readonly env: string;
35
+ readonly app: string;
36
+ }> {
37
+ }
38
+ export interface RequireImageInput {
39
+ readonly e: EnvImages;
40
+ readonly app: string;
41
+ readonly envName: string;
42
+ }
43
+ export declare const requireImage: (input: RequireImageInput) => string;
44
+ export {};
@@ -0,0 +1,21 @@
1
+ export { brand, unsafeCoerce } from "./_cast";
2
+ export { boundary } from "./boundary";
3
+ export type { BundleHandle, BundleSetResult } from "./Bundle";
4
+ export * as Bundle from "./Bundle";
5
+ export * as Compose from "./Compose";
6
+ export type { BuiltImageRefApp, ConfigMapRef, ConfigMapRefKeys, ConfigMapRefName, Need, Provide, PvcRef, PvcRefName, SecretRef, SecretRefKeys, SecretRefName, SecretRefNamespace, ServiceAccountRef } from "./deps";
7
+ export * as Dep from "./deps";
8
+ export { BuiltImageRef } from "./deps";
9
+ export { deepEqual, diffFiles, type DiffFormat, type DiffResult, type DocDiff, type FileDiff, formatDiff, hasDifferences, parseYaml, parseYamlAll, redact, type RedactOptions } from "./diff";
10
+ export * as Helm from "./Helm";
11
+ export { decodeImagesEffect, decodeImagesSync, EnvImages, ImagesAppMissing, ImagesConfig, ImagesEnvMissing, imagesFor, lookupEnv, lookupEnvEffect, requireImage } from "./images";
12
+ export { ClusterSpec, CrdConfig, decodeKonfigConfigEffect, decodeKonfigConfigSync, DiffConfig, EnvEntry, HelmConfig, KonfigConfig, OutDir, type ResolvedKonfigConfig, ServicesConfig } from "./konfigConfig";
13
+ export type { EmbedYamlSource, RawYaml } from "./Manifest";
14
+ export * as Manifest from "./Manifest";
15
+ export * as Module from "./Module";
16
+ export { render, type RenderOptions } from "./render";
17
+ export { RenderContext } from "./RenderContext";
18
+ export { type AnyRenderError, BoundaryDecodeError, CrdExtractError, EmbedYamlReadError, HelmDigestMismatch, HelmRenderError, HelmVersionTooLow, RenderError } from "./RenderError";
19
+ export { renderManifest } from "./renderManifest";
20
+ export { ProcessError, runProcessExit, runProcessString } from "./subprocess";
21
+ export * as Yaml from "./yaml";