@konfig.ts/k8s 0.0.6 → 0.0.8
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/.generated/k8s-types/index.d.ts +5 -5
- package/dist/container.d.ts +1 -3
- package/dist/environmentBind.d.ts +1 -1
- package/dist/index.d.ts +13 -13
- package/dist/index.mjs +71 -71
- package/dist/index.mjs.map +1 -1
- package/dist/network.d.ts +2 -2
- package/dist/podSet.d.ts +1 -1
- package/dist/policy.d.ts +1 -1
- package/dist/refs.d.ts +2 -2
- package/package.json +9 -9
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export type { Deployment, DeploymentSpec, StatefulSet, StatefulSetSpec
|
|
2
|
-
export type { CronJob, Job, JobSpec
|
|
3
|
-
export type { ConfigMap, Container, ContainerPort, EnvVar, EnvVarSource, LocalObjectReference, Namespace, PersistentVolume, PersistentVolumeClaim, PodSpec, PodTemplateSpec, Secret, Service, ServiceAccount, ServicePort, Volume, VolumeMount
|
|
1
|
+
export type { Deployment, DeploymentSpec, StatefulSet, StatefulSetSpec } from "kubernetes-types/apps/v1";
|
|
2
|
+
export type { CronJob, Job, JobSpec } from "kubernetes-types/batch/v1";
|
|
3
|
+
export type { ConfigMap, Container, ContainerPort, EnvVar, EnvVarSource, LocalObjectReference, Namespace, PersistentVolume, PersistentVolumeClaim, PodSpec, PodTemplateSpec, Secret, Service, ServiceAccount, ServicePort, Volume, VolumeMount } from "kubernetes-types/core/v1";
|
|
4
4
|
export type { ObjectMeta } from "kubernetes-types/meta/v1";
|
|
5
|
-
export type { Ingress, IngressRule, IngressSpec, IngressTLS, NetworkPolicy
|
|
6
|
-
export type { ClusterRole, ClusterRoleBinding, Role, RoleBinding
|
|
5
|
+
export type { Ingress, IngressRule, IngressSpec, IngressTLS, NetworkPolicy } from "kubernetes-types/networking/v1";
|
|
6
|
+
export type { ClusterRole, ClusterRoleBinding, Role, RoleBinding } from "kubernetes-types/rbac/v1";
|
package/dist/container.d.ts
CHANGED
|
@@ -104,9 +104,7 @@ type DuplicateEnvNames<Envs extends ReadonlyArray<EnvVar<string>>> = {
|
|
|
104
104
|
* the `env` slot, an unmet property surfaces the sentence inline in the
|
|
105
105
|
* TS error — far more discoverable than a runtime "last-wins" surprise.
|
|
106
106
|
*/
|
|
107
|
-
type EnvDupCheck<Envs extends ReadonlyArray<EnvVar<string>>> = [
|
|
108
|
-
DuplicateEnvNames<Envs>
|
|
109
|
-
] extends [never] ? unknown : {
|
|
107
|
+
type EnvDupCheck<Envs extends ReadonlyArray<EnvVar<string>>> = [DuplicateEnvNames<Envs>] extends [never] ? unknown : {
|
|
110
108
|
readonly _konfig_duplicate_env_names: `Duplicate env name(s): "${DuplicateEnvNames<Envs>}". K8s silently last-wins; rename one of the colliding entries or remove the manual valueEnv that shadows another producer.`;
|
|
111
109
|
};
|
|
112
110
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Manifest, type RenderError } from "@konfig.ts/core";
|
|
2
|
-
import type { DownwardEntry,
|
|
2
|
+
import type { DownwardEntry, Environment, EnvMember, LiteralEntry, SecretEntry, SecretSource } from "@konfig.ts/env";
|
|
3
3
|
import { Layer } from "effect";
|
|
4
4
|
import type { SecretBackend } from "./backend";
|
|
5
5
|
import type { EnvVar } from "./env";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
export * as K8s from "./.generated/k8s-types";
|
|
2
|
-
export { Container, type ContainerInput, type ContainerSpec, type DefineContainerInput, type DefinedPod, type DefinePodInput, Pod, type PodSpecInput
|
|
3
|
-
export { type ContainerPort, type ContainerProtocol, type ExecAction, type GrpcAction, type HttpGetAction, type HttpHeader, type NamesOf, Port, type PortInput, type PortName, type ProbeTarget, type ServicePortSpec, type TcpSocketAction
|
|
4
|
-
export { type ConfigMapEnvInput, EnvVar, type EnvVarSource, type RawEnvInput, type SecretEnvForPodInput, type SecretEnvInput, type ValueEnvInput
|
|
5
|
-
export { ConfigMap, type ConfigMapInput, type ConfigMapManifest, Namespace, type NamespaceInput, type NamespaceManifest, type SecretInput, type SecretManifest, ServiceAccount, type ServiceAccountInput, type ServiceAccountManifest
|
|
2
|
+
export { Container, type ContainerInput, type ContainerSpec, type DefineContainerInput, type DefinedPod, type DefinePodInput, Pod, type PodSpecInput } from "./container";
|
|
3
|
+
export { type ContainerPort, type ContainerProtocol, type ExecAction, type GrpcAction, type HttpGetAction, type HttpHeader, type NamesOf, Port, type PortInput, type PortName, type ProbeTarget, type ServicePortSpec, type TcpSocketAction } from "./ports";
|
|
4
|
+
export { type ConfigMapEnvInput, EnvVar, type EnvVarSource, type RawEnvInput, type SecretEnvForPodInput, type SecretEnvInput, type ValueEnvInput } from "./env";
|
|
5
|
+
export { ConfigMap, type ConfigMapInput, type ConfigMapManifest, Namespace, type NamespaceInput, type NamespaceManifest, type SecretInput, type SecretManifest, ServiceAccount, type ServiceAccountInput, type ServiceAccountManifest } from "./identity";
|
|
6
6
|
import { Environment as _EnvironmentContract } from "@konfig.ts/env";
|
|
7
7
|
/**
|
|
8
8
|
* `Secret` value namespace — merges the env-contracts side (`define`)
|
|
@@ -30,19 +30,19 @@ export declare const Environment: {
|
|
|
30
30
|
readonly _konfig_error: `Environment: envName "${Extract<{ [K in keyof M]: Extract<M[K] extends infer T ? T extends M[K] ? T extends import("@konfig.ts/env").SecretEntry<infer _N extends string, infer _K extends string, infer Envs extends Readonly<Record<infer _K extends string, string>>> ? Envs extends Readonly<Record<string, infer V extends string>> ? V : never : T extends import("@konfig.ts/env").LiteralEntry<infer EnvName extends string, infer _T> ? EnvName : T extends import("@konfig.ts/env").DownwardEntry<infer EnvName_1 extends string> ? EnvName_1 : never : never : never, { [Other in keyof M]: Other extends K ? never : M[Other] extends infer T_1 ? T_1 extends M[Other] ? T_1 extends import("@konfig.ts/env").SecretEntry<infer _N extends string, infer _K extends string, infer Envs extends Readonly<Record<infer _K extends string, string>>> ? Envs extends Readonly<Record<string, infer V extends string>> ? V : never : T_1 extends import("@konfig.ts/env").LiteralEntry<infer EnvName extends string, infer _T> ? EnvName : T_1 extends import("@konfig.ts/env").DownwardEntry<infer EnvName_1 extends string> ? EnvName_1 : never : never : never; }[keyof M]>; }[keyof M], string>}" is claimed by multiple members`;
|
|
31
31
|
})) => _EnvironmentContract<M>;
|
|
32
32
|
};
|
|
33
|
-
export type
|
|
34
|
-
export type { BindEnvironmentInput, DeclaredDownward, DeclaredEnvironment, DeclaredLiteral, DeclaredMember, HasSecrets, SecretMemberOptions, SecretMemberOptionsFor, SecretMembersOpts
|
|
35
|
-
export { type BackendEmitInput, BackendSourceMissing, type BackendTag, type SecretBackend, } from "./backend";
|
|
33
|
+
export { type BackendEmitInput, BackendSourceMissing, type BackendTag, type SecretBackend } from "./backend";
|
|
34
|
+
export type { BindEnvironmentInput, DeclaredDownward, DeclaredEnvironment, DeclaredLiteral, DeclaredMember, HasSecrets, SecretMemberOptions, SecretMemberOptionsFor, SecretMembersOpts } from "./environmentBind";
|
|
36
35
|
export { NativeSecret, type NativeSecretOptions } from "./nativeSecret";
|
|
36
|
+
export { Ingress, type IngressInput, type IngressTLSInput, Service, type ServiceFromContainerInput, type ServiceFromPodSetInput, type ServiceInput } from "./network";
|
|
37
37
|
export { hashSecretValues, type HashSecretValuesInput } from "./podHash";
|
|
38
|
-
export {
|
|
39
|
-
export { ClusterRole, ClusterRoleBinding, type ClusterRoleBindingInput, type ClusterRoleInput, NetworkPolicy, type NetworkPolicyEgressRule, type NetworkPolicyFromPodSetInput, type NetworkPolicyIngressRule, type NetworkPolicyInput, type NetworkPolicyPeer, PersistentVolume, PersistentVolumeClaim, type PersistentVolumeClaimInput, type PersistentVolumeInput, Role, RoleBinding, type RoleBindingInput, type RoleInput, } from "./policy";
|
|
38
|
+
export { ClusterRole, ClusterRoleBinding, type ClusterRoleBindingInput, type ClusterRoleInput, NetworkPolicy, type NetworkPolicyEgressRule, type NetworkPolicyFromPodSetInput, type NetworkPolicyIngressRule, type NetworkPolicyInput, type NetworkPolicyPeer, PersistentVolume, PersistentVolumeClaim, type PersistentVolumeClaimInput, type PersistentVolumeInput, Role, RoleBinding, type RoleBindingInput, type RoleInput } from "./policy";
|
|
40
39
|
export type { ConfigMapRefName, PvcRefName, SecretRefName } from "./refs";
|
|
41
40
|
export { ConfigMapRef, PvcRef, SecretRef, ServiceAccountRef } from "./refs";
|
|
41
|
+
export type { BindSecretInput, DeclaredSecret } from "./secretBind";
|
|
42
42
|
export { Volume } from "./volume";
|
|
43
|
-
export type { EmptyVolumeInput, VolumeFromConfigMapInput, VolumeFromPvcInput, VolumeFromSecretInput, VolumeMount, VolumeName, VolumeNamesOf
|
|
44
|
-
export { CronJob, type CronJobInput, Deployment, type DeploymentFromPodSetInput, type DeploymentInput, Job, type JobInput, StatefulSet, type StatefulSetInput
|
|
45
|
-
export
|
|
43
|
+
export type { EmptyVolumeInput, VolumeFromConfigMapInput, VolumeFromPvcInput, VolumeFromSecretInput, VolumeMount, VolumeName, VolumeNamesOf } from "./volume";
|
|
44
|
+
export { CronJob, type CronJobInput, Deployment, type DeploymentFromPodSetInput, type DeploymentInput, Job, type JobInput, StatefulSet, type StatefulSetInput } from "./workload";
|
|
45
|
+
export { type DefinePodSetInput, PodSet } from "./podSet";
|
|
46
46
|
export { Selector } from "./selector";
|
|
47
47
|
export type { SelectorLabels } from "./selector";
|
|
48
|
-
export
|
|
48
|
+
export * as Workload from "./workloadHelpers";
|
package/dist/index.mjs
CHANGED
|
@@ -420,25 +420,6 @@ const NativeSecret = { backend: (opts) => {
|
|
|
420
420
|
};
|
|
421
421
|
} };
|
|
422
422
|
//#endregion
|
|
423
|
-
//#region src/podHash.ts
|
|
424
|
-
const _frame = (hasher, value) => {
|
|
425
|
-
const bytes = Buffer.from(value, "utf8");
|
|
426
|
-
hasher.update(`${bytes.length}:`);
|
|
427
|
-
hasher.update(bytes);
|
|
428
|
-
hasher.update(",");
|
|
429
|
-
};
|
|
430
|
-
const hashSecretValues = (input) => {
|
|
431
|
-
const hasher = createHash("sha256");
|
|
432
|
-
_frame(hasher, "konfig/secret-values-hash/v1");
|
|
433
|
-
_frame(hasher, input.salt);
|
|
434
|
-
const keys = Object.keys(input.values).sort();
|
|
435
|
-
for (const key of keys) {
|
|
436
|
-
_frame(hasher, key);
|
|
437
|
-
_frame(hasher, Redacted.value(input.values[key]));
|
|
438
|
-
}
|
|
439
|
-
return hasher.digest("hex");
|
|
440
|
-
};
|
|
441
|
-
//#endregion
|
|
442
423
|
//#region src/network.ts
|
|
443
424
|
const Service = {
|
|
444
425
|
make: (input) => {
|
|
@@ -524,6 +505,25 @@ const Ingress = {
|
|
|
524
505
|
})
|
|
525
506
|
};
|
|
526
507
|
//#endregion
|
|
508
|
+
//#region src/podHash.ts
|
|
509
|
+
const _frame = (hasher, value) => {
|
|
510
|
+
const bytes = Buffer.from(value, "utf8");
|
|
511
|
+
hasher.update(`${bytes.length}:`);
|
|
512
|
+
hasher.update(bytes);
|
|
513
|
+
hasher.update(",");
|
|
514
|
+
};
|
|
515
|
+
const hashSecretValues = (input) => {
|
|
516
|
+
const hasher = createHash("sha256");
|
|
517
|
+
_frame(hasher, "konfig/secret-values-hash/v1");
|
|
518
|
+
_frame(hasher, input.salt);
|
|
519
|
+
const keys = Object.keys(input.values).sort();
|
|
520
|
+
for (const key of keys) {
|
|
521
|
+
_frame(hasher, key);
|
|
522
|
+
_frame(hasher, Redacted.value(input.values[key]));
|
|
523
|
+
}
|
|
524
|
+
return hasher.digest("hex");
|
|
525
|
+
};
|
|
526
|
+
//#endregion
|
|
527
527
|
//#region src/policy.ts
|
|
528
528
|
const PersistentVolume = { make: (input) => Manifest.make(() => Effect.succeed({
|
|
529
529
|
apiVersion: "v1",
|
|
@@ -800,6 +800,58 @@ const CronJob = { make: (input) => {
|
|
|
800
800
|
return Manifest.make(() => Effect.succeed(resource));
|
|
801
801
|
} };
|
|
802
802
|
//#endregion
|
|
803
|
+
//#region src/podSet.ts
|
|
804
|
+
/**
|
|
805
|
+
* `PodSet` value namespace.
|
|
806
|
+
*
|
|
807
|
+
* const trio = PodSet.define({
|
|
808
|
+
* podSet: redisCachePods,
|
|
809
|
+
* deployment: { ... },
|
|
810
|
+
* service: { ... },
|
|
811
|
+
* netPol: { ... },
|
|
812
|
+
* });
|
|
813
|
+
*
|
|
814
|
+
* Umbrella over `Deployment.fromPodSet`, `Service.fromPodSet`, and
|
|
815
|
+
* `NetworkPolicy.fromPodSet` — emits whichever subset of the trio the
|
|
816
|
+
* input specifies, all rooted at one `Selector`.
|
|
817
|
+
*/
|
|
818
|
+
const PodSet = { define: (input) => {
|
|
819
|
+
const deployment = Deployment.fromPodSet({
|
|
820
|
+
podSet: input.podSet,
|
|
821
|
+
...input.deployment
|
|
822
|
+
});
|
|
823
|
+
const service = input.service !== void 0 ? Service.fromPodSet({
|
|
824
|
+
podSet: input.podSet,
|
|
825
|
+
...input.service
|
|
826
|
+
}) : void 0;
|
|
827
|
+
const netPol = input.netPol !== void 0 ? NetworkPolicy.fromPodSet({
|
|
828
|
+
podSet: input.podSet,
|
|
829
|
+
...input.netPol
|
|
830
|
+
}) : void 0;
|
|
831
|
+
return Manifest.make((ctx) => Effect.gen(function* () {
|
|
832
|
+
const d = yield* deployment.render(ctx);
|
|
833
|
+
const s = service !== void 0 ? yield* service.render(ctx) : void 0;
|
|
834
|
+
const n = netPol !== void 0 ? yield* netPol.render(ctx) : void 0;
|
|
835
|
+
const reason = "tuple element types are statically known per branch; the array literal is widened by TS, the brand-free runtime shape matches the typed tuple";
|
|
836
|
+
if (s !== void 0 && n !== void 0) return unsafeCoerce([
|
|
837
|
+
d,
|
|
838
|
+
s,
|
|
839
|
+
n
|
|
840
|
+
], reason);
|
|
841
|
+
if (s !== void 0) return unsafeCoerce([d, s], reason);
|
|
842
|
+
if (n !== void 0) return unsafeCoerce([d, n], reason);
|
|
843
|
+
return unsafeCoerce([d], reason);
|
|
844
|
+
}));
|
|
845
|
+
} };
|
|
846
|
+
//#endregion
|
|
847
|
+
//#region src/selector.ts
|
|
848
|
+
/**
|
|
849
|
+
* `Selector` value namespace.
|
|
850
|
+
*
|
|
851
|
+
* const apiPods = Selector.make({ app: "api", tier: "web" });
|
|
852
|
+
*/
|
|
853
|
+
const Selector = { make: (labels) => unsafeCoerce({ labels }, "SelectorBrand is a unique-symbol phantom — no runtime value; runtime shape is { labels }") };
|
|
854
|
+
//#endregion
|
|
803
855
|
//#region src/workloadHelpers.ts
|
|
804
856
|
var workloadHelpers_exports = /* @__PURE__ */ __exportAll({
|
|
805
857
|
cron: () => cron,
|
|
@@ -925,58 +977,6 @@ const cron = (input) => {
|
|
|
925
977
|
return Manifest.make((ctx) => Effect.all([sa.render(ctx), cronJob.render(ctx)], { concurrency: "unbounded" }));
|
|
926
978
|
};
|
|
927
979
|
//#endregion
|
|
928
|
-
//#region src/selector.ts
|
|
929
|
-
/**
|
|
930
|
-
* `Selector` value namespace.
|
|
931
|
-
*
|
|
932
|
-
* const apiPods = Selector.make({ app: "api", tier: "web" });
|
|
933
|
-
*/
|
|
934
|
-
const Selector = { make: (labels) => unsafeCoerce({ labels }, "SelectorBrand is a unique-symbol phantom — no runtime value; runtime shape is { labels }") };
|
|
935
|
-
//#endregion
|
|
936
|
-
//#region src/podSet.ts
|
|
937
|
-
/**
|
|
938
|
-
* `PodSet` value namespace.
|
|
939
|
-
*
|
|
940
|
-
* const trio = PodSet.define({
|
|
941
|
-
* podSet: redisCachePods,
|
|
942
|
-
* deployment: { ... },
|
|
943
|
-
* service: { ... },
|
|
944
|
-
* netPol: { ... },
|
|
945
|
-
* });
|
|
946
|
-
*
|
|
947
|
-
* Umbrella over `Deployment.fromPodSet`, `Service.fromPodSet`, and
|
|
948
|
-
* `NetworkPolicy.fromPodSet` — emits whichever subset of the trio the
|
|
949
|
-
* input specifies, all rooted at one `Selector`.
|
|
950
|
-
*/
|
|
951
|
-
const PodSet = { define: (input) => {
|
|
952
|
-
const deployment = Deployment.fromPodSet({
|
|
953
|
-
podSet: input.podSet,
|
|
954
|
-
...input.deployment
|
|
955
|
-
});
|
|
956
|
-
const service = input.service !== void 0 ? Service.fromPodSet({
|
|
957
|
-
podSet: input.podSet,
|
|
958
|
-
...input.service
|
|
959
|
-
}) : void 0;
|
|
960
|
-
const netPol = input.netPol !== void 0 ? NetworkPolicy.fromPodSet({
|
|
961
|
-
podSet: input.podSet,
|
|
962
|
-
...input.netPol
|
|
963
|
-
}) : void 0;
|
|
964
|
-
return Manifest.make((ctx) => Effect.gen(function* () {
|
|
965
|
-
const d = yield* deployment.render(ctx);
|
|
966
|
-
const s = service !== void 0 ? yield* service.render(ctx) : void 0;
|
|
967
|
-
const n = netPol !== void 0 ? yield* netPol.render(ctx) : void 0;
|
|
968
|
-
const reason = "tuple element types are statically known per branch; the array literal is widened by TS, the brand-free runtime shape matches the typed tuple";
|
|
969
|
-
if (s !== void 0 && n !== void 0) return unsafeCoerce([
|
|
970
|
-
d,
|
|
971
|
-
s,
|
|
972
|
-
n
|
|
973
|
-
], reason);
|
|
974
|
-
if (s !== void 0) return unsafeCoerce([d, s], reason);
|
|
975
|
-
if (n !== void 0) return unsafeCoerce([d, n], reason);
|
|
976
|
-
return unsafeCoerce([d], reason);
|
|
977
|
-
}));
|
|
978
|
-
} };
|
|
979
|
-
//#endregion
|
|
980
980
|
//#region src/index.ts
|
|
981
981
|
/**
|
|
982
982
|
* `Secret` value namespace — merges the env-contracts side (`define`)
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["ServiceAccountRefValue","ConfigMapRefValue","Secret","SecretRefValue","SecretRefValue","L","M","_SecretContract","_SecretIdentity","_EnvironmentContract","envRuntime"],"sources":["../src/.generated/k8s-types/index.ts","../src/container.ts","../src/ports.ts","../src/env.ts","../src/refs.ts","../src/identity.ts","../src/secretBind.ts","../src/environmentBind.ts","../src/backend.ts","../src/nativeSecret.ts","../src/podHash.ts","../src/network.ts","../src/policy.ts","../src/volume.ts","../src/workload.ts","../src/workloadHelpers.ts","../src/selector.ts","../src/podSet.ts","../src/index.ts"],"sourcesContent":["// Pinned re-export of Kubernetes API types. The directory name is\n// historical — we don't regenerate from OpenAPI; we re-export the\n// pinned `kubernetes-types` package, which is itself a stable mirror\n// of the upstream Kubernetes Go types.\n//\n// Version policy: `kubernetes-types` is pinned to an exact patch\n// version in packages/k8s/package.json — no caret. The minor\n// (currently 1.30) tracks the cluster minor we test against. Bumping\n// is intentional: read upstream release notes, run `bun run check &&\n// bun run test`, and update CHANGELOG.\n//\n// Each export here is the K8s API type as-is. konfig wrappers (e.g.\n// `ContainerInput` in container.ts) accept a wider, branded shape\n// and lower into these types when emitting manifests.\n\nexport type {\n\tDeployment,\n\tDeploymentSpec,\n\tStatefulSet,\n\tStatefulSetSpec,\n} from \"kubernetes-types/apps/v1\";\n\nexport type {\n\tCronJob,\n\tJob,\n\tJobSpec,\n} from \"kubernetes-types/batch/v1\";\nexport type {\n\tConfigMap,\n\tContainer,\n\tContainerPort,\n\tEnvVar,\n\tEnvVarSource,\n\tLocalObjectReference,\n\tNamespace,\n\tPersistentVolume,\n\tPersistentVolumeClaim,\n\tPodSpec,\n\tPodTemplateSpec,\n\tSecret,\n\tService,\n\tServiceAccount,\n\tServicePort,\n\tVolume,\n\tVolumeMount,\n} from \"kubernetes-types/core/v1\";\nexport type { ObjectMeta } from \"kubernetes-types/meta/v1\";\nexport type {\n\tIngress,\n\tIngressRule,\n\tIngressSpec,\n\tIngressTLS,\n\tNetworkPolicy,\n} from \"kubernetes-types/networking/v1\";\nexport type {\n\tClusterRole,\n\tClusterRoleBinding,\n\tRole,\n\tRoleBinding,\n} from \"kubernetes-types/rbac/v1\";\n","\nimport type { BuiltImageRef, SecretRef, ServiceAccountRef } from \"@konfig.ts/core\";\nimport { unsafeCoerce } from \"@konfig.ts/core\";\nimport type {\n\tContainer as K8sContainer,\n\tPodSpec as K8sPodSpec,\n} from \"./.generated/k8s-types\";\nimport type { EnvVar } from \"./env\";\nimport type {\n\tContainerPort,\n\tNamesOf,\n\tProbeTarget,\n} from \"./ports\";\nimport type { Volume, VolumeMount, VolumeNamesOf } from \"./volume\";\n\n/**\n * Container input — extends the full K8s Container API. Konfig's\n * branded helpers (`EnvVar.value`, `EnvVar.fromSecret`,\n * `EnvVar.fromConfigMap`) produce `EnvVar` instances whose runtime\n * shape matches `K8sEnvVar`; the override\n * here narrows the field to readonly + the branded helper output so\n * `secretKeyRef.name` carries its `SecretRef<N>` brand at construction\n * time.\n *\n * `image` is overridden as required (K8s lets it be optional for\n * higher-level controllers that default it; konfig wants every\n * container to have an explicit image).\n *\n * `ports[i].name` accepts the branded `PortName<string>` from `Port.make(...)`\n * as well as a raw string; the typed builder `Container` is the\n * link that captures the literal name union for cross-reference checks.\n */\nexport interface ContainerInput\n\textends Omit<\n\t\tK8sContainer,\n\t\t| \"env\"\n\t\t| \"image\"\n\t\t| \"ports\"\n\t\t| \"readinessProbe\"\n\t\t| \"livenessProbe\"\n\t\t| \"startupProbe\"\n\t\t| \"volumeMounts\"\n\t> {\n\t/**\n\t * Container image. Accepts a raw string (escape hatch for vendor\n\t * images: `ghcr.io/bitnami/postgresql:16.0.0`) or a `BuiltImageRef<App>`\n\t * produced by `Dep.builtImageRef` / `Dep.provideImage`. The branded\n\t * path ties the workload into the dep graph — a workload referencing\n\t * an image whose build module isn't in the composition fails at\n\t * `AppOfApps.entrypoint`.\n\t */\n\treadonly image: string | BuiltImageRef<string>;\n\treadonly env?: ReadonlyArray<EnvVar>;\n\treadonly ports?: ReadonlyArray<ContainerPort | { readonly containerPort: number; readonly name?: string; readonly protocol?: \"TCP\" | \"UDP\" | \"SCTP\" }>;\n\t/**\n\t * Probes accept either the upstream K8s shape or konfig's branded\n\t * `ProbeTarget<string>` (from `Container`). The two are\n\t * structurally close — the union lets a `ContainerSpec` flow\n\t * through `Workload.web`'s containers slot without a cast.\n\t */\n\treadonly readinessProbe?: K8sContainer[\"readinessProbe\"] | ProbeTarget<string>;\n\treadonly livenessProbe?: K8sContainer[\"livenessProbe\"] | ProbeTarget<string>;\n\treadonly startupProbe?: K8sContainer[\"startupProbe\"] | ProbeTarget<string>;\n\t/**\n\t * Volume mounts accept the upstream K8s shape or konfig's branded\n\t * `VolumeMount<string>` (from `Container` / `mountRef`). Same\n\t * rationale as the probe widening above.\n\t */\n\treadonly volumeMounts?:\n\t\t| K8sContainer[\"volumeMounts\"]\n\t\t| ReadonlyArray<VolumeMount<string>>;\n}\n\n/**\n * Strongly-typed container builder. Captures the union of named ports\n * declared via `port({ name, containerPort })` as a phantom type\n * parameter, then constrains every probe's `port` field to that union.\n *\n * Pair with `Service.fromContainer({ forContainer })` in `network.ts`\n * to link a Service's `targetPort` to the same union — a typo or\n * undeclared port name is a compile error.\n */\nexport interface ContainerSpec<Ports extends string = string, Mounts extends string = string>\n\textends Omit<\n\t\tContainerInput,\n\t\t\"ports\" | \"readinessProbe\" | \"livenessProbe\" | \"startupProbe\" | \"volumeMounts\"\n\t> {\n\treadonly name: string;\n\treadonly image: string;\n\treadonly ports: ReadonlyArray<ContainerPort<Ports>>;\n\treadonly readinessProbe?: ProbeTarget<Ports>;\n\treadonly livenessProbe?: ProbeTarget<Ports>;\n\treadonly startupProbe?: ProbeTarget<Ports>;\n\treadonly volumeMounts?: ReadonlyArray<VolumeMount<Mounts>>;\n\treadonly __portNames?: Ports;\n\treadonly __mountNames?: Mounts;\n}\n\nexport interface DefineContainerInput<\n\tPorts extends ReadonlyArray<ContainerPort<string>>,\n\tMounts extends ReadonlyArray<VolumeMount<string>>,\n\tEnvs extends ReadonlyArray<EnvVar<string>>,\n> extends Omit<\n\t\tContainerInput,\n\t\t\"ports\" | \"readinessProbe\" | \"livenessProbe\" | \"startupProbe\" | \"volumeMounts\" | \"env\"\n\t> {\n\treadonly name: string;\n\treadonly image: string;\n\treadonly ports: Ports;\n\treadonly readinessProbe?: ProbeTarget<NamesOf<Ports>>;\n\treadonly livenessProbe?: ProbeTarget<NamesOf<Ports>>;\n\treadonly startupProbe?: ProbeTarget<NamesOf<Ports>>;\n\treadonly volumeMounts?: Mounts;\n\treadonly env?: Envs & EnvDupCheck<Envs>;\n}\n\ntype MountNamesOf<M extends ReadonlyArray<VolumeMount<string>>> = {\n\treadonly [I in keyof M]: M[I] extends VolumeMount<infer N> ? N : never;\n}[number];\n\ntype _EnvNameOf<X> = X extends EnvVar<infer N> ? N : never;\n\n/**\n * Union of any literal env-var names that appear more than once in `Envs`.\n * Computes the intersection of pairwise names — if `Envs[I]` and `Envs[J]`\n * share a literal name (i ≠ j), that name leaks into the union. Empty\n * when every name is unique.\n */\ntype DuplicateEnvNames<Envs extends ReadonlyArray<EnvVar<string>>> = {\n\t[I in keyof Envs]: {\n\t\t[J in keyof Envs]: J extends I\n\t\t\t? never\n\t\t\t: _EnvNameOf<Envs[I]> & _EnvNameOf<Envs[J]> extends never\n\t\t\t\t? never\n\t\t\t\t: _EnvNameOf<Envs[I]> & _EnvNameOf<Envs[J]>;\n\t}[number];\n}[number];\n\n/**\n * Empty (`unknown`) when `Envs` has no duplicate names; otherwise an\n * inline object type whose required `_konfig_duplicate_env_names`\n * property carries a template-literal hint sentence. Intersected with\n * the `env` slot, an unmet property surfaces the sentence inline in the\n * TS error — far more discoverable than a runtime \"last-wins\" surprise.\n */\ntype EnvDupCheck<Envs extends ReadonlyArray<EnvVar<string>>> =\n\t[DuplicateEnvNames<Envs>] extends [never]\n\t\t? unknown\n\t\t: {\n\t\t\t\treadonly _konfig_duplicate_env_names: `Duplicate env name(s): \"${DuplicateEnvNames<Envs>}\". K8s silently last-wins; rename one of the colliding entries or remove the manual valueEnv that shadows another producer.`;\n\t\t\t};\n\n/**\n * `Container` value namespace.\n *\n * const apiContainer = Container.define({\n * name: \"api\",\n * image: apiImage,\n * ports: [Port.make({ name: \"http\", containerPort: 8080 })],\n * readinessProbe: { httpGet: { port: Port.ref(\"http\") } },\n * env: [...],\n * });\n *\n * `Container.define` captures the union of named ports (from\n * `Port.make`) as `Ports`, the union of mounted volume names (from\n * `Volume.mountRef`) as `Mounts`, and validates that the `env` list\n * has no duplicate env-var names. The first two phantoms travel on\n * `ContainerSpec`; `Pod.define` checks the container's Mounts against\n * the pod's declared volume names.\n *\n * Duplicate env names are caught at the call site via a template-literal\n * error message — see `EnvDupCheck`. With no volumeMounts and no env,\n * all phantoms collapse to `never` so the container slots into any pod.\n */\nexport const Container = {\n\tdefine: <\n\t\tconst Ports extends ReadonlyArray<ContainerPort<string>>,\n\t\tconst Mounts extends ReadonlyArray<VolumeMount<string>> = readonly [],\n\t\tconst Envs extends ReadonlyArray<EnvVar<string>> = readonly [],\n\t>(\n\t\tinput: DefineContainerInput<Ports, Mounts, Envs>,\n\t): ContainerSpec<NamesOf<Ports>, MountNamesOf<Mounts>> => {\n\t\ttype P = NamesOf<Ports>;\n\t\ttype M = MountNamesOf<Mounts>;\n\t\tconst out: ContainerSpec<P, M> = {\n\t\t\t...input,\n\t\t\tports: unsafeCoerce<ReadonlyArray<ContainerPort<P>>>(\n\t\t\t\tinput.ports,\n\t\t\t\t\"Ports tuple's element brands are the same PortName<N>; widening Ports → readonly ContainerPort<P>[] only changes the static shape, not the runtime values\",\n\t\t\t),\n\t\t\treadinessProbe: input.readinessProbe,\n\t\t\tlivenessProbe: input.livenessProbe,\n\t\t\tstartupProbe: input.startupProbe,\n\t\t\tvolumeMounts: unsafeCoerce<ReadonlyArray<VolumeMount<M>> | undefined>(\n\t\t\t\tinput.volumeMounts,\n\t\t\t\t\"Mounts tuple's element brands are the same VolumeMount<N>; widening Mounts → readonly VolumeMount<M>[] preserves runtime shape\",\n\t\t\t),\n\t\t\tenv: unsafeCoerce<ReadonlyArray<EnvVar<string>> | undefined>(\n\t\t\t\tinput.env,\n\t\t\t\t\"EnvDupCheck<Envs> intersection vanishes at runtime; the runtime value is the original EnvVar[]\",\n\t\t\t),\n\t\t};\n\t\treturn out;\n\t},\n};\n\n/**\n * `Pod.define` input. The pod declares a tuple of `Volume`s and lists\n * containers whose `Mounts` phantom is checked against the declared\n * volume names via `NoInfer`. A container referencing an undeclared\n * volume — or a typo — fails at the call site rather than at pod-startup\n * time with \"container references volume not found.\"\n */\nexport interface DefinePodInput<V extends ReadonlyArray<Volume<string>>> {\n\treadonly volumes: V;\n\treadonly containers: ReadonlyArray<ContainerSpec<string, NoInfer<VolumeNamesOf<V>>>>;\n\treadonly initContainers?: ReadonlyArray<ContainerSpec<string, NoInfer<VolumeNamesOf<V>>>>;\n}\n\nexport interface DefinedPod<MountNames extends string> {\n\treadonly volumes: ReadonlyArray<Volume<MountNames>>;\n\treadonly containers: ReadonlyArray<ContainerSpec<string, MountNames>>;\n\treadonly initContainers?: ReadonlyArray<ContainerSpec<string, MountNames>>;\n}\n\n/**\n * Pod spec input — extends K8s PodSpec but tightens the fields where\n * konfig adds brand checking: `imagePullSecrets`, `serviceAccountName`,\n * and `volumes` (the helpers in `volume.ts` produce konfig `Volume`\n * objects that lower to K8s `Volume`).\n */\nexport interface PodSpecInput\n\textends Omit<\n\t\tK8sPodSpec,\n\t\t| \"containers\"\n\t\t| \"initContainers\"\n\t\t| \"volumes\"\n\t\t| \"imagePullSecrets\"\n\t\t| \"serviceAccountName\"\n\t> {\n\treadonly containers: ReadonlyArray<ContainerInput>;\n\treadonly initContainers?: ReadonlyArray<ContainerInput>;\n\treadonly volumes?: ReadonlyArray<Volume>;\n\treadonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>;\n\treadonly serviceAccountName?: ServiceAccountRef<string> | string;\n}\n\n/**\n * `Pod` value namespace.\n *\n * const pod = Pod.define({\n * volumes: [Volume.empty({ name: \"config\" })],\n * containers: [Container.define({ ..., volumeMounts: [...] })],\n * });\n *\n * imagePullSecrets: [Pod.imagePullSecret(ghcrRef)],\n *\n * - `Pod.define(input)` ties container `volumeMounts[i].name` to the\n * pod's declared volume names via `NoInfer`.\n * - `Pod.imagePullSecret(ref)` returns the `{ name: SecretRef }` entry\n * consumed by Deployment / StatefulSet / Job / CronJob workloads.\n */\nexport const Pod = {\n\tdefine: <const V extends ReadonlyArray<Volume<string>>>(\n\t\tinput: DefinePodInput<V>,\n\t): DefinedPod<VolumeNamesOf<V>> => ({\n\t\tvolumes: unsafeCoerce<ReadonlyArray<Volume<VolumeNamesOf<V>>>>(\n\t\t\tinput.volumes,\n\t\t\t\"V tuple's elements are Volume<N>; widening V → readonly Volume<VolumeNamesOf<V>>[] is a structural relaxation, runtime value unchanged\",\n\t\t),\n\t\tcontainers: input.containers,\n\t\tinitContainers: input.initContainers,\n\t}),\n\timagePullSecret: (ref: SecretRef<string>): { readonly name: SecretRef<string> } => ({\n\t\tname: ref,\n\t}),\n};\n","import { brand } from \"@konfig.ts/core\";\n\n/**\n * Branded port name — a string carrying the literal `N` in its type.\n * Constructed by `Port.make({ name, containerPort })` and `Port.ref(name)`.\n * The brand lets probes and Service `targetPort` constrain their\n * `port` field to a member of the container's declared port-name union\n * rather than `string`.\n */\ndeclare const PortNameBrand: unique symbol;\nexport type PortName<N extends string> = string & {\n\treadonly [PortNameBrand]: N;\n};\n\nconst _portName = <const N extends string>(name: N): PortName<N> => brand<PortName<N>>(name);\n\nexport type ContainerProtocol = \"TCP\" | \"UDP\" | \"SCTP\";\n\nexport interface ContainerPort<N extends string = string> {\n\treadonly containerPort: number;\n\treadonly name?: PortName<N>;\n\treadonly protocol?: ContainerProtocol;\n\treadonly hostPort?: number;\n\treadonly hostIP?: string;\n}\n\nexport interface PortInput<N extends string> {\n\treadonly name: N;\n\treadonly containerPort: number;\n\treadonly protocol?: ContainerProtocol;\n\treadonly hostPort?: number;\n\treadonly hostIP?: string;\n}\n\n/**\n * `Port` value namespace.\n *\n * ports: [Port.make({ name: \"http\", containerPort: 8080 })],\n * readinessProbe: { httpGet: { port: Port.ref(\"http\") } },\n *\n * - `Port.make(input)` constructs a named container port; the literal\n * `name` is captured in the returned `ContainerPort<N>` brand so\n * `Container` can infer the port-name union and constrain\n * cross-references (probes, Service.targetPort).\n * - `Port.ref(name)` returns the brand alone, for probe targets and\n * `targetPort` references that need to name an existing declared port.\n */\nexport const Port = {\n\tmake: <const N extends string>(input: PortInput<N>): ContainerPort<N> => ({\n\t\tcontainerPort: input.containerPort,\n\t\tname: _portName(input.name),\n\t\tprotocol: input.protocol,\n\t\thostPort: input.hostPort,\n\t\thostIP: input.hostIP,\n\t}),\n\tref: <const N extends string>(name: N): PortName<N> => _portName(name),\n};\n\nexport interface HttpHeader {\n\treadonly name: string;\n\treadonly value: string;\n}\n\nexport interface HttpGetAction<Ports extends string> {\n\treadonly path?: string;\n\treadonly port: number | PortName<Ports>;\n\treadonly host?: string;\n\treadonly scheme?: \"HTTP\" | \"HTTPS\";\n\treadonly httpHeaders?: ReadonlyArray<HttpHeader>;\n}\n\nexport interface TcpSocketAction<Ports extends string> {\n\treadonly port: number | PortName<Ports>;\n\treadonly host?: string;\n}\n\nexport interface GrpcAction<Ports extends string> {\n\treadonly port: number | PortName<Ports>;\n\treadonly service?: string;\n}\n\nexport interface ExecAction {\n\treadonly command: ReadonlyArray<string>;\n}\n\n/**\n * Probe target — `port` references on httpGet/tcpSocket/grpc are\n * constrained to `Ports`, the union of names declared on the owning\n * container. A bare number is always accepted; only the named variant\n * is checked.\n */\nexport interface ProbeTarget<Ports extends string> {\n\treadonly httpGet?: HttpGetAction<Ports>;\n\treadonly tcpSocket?: TcpSocketAction<Ports>;\n\treadonly grpc?: GrpcAction<Ports>;\n\treadonly exec?: ExecAction;\n\treadonly initialDelaySeconds?: number;\n\treadonly periodSeconds?: number;\n\treadonly timeoutSeconds?: number;\n\treadonly successThreshold?: number;\n\treadonly failureThreshold?: number;\n\treadonly terminationGracePeriodSeconds?: number;\n}\n\nexport type NamesOf<P extends ReadonlyArray<unknown>> = {\n\treadonly [K in keyof P]: P[K] extends ContainerPort<infer N> ? N : never;\n}[number];\n\n/**\n * Service-port input bound to a container's port-name union. `targetPort`\n * accepts a bare number or a `PortName<Ports>`. The `Ports` parameter is\n * locked by `forContainer` on `Service.fromContainer`; use `Port.ref(name)`\n * to reference declared ports.\n */\nexport interface ServicePortSpec<Ports extends string> {\n\treadonly name?: string;\n\treadonly port: number;\n\treadonly targetPort: number | PortName<Ports>;\n\treadonly protocol?: ContainerProtocol;\n\treadonly appProtocol?: string;\n\treadonly nodePort?: number;\n}\n","import type { ConfigMapRef, SecretRef } from \"@konfig.ts/core\";\n\nexport interface EnvVarSource {\n\treadonly secretKeyRef?: {\n\t\treadonly name: string;\n\t\treadonly key: string;\n\t\treadonly optional?: boolean;\n\t};\n\treadonly configMapKeyRef?: {\n\t\treadonly name: string;\n\t\treadonly key: string;\n\t\treadonly optional?: boolean;\n\t};\n\treadonly fieldRef?: { readonly fieldPath: string; readonly apiVersion?: string };\n\treadonly resourceFieldRef?: { readonly containerName?: string; readonly resource: string };\n}\n\n/**\n * Container env-var entry. The phantom `N` records the literal env-var\n * name at the type level so `Container` can detect duplicates\n * across the entry list. The default `N = string` preserves loose-typed\n * call sites.\n */\nexport interface EnvVarShape<N extends string = string> {\n\treadonly name: N;\n\treadonly value?: string;\n\treadonly valueFrom?: EnvVarSource;\n}\n\nexport interface ValueEnvInput<N extends string> {\n\treadonly name: N;\n\treadonly value: string;\n}\n\nexport interface SecretEnvInput<EnvName extends string, N extends string, K extends string> {\n\treadonly name: EnvName;\n\treadonly ref: SecretRef<N, K>;\n\t/**\n\t * Constrained to the keys carried by `ref`. `NoInfer` locks `K` to\n\t * whatever the ref declares, so the typo `key: \"passowrd\"` fails at\n\t * compile time when the ref's K is `\"url\" | \"username\" | \"password\"`.\n\t * Refs constructed with the default `K = string` accept any string.\n\t */\n\treadonly key: NoInfer<K>;\n\treadonly optional?: boolean;\n}\n\nexport interface SecretEnvForPodInput<\n\tEnvName extends string,\n\tN extends string,\n\tK extends string,\n\tNs extends string,\n> {\n\treadonly name: EnvName;\n\t/**\n\t * Ref whose namespace slot must match `podNamespace`. Pass refs that\n\t * came from `Secret.make({ namespace })` in the same namespace as\n\t * the consuming pod. For legitimate cross-namespace cases, widen\n\t * via `SecretRef.unsafeReNamespace(ref)` first.\n\t */\n\treadonly ref: SecretRef<N, K, NoInfer<Ns>>;\n\treadonly key: NoInfer<K>;\n\treadonly podNamespace: Ns;\n\treadonly optional?: boolean;\n}\n\nexport interface ConfigMapEnvInput<EnvName extends string, N extends string, K extends string> {\n\treadonly name: EnvName;\n\treadonly ref: ConfigMapRef<N, K>;\n\t/**\n\t * Constrained to the keys carried by `ref`. `NoInfer` locks `K` to\n\t * whatever the ref declares — typos like `key: \"passwrod\"` fail at\n\t * compile time when the ref's K is `\"HOST\" | \"PORT\" | \"LOG_LEVEL\"`.\n\t * Refs constructed with the default `K = string` accept any string.\n\t */\n\treadonly key: NoInfer<K>;\n\treadonly optional?: boolean;\n}\n\nexport interface RawEnvInput<N extends string> {\n\treadonly name: N;\n\treadonly value?: string;\n\treadonly valueFrom?: EnvVarSource;\n}\n\n/**\n * `EnvVar` value namespace.\n *\n * env: [\n * EnvVar.value({ name: \"PORT\", value: \"8080\" }),\n * EnvVar.fromSecret({ name: \"DB_URL\", ref: dbCreds.ref, key: \"url\" }),\n * EnvVar.fromSecretForPod({\n * name: \"DB_URL_PRIMARY\", ref: dbCreds.ref, key: \"url\",\n * podNamespace: \"app\",\n * }),\n * EnvVar.fromConfigMap({ name: \"NEW_UI\", ref: flags.ref, key: \"NEW_UI\" }),\n * EnvVar.raw({ name: \"POD_NAME\", valueFrom: { fieldRef: ... } }),\n * ]\n *\n * Each constructor captures the literal env-var name (`N`) so\n * `Container` can detect duplicate entries across the env list.\n */\nexport const EnvVar = {\n\tvalue: <const N extends string>(input: ValueEnvInput<N>): EnvVar<N> => ({\n\t\tname: input.name,\n\t\tvalue: input.value,\n\t}),\n\tfromSecret: <const EnvName extends string, N extends string, K extends string = string>(\n\t\tinput: SecretEnvInput<EnvName, N, K>,\n\t): EnvVar<EnvName> => ({\n\t\tname: input.name,\n\t\tvalueFrom: {\n\t\t\tsecretKeyRef: { name: input.ref, key: input.key, optional: input.optional },\n\t\t},\n\t}),\n\t/**\n\t * Namespace-checked variant. The ref's namespace slot (`Ns`) must\n\t * match `podNamespace`. Catches \"pod in namespace A references a\n\t * Secret in namespace B\" at compile time — kube-apiserver only\n\t * resolves `valueFrom.secretKeyRef` against the pod's own namespace,\n\t * so cross-namespace refs are runtime errors.\n\t */\n\tfromSecretForPod: <\n\t\tconst EnvName extends string,\n\t\tN extends string,\n\t\tK extends string,\n\t\tconst Ns extends string,\n\t>(\n\t\tinput: SecretEnvForPodInput<EnvName, N, K, Ns>,\n\t): EnvVar<EnvName> => ({\n\t\tname: input.name,\n\t\tvalueFrom: {\n\t\t\tsecretKeyRef: { name: input.ref, key: input.key, optional: input.optional },\n\t\t},\n\t}),\n\tfromConfigMap: <const EnvName extends string, N extends string, K extends string = string>(\n\t\tinput: ConfigMapEnvInput<EnvName, N, K>,\n\t): EnvVar<EnvName> => ({\n\t\tname: input.name,\n\t\tvalueFrom: {\n\t\t\tconfigMapKeyRef: { name: input.ref, key: input.key, optional: input.optional },\n\t\t},\n\t}),\n\traw: <const N extends string>(input: RawEnvInput<N>): EnvVar<N> => input,\n};\n\n// Alias the shape interface as the user-facing `EnvVar<N>` type. The\n// namespace `EnvVar` (value) and the type `EnvVar<N>` share a name —\n// TypeScript merges them.\nexport type EnvVar<N extends string = string> = EnvVarShape<N>;\n","import {\n\tbrand,\n\ttype ConfigMapRef as CMRef,\n\ttype PvcRef as PRef,\n\ttype ServiceAccountRef as SARef,\n\ttype SecretRef as SRef,\n} from \"@konfig.ts/core\";\n\nexport type SecretRef<\n\tN extends string = string,\n\tK extends string = string,\n\tNs extends string = string,\n> = SRef<N, K, Ns>;\nexport type ConfigMapRef<N extends string = string, K extends string = string> = CMRef<N, K>;\nexport type ServiceAccountRef<N extends string = string> = SARef<N>;\nexport type PvcRef<N extends string = string> = PRef<N>;\nexport type {\n\tConfigMapRefKeys,\n\tConfigMapRefName,\n\tPvcRefName,\n\tSecretRefKeys,\n\tSecretRefName,\n} from \"@konfig.ts/core\";\nexport type { SecretRefNamespace } from \"@konfig.ts/core\";\n\nexport const SecretRef = {\n\tof: <N extends string, K extends string = string, Ns extends string = string>(\n\t\tname: N,\n\t): SecretRef<N, K, Ns> => brand<SecretRef<N, K, Ns>>(name),\n\t/**\n\t * Escape hatch — widen a typed ref's namespace slot to `any`, making\n\t * it usable across any pod context. Use sparingly (legitimate\n\t * cross-namespace cases: ExternalSecret reflection, in-cluster\n\t * shared infra). The cast is grep-able so PR reviewers see opt-ins.\n\t */\n\t// oxlint-disable-next-line app/no-type-assertion\n\tunsafeReNamespace: <N extends string, K extends string>(\n\t\t// oxlint-disable-next-line app/no-type-assertion\n\t\tref: SecretRef<N, K, any>,\n\t\t// oxlint-disable-next-line app/no-type-assertion\n\t): SecretRef<N, K, any> => ref,\n};\n\nexport const ConfigMapRef = {\n\tof: <N extends string, K extends string = string>(name: N): ConfigMapRef<N, K> =>\n\t\tbrand<ConfigMapRef<N, K>>(name),\n};\n\nexport const ServiceAccountRef = {\n\tof: <N extends string>(name: N): ServiceAccountRef<N> => brand<ServiceAccountRef<N>>(name),\n};\n\nexport const PvcRef = {\n\tof: <N extends string>(name: N): PvcRef<N> => brand<PvcRef<N>>(name),\n};\n","\nimport type { ConfigMapRef, SecretRef, ServiceAccountRef } from \"@konfig.ts/core\";\nimport { Manifest } from \"@konfig.ts/core\";\nimport { Effect } from \"effect\";\nimport type {\n\tConfigMap as K8sConfigMap,\n\tNamespace as K8sNamespace,\n\tSecret as K8sSecret,\n\tServiceAccount as K8sServiceAccount,\n} from \"./.generated/k8s-types\";\nimport {\n\tConfigMapRef as ConfigMapRefValue,\n\tSecretRef as SecretRefValue,\n\tServiceAccountRef as ServiceAccountRefValue,\n} from \"./refs\";\n\ntype CommonMeta = {\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n};\n\nexport interface NamespaceInput<N extends string> extends CommonMeta {\n\treadonly name: N;\n}\n\nexport interface NamespaceManifest<N extends string> extends Manifest.Manifest<K8sNamespace> {\n\treadonly ref: N;\n}\n\nexport const Namespace = {\n\tmake: <N extends string>(input: NamespaceInput<N>): NamespaceManifest<N> => {\n\t\tconst resource: K8sNamespace = {\n\t\t\tapiVersion: \"v1\",\n\t\t\tkind: \"Namespace\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t};\n\t\tconst m = Manifest.make<K8sNamespace>(() => Effect.succeed(resource));\n\t\treturn Object.assign(m, { ref: input.name });\n\t},\n};\n\nexport interface ServiceAccountInput<N extends string> extends CommonMeta {\n\treadonly name: N;\n\treadonly namespace: string;\n\treadonly automountServiceAccountToken?: boolean;\n\treadonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>;\n}\n\nexport interface ServiceAccountManifest<N extends string>\n\textends Manifest.Manifest<K8sServiceAccount> {\n\treadonly ref: ServiceAccountRef<N>;\n}\n\nexport const ServiceAccount = {\n\tmake: <N extends string>(input: ServiceAccountInput<N>): ServiceAccountManifest<N> => {\n\t\tconst resource: K8sServiceAccount = {\n\t\t\tapiVersion: \"v1\",\n\t\t\tkind: \"ServiceAccount\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tnamespace: input.namespace,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t\tautomountServiceAccountToken: input.automountServiceAccountToken,\n\t\t\timagePullSecrets: input.imagePullSecrets?.map((s) => ({ name: s.name })),\n\t\t};\n\t\tconst m = Manifest.make<K8sServiceAccount>(() => Effect.succeed(resource));\n\t\treturn Object.assign(m, { ref: ServiceAccountRefValue.of(input.name) });\n\t},\n};\n\nexport interface ConfigMapInput<N extends string, K extends string = string> extends CommonMeta {\n\treadonly name: N;\n\treadonly namespace: string;\n\treadonly data?: Readonly<Record<K, string>>;\n\treadonly binaryData?: Readonly<Record<K, string>>;\n\treadonly immutable?: boolean;\n}\n\nexport interface ConfigMapManifest<N extends string, K extends string = string>\n\textends Manifest.Manifest<K8sConfigMap> {\n\treadonly ref: ConfigMapRef<N, K>;\n}\n\nexport const ConfigMap = {\n\tmake: <const N extends string, const K extends string = string>(\n\t\tinput: ConfigMapInput<N, K>,\n\t): ConfigMapManifest<N, K> => {\n\t\tconst resource: K8sConfigMap = {\n\t\t\tapiVersion: \"v1\",\n\t\t\tkind: \"ConfigMap\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tnamespace: input.namespace,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t\tdata: input.data,\n\t\t\tbinaryData: input.binaryData,\n\t\t\timmutable: input.immutable,\n\t\t};\n\t\tconst m = Manifest.make<K8sConfigMap>(() => Effect.succeed(resource));\n\t\treturn Object.assign(m, { ref: ConfigMapRefValue.of<N, K>(input.name) });\n\t},\n};\n\nexport interface SecretInput<\n\tN extends string,\n\tNs extends string = string,\n\tK extends string = string,\n> extends CommonMeta {\n\treadonly name: N;\n\treadonly namespace: Ns;\n\treadonly type?: string;\n\treadonly data?: Readonly<Record<K, string>>;\n\treadonly stringData?: Readonly<Record<K, string>>;\n\treadonly immutable?: boolean;\n}\n\nexport interface SecretManifest<\n\tN extends string,\n\tNs extends string = string,\n\tK extends string = string,\n> extends Manifest.Manifest<K8sSecret> {\n\treadonly ref: SecretRef<N, K, Ns>;\n}\n\nexport const Secret = {\n\tmake: <\n\t\tconst N extends string,\n\t\tconst Ns extends string = string,\n\t\tconst K extends string = string,\n\t>(\n\t\tinput: SecretInput<N, Ns, K>,\n\t): SecretManifest<N, Ns, K> => {\n\t\tconst resource: K8sSecret = {\n\t\t\tapiVersion: \"v1\",\n\t\t\tkind: \"Secret\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tnamespace: input.namespace,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t\ttype: input.type,\n\t\t\tdata: input.data,\n\t\t\tstringData: input.stringData,\n\t\t\timmutable: input.immutable,\n\t\t};\n\t\tconst m = Manifest.make<K8sSecret>(() => Effect.succeed(resource));\n\t\treturn Object.assign(m, { ref: SecretRefValue.of<N, K, Ns>(input.name) });\n\t},\n};\n","import { Dep, type Manifest, RenderError, type SecretRef, unsafeCoerce } from \"@konfig.ts/core\"\nimport type { SecretEntry, SecretSource } from \"@konfig.ts/env\"\nimport { type Context, Effect, type Layer, Layer as L } from \"effect\"\nimport type { SecretBackend } from \"./backend\"\nimport { EnvVar } from \"./env\"\nimport { SecretRef as SecretRefValue } from \"./refs\"\n\nexport interface DeclaredSecret<N extends string, K extends string, Ns extends string = string> {\n readonly ref: SecretRef<N, K, Ns>\n readonly name: N\n readonly namespace: Ns\n readonly keys: ReadonlyArray<K>\n readonly envVars: ReadonlyArray<EnvVar>\n readonly manifest?: Manifest.Manifest<unknown>\n readonly refLayer: Layer.Layer<Dep.Provide<\"Secret\", N>>\n // values + layer present iff a source was supplied at bind time.\n readonly values?: Context.Service<\n Dep.Need<\"SecretValues\", N>,\n Dep.SecretValuesRecord<K>\n >\n readonly layer?: Layer.Layer<\n Dep.Provide<\"SecretValues\", N>,\n RenderError,\n Manifest.RenderServices\n >\n}\n\nexport interface BindSecretInput<\n N extends string,\n K extends string,\n E extends Readonly<Record<K, string>>,\n Ns extends string = string\n> {\n readonly secret: SecretEntry<N, K, E>\n readonly backend?: SecretBackend<N, K>\n readonly source?: SecretSource<K, Manifest.RenderServices>\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n /**\n * Override the contract's baked-in `namespace` for this bind. Useful\n * when the same `Secret` declaration is consumed across multiple\n * k8s namespaces (e.g. prod / staging / local of the same workload)\n * — the runtime read is namespace-independent, but each binding emits\n * its manifest into a different namespace.\n *\n * When passed as a string literal (via `Environment.bind`'s\n * `const namespace`), the literal flows into the ref's brand so\n * `secretEnvForPod` can enforce cross-namespace coherence.\n */\n readonly namespace?: Ns\n}\n\nexport const bindSecret = <\n N extends string,\n K extends string,\n E extends Readonly<Record<K, string>>,\n const Ns extends string = string\n>(\n input: BindSecretInput<N, K, E, Ns>\n): DeclaredSecret<N, K, Ns> => {\n const { secret } = input\n const namespace = unsafeCoerce<Ns>(\n input.namespace ?? secret.namespace,\n \"Ns defaults to `string`; the override (if present) is `Ns`, the secret's own namespace is `string` — runtime value either way is a string\"\n )\n const ref = SecretRefValue.of<N, K, Ns>(secret.name)\n const envVars: EnvVar[] = secret.keys.map((key: K) => EnvVar.fromSecret({ name: secret.env[key], ref, key }))\n const refLayer = Dep.provideSecret(secret.name)\n\n const manifest = input.backend === undefined\n ? undefined\n : input.backend.emit({\n name: secret.name,\n namespace,\n keys: secret.keys,\n labels: input.labels,\n annotations: input.annotations,\n source: input.source\n })\n\n const out: DeclaredSecret<N, K, Ns> = {\n ref,\n name: secret.name,\n namespace,\n keys: secret.keys,\n envVars,\n manifest,\n refLayer\n }\n\n if (input.source === undefined) return out\n\n const source = input.source\n const valuesTag = Dep.SecretValues<N, K>(secret.name)\n const layer = L.effect(\n valuesTag,\n source.resolve.pipe(\n Effect.mapError(\n (cause) =>\n new RenderError({\n message: `SecretValues(${namespace}/${secret.name}): source failed for key \"${cause.key}\"`,\n cause\n })\n )\n )\n )\n return { ...out, values: valuesTag, layer }\n}\n","import { type Manifest, type RenderError, unsafeCoerce } from \"@konfig.ts/core\";\nimport type {\n\tAnyEnvironment,\n\tDownwardEntry,\n\tEnvMember,\n\tEnvironment,\n\tLiteralEntry,\n\tSecretEntry,\n\tSecretSource,\n} from \"@konfig.ts/env\";\nimport { Layer, Match } from \"effect\";\nimport type { SecretBackend } from \"./backend\";\nimport type { EnvVar } from \"./env\";\nimport { bindSecret, type DeclaredSecret } from \"./secretBind\";\n\nexport interface DeclaredLiteral<EnvName extends string, T> {\n\treadonly envName: EnvName;\n\treadonly value: T;\n\treadonly envVar: EnvVar;\n}\n\nexport interface DeclaredDownward<EnvName extends string> {\n\treadonly envName: EnvName;\n\treadonly fieldPath: string;\n\treadonly envVar: EnvVar;\n}\n\n/**\n * Per-member declared shape produced by `Environment.bind`. Mirrors the\n * structure of the bundle: secrets give `DeclaredSecret`, literals\n * `DeclaredLiteral`, downwards `DeclaredDownward`, and nested\n * `Environment` members give a `members` sub-record with the same\n * recursive shape.\n */\nexport type DeclaredMember<\n\tA extends EnvMember,\n\tNs extends string = string,\n> = A extends SecretEntry<infer N, infer K, infer _E>\n\t? [N, K] extends [string, string]\n\t\t? DeclaredSecret<N, K, Ns>\n\t\t: never\n\t: A extends LiteralEntry<infer EnvName, infer T>\n\t\t? [EnvName] extends [string]\n\t\t\t? DeclaredLiteral<EnvName, T>\n\t\t\t: never\n\t\t: A extends DownwardEntry<infer EnvName>\n\t\t\t? [EnvName] extends [string]\n\t\t\t\t? DeclaredDownward<EnvName>\n\t\t\t\t: never\n\t\t\t: A extends Environment<infer SubM>\n\t\t\t\t? { readonly [K in keyof SubM]: DeclaredMember<SubM[K], Ns> }\n\t\t\t\t: never;\n\nexport interface DeclaredEnvironment<\n\tM extends Readonly<Record<string, EnvMember>>,\n\tNs extends string = string,\n> {\n\treadonly envVars: ReadonlyArray<EnvVar>;\n\treadonly manifests: ReadonlyArray<Manifest.Manifest<unknown>>;\n\treadonly members: { readonly [K in keyof M]: DeclaredMember<M[K], Ns> };\n\t// merged values layer over every secret member with a source.\n\treadonly valuesLayer: Layer.Layer<unknown, RenderError, Manifest.RenderServices>;\n}\n\ninterface _SecretMemberOptionsBase {\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n}\n\ninterface _SecretMemberBackendRequiresSource<N extends string, K extends string>\n\textends _SecretMemberOptionsBase {\n\treadonly backend: SecretBackend<N, K, true>;\n\treadonly source: SecretSource<K, Manifest.RenderServices>;\n}\n\ninterface _SecretMemberBackendOptionalSource<N extends string, K extends string>\n\textends _SecretMemberOptionsBase {\n\treadonly backend: SecretBackend<N, K, false>;\n\treadonly source?: SecretSource<K, Manifest.RenderServices>;\n}\n\ninterface _SecretMemberSourceOnly<_N extends string, K extends string>\n\textends _SecretMemberOptionsBase {\n\treadonly backend?: undefined;\n\treadonly source: SecretSource<K, Manifest.RenderServices>;\n}\n\n/**\n * Per-secret-member options at bind time. Backends with `RequiresSource: true`\n * (`Sops.backend`, `SealedSecrets.backend`, `NativeSecret.backend`) make\n * `source` mandatory at the type level. Backends with `false`\n * (`ExternalSecrets.backend`, `Sops.passthrough`) make it optional. With no\n * backend, `source` becomes mandatory — used to feed the in-process\n * `SecretValues` layer for tests / local renders.\n */\nexport type SecretMemberOptions<N extends string, K extends string> =\n\t| _SecretMemberBackendRequiresSource<N, K>\n\t| _SecretMemberBackendOptionalSource<N, K>\n\t| _SecretMemberSourceOnly<N, K>;\n\nexport type SecretMemberOptionsFor<A> = A extends SecretEntry<infer N, infer K, infer _E>\n\t? [N, K] extends [string, string]\n\t\t? SecretMemberOptions<N, K>\n\t\t: never\n\t: never;\n\n/**\n * True iff `M` (recursively, via nested `Environment` members)\n * contains at least one `SecretEntry`. Used to flip `secrets` between\n * required (any secrets present) and optional (literals/downwards\n * only) on `BindEnvironmentInput`.\n */\nexport type HasSecrets<M extends Readonly<Record<string, EnvMember>>> = true extends {\n\treadonly [K in keyof M]: M[K] extends SecretEntry<infer _N, infer _K, infer _E>\n\t\t? true\n\t\t: M[K] extends Environment<infer Sub>\n\t\t\t? HasSecrets<Sub>\n\t\t\t: false;\n}[keyof M]\n\t? true\n\t: false;\n\n/**\n * Recursive per-member secret options. For a secret member, the option\n * matches its `SecretMemberOptionsFor` and is required. For a nested\n * `Environment` member that itself contains secrets, the option is\n * `SecretMembersOpts<SubM>` and is also required. Nested environments\n * with no secrets are omitted entirely (no key needed).\n *\n * Together with `HasSecrets`, this enforces at compile time that every\n * `Secret` reachable from the bundle is acknowledged at bind\n * time — adding a new secret to the env contract forces every call\n * site to update.\n */\nexport type SecretMembersOpts<M extends Readonly<Record<string, EnvMember>>> = {\n\treadonly [K in keyof M as M[K] extends SecretEntry<infer _N, infer _K, infer _E>\n\t\t? K\n\t\t: M[K] extends Environment<infer SubM>\n\t\t\t? HasSecrets<SubM> extends true\n\t\t\t\t? K\n\t\t\t\t: never\n\t\t\t: never]: M[K] extends SecretEntry<infer _N, infer _K, infer _E>\n\t\t? SecretMemberOptionsFor<M[K]>\n\t\t: M[K] extends Environment<infer SubM>\n\t\t\t? SecretMembersOpts<SubM>\n\t\t\t: never;\n};\n\n/**\n * Per-literal value override for bind time. Keyed by member name, typed\n * to each literal's declared `T`. Useful when a `Literal` is a\n * runtime contract (carries a `schema: Config.string(envName)` for app\n * code to yield) but the manifest's emitted value differs per env —\n * e.g. `CLIENT_URL`, `S3_ENDPOINT`, host/URL literals.\n *\n * Recurses on nested `Environment` members — pass `{group: {host: \"x\"}}`\n * to override a literal nested inside a sub-bundle.\n */\nexport type LiteralMembersOpts<M extends Readonly<Record<string, EnvMember>>> = {\n\treadonly [K in keyof M as M[K] extends LiteralEntry<infer _EnvName, infer _T>\n\t\t? K\n\t\t: M[K] extends Environment<infer _SubM>\n\t\t\t? K\n\t\t\t: never]?: M[K] extends LiteralEntry<infer _EnvName, infer T>\n\t\t? T\n\t\t: M[K] extends Environment<infer SubM>\n\t\t\t? LiteralMembersOpts<SubM>\n\t\t\t: never;\n};\n\ninterface _BindEnvironmentInputBase<\n\tM extends Readonly<Record<string, EnvMember>>,\n\tNs extends string = string,\n> {\n\treadonly env: Environment<M>;\n\t/**\n\t * Per-literal value override for the manifest's emitted env var. The\n\t * runtime read (via `entry.schema`, if provided) is unchanged —\n\t * overrides only affect what the konfig module writes into the\n\t * Deployment's `env` array.\n\t */\n\treadonly literals?: LiteralMembersOpts<M>;\n\t/**\n\t * Override every secret member's namespace for this bind. Useful when\n\t * the bundle is consumed across multiple k8s namespaces (e.g. prod /\n\t * staging / local) without redeclaring each contract. Recurses into\n\t * nested `Environment` members.\n\t *\n\t * When passed as a string literal, the literal flows into each\n\t * `DeclaredSecret.ref`'s brand so `secretEnvForPod` can enforce\n\t * cross-namespace coherence on hand-spliced env entries.\n\t */\n\treadonly namespace?: Ns;\n}\n\n/**\n * `secrets` flips between required and optional based on whether `M`\n * actually contains any secrets. A bundle of literals/downwards only\n * has nothing to bind, so `secrets` stays optional. A bundle with even\n * one `Secret` (directly or nested) forces the caller to supply\n * every secret member — and for each member, either a `backend` or a\n * `source` (see `SecretMemberOptions`).\n */\nexport type BindEnvironmentInput<\n\tM extends Readonly<Record<string, EnvMember>>,\n\tNs extends string = string,\n> = _BindEnvironmentInputBase<M, Ns> &\n\t\t(HasSecrets<M> extends true\n\t\t\t? { readonly secrets: SecretMembersOpts<M> }\n\t\t\t: { readonly secrets?: SecretMembersOpts<M> });\n\ninterface _BindLiteralInput {\n\treadonly entry: LiteralEntry<string, unknown>;\n\treadonly override?: unknown;\n}\nconst _bindLiteral = (input: _BindLiteralInput): DeclaredLiteral<string, unknown> => {\n\tconst hasOverride = input.override !== undefined;\n\tconst value = hasOverride ? input.override : input.entry.value;\n\tconst serialized = hasOverride\n\t\t? input.entry.serialize(input.override)\n\t\t: input.entry.serialized;\n\treturn {\n\t\tenvName: input.entry.envName,\n\t\tvalue,\n\t\tenvVar: { name: input.entry.envName, value: serialized },\n\t};\n};\n\ninterface _BindDownwardInput {\n\treadonly entry: DownwardEntry<string>;\n}\nconst _bindDownward = (input: _BindDownwardInput): DeclaredDownward<string> => ({\n\tenvName: input.entry.envName,\n\tfieldPath: input.entry.fieldPath,\n\tenvVar: {\n\t\tname: input.entry.envName,\n\t\tvalueFrom: { fieldRef: { fieldPath: input.entry.fieldPath } },\n\t},\n});\n\ntype _AnyValuesLayer = Layer.Layer<unknown, RenderError, Manifest.RenderServices>;\n\ninterface _BindAcc {\n\treadonly declared: Record<string, unknown>;\n\treadonly envVars: EnvVar[];\n\treadonly manifests: Manifest.Manifest<unknown>[];\n\treadonly valuesLayers: _AnyValuesLayer[];\n}\n\ninterface _DispatchInput {\n\treadonly memberKey: string;\n\treadonly entry: EnvMember;\n\treadonly secretsOpts: Record<string, unknown> | undefined;\n\treadonly literalsOpts: Record<string, unknown> | undefined;\n\treadonly namespace: string | undefined;\n\treadonly acc: _BindAcc;\n}\n\nconst _handleSecret = (input: _DispatchInput): void => {\n\tconst memberOpts = unsafeCoerce<SecretMemberOptions<string, string> | undefined>(\n\t\tinput.secretsOpts?.[input.memberKey],\n\t\t\"SecretMembersOpts<M> shape — runtime key lookup against the typed input\",\n\t);\n\tconst secret = unsafeCoerce<SecretEntry<string, string, Readonly<Record<string, string>>>>(\n\t\tinput.entry,\n\t\t\"Match.tag('Secret') narrowed entry to SecretEntry; the helper-level signature is the general SecretEntry shape\",\n\t);\n\tconst d = bindSecret({\n\t\tsecret,\n\t\tbackend: memberOpts?.backend,\n\t\tsource: memberOpts?.source,\n\t\tlabels: memberOpts?.labels,\n\t\tannotations: memberOpts?.annotations,\n\t\tnamespace: input.namespace,\n\t});\n\tinput.acc.declared[input.memberKey] = d;\n\tinput.acc.envVars.push(...d.envVars);\n\tif (d.manifest !== undefined) input.acc.manifests.push(d.manifest);\n\tif (d.layer !== undefined) {\n\t\tinput.acc.valuesLayers.push(\n\t\t\tunsafeCoerce<_AnyValuesLayer>(\n\t\t\t\td.layer,\n\t\t\t\t\"DeclaredSecret.layer is Layer<Provide<SecretValues, N>, ...>; widen to unknown for the heterogeneous Layer.mergeAll\",\n\t\t\t),\n\t\t);\n\t}\n};\n\nconst _handleLiteral = (input: _DispatchInput): void => {\n\tconst literal = unsafeCoerce<LiteralEntry<string, unknown>>(\n\t\tinput.entry,\n\t\t\"Match.tag('Literal') narrowed entry to LiteralEntry<string, unknown>\",\n\t);\n\tconst d = _bindLiteral({ entry: literal, override: input.literalsOpts?.[input.memberKey] });\n\tinput.acc.declared[input.memberKey] = d;\n\tinput.acc.envVars.push(d.envVar);\n};\n\nconst _handleDownward = (input: _DispatchInput): void => {\n\tconst downward = unsafeCoerce<DownwardEntry<string>>(\n\t\tinput.entry,\n\t\t\"Match.tag('Downward') narrowed entry to DownwardEntry<string>\",\n\t);\n\tconst d = _bindDownward({ entry: downward });\n\tinput.acc.declared[input.memberKey] = d;\n\tinput.acc.envVars.push(d.envVar);\n};\n\nconst _handleEnvironment = (input: _DispatchInput): void => {\n\tconst subEnv = unsafeCoerce<AnyEnvironment>(\n\t\tinput.entry,\n\t\t\"Match.tag('Environment') narrowed entry to a nested Environment\",\n\t);\n\tconst sub = bindEnvironment({\n\t\tenv: subEnv,\n\t\tsecrets: unsafeCoerce<SecretMembersOpts<Readonly<Record<string, EnvMember>>>>(\n\t\t\tinput.secretsOpts?.[input.memberKey] ?? {},\n\t\t\t\"sub-record from SecretMembersOpts<M> — type is checked at the outer call site\",\n\t\t),\n\t\tliterals: unsafeCoerce<LiteralMembersOpts<Readonly<Record<string, EnvMember>>>>(\n\t\t\tinput.literalsOpts?.[input.memberKey] ?? {},\n\t\t\t\"sub-record from LiteralMembersOpts<M> — type is checked at the outer call site\",\n\t\t),\n\t\tnamespace: input.namespace,\n\t});\n\tinput.acc.declared[input.memberKey] = sub.members;\n\tinput.acc.envVars.push(...sub.envVars);\n\tinput.acc.manifests.push(...sub.manifests);\n\tinput.acc.valuesLayers.push(\n\t\tunsafeCoerce<_AnyValuesLayer>(\n\t\t\tsub.valuesLayer,\n\t\t\t\"valuesLayer aggregate over the recursive merge\",\n\t\t),\n\t);\n};\n\nconst _dispatch = (input: _DispatchInput): void =>\n\tMatch.value(input.entry._kind).pipe(\n\t\tMatch.when(\"Secret\", () => _handleSecret(input)),\n\t\tMatch.when(\"Literal\", () => _handleLiteral(input)),\n\t\tMatch.when(\"Downward\", () => _handleDownward(input)),\n\t\tMatch.when(\"Environment\", () => _handleEnvironment(input)),\n\t\tMatch.exhaustive,\n\t);\n\nexport const bindEnvironment = <\n\tconst M extends Readonly<Record<string, EnvMember>>,\n\tconst Ns extends string = string,\n>(\n\tinput: BindEnvironmentInput<M, Ns>,\n): DeclaredEnvironment<M, Ns> => {\n\tconst { env } = input;\n\tconst acc: _BindAcc = {\n\t\tdeclared: {},\n\t\tenvVars: [],\n\t\tmanifests: [],\n\t\tvaluesLayers: [],\n\t};\n\tconst secretsOpts = unsafeCoerce<Record<string, unknown> | undefined>(\n\t\tinput.secrets,\n\t\t\"discriminated union from BindEnvironmentInput; iterate keys at runtime\",\n\t);\n\tconst literalsOpts = unsafeCoerce<Record<string, unknown> | undefined>(\n\t\tinput.literals,\n\t\t\"discriminated union from BindEnvironmentInput; iterate keys at runtime\",\n\t);\n\n\tfor (const memberKey of Object.keys(env.members)) {\n\t\tconst entry = unsafeCoerce<EnvMember>(\n\t\t\tenv.members[memberKey],\n\t\t\t\"env.members values are EnvMember by construction\",\n\t\t);\n\t\t_dispatch({\n\t\t\tmemberKey,\n\t\t\tentry,\n\t\t\tsecretsOpts,\n\t\t\tliteralsOpts,\n\t\t\tnamespace: input.namespace,\n\t\t\tacc,\n\t\t});\n\t}\n\n\tconst valuesLayer = unsafeCoerce<_AnyValuesLayer>(\n\t\tacc.valuesLayers.length === 0\n\t\t\t? Layer.empty\n\t\t\t: Layer.mergeAll(acc.valuesLayers[0]!, ...acc.valuesLayers.slice(1)),\n\t\t\"merged Layer over a heterogeneous list of per-secret value layers\",\n\t);\n\n\treturn {\n\t\tenvVars: acc.envVars,\n\t\tmanifests: acc.manifests,\n\t\tmembers: unsafeCoerce<{ readonly [K in keyof M]: DeclaredMember<M[K], Ns> }>(\n\t\t\tacc.declared,\n\t\t\t\"declared populated by iterating env.members; each key maps to its DeclaredMember<M[K], Ns>\",\n\t\t),\n\t\tvaluesLayer,\n\t};\n};\n","import type { Manifest } from \"@konfig.ts/core\"\nimport type { SecretSource } from \"@konfig.ts/env\"\nimport { Data } from \"effect\"\n\nexport type BackendTag =\n | \"Sops\"\n | \"Sops.passthrough\"\n | \"SealedSecrets\"\n | \"ExternalSecrets\"\n | \"NativeSecret\"\n\nexport interface BackendEmitInput<N extends string, K extends string> {\n readonly name: N\n readonly namespace: string\n readonly keys: ReadonlyArray<K>\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly source?: SecretSource<K, Manifest.RenderServices>\n}\n\nexport interface SecretBackend<\n N extends string,\n K extends string,\n RequiresSource extends boolean = boolean\n> {\n readonly _tag: BackendTag\n readonly requiresSource: RequiresSource\n readonly emit: (input: BackendEmitInput<N, K>) => Manifest.Manifest<unknown>\n}\n\nexport class BackendSourceMissing extends Data.TaggedError(\"BackendSourceMissing\")<{\n readonly backend: BackendTag\n readonly secret: string\n}> {\n get message(): string {\n return `backend \"${this.backend}\" requires a source but none was provided for secret \"${this.secret}\"`\n }\n}\n","import { Manifest, RenderError } from \"@konfig.ts/core\";\nimport type { SecretSource } from \"@konfig.ts/env\";\nimport { Effect, Redacted } from \"effect\";\nimport type { Secret as K8sSecret } from \"./.generated/k8s-types\";\nimport { BackendSourceMissing, type BackendEmitInput, type SecretBackend } from \"./backend\";\n\nexport interface NativeSecretOptions {\n\treadonly type?: string;\n\treadonly immutable?: boolean;\n\treadonly silenceWarning?: boolean;\n}\n\ninterface _EmitInput<N extends string, K extends string> {\n\treadonly base: BackendEmitInput<N, K>;\n\treadonly opts: NativeSecretOptions;\n\treadonly source: SecretSource<K, Manifest.RenderServices>;\n}\n\nconst _emit = <N extends string, K extends string>(\n\tinput: _EmitInput<N, K>,\n): Manifest.Manifest<K8sSecret> =>\n\tManifest.make<K8sSecret>((_ctx) =>\n\t\tEffect.gen(function* () {\n\t\t\tif (input.opts.silenceWarning !== true) {\n\t\t\t\tyield* Effect.logWarning(\n\t\t\t\t\t`NativeSecret backend emits a plaintext Secret with stringData on disk for \"${input.base.namespace}/${input.base.name}\". Pass { silenceWarning: true } to suppress, or switch to ExternalSecrets / SealedSecrets / Sops for production.`,\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst resolved = yield* input.source.resolve.pipe(\n\t\t\t\tEffect.mapError(\n\t\t\t\t\t(cause) =>\n\t\t\t\t\t\tnew RenderError({\n\t\t\t\t\t\t\tmessage: `NativeSecret(${input.base.namespace}/${input.base.name}): source failed for key \"${cause.key}\"`,\n\t\t\t\t\t\t\tcause,\n\t\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t);\n\t\t\tconst stringData: Record<string, string> = {};\n\t\t\tfor (const key of input.base.keys) {\n\t\t\t\tstringData[key] = Redacted.value(resolved[key]);\n\t\t\t}\n\t\t\tconst out: K8sSecret = {\n\t\t\t\tapiVersion: \"v1\",\n\t\t\t\tkind: \"Secret\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.base.name,\n\t\t\t\t\tnamespace: input.base.namespace,\n\t\t\t\t\tlabels: input.base.labels,\n\t\t\t\t\tannotations: input.base.annotations,\n\t\t\t\t},\n\t\t\t\ttype: input.opts.type,\n\t\t\t\tstringData,\n\t\t\t\timmutable: input.opts.immutable,\n\t\t\t};\n\t\t\treturn out;\n\t\t}),\n\t);\n\nexport const NativeSecret = {\n\tbackend: <N extends string, K extends string>(\n\t\topts?: NativeSecretOptions,\n\t): SecretBackend<N, K, true> => {\n\t\tconst resolvedOpts = opts ?? {};\n\t\treturn {\n\t\t\t_tag: \"NativeSecret\",\n\t\t\trequiresSource: true,\n\t\t\temit: (input: BackendEmitInput<N, K>) => {\n\t\t\t\tif (input.source === undefined) {\n\t\t\t\t\tthrow new BackendSourceMissing({ backend: \"NativeSecret\", secret: input.name });\n\t\t\t\t}\n\t\t\t\treturn _emit({ base: input, opts: resolvedOpts, source: input.source });\n\t\t\t},\n\t\t};\n\t},\n};\n","import { Redacted } from \"effect\"\nimport { createHash, type Hash } from \"node:crypto\"\n\nexport interface HashSecretValuesInput {\n readonly values: Readonly<Record<string, Redacted.Redacted<string>>>\n /**\n * Non-secret salt folded into the digest so it is NOT a pure function of the\n * plaintext — this defeats offline brute-force / rainbow-table recovery of\n * low-entropy secrets from the annotation. Use a stable per-workload\n * identifier such as `\"<namespace>/<name>\"`.\n */\n readonly salt: string\n}\n\n// Netstring-frames every field (`<byteLen>:<bytes>,`) before hashing. Plain\n// `key + \"=\" + value + \"\\n\"` concatenation is ambiguous — `{ \"a=b\": \"c\" }` and\n// `{ \"a\": \"b\\nc\" }` would hash identically. Length-prefixing makes each field\n// boundary unforgeable, so distinct records always produce distinct digests.\nconst _frame = (hasher: Hash, value: string): void => {\n const bytes = Buffer.from(value, \"utf8\")\n hasher.update(`${bytes.length}:`)\n hasher.update(bytes)\n hasher.update(\",\")\n}\n\n// Captures values AT BUILD TIME ONLY — rotations between builds need an\n// in-cluster watcher (e.g. Reloader). Redacted.value is inline so plaintext\n// is not bound to a local.\n//\n// NOTE: the returned digest is a change-detection fingerprint, NOT a\n// cryptographic commitment you may safely publish for a low-entropy secret.\n// It is salted (so it is not a bare sha256 of the plaintext) and emitted at\n// full width (no truncation), but it must not be treated as secret-safe.\nexport const hashSecretValues = (input: HashSecretValuesInput): string => {\n const hasher = createHash(\"sha256\")\n _frame(hasher, \"konfig/secret-values-hash/v1\")\n _frame(hasher, input.salt)\n const keys = Object.keys(input.values).sort()\n for (const key of keys) {\n _frame(hasher, key)\n _frame(hasher, Redacted.value(input.values[key]!))\n }\n return hasher.digest(\"hex\")\n}\n","import { Manifest, type SecretRef, unsafeCoerce } from \"@konfig.ts/core\";\nimport { Effect } from \"effect\";\nimport type { ContainerSpec } from \"./container\";\nimport type {\n\tIngress as K8sIngress,\n\tIngressRule as K8sIngressRule,\n\tIngressTLS as K8sIngressTLS,\n\tService as K8sService,\n\tServicePort as K8sServicePort,\n} from \"./.generated/k8s-types\";\nimport type { IngressBackend as K8sIngressBackend } from \"kubernetes-types/networking/v1\";\nimport type { ServicePortSpec } from \"./ports\";\nimport type { Selector } from \"./selector\";\n\n/**\n * Strict input for a `Service`. `selector` and `ports` are required:\n * a Service with no selector has no endpoints, and one with no ports\n * is meaningless. ServicePort needs at minimum a `port`; the upstream\n * `K8sServicePort` only marks `port` as required — names/protocol\n * defaults match kube-apiserver behaviour.\n */\nexport interface ServiceInput {\n\treadonly name: string;\n\treadonly namespace: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n\treadonly selector: Readonly<Record<string, string>>;\n\treadonly ports: ReadonlyArray<K8sServicePort>;\n\treadonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\";\n\treadonly clusterIP?: string;\n\treadonly sessionAffinity?: string;\n\treadonly publishNotReadyAddresses?: boolean;\n\treadonly externalTrafficPolicy?: string;\n\treadonly internalTrafficPolicy?: string;\n}\n\n/**\n * Strongly-typed Service input bound to a container's declared port-name\n * union. `selector` and `ports` are required; `ports[i].targetPort`\n * accepts a bare number or `Port.ref(name)` referencing a name declared\n * on `forContainer`. `NoInfer` locks `Ports` to `forContainer`, so the\n * port list is validated against that union rather than inferred from.\n */\nexport interface ServiceFromContainerInput<Ports extends string> {\n\treadonly name: string;\n\treadonly namespace: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n\treadonly selector: Readonly<Record<string, string>>;\n\treadonly forContainer: ContainerSpec<Ports>;\n\treadonly ports: ReadonlyArray<ServicePortSpec<NoInfer<Ports>>>;\n\treadonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\";\n\treadonly clusterIP?: string;\n\treadonly sessionAffinity?: string;\n\treadonly publishNotReadyAddresses?: boolean;\n\treadonly externalTrafficPolicy?: string;\n\treadonly internalTrafficPolicy?: string;\n}\n\n/**\n * Service built from a `Selector`. The selector's labels populate\n * `spec.selector` — drift versus the matching Deployment is impossible\n * once both consume the same `podSet`.\n */\nexport interface ServiceFromPodSetInput<L extends Readonly<Record<string, string>>> {\n\treadonly name: string;\n\treadonly namespace: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n\treadonly podSet: Selector<L>;\n\treadonly ports: ReadonlyArray<K8sServicePort>;\n\treadonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\";\n\treadonly clusterIP?: string;\n\treadonly sessionAffinity?: string;\n\treadonly publishNotReadyAddresses?: boolean;\n\treadonly externalTrafficPolicy?: string;\n\treadonly internalTrafficPolicy?: string;\n}\n\nexport const Service = {\n\tmake: (input: ServiceInput): Manifest.Manifest<K8sService> => {\n\t\tconst resource: K8sService = {\n\t\t\tapiVersion: \"v1\",\n\t\t\tkind: \"Service\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tnamespace: input.namespace,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t\tspec: {\n\t\t\t\tselector: input.selector,\n\t\t\t\ttype: input.type,\n\t\t\t\tports: unsafeCoerce(input.ports, \"input.ports is the user-typed Service spec; K8s ServicePort allows the same fields\"),\n\t\t\t\tclusterIP: input.clusterIP,\n\t\t\t\tsessionAffinity: input.sessionAffinity,\n\t\t\t\tpublishNotReadyAddresses: input.publishNotReadyAddresses,\n\t\t\t\texternalTrafficPolicy: input.externalTrafficPolicy,\n\t\t\t\tinternalTrafficPolicy: input.internalTrafficPolicy,\n\t\t\t},\n\t\t};\n\t\treturn Manifest.make<K8sService>(() => Effect.succeed(resource));\n\t},\n\tfromContainer: <Ports extends string>(\n\t\tinput: ServiceFromContainerInput<Ports>,\n\t): Manifest.Manifest<K8sService> =>\n\t\tService.make({\n\t\t\tname: input.name,\n\t\t\tnamespace: input.namespace,\n\t\t\tlabels: input.labels,\n\t\t\tannotations: input.annotations,\n\t\t\tselector: input.selector,\n\t\t\tports: unsafeCoerce<ReadonlyArray<K8sServicePort>>(\n\t\t\t\tinput.ports,\n\t\t\t\t\"ServicePortSpec<Ports> structurally matches K8sServicePort; targetPort's PortName<Ports> brand is a phantom — runtime value is the underlying string\",\n\t\t\t),\n\t\t\ttype: input.type,\n\t\t\tclusterIP: input.clusterIP,\n\t\t\tsessionAffinity: input.sessionAffinity,\n\t\t\tpublishNotReadyAddresses: input.publishNotReadyAddresses,\n\t\t\texternalTrafficPolicy: input.externalTrafficPolicy,\n\t\t\tinternalTrafficPolicy: input.internalTrafficPolicy,\n\t\t}),\n\tfromPodSet: <L extends Readonly<Record<string, string>>>(\n\t\tinput: ServiceFromPodSetInput<L>,\n\t): Manifest.Manifest<K8sService> =>\n\t\tService.make({\n\t\t\tname: input.name,\n\t\t\tnamespace: input.namespace,\n\t\t\tlabels: input.labels,\n\t\t\tannotations: input.annotations,\n\t\t\tselector: input.podSet.labels,\n\t\t\tports: input.ports,\n\t\t\ttype: input.type,\n\t\t\tclusterIP: input.clusterIP,\n\t\t\tsessionAffinity: input.sessionAffinity,\n\t\t\tpublishNotReadyAddresses: input.publishNotReadyAddresses,\n\t\t\texternalTrafficPolicy: input.externalTrafficPolicy,\n\t\t\tinternalTrafficPolicy: input.internalTrafficPolicy,\n\t\t}),\n};\n\nexport interface IngressTLSInput {\n\treadonly hosts?: ReadonlyArray<string>;\n\treadonly secretName: SecretRef<string>;\n}\n\nexport interface IngressInput {\n\treadonly name: string;\n\treadonly namespace: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n\treadonly ingressClassName?: string;\n\treadonly rules?: ReadonlyArray<K8sIngressRule>;\n\treadonly tls?: ReadonlyArray<IngressTLSInput>;\n\treadonly defaultBackend?: K8sIngressBackend;\n}\n\nexport const Ingress = {\n\tmake: (input: IngressInput): Manifest.Manifest<K8sIngress> => {\n\t\tconst resource: K8sIngress = {\n\t\t\tapiVersion: \"networking.k8s.io/v1\",\n\t\t\tkind: \"Ingress\",\n\t\t\tmetadata: {\n\t\t\t\tname: input.name,\n\t\t\t\tnamespace: input.namespace,\n\t\t\t\tlabels: input.labels,\n\t\t\t\tannotations: input.annotations,\n\t\t\t},\n\t\t\tspec: {\n\t\t\t\tingressClassName: input.ingressClassName,\n\t\t\t\trules: unsafeCoerce(input.rules, \"user-supplied Ingress rules; widening from our convenience type to the K8s type\"),\n\t\t\t\ttls: unsafeCoerce<K8sIngressTLS[]>(input.tls, \"Ingress.tls produces K8sIngressTLS with branded secretName\"),\n\t\t\t\tdefaultBackend: unsafeCoerce(input.defaultBackend, \"user-supplied IngressBackend; structural match to K8s type\"),\n\t\t\t},\n\t\t};\n\t\treturn Manifest.make<K8sIngress>(() => Effect.succeed(resource));\n\t},\n\t/**\n\t * TLS entry constructor for `Ingress.make({ tls: [...] })`. Takes a\n\t * branded `SecretRef` so the secret's name can't widen to a raw\n\t * string at the call site.\n\t */\n\ttls: (input: {\n\t\treadonly secretName: SecretRef<string>;\n\t\treadonly hosts?: ReadonlyArray<string>;\n\t}): IngressTLSInput => ({ secretName: input.secretName, hosts: input.hosts }),\n};\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\";\nimport { Effect } from \"effect\";\nimport type {\n\tClusterRole as K8sClusterRole,\n\tClusterRoleBinding as K8sClusterRoleBinding,\n\tNetworkPolicy as K8sNetworkPolicy,\n\tPersistentVolume as K8sPersistentVolume,\n\tPersistentVolumeClaim as K8sPersistentVolumeClaim,\n\tRole as K8sRole,\n\tRoleBinding as K8sRoleBinding,\n} from \"./.generated/k8s-types\";\nimport type { PersistentVolumeSpec as K8sPersistentVolumeSpec } from \"kubernetes-types/core/v1\";\nimport type {\n\tNetworkPolicyEgressRule as K8sNetworkPolicyEgressRule,\n\tNetworkPolicyIngressRule as K8sNetworkPolicyIngressRule,\n} from \"kubernetes-types/networking/v1\";\nimport type { Selector } from \"./selector\";\n\ninterface NamespacedMeta {\n\treadonly name: string;\n\treadonly namespace: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n}\n\ninterface ClusterMeta {\n\treadonly name: string;\n\treadonly labels?: Readonly<Record<string, string>>;\n\treadonly annotations?: Readonly<Record<string, string>>;\n}\n\n/**\n * Standard k8s PV access modes. Constrained to the four documented\n * values so a typo (`\"ReadWriteonce\"`) is a compile-time error.\n */\nexport type PersistentVolumeAccessMode =\n\t| \"ReadWriteOnce\"\n\t| \"ReadOnlyMany\"\n\t| \"ReadWriteMany\"\n\t| \"ReadWriteOncePod\";\n\nexport type PersistentVolumeReclaimPolicy = \"Retain\" | \"Recycle\" | \"Delete\";\n\nexport type PersistentVolumeMode = \"Filesystem\" | \"Block\";\n\n/**\n * Strict input shape for a `PersistentVolume.spec`. Upstream\n * `kubernetes-types` types every field as optional (because the\n * OpenAPI generator emits the entire union), which makes invalid\n * specs (no capacity, no accessModes, no volume source) compile.\n * The fields the kube-apiserver actually requires are required here.\n *\n * Volume-source fields (`hostPath`, `csi`, `nfs`, `local`, etc.) are\n * inherited from the upstream `PersistentVolumeSpec` via `Omit` so\n * users can use whichever source they need. \"At least one source\"\n * isn't enforced statically (TS unions over 20+ variants would be\n * unwieldy) — the kube-apiserver rejects a spec with no source.\n */\nexport interface PersistentVolumeSpecInput\n\textends Omit<\n\t\tK8sPersistentVolumeSpec,\n\t\t\"capacity\" | \"accessModes\" | \"persistentVolumeReclaimPolicy\" | \"volumeMode\" | \"claimRef\"\n\t> {\n\treadonly capacity: { readonly storage: string };\n\treadonly accessModes: ReadonlyArray<PersistentVolumeAccessMode>;\n\treadonly persistentVolumeReclaimPolicy?: PersistentVolumeReclaimPolicy;\n\treadonly volumeMode?: PersistentVolumeMode;\n\treadonly claimRef?: { readonly namespace: string; readonly name: string };\n}\n\nexport interface PersistentVolumeInput extends ClusterMeta {\n\treadonly spec: PersistentVolumeSpecInput;\n}\n\nexport const PersistentVolume = {\n\tmake: (input: PersistentVolumeInput): Manifest.Manifest<K8sPersistentVolume> =>\n\t\tManifest.make<K8sPersistentVolume>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"v1\",\n\t\t\t\tkind: \"PersistentVolume\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\tspec: unsafeCoerce<K8sPersistentVolume[\"spec\"]>(input.spec, \"user-supplied PV spec; structural match to the K8s type\"),\n\t\t\t}),\n\t\t),\n};\n\n/**\n * Strict input shape for a `PersistentVolumeClaim.spec`. Same\n * rationale as `PersistentVolumeSpecInput` — accessModes + a storage\n * request are the fields the apiserver requires.\n */\nexport interface PersistentVolumeClaimSpecInput {\n\treadonly accessModes: ReadonlyArray<PersistentVolumeAccessMode>;\n\treadonly resources: { readonly requests: { readonly storage: string } };\n\treadonly storageClassName?: string;\n\treadonly volumeMode?: PersistentVolumeMode;\n\treadonly volumeName?: string;\n\treadonly selector?: { readonly matchLabels?: Readonly<Record<string, string>> };\n}\n\nexport interface PersistentVolumeClaimInput extends NamespacedMeta {\n\treadonly spec: PersistentVolumeClaimSpecInput;\n}\n\nexport const PersistentVolumeClaim = {\n\tmake: (input: PersistentVolumeClaimInput): Manifest.Manifest<K8sPersistentVolumeClaim> =>\n\t\tManifest.make<K8sPersistentVolumeClaim>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"v1\",\n\t\t\t\tkind: \"PersistentVolumeClaim\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tnamespace: input.namespace,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\tspec: unsafeCoerce<K8sPersistentVolumeClaim[\"spec\"]>(input.spec, \"user-supplied PVC spec; structural match to the K8s type\"),\n\t\t\t}),\n\t\t),\n};\n\nexport interface NetworkPolicyInput extends NamespacedMeta {\n\treadonly spec: K8sNetworkPolicy[\"spec\"];\n}\n\n/**\n * Peer rule for `NetworkPolicy.fromPodSet`. A peer is either a typed\n * `Selector` (matched as `podSelector.matchLabels`), a `namespaceSelector`,\n * or a CIDR block.\n */\nexport interface NetworkPolicyPeer {\n\treadonly podSet?: Selector<Readonly<Record<string, string>>>;\n\treadonly namespaceSelector?: { readonly matchLabels?: Readonly<Record<string, string>> };\n\treadonly ipBlock?: { readonly cidr: string; readonly except?: ReadonlyArray<string> };\n}\n\nexport interface NetworkPolicyIngressRule {\n\treadonly from?: ReadonlyArray<NetworkPolicyPeer>;\n\treadonly ports?: K8sNetworkPolicyIngressRule[\"ports\"];\n}\n\nexport interface NetworkPolicyEgressRule {\n\treadonly to?: ReadonlyArray<NetworkPolicyPeer>;\n\treadonly ports?: K8sNetworkPolicyEgressRule[\"ports\"];\n}\n\n/**\n * NetworkPolicy built from typed `Selector`s. `podSet` drives\n * `spec.podSelector`; ingress/egress peer rules accept further selectors\n * via `from[].podSet` / `to[].podSet`. Peer selectors need not match the\n * owning selector — the typing ties this NetworkPolicy's selection to a\n * single source of truth and lets peers be independently typed.\n */\nexport interface NetworkPolicyFromPodSetInput<L extends Readonly<Record<string, string>>>\n\textends NamespacedMeta {\n\treadonly podSet: Selector<L>;\n\treadonly policyTypes?: ReadonlyArray<\"Ingress\" | \"Egress\">;\n\treadonly ingress?: ReadonlyArray<NetworkPolicyIngressRule>;\n\treadonly egress?: ReadonlyArray<NetworkPolicyEgressRule>;\n}\n\nconst _lowerPeer = (peer: NetworkPolicyPeer): {\n\treadonly podSelector?: { readonly matchLabels?: Readonly<Record<string, string>> };\n\treadonly namespaceSelector?: { readonly matchLabels?: Readonly<Record<string, string>> };\n\treadonly ipBlock?: { readonly cidr: string; readonly except?: ReadonlyArray<string> };\n} => ({\n\t...(peer.podSet !== undefined ? { podSelector: { matchLabels: peer.podSet.labels } } : {}),\n\t...(peer.namespaceSelector !== undefined ? { namespaceSelector: peer.namespaceSelector } : {}),\n\t...(peer.ipBlock !== undefined ? { ipBlock: peer.ipBlock } : {}),\n});\n\nexport const NetworkPolicy = {\n\tmake: (input: NetworkPolicyInput): Manifest.Manifest<K8sNetworkPolicy> =>\n\t\tManifest.make<K8sNetworkPolicy>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"networking.k8s.io/v1\",\n\t\t\t\tkind: \"NetworkPolicy\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tnamespace: input.namespace,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\tspec: input.spec,\n\t\t\t}),\n\t\t),\n\tfromPodSet: <L extends Readonly<Record<string, string>>>(\n\t\tinput: NetworkPolicyFromPodSetInput<L>,\n\t): Manifest.Manifest<K8sNetworkPolicy> => {\n\t\tconst ingress = input.ingress?.map((rule) => ({\n\t\t\tfrom: rule.from?.map(_lowerPeer),\n\t\t\tports: rule.ports,\n\t\t}));\n\t\tconst egress = input.egress?.map((rule) => ({\n\t\t\tto: rule.to?.map(_lowerPeer),\n\t\t\tports: rule.ports,\n\t\t}));\n\t\treturn NetworkPolicy.make({\n\t\t\tname: input.name,\n\t\t\tnamespace: input.namespace,\n\t\t\tlabels: input.labels,\n\t\t\tannotations: input.annotations,\n\t\t\tspec: unsafeCoerce<K8sNetworkPolicy[\"spec\"]>(\n\t\t\t\t{\n\t\t\t\t\tpodSelector: { matchLabels: input.podSet.labels },\n\t\t\t\t\tpolicyTypes: input.policyTypes,\n\t\t\t\t\tingress,\n\t\t\t\t\tegress,\n\t\t\t\t},\n\t\t\t\t\"konfig peers carry readonly arrays; upstream NetworkPolicySpec is mutable but the runtime shape matches\",\n\t\t\t),\n\t\t});\n\t},\n};\n\nexport interface ClusterRoleInput extends ClusterMeta {\n\treadonly rules?: K8sClusterRole[\"rules\"];\n\treadonly aggregationRule?: K8sClusterRole[\"aggregationRule\"];\n}\n\nexport const ClusterRole = {\n\tmake: (input: ClusterRoleInput): Manifest.Manifest<K8sClusterRole> =>\n\t\tManifest.make<K8sClusterRole>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"rbac.authorization.k8s.io/v1\",\n\t\t\t\tkind: \"ClusterRole\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\trules: input.rules,\n\t\t\t\taggregationRule: input.aggregationRule,\n\t\t\t}),\n\t\t),\n};\n\nexport interface ClusterRoleBindingInput extends ClusterMeta {\n\treadonly roleRef: K8sClusterRoleBinding[\"roleRef\"];\n\treadonly subjects?: K8sClusterRoleBinding[\"subjects\"];\n}\n\nexport const ClusterRoleBinding = {\n\tmake: (input: ClusterRoleBindingInput): Manifest.Manifest<K8sClusterRoleBinding> =>\n\t\tManifest.make<K8sClusterRoleBinding>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"rbac.authorization.k8s.io/v1\",\n\t\t\t\tkind: \"ClusterRoleBinding\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\troleRef: input.roleRef,\n\t\t\t\tsubjects: input.subjects,\n\t\t\t}),\n\t\t),\n};\n\nexport interface RoleInput extends NamespacedMeta {\n\treadonly rules?: K8sRole[\"rules\"];\n}\n\nexport const Role = {\n\tmake: (input: RoleInput): Manifest.Manifest<K8sRole> =>\n\t\tManifest.make<K8sRole>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"rbac.authorization.k8s.io/v1\",\n\t\t\t\tkind: \"Role\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tnamespace: input.namespace,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\trules: input.rules,\n\t\t\t}),\n\t\t),\n};\n\nexport interface RoleBindingInput extends NamespacedMeta {\n\treadonly roleRef: K8sRoleBinding[\"roleRef\"];\n\treadonly subjects?: K8sRoleBinding[\"subjects\"];\n}\n\nexport const RoleBinding = {\n\tmake: (input: RoleBindingInput): Manifest.Manifest<K8sRoleBinding> =>\n\t\tManifest.make<K8sRoleBinding>(() =>\n\t\t\tEffect.succeed({\n\t\t\t\tapiVersion: \"rbac.authorization.k8s.io/v1\",\n\t\t\t\tkind: \"RoleBinding\",\n\t\t\t\tmetadata: {\n\t\t\t\t\tname: input.name,\n\t\t\t\t\tnamespace: input.namespace,\n\t\t\t\t\tlabels: input.labels,\n\t\t\t\t\tannotations: input.annotations,\n\t\t\t\t},\n\t\t\t\troleRef: input.roleRef,\n\t\t\t\tsubjects: input.subjects,\n\t\t\t}),\n\t\t),\n};\n","import { brand } from \"@konfig.ts/core\";\nimport type { ConfigMapRef, PvcRef, SecretRef } from \"@konfig.ts/core\";\n\n/**\n * Branded volume name — a string carrying the literal `N` in its\n * phantom. Constructed by the volume factories\n * (`Volume.empty`, `Volume.fromSecret`, …) and `Volume.mountRef`. Lets\n * `VolumeMount<Mounts>` and `Pod` constrain a container's\n * `volumeMounts[i].name` to volumes that the pod actually declares.\n */\ndeclare const VolumeNameBrand: unique symbol;\nexport type VolumeName<N extends string> = string & {\n\treadonly [VolumeNameBrand]: N;\n};\n\nconst _volumeName = <const N extends string>(name: N): VolumeName<N> =>\n\tbrand<VolumeName<N>>(name);\n\nexport interface Volume<N extends string = string> {\n\treadonly name: VolumeName<N>;\n\treadonly secret?: {\n\t\treadonly secretName: string;\n\t\treadonly optional?: boolean;\n\t\treadonly defaultMode?: number;\n\t};\n\treadonly configMap?: {\n\t\treadonly name: string;\n\t\treadonly optional?: boolean;\n\t\treadonly defaultMode?: number;\n\t\treadonly items?: ReadonlyArray<{ readonly key: string; readonly path: string }>;\n\t};\n\treadonly emptyDir?: { readonly medium?: string; readonly sizeLimit?: string };\n\treadonly persistentVolumeClaim?: {\n\t\treadonly claimName: PvcRef<string>;\n\t\treadonly readOnly?: boolean;\n\t};\n\treadonly hostPath?: { readonly path: string; readonly type?: string };\n}\n\nexport interface EmptyVolumeInput<N extends string> {\n\treadonly name: N;\n\treadonly medium?: string;\n\treadonly sizeLimit?: string;\n}\n\nexport interface VolumeFromSecretInput<N extends string> {\n\treadonly name: N;\n\treadonly ref: SecretRef<string>;\n\treadonly optional?: boolean;\n\treadonly defaultMode?: number;\n}\n\nexport interface VolumeFromConfigMapInput<N extends string> {\n\treadonly name: N;\n\treadonly ref: ConfigMapRef<string>;\n\treadonly optional?: boolean;\n\treadonly defaultMode?: number;\n\treadonly items?: ReadonlyArray<{ readonly key: string; readonly path: string }>;\n}\n\nexport interface VolumeFromPvcInput<N extends string, PvcN extends string> {\n\treadonly name: N;\n\treadonly claim: PvcRef<PvcN>;\n\treadonly readOnly?: boolean;\n}\n\n/**\n * `Volume` value namespace.\n *\n * volumes: [\n * Volume.empty({ name: \"config\" }),\n * Volume.fromSecret({ name: \"tls\", ref: tlsSecret.ref }),\n * Volume.fromConfigMap({ name: \"settings\", ref: cfg.ref }),\n * Volume.fromPvc({ name: \"data\", claim: pvc.ref }),\n * ],\n * volumeMounts: [\n * { name: Volume.mountRef(\"config\"), mountPath: \"/etc/conf\" },\n * ],\n *\n * All four constructors capture the literal `name` in the returned\n * `Volume<N>` brand; `Pod` infers the union and constrains each\n * container's `volumeMounts[i].name` to it.\n */\nexport const Volume = {\n\tempty: <const N extends string>(input: EmptyVolumeInput<N>): Volume<N> => ({\n\t\tname: _volumeName(input.name),\n\t\temptyDir: { medium: input.medium, sizeLimit: input.sizeLimit },\n\t}),\n\tfromSecret: <const N extends string>(input: VolumeFromSecretInput<N>): Volume<N> => ({\n\t\tname: _volumeName(input.name),\n\t\tsecret: {\n\t\t\tsecretName: input.ref,\n\t\t\toptional: input.optional,\n\t\t\tdefaultMode: input.defaultMode,\n\t\t},\n\t}),\n\tfromConfigMap: <const N extends string>(input: VolumeFromConfigMapInput<N>): Volume<N> => ({\n\t\tname: _volumeName(input.name),\n\t\tconfigMap: {\n\t\t\tname: input.ref,\n\t\t\toptional: input.optional,\n\t\t\tdefaultMode: input.defaultMode,\n\t\t\titems: input.items,\n\t\t},\n\t}),\n\tfromPvc: <const N extends string, const PvcN extends string>(\n\t\tinput: VolumeFromPvcInput<N, PvcN>,\n\t): Volume<N> => ({\n\t\tname: _volumeName(input.name),\n\t\tpersistentVolumeClaim: { claimName: input.claim, readOnly: input.readOnly },\n\t}),\n\tmountRef: <const N extends string>(name: N): VolumeName<N> => _volumeName(name),\n};\n\n/**\n * Typed container volumeMount. `Mounts` is the union of volume names\n * declared on the surrounding pod; `name` must reference one of them.\n * Bare-number variants don't apply (mounts are always by name).\n */\nexport interface VolumeMount<Mounts extends string = string> {\n\treadonly name: VolumeName<Mounts>;\n\treadonly mountPath: string;\n\treadonly readOnly?: boolean;\n\treadonly subPath?: string;\n\treadonly subPathExpr?: string;\n\treadonly mountPropagation?: string;\n}\n\nexport type VolumeNamesOf<V extends ReadonlyArray<Volume<string>>> = {\n\treadonly [I in keyof V]: V[I] extends Volume<infer N> ? N : never;\n}[number];\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n CronJob as K8sCronJob,\n Deployment as K8sDeployment,\n Job as K8sJob,\n StatefulSet as K8sStatefulSet\n} from \"./.generated/k8s-types\"\nimport type { PodSpecInput } from \"./container\"\nimport type { Selector } from \"./selector\"\n\ninterface WorkloadMeta {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\ninterface SelectorAndTemplate {\n readonly selector: { readonly matchLabels: Readonly<Record<string, string>> }\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n}\n\nexport interface DeploymentInput extends WorkloadMeta, SelectorAndTemplate {\n readonly replicas?: number\n readonly strategy?: unknown\n readonly revisionHistoryLimit?: number\n readonly progressDeadlineSeconds?: number\n readonly minReadySeconds?: number\n}\n\n/**\n * Deployment built from a `Selector`. The selector's labels become both\n * the Deployment's `spec.selector.matchLabels` and the pod template's\n * `metadata.labels` — coherent by construction. Drift between selector\n * and template (the classic \"service has no endpoints\" footgun) is\n * structurally impossible once both consume the same `podSet`.\n */\nexport interface DeploymentFromPodSetInput<L extends Readonly<Record<string, string>>> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly podSet: Selector<L>\n readonly replicas?: number\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n readonly strategy?: unknown\n readonly revisionHistoryLimit?: number\n readonly progressDeadlineSeconds?: number\n readonly minReadySeconds?: number\n}\n\nexport const Deployment = {\n make: (input: DeploymentInput): Manifest.Manifest<K8sDeployment> => {\n const resource: K8sDeployment = {\n apiVersion: \"apps/v1\",\n kind: \"Deployment\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n replicas: input.replicas,\n selector: input.selector,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n ),\n strategy: unsafeCoerce(\n input.strategy,\n \"DeploymentStrategy is escape-hatch unknown; lift to K8s type for serialization\"\n ),\n revisionHistoryLimit: input.revisionHistoryLimit,\n progressDeadlineSeconds: input.progressDeadlineSeconds,\n minReadySeconds: input.minReadySeconds\n }\n }\n return Manifest.make<K8sDeployment>(() => Effect.succeed(resource))\n },\n fromPodSet: <L extends Readonly<Record<string, string>>>(\n input: DeploymentFromPodSetInput<L>\n ): Manifest.Manifest<K8sDeployment> =>\n Deployment.make({\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations,\n replicas: input.replicas,\n selector: { matchLabels: input.podSet.labels },\n template: {\n metadata: {\n // podSet labels are spread LAST so a colliding caller-supplied\n // template label can never shadow a selector label — that would\n // desync the pod template from `spec.selector` and strand the\n // Deployment with zero matching endpoints.\n labels: { ...input.template.metadata?.labels, ...input.podSet.labels },\n annotations: input.template.metadata?.annotations\n },\n spec: input.template.spec\n },\n strategy: input.strategy,\n revisionHistoryLimit: input.revisionHistoryLimit,\n progressDeadlineSeconds: input.progressDeadlineSeconds,\n minReadySeconds: input.minReadySeconds\n })\n}\n\nexport interface StatefulSetInput extends WorkloadMeta, SelectorAndTemplate {\n readonly replicas?: number\n readonly serviceName: string\n readonly volumeClaimTemplates?: ReadonlyArray<unknown>\n readonly podManagementPolicy?: string\n readonly updateStrategy?: unknown\n}\n\nexport const StatefulSet = {\n make: (input: StatefulSetInput): Manifest.Manifest<K8sStatefulSet> => {\n const resource: K8sStatefulSet = {\n apiVersion: \"apps/v1\",\n kind: \"StatefulSet\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n replicas: input.replicas,\n selector: input.selector,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n ),\n serviceName: input.serviceName,\n volumeClaimTemplates: unsafeCoerce(\n input.volumeClaimTemplates,\n \"StatefulSet volumeClaimTemplates is escape-hatch unknown; lift to K8s type\"\n ),\n podManagementPolicy: input.podManagementPolicy,\n updateStrategy: unsafeCoerce(input.updateStrategy, \"StatefulSetUpdateStrategy is escape-hatch unknown\")\n }\n }\n return Manifest.make<K8sStatefulSet>(() => Effect.succeed(resource))\n }\n}\n\nexport interface JobInput extends WorkloadMeta {\n readonly parallelism?: number\n readonly completions?: number\n readonly backoffLimit?: number\n readonly activeDeadlineSeconds?: number\n readonly ttlSecondsAfterFinished?: number\n readonly suspend?: boolean\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n}\n\nexport const Job = {\n make: (input: JobInput): Manifest.Manifest<K8sJob> => {\n const resource: K8sJob = {\n apiVersion: \"batch/v1\",\n kind: \"Job\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n parallelism: input.parallelism,\n completions: input.completions,\n backoffLimit: input.backoffLimit,\n activeDeadlineSeconds: input.activeDeadlineSeconds,\n ttlSecondsAfterFinished: input.ttlSecondsAfterFinished,\n suspend: input.suspend,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n )\n }\n }\n return Manifest.make<K8sJob>(() => Effect.succeed(resource))\n }\n}\n\nexport interface CronJobInput extends WorkloadMeta {\n readonly schedule: string\n readonly concurrencyPolicy?: string\n readonly successfulJobsHistoryLimit?: number\n readonly failedJobsHistoryLimit?: number\n readonly startingDeadlineSeconds?: number\n readonly suspend?: boolean\n readonly jobTemplate: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: {\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n readonly backoffLimit?: number\n readonly activeDeadlineSeconds?: number\n readonly ttlSecondsAfterFinished?: number\n }\n }\n}\n\nexport const CronJob = {\n make: (input: CronJobInput): Manifest.Manifest<K8sCronJob> => {\n const resource: K8sCronJob = {\n apiVersion: \"batch/v1\",\n kind: \"CronJob\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n schedule: input.schedule,\n concurrencyPolicy: input.concurrencyPolicy,\n successfulJobsHistoryLimit: input.successfulJobsHistoryLimit,\n failedJobsHistoryLimit: input.failedJobsHistoryLimit,\n startingDeadlineSeconds: input.startingDeadlineSeconds,\n suspend: input.suspend,\n jobTemplate: unsafeCoerce(\n input.jobTemplate,\n \"konfig CronJob jobTemplate is structurally a K8s JobTemplateSpec body\"\n )\n }\n }\n return Manifest.make<K8sCronJob>(() => Effect.succeed(resource))\n }\n}\n","import type { Manifest, SecretRef } from \"@konfig.ts/core\"\nimport { Manifest as M, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n CronJob as K8sCronJob,\n Deployment as K8sDeployment,\n Ingress as K8sIngress,\n IngressRule as K8sIngressRule,\n Service as K8sService,\n ServiceAccount as K8sServiceAccount,\n ServicePort as K8sServicePort\n} from \"./.generated/k8s-types\"\nimport type { ContainerInput, ContainerSpec } from \"./container\"\nimport { Ingress, type IngressTLSInput, Service } from \"./network\"\nimport type { ServicePortSpec } from \"./ports\"\nimport type { Volume } from \"./volume\"\nimport { CronJob, Deployment } from \"./workload\"\n\n/**\n * Union of port names declared by every `ContainerSpec` in `Cs`. Raw\n * `ContainerInput` entries (no `Container.define`) contribute `never`,\n * so untyped containers don't widen the result — they just don't add\n * any named-port options to the Service. With every container untyped,\n * the union collapses to `never` and `targetPort` is effectively\n * `number`-only, matching Kubernetes' behaviour when no port is named.\n */\ntype _PortNamesOfContainers<Cs extends ReadonlyArray<ContainerInput>> = {\n readonly [K in keyof Cs]: Cs[K] extends ContainerSpec<infer P, string> ? P : never\n}[number]\n\n/**\n * Reloader integration shorthand. Two complementary rotation models:\n *\n * - *Build-time* rotation (re-render → new hash → rolling update). konfig\n * does NOT stamp this automatically; it ships `hashSecretValues` as a\n * helper you attach yourself — feed it your resolved secret values and\n * place the digest into `deployment.podAnnotations`, so a value change\n * flips the pod template and triggers a rollout.\n * - *Runtime* rotation via Stakater's Reloader (operator watches mounted\n * Secrets/ConfigMaps and patches the workload to restart pods on change),\n * selected by the option below.\n *\n * Pick:\n *\n * - `\"off\"` (default) — no Reloader annotation. Pair with a build-time\n * `hashSecretValues` annotation if you accept the redeploy-on-edit model.\n * - `\"stakater\"` — emit `reloader.stakater.com/auto: \"true\"`. Reloader\n * watches every Secret/ConfigMap referenced by the pod spec.\n * - `\"stakater-strict\"` — emit `reloader.stakater.com/auto: \"true\"`\n * plus `reloader.stakater.com/match: \"true\"`, restricting watch\n * to objects with the matching annotation set on them.\n * - `{ secrets, configMaps }` — explicit per-resource lists, emitted\n * as `secret.reloader.stakater.com/reload` /\n * `configmap.reloader.stakater.com/reload` (comma-joined).\n *\n * See packages/k8s/README.md for the trade-off between build-time\n * hashes and runtime reloader.\n */\nexport type ReloaderOption =\n | \"off\"\n | \"stakater\"\n | \"stakater-strict\"\n | {\n readonly secrets?: ReadonlyArray<string>\n readonly configMaps?: ReadonlyArray<string>\n }\n\nconst _reloaderAnnotations = (\n opt: ReloaderOption | undefined\n): Readonly<Record<string, string>> => {\n if (opt === undefined || opt === \"off\") return {}\n if (opt === \"stakater\") return { \"reloader.stakater.com/auto\": \"true\" }\n if (opt === \"stakater-strict\") {\n return {\n \"reloader.stakater.com/auto\": \"true\",\n \"reloader.stakater.com/match\": \"true\"\n }\n }\n const out: Record<string, string> = {}\n if (opt.secrets && opt.secrets.length > 0) {\n out[\"secret.reloader.stakater.com/reload\"] = opt.secrets.join(\",\")\n }\n if (opt.configMaps && opt.configMaps.length > 0) {\n out[\"configmap.reloader.stakater.com/reload\"] = opt.configMaps.join(\",\")\n }\n return out\n}\n\ninterface WebInput<Cs extends ReadonlyArray<ContainerInput>> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n /** Pod-restart-on-rotation integration. See `ReloaderOption`. */\n readonly reloader?: ReloaderOption\n readonly deployment: {\n readonly replicas?: number\n readonly containers: Cs\n readonly volumes?: ReadonlyArray<Volume>\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n readonly serviceAccountName?: string\n readonly podLabels?: Readonly<Record<string, string>>\n readonly podAnnotations?: Readonly<Record<string, string>>\n }\n readonly service: {\n readonly ports: ReadonlyArray<ServicePortSpec<NoInfer<_PortNamesOfContainers<Cs>>>>\n readonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\"\n }\n readonly ingress?: {\n readonly ingressClassName?: string\n readonly rules?: ReadonlyArray<K8sIngressRule>\n readonly tls?: ReadonlyArray<IngressTLSInput>\n readonly annotations?: Readonly<Record<string, string>>\n }\n}\n\nexport const web = <const Cs extends ReadonlyArray<ContainerInput>>(\n input: WebInput<Cs>\n): Manifest.Manifest<\n readonly [K8sDeployment, K8sService] | readonly [K8sDeployment, K8sService, K8sIngress]\n> => {\n const selectorLabels = { app: input.name }\n // selectorLabels are spread LAST so a colliding user pod label can never\n // override the `app` selector — that would desync the pod template from\n // `spec.selector` and leave the Service with zero endpoints.\n const podLabels = { ...input.deployment.podLabels, ...selectorLabels }\n\n const reloaderAnns = _reloaderAnnotations(input.reloader)\n const deployment = Deployment.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: { ...input.annotations, ...reloaderAnns },\n replicas: input.deployment.replicas,\n selector: { matchLabels: selectorLabels },\n template: {\n metadata: { labels: podLabels, annotations: input.deployment.podAnnotations },\n spec: {\n containers: input.deployment.containers,\n volumes: input.deployment.volumes,\n imagePullSecrets: input.deployment.imagePullSecrets,\n serviceAccountName: input.deployment.serviceAccountName\n }\n }\n })\n\n const service = Service.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations,\n selector: selectorLabels,\n type: input.service.type ?? \"ClusterIP\",\n ports: unsafeCoerce<ReadonlyArray<K8sServicePort>>(\n input.service.ports,\n \"ServicePortSpec<Ports> structurally matches K8sServicePort; the PortName<Ports> brand on targetPort is a phantom whose runtime value is the underlying string\"\n )\n })\n\n if (input.ingress === undefined) {\n return M.make((ctx) => Effect.all([deployment.render(ctx), service.render(ctx)], { concurrency: \"unbounded\" }))\n }\n\n const ingress = Ingress.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: { ...input.annotations, ...input.ingress.annotations },\n ingressClassName: input.ingress.ingressClassName,\n rules: input.ingress.rules,\n tls: input.ingress.tls\n })\n\n return M.make((ctx) =>\n Effect.all([deployment.render(ctx), service.render(ctx), ingress.render(ctx)], {\n concurrency: \"unbounded\"\n })\n )\n}\n\ninterface CronInput {\n readonly name: string\n readonly namespace: string\n readonly schedule: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly concurrencyPolicy?: \"Allow\" | \"Forbid\" | \"Replace\"\n readonly successfulJobsHistoryLimit?: number\n readonly failedJobsHistoryLimit?: number\n readonly containers: ReadonlyArray<ContainerInput>\n readonly volumes?: ReadonlyArray<Volume>\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n readonly restartPolicy?: \"OnFailure\" | \"Never\"\n}\n\nexport const cron = (\n input: CronInput\n): Manifest.Manifest<readonly [K8sServiceAccount, K8sCronJob]> => {\n const selectorLabels = { app: input.name }\n\n const sa: Manifest.Manifest<K8sServiceAccount> = M.make<K8sServiceAccount>(() =>\n Effect.succeed({\n apiVersion: \"v1\",\n kind: \"ServiceAccount\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations\n }\n })\n )\n\n const cronJob = CronJob.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations,\n schedule: input.schedule,\n concurrencyPolicy: input.concurrencyPolicy,\n successfulJobsHistoryLimit: input.successfulJobsHistoryLimit,\n failedJobsHistoryLimit: input.failedJobsHistoryLimit,\n jobTemplate: {\n spec: {\n template: {\n metadata: { labels: selectorLabels },\n spec: {\n containers: input.containers,\n volumes: input.volumes,\n imagePullSecrets: input.imagePullSecrets,\n serviceAccountName: input.name,\n restartPolicy: input.restartPolicy ?? \"OnFailure\"\n }\n }\n }\n }\n })\n\n return M.make((ctx) => Effect.all([sa.render(ctx), cronJob.render(ctx)], { concurrency: \"unbounded\" }))\n}\n","import { unsafeCoerce } from \"@konfig.ts/core\";\n\n/**\n * Selector — one source of truth for \"this pod set.\"\n *\n * `Selector<L>` wraps a literal label record and brands it. Resources\n * that *select* pods — Deployment.selector, Service.selector,\n * NetworkPolicy.podSelector, HPA target — take the bundle directly via\n * `Deployment.fromPodSet` / `Service.fromPodSet` / `NetworkPolicy.fromPodSet`\n * so a drift across three resources (the classic \"service has no\n * endpoints / netpol denies everything\" bug) becomes a compile error.\n *\n * `Workload.web` already keeps these labels coherent internally; the\n * Selector is the win when users go off-script: StatefulSet, DaemonSet,\n * cross-namespace selectors, or wiring a NetworkPolicy from app A to\n * peer pods B.\n */\ndeclare const SelectorBrand: unique symbol;\n\nexport interface Selector<L extends Readonly<Record<string, string>>> {\n\treadonly [SelectorBrand]: L;\n\treadonly labels: L;\n}\n\n/**\n * `Selector` value namespace.\n *\n * const apiPods = Selector.make({ app: \"api\", tier: \"web\" });\n */\nexport const Selector = {\n\tmake: <const L extends Readonly<Record<string, string>>>(labels: L): Selector<L> =>\n\t\tunsafeCoerce<Selector<L>>(\n\t\t\t{ labels },\n\t\t\t\"SelectorBrand is a unique-symbol phantom — no runtime value; runtime shape is { labels }\",\n\t\t),\n};\n\nexport type SelectorLabels<S> = S extends Selector<infer L> ? L : never;\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\";\nimport { Effect } from \"effect\";\nimport type {\n\tDeployment as K8sDeployment,\n\tNetworkPolicy as K8sNetworkPolicy,\n\tService as K8sService,\n} from \"./.generated/k8s-types\";\nimport { NetworkPolicy, type NetworkPolicyFromPodSetInput } from \"./policy\";\nimport type { Selector } from \"./selector\";\nimport { Service, type ServiceFromPodSetInput } from \"./network\";\nimport { Deployment, type DeploymentFromPodSetInput } from \"./workload\";\n\n/**\n * `PodSet.define` input. Drives a coherent Deployment + Service +\n * (optional) NetworkPolicy from a single `Selector` — every resource\n * derives its selector from `podSet`, so the trio cannot drift.\n */\nexport interface DefinePodSetInput<L extends Readonly<Record<string, string>>> {\n\treadonly podSet: Selector<L>;\n\treadonly deployment: Omit<DeploymentFromPodSetInput<L>, \"podSet\">;\n\treadonly service?: Omit<ServiceFromPodSetInput<L>, \"podSet\">;\n\treadonly netPol?: Omit<NetworkPolicyFromPodSetInput<L>, \"podSet\">;\n}\n\ntype PodSetOutput =\n\t| readonly [K8sDeployment, K8sService]\n\t| readonly [K8sDeployment, K8sService, K8sNetworkPolicy]\n\t| readonly [K8sDeployment, K8sNetworkPolicy]\n\t| readonly [K8sDeployment];\n\n/**\n * `PodSet` value namespace.\n *\n * const trio = PodSet.define({\n * podSet: redisCachePods,\n * deployment: { ... },\n * service: { ... },\n * netPol: { ... },\n * });\n *\n * Umbrella over `Deployment.fromPodSet`, `Service.fromPodSet`, and\n * `NetworkPolicy.fromPodSet` — emits whichever subset of the trio the\n * input specifies, all rooted at one `Selector`.\n */\nexport const PodSet = {\n\tdefine: <L extends Readonly<Record<string, string>>>(\n\t\tinput: DefinePodSetInput<L>,\n\t): Manifest.Manifest<PodSetOutput> => {\n\t\tconst deployment = Deployment.fromPodSet({ podSet: input.podSet, ...input.deployment });\n\t\tconst service =\n\t\t\tinput.service !== undefined\n\t\t\t\t? Service.fromPodSet({ podSet: input.podSet, ...input.service })\n\t\t\t\t: undefined;\n\t\tconst netPol =\n\t\t\tinput.netPol !== undefined\n\t\t\t\t? NetworkPolicy.fromPodSet({ podSet: input.podSet, ...input.netPol })\n\t\t\t\t: undefined;\n\n\t\treturn Manifest.make<PodSetOutput>((ctx) =>\n\t\t\tEffect.gen(function* () {\n\t\t\t\tconst d = yield* deployment.render(ctx);\n\t\t\t\tconst s = service !== undefined ? yield* service.render(ctx) : undefined;\n\t\t\t\tconst n = netPol !== undefined ? yield* netPol.render(ctx) : undefined;\n\t\t\t\tconst reason = \"tuple element types are statically known per branch; the array literal is widened by TS, the brand-free runtime shape matches the typed tuple\";\n\t\t\t\tif (s !== undefined && n !== undefined)\n\t\t\t\t\treturn unsafeCoerce<readonly [K8sDeployment, K8sService, K8sNetworkPolicy]>([d, s, n], reason);\n\t\t\t\tif (s !== undefined) return unsafeCoerce<readonly [K8sDeployment, K8sService]>([d, s], reason);\n\t\t\t\tif (n !== undefined) return unsafeCoerce<readonly [K8sDeployment, K8sNetworkPolicy]>([d, n], reason);\n\t\t\t\treturn unsafeCoerce<readonly [K8sDeployment]>([d], reason);\n\t\t\t}),\n\t\t);\n\t},\n};\n","\nexport * as K8s from \"./.generated/k8s-types\";\nexport {\n\tContainer,\n\ttype ContainerInput,\n\ttype ContainerSpec,\n\ttype DefineContainerInput,\n\ttype DefinedPod,\n\ttype DefinePodInput,\n\tPod,\n\ttype PodSpecInput,\n} from \"./container\";\nexport {\n\ttype ContainerPort,\n\ttype ContainerProtocol,\n\ttype ExecAction,\n\ttype GrpcAction,\n\ttype HttpGetAction,\n\ttype HttpHeader,\n\ttype NamesOf,\n\tPort,\n\ttype PortInput,\n\ttype PortName,\n\ttype ProbeTarget,\n\ttype ServicePortSpec,\n\ttype TcpSocketAction,\n} from \"./ports\";\n\nexport {\n\ttype ConfigMapEnvInput,\n\tEnvVar,\n\ttype EnvVarSource,\n\ttype RawEnvInput,\n\ttype SecretEnvForPodInput,\n\ttype SecretEnvInput,\n\ttype ValueEnvInput,\n} from \"./env\";\nexport {\n\tConfigMap,\n\ttype ConfigMapInput,\n\ttype ConfigMapManifest,\n\tNamespace,\n\ttype NamespaceInput,\n\ttype NamespaceManifest,\n\ttype SecretInput,\n\ttype SecretManifest,\n\tServiceAccount,\n\ttype ServiceAccountInput,\n\ttype ServiceAccountManifest,\n} from \"./identity\";\nimport {\n\tEnvironment as _EnvironmentContract,\n\truntime as envRuntime,\n\tSecret as _SecretContract,\n} from \"@konfig.ts/env\";\nimport { Secret as _SecretIdentity } from \"./identity\";\nimport { bindSecret } from \"./secretBind\";\nimport { bindEnvironment } from \"./environmentBind\";\n\n/**\n * `Secret` value namespace — merges the env-contracts side (`define`)\n * with the K8s side (`make`, `bind`, identity helpers). Importing\n * `Secret` from `@konfig.ts/k8s` gives you the full surface:\n *\n * Secret.define({ name, namespace, env }) — env contract (from @konfig.ts/env)\n * Secret.make({ name, namespace, stringData }) — K8s Secret manifest\n * Secret.bind({ secret, backend, source }) — env-to-manifest binder\n */\nexport const Secret = { ..._SecretContract, ..._SecretIdentity, bind: bindSecret };\n\n/**\n * `Environment` value namespace — merges `define` (env-contracts) with\n * `bind` + `runtime` (K8s). The same `Environment` symbol carries the\n * declaration, the manifest binder, and the runtime decoder.\n */\nexport const Environment = {\n\t..._EnvironmentContract,\n\tbind: bindEnvironment,\n\truntime: envRuntime,\n};\nexport type {\n\tBindSecretInput,\n\tDeclaredSecret,\n} from \"./secretBind\";\nexport type {\n\tBindEnvironmentInput,\n\tDeclaredDownward,\n\tDeclaredEnvironment,\n\tDeclaredLiteral,\n\tDeclaredMember,\n\tHasSecrets,\n\tSecretMemberOptions,\n\tSecretMemberOptionsFor,\n\tSecretMembersOpts,\n} from \"./environmentBind\";\nexport {\n\ttype BackendEmitInput,\n\tBackendSourceMissing,\n\ttype BackendTag,\n\ttype SecretBackend,\n} from \"./backend\";\nexport { NativeSecret, type NativeSecretOptions } from \"./nativeSecret\";\nexport { hashSecretValues, type HashSecretValuesInput } from \"./podHash\";\nexport {\n\tIngress,\n\ttype IngressInput,\n\ttype IngressTLSInput,\n\tService,\n\ttype ServiceFromContainerInput,\n\ttype ServiceFromPodSetInput,\n\ttype ServiceInput,\n} from \"./network\";\nexport {\n\tClusterRole,\n\tClusterRoleBinding,\n\ttype ClusterRoleBindingInput,\n\ttype ClusterRoleInput,\n\tNetworkPolicy,\n\ttype NetworkPolicyEgressRule,\n\ttype NetworkPolicyFromPodSetInput,\n\ttype NetworkPolicyIngressRule,\n\ttype NetworkPolicyInput,\n\ttype NetworkPolicyPeer,\n\tPersistentVolume,\n\tPersistentVolumeClaim,\n\ttype PersistentVolumeClaimInput,\n\ttype PersistentVolumeInput,\n\tRole,\n\tRoleBinding,\n\ttype RoleBindingInput,\n\ttype RoleInput,\n} from \"./policy\";\nexport type { ConfigMapRefName, PvcRefName, SecretRefName } from \"./refs\";\nexport { ConfigMapRef, PvcRef, SecretRef, ServiceAccountRef } from \"./refs\";\nexport { Volume } from \"./volume\";\nexport type {\n\tEmptyVolumeInput,\n\tVolumeFromConfigMapInput,\n\tVolumeFromPvcInput,\n\tVolumeFromSecretInput,\n\tVolumeMount,\n\tVolumeName,\n\tVolumeNamesOf,\n} from \"./volume\";\nexport {\n\tCronJob,\n\ttype CronJobInput,\n\tDeployment,\n\ttype DeploymentFromPodSetInput,\n\ttype DeploymentInput,\n\tJob,\n\ttype JobInput,\n\tStatefulSet,\n\ttype StatefulSetInput,\n} from \"./workload\";\n\nexport * as Workload from \"./workloadHelpers\";\nexport { Selector } from \"./selector\";\nexport type { SelectorLabels } from \"./selector\";\nexport { type DefinePodSetInput, PodSet } from \"./podSet\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["ServiceAccountRefValue","ConfigMapRefValue","Secret","SecretRefValue","SecretRefValue","L","M","_SecretContract","_SecretIdentity","_EnvironmentContract","envRuntime"],"sources":["../src/.generated/k8s-types/index.ts","../src/container.ts","../src/ports.ts","../src/env.ts","../src/refs.ts","../src/identity.ts","../src/secretBind.ts","../src/environmentBind.ts","../src/backend.ts","../src/nativeSecret.ts","../src/network.ts","../src/podHash.ts","../src/policy.ts","../src/volume.ts","../src/workload.ts","../src/podSet.ts","../src/selector.ts","../src/workloadHelpers.ts","../src/index.ts"],"sourcesContent":["// Pinned re-export of Kubernetes API types. The directory name is\n// historical — we don't regenerate from OpenAPI; we re-export the\n// pinned `kubernetes-types` package, which is itself a stable mirror\n// of the upstream Kubernetes Go types.\n//\n// Version policy: `kubernetes-types` is pinned to an exact patch\n// version in packages/k8s/package.json — no caret. The minor\n// (currently 1.30) tracks the cluster minor we test against. Bumping\n// is intentional: read upstream release notes, run `bun run check &&\n// bun run test`, and update CHANGELOG.\n//\n// Each export here is the K8s API type as-is. konfig wrappers (e.g.\n// `ContainerInput` in container.ts) accept a wider, branded shape\n// and lower into these types when emitting manifests.\n\nexport type { Deployment, DeploymentSpec, StatefulSet, StatefulSetSpec } from \"kubernetes-types/apps/v1\"\n\nexport type { CronJob, Job, JobSpec } from \"kubernetes-types/batch/v1\"\nexport type {\n ConfigMap,\n Container,\n ContainerPort,\n EnvVar,\n EnvVarSource,\n LocalObjectReference,\n Namespace,\n PersistentVolume,\n PersistentVolumeClaim,\n PodSpec,\n PodTemplateSpec,\n Secret,\n Service,\n ServiceAccount,\n ServicePort,\n Volume,\n VolumeMount\n} from \"kubernetes-types/core/v1\"\nexport type { ObjectMeta } from \"kubernetes-types/meta/v1\"\nexport type { Ingress, IngressRule, IngressSpec, IngressTLS, NetworkPolicy } from \"kubernetes-types/networking/v1\"\nexport type { ClusterRole, ClusterRoleBinding, Role, RoleBinding } from \"kubernetes-types/rbac/v1\"\n","import type { BuiltImageRef, SecretRef, ServiceAccountRef } from \"@konfig.ts/core\"\nimport { unsafeCoerce } from \"@konfig.ts/core\"\nimport type { Container as K8sContainer, PodSpec as K8sPodSpec } from \"./.generated/k8s-types\"\nimport type { EnvVar } from \"./env\"\nimport type { ContainerPort, NamesOf, ProbeTarget } from \"./ports\"\nimport type { Volume, VolumeMount, VolumeNamesOf } from \"./volume\"\n\n/**\n * Container input — extends the full K8s Container API. Konfig's\n * branded helpers (`EnvVar.value`, `EnvVar.fromSecret`,\n * `EnvVar.fromConfigMap`) produce `EnvVar` instances whose runtime\n * shape matches `K8sEnvVar`; the override\n * here narrows the field to readonly + the branded helper output so\n * `secretKeyRef.name` carries its `SecretRef<N>` brand at construction\n * time.\n *\n * `image` is overridden as required (K8s lets it be optional for\n * higher-level controllers that default it; konfig wants every\n * container to have an explicit image).\n *\n * `ports[i].name` accepts the branded `PortName<string>` from `Port.make(...)`\n * as well as a raw string; the typed builder `Container` is the\n * link that captures the literal name union for cross-reference checks.\n */\nexport interface ContainerInput extends\n Omit<\n K8sContainer,\n | \"env\"\n | \"image\"\n | \"ports\"\n | \"readinessProbe\"\n | \"livenessProbe\"\n | \"startupProbe\"\n | \"volumeMounts\"\n >\n{\n /**\n * Container image. Accepts a raw string (escape hatch for vendor\n * images: `ghcr.io/bitnami/postgresql:16.0.0`) or a `BuiltImageRef<App>`\n * produced by `Dep.builtImageRef` / `Dep.provideImage`. The branded\n * path ties the workload into the dep graph — a workload referencing\n * an image whose build module isn't in the composition fails at\n * `AppOfApps.entrypoint`.\n */\n readonly image: string | BuiltImageRef<string>\n readonly env?: ReadonlyArray<EnvVar>\n readonly ports?: ReadonlyArray<\n ContainerPort | {\n readonly containerPort: number\n readonly name?: string\n readonly protocol?: \"TCP\" | \"UDP\" | \"SCTP\"\n }\n >\n /**\n * Probes accept either the upstream K8s shape or konfig's branded\n * `ProbeTarget<string>` (from `Container`). The two are\n * structurally close — the union lets a `ContainerSpec` flow\n * through `Workload.web`'s containers slot without a cast.\n */\n readonly readinessProbe?: K8sContainer[\"readinessProbe\"] | ProbeTarget<string>\n readonly livenessProbe?: K8sContainer[\"livenessProbe\"] | ProbeTarget<string>\n readonly startupProbe?: K8sContainer[\"startupProbe\"] | ProbeTarget<string>\n /**\n * Volume mounts accept the upstream K8s shape or konfig's branded\n * `VolumeMount<string>` (from `Container` / `mountRef`). Same\n * rationale as the probe widening above.\n */\n readonly volumeMounts?:\n | K8sContainer[\"volumeMounts\"]\n | ReadonlyArray<VolumeMount<string>>\n}\n\n/**\n * Strongly-typed container builder. Captures the union of named ports\n * declared via `port({ name, containerPort })` as a phantom type\n * parameter, then constrains every probe's `port` field to that union.\n *\n * Pair with `Service.fromContainer({ forContainer })` in `network.ts`\n * to link a Service's `targetPort` to the same union — a typo or\n * undeclared port name is a compile error.\n */\nexport interface ContainerSpec<Ports extends string = string, Mounts extends string = string> extends\n Omit<\n ContainerInput,\n \"ports\" | \"readinessProbe\" | \"livenessProbe\" | \"startupProbe\" | \"volumeMounts\"\n >\n{\n readonly name: string\n readonly image: string\n readonly ports: ReadonlyArray<ContainerPort<Ports>>\n readonly readinessProbe?: ProbeTarget<Ports>\n readonly livenessProbe?: ProbeTarget<Ports>\n readonly startupProbe?: ProbeTarget<Ports>\n readonly volumeMounts?: ReadonlyArray<VolumeMount<Mounts>>\n readonly __portNames?: Ports\n readonly __mountNames?: Mounts\n}\n\nexport interface DefineContainerInput<\n Ports extends ReadonlyArray<ContainerPort<string>>,\n Mounts extends ReadonlyArray<VolumeMount<string>>,\n Envs extends ReadonlyArray<EnvVar<string>>\n> extends\n Omit<\n ContainerInput,\n \"ports\" | \"readinessProbe\" | \"livenessProbe\" | \"startupProbe\" | \"volumeMounts\" | \"env\"\n >\n{\n readonly name: string\n readonly image: string\n readonly ports: Ports\n readonly readinessProbe?: ProbeTarget<NamesOf<Ports>>\n readonly livenessProbe?: ProbeTarget<NamesOf<Ports>>\n readonly startupProbe?: ProbeTarget<NamesOf<Ports>>\n readonly volumeMounts?: Mounts\n readonly env?: Envs & EnvDupCheck<Envs>\n}\n\ntype MountNamesOf<M extends ReadonlyArray<VolumeMount<string>>> = {\n readonly [I in keyof M]: M[I] extends VolumeMount<infer N> ? N : never\n}[number]\n\ntype _EnvNameOf<X> = X extends EnvVar<infer N> ? N : never\n\n/**\n * Union of any literal env-var names that appear more than once in `Envs`.\n * Computes the intersection of pairwise names — if `Envs[I]` and `Envs[J]`\n * share a literal name (i ≠ j), that name leaks into the union. Empty\n * when every name is unique.\n */\ntype DuplicateEnvNames<Envs extends ReadonlyArray<EnvVar<string>>> = {\n [I in keyof Envs]: {\n [J in keyof Envs]: J extends I ? never\n : _EnvNameOf<Envs[I]> & _EnvNameOf<Envs[J]> extends never ? never\n : _EnvNameOf<Envs[I]> & _EnvNameOf<Envs[J]>\n }[number]\n}[number]\n\n/**\n * Empty (`unknown`) when `Envs` has no duplicate names; otherwise an\n * inline object type whose required `_konfig_duplicate_env_names`\n * property carries a template-literal hint sentence. Intersected with\n * the `env` slot, an unmet property surfaces the sentence inline in the\n * TS error — far more discoverable than a runtime \"last-wins\" surprise.\n */\ntype EnvDupCheck<Envs extends ReadonlyArray<EnvVar<string>>> = [DuplicateEnvNames<Envs>] extends [never] ? unknown\n : {\n readonly _konfig_duplicate_env_names: `Duplicate env name(s): \"${DuplicateEnvNames<\n Envs\n >}\". K8s silently last-wins; rename one of the colliding entries or remove the manual valueEnv that shadows another producer.`\n }\n\n/**\n * `Container` value namespace.\n *\n * const apiContainer = Container.define({\n * name: \"api\",\n * image: apiImage,\n * ports: [Port.make({ name: \"http\", containerPort: 8080 })],\n * readinessProbe: { httpGet: { port: Port.ref(\"http\") } },\n * env: [...],\n * });\n *\n * `Container.define` captures the union of named ports (from\n * `Port.make`) as `Ports`, the union of mounted volume names (from\n * `Volume.mountRef`) as `Mounts`, and validates that the `env` list\n * has no duplicate env-var names. The first two phantoms travel on\n * `ContainerSpec`; `Pod.define` checks the container's Mounts against\n * the pod's declared volume names.\n *\n * Duplicate env names are caught at the call site via a template-literal\n * error message — see `EnvDupCheck`. With no volumeMounts and no env,\n * all phantoms collapse to `never` so the container slots into any pod.\n */\nexport const Container = {\n define: <\n const Ports extends ReadonlyArray<ContainerPort<string>>,\n const Mounts extends ReadonlyArray<VolumeMount<string>> = readonly [],\n const Envs extends ReadonlyArray<EnvVar<string>> = readonly []\n >(\n input: DefineContainerInput<Ports, Mounts, Envs>\n ): ContainerSpec<NamesOf<Ports>, MountNamesOf<Mounts>> => {\n type P = NamesOf<Ports>\n type M = MountNamesOf<Mounts>\n const out: ContainerSpec<P, M> = {\n ...input,\n ports: unsafeCoerce<ReadonlyArray<ContainerPort<P>>>(\n input.ports,\n \"Ports tuple's element brands are the same PortName<N>; widening Ports → readonly ContainerPort<P>[] only changes the static shape, not the runtime values\"\n ),\n readinessProbe: input.readinessProbe,\n livenessProbe: input.livenessProbe,\n startupProbe: input.startupProbe,\n volumeMounts: unsafeCoerce<ReadonlyArray<VolumeMount<M>> | undefined>(\n input.volumeMounts,\n \"Mounts tuple's element brands are the same VolumeMount<N>; widening Mounts → readonly VolumeMount<M>[] preserves runtime shape\"\n ),\n env: unsafeCoerce<ReadonlyArray<EnvVar<string>> | undefined>(\n input.env,\n \"EnvDupCheck<Envs> intersection vanishes at runtime; the runtime value is the original EnvVar[]\"\n )\n }\n return out\n }\n}\n\n/**\n * `Pod.define` input. The pod declares a tuple of `Volume`s and lists\n * containers whose `Mounts` phantom is checked against the declared\n * volume names via `NoInfer`. A container referencing an undeclared\n * volume — or a typo — fails at the call site rather than at pod-startup\n * time with \"container references volume not found.\"\n */\nexport interface DefinePodInput<V extends ReadonlyArray<Volume<string>>> {\n readonly volumes: V\n readonly containers: ReadonlyArray<ContainerSpec<string, NoInfer<VolumeNamesOf<V>>>>\n readonly initContainers?: ReadonlyArray<ContainerSpec<string, NoInfer<VolumeNamesOf<V>>>>\n}\n\nexport interface DefinedPod<MountNames extends string> {\n readonly volumes: ReadonlyArray<Volume<MountNames>>\n readonly containers: ReadonlyArray<ContainerSpec<string, MountNames>>\n readonly initContainers?: ReadonlyArray<ContainerSpec<string, MountNames>>\n}\n\n/**\n * Pod spec input — extends K8s PodSpec but tightens the fields where\n * konfig adds brand checking: `imagePullSecrets`, `serviceAccountName`,\n * and `volumes` (the helpers in `volume.ts` produce konfig `Volume`\n * objects that lower to K8s `Volume`).\n */\nexport interface PodSpecInput extends\n Omit<\n K8sPodSpec,\n | \"containers\"\n | \"initContainers\"\n | \"volumes\"\n | \"imagePullSecrets\"\n | \"serviceAccountName\"\n >\n{\n readonly containers: ReadonlyArray<ContainerInput>\n readonly initContainers?: ReadonlyArray<ContainerInput>\n readonly volumes?: ReadonlyArray<Volume>\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n readonly serviceAccountName?: ServiceAccountRef<string> | string\n}\n\n/**\n * `Pod` value namespace.\n *\n * const pod = Pod.define({\n * volumes: [Volume.empty({ name: \"config\" })],\n * containers: [Container.define({ ..., volumeMounts: [...] })],\n * });\n *\n * imagePullSecrets: [Pod.imagePullSecret(ghcrRef)],\n *\n * - `Pod.define(input)` ties container `volumeMounts[i].name` to the\n * pod's declared volume names via `NoInfer`.\n * - `Pod.imagePullSecret(ref)` returns the `{ name: SecretRef }` entry\n * consumed by Deployment / StatefulSet / Job / CronJob workloads.\n */\nexport const Pod = {\n define: <const V extends ReadonlyArray<Volume<string>>>(\n input: DefinePodInput<V>\n ): DefinedPod<VolumeNamesOf<V>> => ({\n volumes: unsafeCoerce<ReadonlyArray<Volume<VolumeNamesOf<V>>>>(\n input.volumes,\n \"V tuple's elements are Volume<N>; widening V → readonly Volume<VolumeNamesOf<V>>[] is a structural relaxation, runtime value unchanged\"\n ),\n containers: input.containers,\n initContainers: input.initContainers\n }),\n imagePullSecret: (ref: SecretRef<string>): { readonly name: SecretRef<string> } => ({\n name: ref\n })\n}\n","import { brand } from \"@konfig.ts/core\"\n\n/**\n * Branded port name — a string carrying the literal `N` in its type.\n * Constructed by `Port.make({ name, containerPort })` and `Port.ref(name)`.\n * The brand lets probes and Service `targetPort` constrain their\n * `port` field to a member of the container's declared port-name union\n * rather than `string`.\n */\ndeclare const PortNameBrand: unique symbol\nexport type PortName<N extends string> = string & {\n readonly [PortNameBrand]: N\n}\n\nconst _portName = <const N extends string>(name: N): PortName<N> => brand<PortName<N>>(name)\n\nexport type ContainerProtocol = \"TCP\" | \"UDP\" | \"SCTP\"\n\nexport interface ContainerPort<N extends string = string> {\n readonly containerPort: number\n readonly name?: PortName<N>\n readonly protocol?: ContainerProtocol\n readonly hostPort?: number\n readonly hostIP?: string\n}\n\nexport interface PortInput<N extends string> {\n readonly name: N\n readonly containerPort: number\n readonly protocol?: ContainerProtocol\n readonly hostPort?: number\n readonly hostIP?: string\n}\n\n/**\n * `Port` value namespace.\n *\n * ports: [Port.make({ name: \"http\", containerPort: 8080 })],\n * readinessProbe: { httpGet: { port: Port.ref(\"http\") } },\n *\n * - `Port.make(input)` constructs a named container port; the literal\n * `name` is captured in the returned `ContainerPort<N>` brand so\n * `Container` can infer the port-name union and constrain\n * cross-references (probes, Service.targetPort).\n * - `Port.ref(name)` returns the brand alone, for probe targets and\n * `targetPort` references that need to name an existing declared port.\n */\nexport const Port = {\n make: <const N extends string>(input: PortInput<N>): ContainerPort<N> => ({\n containerPort: input.containerPort,\n name: _portName(input.name),\n protocol: input.protocol,\n hostPort: input.hostPort,\n hostIP: input.hostIP\n }),\n ref: <const N extends string>(name: N): PortName<N> => _portName(name)\n}\n\nexport interface HttpHeader {\n readonly name: string\n readonly value: string\n}\n\nexport interface HttpGetAction<Ports extends string> {\n readonly path?: string\n readonly port: number | PortName<Ports>\n readonly host?: string\n readonly scheme?: \"HTTP\" | \"HTTPS\"\n readonly httpHeaders?: ReadonlyArray<HttpHeader>\n}\n\nexport interface TcpSocketAction<Ports extends string> {\n readonly port: number | PortName<Ports>\n readonly host?: string\n}\n\nexport interface GrpcAction<Ports extends string> {\n readonly port: number | PortName<Ports>\n readonly service?: string\n}\n\nexport interface ExecAction {\n readonly command: ReadonlyArray<string>\n}\n\n/**\n * Probe target — `port` references on httpGet/tcpSocket/grpc are\n * constrained to `Ports`, the union of names declared on the owning\n * container. A bare number is always accepted; only the named variant\n * is checked.\n */\nexport interface ProbeTarget<Ports extends string> {\n readonly httpGet?: HttpGetAction<Ports>\n readonly tcpSocket?: TcpSocketAction<Ports>\n readonly grpc?: GrpcAction<Ports>\n readonly exec?: ExecAction\n readonly initialDelaySeconds?: number\n readonly periodSeconds?: number\n readonly timeoutSeconds?: number\n readonly successThreshold?: number\n readonly failureThreshold?: number\n readonly terminationGracePeriodSeconds?: number\n}\n\nexport type NamesOf<P extends ReadonlyArray<unknown>> = {\n readonly [K in keyof P]: P[K] extends ContainerPort<infer N> ? N : never\n}[number]\n\n/**\n * Service-port input bound to a container's port-name union. `targetPort`\n * accepts a bare number or a `PortName<Ports>`. The `Ports` parameter is\n * locked by `forContainer` on `Service.fromContainer`; use `Port.ref(name)`\n * to reference declared ports.\n */\nexport interface ServicePortSpec<Ports extends string> {\n readonly name?: string\n readonly port: number\n readonly targetPort: number | PortName<Ports>\n readonly protocol?: ContainerProtocol\n readonly appProtocol?: string\n readonly nodePort?: number\n}\n","import type { ConfigMapRef, SecretRef } from \"@konfig.ts/core\"\n\nexport interface EnvVarSource {\n readonly secretKeyRef?: {\n readonly name: string\n readonly key: string\n readonly optional?: boolean\n }\n readonly configMapKeyRef?: {\n readonly name: string\n readonly key: string\n readonly optional?: boolean\n }\n readonly fieldRef?: { readonly fieldPath: string; readonly apiVersion?: string }\n readonly resourceFieldRef?: { readonly containerName?: string; readonly resource: string }\n}\n\n/**\n * Container env-var entry. The phantom `N` records the literal env-var\n * name at the type level so `Container` can detect duplicates\n * across the entry list. The default `N = string` preserves loose-typed\n * call sites.\n */\nexport interface EnvVarShape<N extends string = string> {\n readonly name: N\n readonly value?: string\n readonly valueFrom?: EnvVarSource\n}\n\nexport interface ValueEnvInput<N extends string> {\n readonly name: N\n readonly value: string\n}\n\nexport interface SecretEnvInput<EnvName extends string, N extends string, K extends string> {\n readonly name: EnvName\n readonly ref: SecretRef<N, K>\n /**\n * Constrained to the keys carried by `ref`. `NoInfer` locks `K` to\n * whatever the ref declares, so the typo `key: \"passowrd\"` fails at\n * compile time when the ref's K is `\"url\" | \"username\" | \"password\"`.\n * Refs constructed with the default `K = string` accept any string.\n */\n readonly key: NoInfer<K>\n readonly optional?: boolean\n}\n\nexport interface SecretEnvForPodInput<\n EnvName extends string,\n N extends string,\n K extends string,\n Ns extends string\n> {\n readonly name: EnvName\n /**\n * Ref whose namespace slot must match `podNamespace`. Pass refs that\n * came from `Secret.make({ namespace })` in the same namespace as\n * the consuming pod. For legitimate cross-namespace cases, widen\n * via `SecretRef.unsafeReNamespace(ref)` first.\n */\n readonly ref: SecretRef<N, K, NoInfer<Ns>>\n readonly key: NoInfer<K>\n readonly podNamespace: Ns\n readonly optional?: boolean\n}\n\nexport interface ConfigMapEnvInput<EnvName extends string, N extends string, K extends string> {\n readonly name: EnvName\n readonly ref: ConfigMapRef<N, K>\n /**\n * Constrained to the keys carried by `ref`. `NoInfer` locks `K` to\n * whatever the ref declares — typos like `key: \"passwrod\"` fail at\n * compile time when the ref's K is `\"HOST\" | \"PORT\" | \"LOG_LEVEL\"`.\n * Refs constructed with the default `K = string` accept any string.\n */\n readonly key: NoInfer<K>\n readonly optional?: boolean\n}\n\nexport interface RawEnvInput<N extends string> {\n readonly name: N\n readonly value?: string\n readonly valueFrom?: EnvVarSource\n}\n\n/**\n * `EnvVar` value namespace.\n *\n * env: [\n * EnvVar.value({ name: \"PORT\", value: \"8080\" }),\n * EnvVar.fromSecret({ name: \"DB_URL\", ref: dbCreds.ref, key: \"url\" }),\n * EnvVar.fromSecretForPod({\n * name: \"DB_URL_PRIMARY\", ref: dbCreds.ref, key: \"url\",\n * podNamespace: \"app\",\n * }),\n * EnvVar.fromConfigMap({ name: \"NEW_UI\", ref: flags.ref, key: \"NEW_UI\" }),\n * EnvVar.raw({ name: \"POD_NAME\", valueFrom: { fieldRef: ... } }),\n * ]\n *\n * Each constructor captures the literal env-var name (`N`) so\n * `Container` can detect duplicate entries across the env list.\n */\nexport const EnvVar = {\n value: <const N extends string>(input: ValueEnvInput<N>): EnvVar<N> => ({\n name: input.name,\n value: input.value\n }),\n fromSecret: <const EnvName extends string, N extends string, K extends string = string>(\n input: SecretEnvInput<EnvName, N, K>\n ): EnvVar<EnvName> => ({\n name: input.name,\n valueFrom: {\n secretKeyRef: { name: input.ref, key: input.key, optional: input.optional }\n }\n }),\n /**\n * Namespace-checked variant. The ref's namespace slot (`Ns`) must\n * match `podNamespace`. Catches \"pod in namespace A references a\n * Secret in namespace B\" at compile time — kube-apiserver only\n * resolves `valueFrom.secretKeyRef` against the pod's own namespace,\n * so cross-namespace refs are runtime errors.\n */\n fromSecretForPod: <\n const EnvName extends string,\n N extends string,\n K extends string,\n const Ns extends string\n >(\n input: SecretEnvForPodInput<EnvName, N, K, Ns>\n ): EnvVar<EnvName> => ({\n name: input.name,\n valueFrom: {\n secretKeyRef: { name: input.ref, key: input.key, optional: input.optional }\n }\n }),\n fromConfigMap: <const EnvName extends string, N extends string, K extends string = string>(\n input: ConfigMapEnvInput<EnvName, N, K>\n ): EnvVar<EnvName> => ({\n name: input.name,\n valueFrom: {\n configMapKeyRef: { name: input.ref, key: input.key, optional: input.optional }\n }\n }),\n raw: <const N extends string>(input: RawEnvInput<N>): EnvVar<N> => input\n}\n\n// Alias the shape interface as the user-facing `EnvVar<N>` type. The\n// namespace `EnvVar` (value) and the type `EnvVar<N>` share a name —\n// TypeScript merges them.\nexport type EnvVar<N extends string = string> = EnvVarShape<N>\n","import {\n brand,\n type ConfigMapRef as CMRef,\n type PvcRef as PRef,\n type SecretRef as SRef,\n type ServiceAccountRef as SARef\n} from \"@konfig.ts/core\"\n\nexport type SecretRef<\n N extends string = string,\n K extends string = string,\n Ns extends string = string\n> = SRef<N, K, Ns>\nexport type ConfigMapRef<N extends string = string, K extends string = string> = CMRef<N, K>\nexport type ServiceAccountRef<N extends string = string> = SARef<N>\nexport type PvcRef<N extends string = string> = PRef<N>\nexport type { ConfigMapRefKeys, ConfigMapRefName, PvcRefName, SecretRefKeys, SecretRefName } from \"@konfig.ts/core\"\nexport type { SecretRefNamespace } from \"@konfig.ts/core\"\n\nexport const SecretRef = {\n of: <N extends string, K extends string = string, Ns extends string = string>(\n name: N\n ): SecretRef<N, K, Ns> => brand<SecretRef<N, K, Ns>>(name),\n /**\n * Escape hatch — widen a typed ref's namespace slot to `any`, making\n * it usable across any pod context. Use sparingly (legitimate\n * cross-namespace cases: ExternalSecret reflection, in-cluster\n * shared infra). The cast is grep-able so PR reviewers see opt-ins.\n */\n // oxlint-disable-next-line app/no-type-assertion\n unsafeReNamespace: <N extends string, K extends string>(\n // oxlint-disable-next-line app/no-type-assertion\n ref: SecretRef<N, K, any>\n // oxlint-disable-next-line app/no-type-assertion\n ): SecretRef<N, K, any> => ref\n}\n\nexport const ConfigMapRef = {\n of: <N extends string, K extends string = string>(name: N): ConfigMapRef<N, K> => brand<ConfigMapRef<N, K>>(name)\n}\n\nexport const ServiceAccountRef = {\n of: <N extends string>(name: N): ServiceAccountRef<N> => brand<ServiceAccountRef<N>>(name)\n}\n\nexport const PvcRef = {\n of: <N extends string>(name: N): PvcRef<N> => brand<PvcRef<N>>(name)\n}\n","import type { ConfigMapRef, SecretRef, ServiceAccountRef } from \"@konfig.ts/core\"\nimport { Manifest } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n ConfigMap as K8sConfigMap,\n Namespace as K8sNamespace,\n Secret as K8sSecret,\n ServiceAccount as K8sServiceAccount\n} from \"./.generated/k8s-types\"\nimport {\n ConfigMapRef as ConfigMapRefValue,\n SecretRef as SecretRefValue,\n ServiceAccountRef as ServiceAccountRefValue\n} from \"./refs\"\n\ntype CommonMeta = {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\nexport interface NamespaceInput<N extends string> extends CommonMeta {\n readonly name: N\n}\n\nexport interface NamespaceManifest<N extends string> extends Manifest.Manifest<K8sNamespace> {\n readonly ref: N\n}\n\nexport const Namespace = {\n make: <N extends string>(input: NamespaceInput<N>): NamespaceManifest<N> => {\n const resource: K8sNamespace = {\n apiVersion: \"v1\",\n kind: \"Namespace\",\n metadata: {\n name: input.name,\n labels: input.labels,\n annotations: input.annotations\n }\n }\n const m = Manifest.make<K8sNamespace>(() => Effect.succeed(resource))\n return Object.assign(m, { ref: input.name })\n }\n}\n\nexport interface ServiceAccountInput<N extends string> extends CommonMeta {\n readonly name: N\n readonly namespace: string\n readonly automountServiceAccountToken?: boolean\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n}\n\nexport interface ServiceAccountManifest<N extends string> extends Manifest.Manifest<K8sServiceAccount> {\n readonly ref: ServiceAccountRef<N>\n}\n\nexport const ServiceAccount = {\n make: <N extends string>(input: ServiceAccountInput<N>): ServiceAccountManifest<N> => {\n const resource: K8sServiceAccount = {\n apiVersion: \"v1\",\n kind: \"ServiceAccount\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n automountServiceAccountToken: input.automountServiceAccountToken,\n imagePullSecrets: input.imagePullSecrets?.map((s) => ({ name: s.name }))\n }\n const m = Manifest.make<K8sServiceAccount>(() => Effect.succeed(resource))\n return Object.assign(m, { ref: ServiceAccountRefValue.of(input.name) })\n }\n}\n\nexport interface ConfigMapInput<N extends string, K extends string = string> extends CommonMeta {\n readonly name: N\n readonly namespace: string\n readonly data?: Readonly<Record<K, string>>\n readonly binaryData?: Readonly<Record<K, string>>\n readonly immutable?: boolean\n}\n\nexport interface ConfigMapManifest<N extends string, K extends string = string>\n extends Manifest.Manifest<K8sConfigMap>\n{\n readonly ref: ConfigMapRef<N, K>\n}\n\nexport const ConfigMap = {\n make: <const N extends string, const K extends string = string>(\n input: ConfigMapInput<N, K>\n ): ConfigMapManifest<N, K> => {\n const resource: K8sConfigMap = {\n apiVersion: \"v1\",\n kind: \"ConfigMap\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n data: input.data,\n binaryData: input.binaryData,\n immutable: input.immutable\n }\n const m = Manifest.make<K8sConfigMap>(() => Effect.succeed(resource))\n return Object.assign(m, { ref: ConfigMapRefValue.of<N, K>(input.name) })\n }\n}\n\nexport interface SecretInput<\n N extends string,\n Ns extends string = string,\n K extends string = string\n> extends CommonMeta {\n readonly name: N\n readonly namespace: Ns\n readonly type?: string\n readonly data?: Readonly<Record<K, string>>\n readonly stringData?: Readonly<Record<K, string>>\n readonly immutable?: boolean\n}\n\nexport interface SecretManifest<\n N extends string,\n Ns extends string = string,\n K extends string = string\n> extends Manifest.Manifest<K8sSecret> {\n readonly ref: SecretRef<N, K, Ns>\n}\n\nexport const Secret = {\n make: <\n const N extends string,\n const Ns extends string = string,\n const K extends string = string\n >(\n input: SecretInput<N, Ns, K>\n ): SecretManifest<N, Ns, K> => {\n const resource: K8sSecret = {\n apiVersion: \"v1\",\n kind: \"Secret\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n type: input.type,\n data: input.data,\n stringData: input.stringData,\n immutable: input.immutable\n }\n const m = Manifest.make<K8sSecret>(() => Effect.succeed(resource))\n return Object.assign(m, { ref: SecretRefValue.of<N, K, Ns>(input.name) })\n }\n}\n","import { Dep, type Manifest, RenderError, type SecretRef, unsafeCoerce } from \"@konfig.ts/core\"\nimport type { SecretEntry, SecretSource } from \"@konfig.ts/env\"\nimport { type Context, Effect, type Layer, Layer as L } from \"effect\"\nimport type { SecretBackend } from \"./backend\"\nimport { EnvVar } from \"./env\"\nimport { SecretRef as SecretRefValue } from \"./refs\"\n\nexport interface DeclaredSecret<N extends string, K extends string, Ns extends string = string> {\n readonly ref: SecretRef<N, K, Ns>\n readonly name: N\n readonly namespace: Ns\n readonly keys: ReadonlyArray<K>\n readonly envVars: ReadonlyArray<EnvVar>\n readonly manifest?: Manifest.Manifest<unknown>\n readonly refLayer: Layer.Layer<Dep.Provide<\"Secret\", N>>\n // values + layer present iff a source was supplied at bind time.\n readonly values?: Context.Service<\n Dep.Need<\"SecretValues\", N>,\n Dep.SecretValuesRecord<K>\n >\n readonly layer?: Layer.Layer<\n Dep.Provide<\"SecretValues\", N>,\n RenderError,\n Manifest.RenderServices\n >\n}\n\nexport interface BindSecretInput<\n N extends string,\n K extends string,\n E extends Readonly<Record<K, string>>,\n Ns extends string = string\n> {\n readonly secret: SecretEntry<N, K, E>\n readonly backend?: SecretBackend<N, K>\n readonly source?: SecretSource<K, Manifest.RenderServices>\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n /**\n * Override the contract's baked-in `namespace` for this bind. Useful\n * when the same `Secret` declaration is consumed across multiple\n * k8s namespaces (e.g. prod / staging / local of the same workload)\n * — the runtime read is namespace-independent, but each binding emits\n * its manifest into a different namespace.\n *\n * When passed as a string literal (via `Environment.bind`'s\n * `const namespace`), the literal flows into the ref's brand so\n * `secretEnvForPod` can enforce cross-namespace coherence.\n */\n readonly namespace?: Ns\n}\n\nexport const bindSecret = <\n N extends string,\n K extends string,\n E extends Readonly<Record<K, string>>,\n const Ns extends string = string\n>(\n input: BindSecretInput<N, K, E, Ns>\n): DeclaredSecret<N, K, Ns> => {\n const { secret } = input\n const namespace = unsafeCoerce<Ns>(\n input.namespace ?? secret.namespace,\n \"Ns defaults to `string`; the override (if present) is `Ns`, the secret's own namespace is `string` — runtime value either way is a string\"\n )\n const ref = SecretRefValue.of<N, K, Ns>(secret.name)\n const envVars: EnvVar[] = secret.keys.map((key: K) => EnvVar.fromSecret({ name: secret.env[key], ref, key }))\n const refLayer = Dep.provideSecret(secret.name)\n\n const manifest = input.backend === undefined\n ? undefined\n : input.backend.emit({\n name: secret.name,\n namespace,\n keys: secret.keys,\n labels: input.labels,\n annotations: input.annotations,\n source: input.source\n })\n\n const out: DeclaredSecret<N, K, Ns> = {\n ref,\n name: secret.name,\n namespace,\n keys: secret.keys,\n envVars,\n manifest,\n refLayer\n }\n\n if (input.source === undefined) return out\n\n const source = input.source\n const valuesTag = Dep.SecretValues<N, K>(secret.name)\n const layer = L.effect(\n valuesTag,\n source.resolve.pipe(\n Effect.mapError(\n (cause) =>\n new RenderError({\n message: `SecretValues(${namespace}/${secret.name}): source failed for key \"${cause.key}\"`,\n cause\n })\n )\n )\n )\n return { ...out, values: valuesTag, layer }\n}\n","import { type Manifest, type RenderError, unsafeCoerce } from \"@konfig.ts/core\"\nimport type {\n AnyEnvironment,\n DownwardEntry,\n Environment,\n EnvMember,\n LiteralEntry,\n SecretEntry,\n SecretSource\n} from \"@konfig.ts/env\"\nimport { Layer, Match } from \"effect\"\nimport type { SecretBackend } from \"./backend\"\nimport type { EnvVar } from \"./env\"\nimport { bindSecret, type DeclaredSecret } from \"./secretBind\"\n\nexport interface DeclaredLiteral<EnvName extends string, T> {\n readonly envName: EnvName\n readonly value: T\n readonly envVar: EnvVar\n}\n\nexport interface DeclaredDownward<EnvName extends string> {\n readonly envName: EnvName\n readonly fieldPath: string\n readonly envVar: EnvVar\n}\n\n/**\n * Per-member declared shape produced by `Environment.bind`. Mirrors the\n * structure of the bundle: secrets give `DeclaredSecret`, literals\n * `DeclaredLiteral`, downwards `DeclaredDownward`, and nested\n * `Environment` members give a `members` sub-record with the same\n * recursive shape.\n */\nexport type DeclaredMember<\n A extends EnvMember,\n Ns extends string = string\n> = A extends SecretEntry<infer N, infer K, infer _E> ? [N, K] extends [string, string] ? DeclaredSecret<N, K, Ns>\n : never\n : A extends LiteralEntry<infer EnvName, infer T> ? [EnvName] extends [string] ? DeclaredLiteral<EnvName, T>\n : never\n : A extends DownwardEntry<infer EnvName> ? [EnvName] extends [string] ? DeclaredDownward<EnvName>\n : never\n : A extends Environment<infer SubM> ? { readonly [K in keyof SubM]: DeclaredMember<SubM[K], Ns> }\n : never\n\nexport interface DeclaredEnvironment<\n M extends Readonly<Record<string, EnvMember>>,\n Ns extends string = string\n> {\n readonly envVars: ReadonlyArray<EnvVar>\n readonly manifests: ReadonlyArray<Manifest.Manifest<unknown>>\n readonly members: { readonly [K in keyof M]: DeclaredMember<M[K], Ns> }\n // merged values layer over every secret member with a source.\n readonly valuesLayer: Layer.Layer<unknown, RenderError, Manifest.RenderServices>\n}\n\ninterface _SecretMemberOptionsBase {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\ninterface _SecretMemberBackendRequiresSource<N extends string, K extends string> extends _SecretMemberOptionsBase {\n readonly backend: SecretBackend<N, K, true>\n readonly source: SecretSource<K, Manifest.RenderServices>\n}\n\ninterface _SecretMemberBackendOptionalSource<N extends string, K extends string> extends _SecretMemberOptionsBase {\n readonly backend: SecretBackend<N, K, false>\n readonly source?: SecretSource<K, Manifest.RenderServices>\n}\n\ninterface _SecretMemberSourceOnly<_N extends string, K extends string> extends _SecretMemberOptionsBase {\n readonly backend?: undefined\n readonly source: SecretSource<K, Manifest.RenderServices>\n}\n\n/**\n * Per-secret-member options at bind time. Backends with `RequiresSource: true`\n * (`Sops.backend`, `SealedSecrets.backend`, `NativeSecret.backend`) make\n * `source` mandatory at the type level. Backends with `false`\n * (`ExternalSecrets.backend`, `Sops.passthrough`) make it optional. With no\n * backend, `source` becomes mandatory — used to feed the in-process\n * `SecretValues` layer for tests / local renders.\n */\nexport type SecretMemberOptions<N extends string, K extends string> =\n | _SecretMemberBackendRequiresSource<N, K>\n | _SecretMemberBackendOptionalSource<N, K>\n | _SecretMemberSourceOnly<N, K>\n\nexport type SecretMemberOptionsFor<A> = A extends SecretEntry<infer N, infer K, infer _E>\n ? [N, K] extends [string, string] ? SecretMemberOptions<N, K>\n : never\n : never\n\n/**\n * True iff `M` (recursively, via nested `Environment` members)\n * contains at least one `SecretEntry`. Used to flip `secrets` between\n * required (any secrets present) and optional (literals/downwards\n * only) on `BindEnvironmentInput`.\n */\nexport type HasSecrets<M extends Readonly<Record<string, EnvMember>>> = true extends {\n readonly [K in keyof M]: M[K] extends SecretEntry<infer _N, infer _K, infer _E> ? true\n : M[K] extends Environment<infer Sub> ? HasSecrets<Sub>\n : false\n}[keyof M] ? true\n : false\n\n/**\n * Recursive per-member secret options. For a secret member, the option\n * matches its `SecretMemberOptionsFor` and is required. For a nested\n * `Environment` member that itself contains secrets, the option is\n * `SecretMembersOpts<SubM>` and is also required. Nested environments\n * with no secrets are omitted entirely (no key needed).\n *\n * Together with `HasSecrets`, this enforces at compile time that every\n * `Secret` reachable from the bundle is acknowledged at bind\n * time — adding a new secret to the env contract forces every call\n * site to update.\n */\nexport type SecretMembersOpts<M extends Readonly<Record<string, EnvMember>>> = {\n readonly [\n K in keyof M as M[K] extends SecretEntry<infer _N, infer _K, infer _E> ? K\n : M[K] extends Environment<infer SubM> ? HasSecrets<SubM> extends true ? K\n : never\n : never\n ]: M[K] extends SecretEntry<infer _N, infer _K, infer _E> ? SecretMemberOptionsFor<M[K]>\n : M[K] extends Environment<infer SubM> ? SecretMembersOpts<SubM>\n : never\n}\n\n/**\n * Per-literal value override for bind time. Keyed by member name, typed\n * to each literal's declared `T`. Useful when a `Literal` is a\n * runtime contract (carries a `schema: Config.string(envName)` for app\n * code to yield) but the manifest's emitted value differs per env —\n * e.g. `CLIENT_URL`, `S3_ENDPOINT`, host/URL literals.\n *\n * Recurses on nested `Environment` members — pass `{group: {host: \"x\"}}`\n * to override a literal nested inside a sub-bundle.\n */\nexport type LiteralMembersOpts<M extends Readonly<Record<string, EnvMember>>> = {\n readonly [\n K in keyof M as M[K] extends LiteralEntry<infer _EnvName, infer _T> ? K\n : M[K] extends Environment<infer _SubM> ? K\n : never\n ]?: M[K] extends LiteralEntry<infer _EnvName, infer T> ? T\n : M[K] extends Environment<infer SubM> ? LiteralMembersOpts<SubM>\n : never\n}\n\ninterface _BindEnvironmentInputBase<\n M extends Readonly<Record<string, EnvMember>>,\n Ns extends string = string\n> {\n readonly env: Environment<M>\n /**\n * Per-literal value override for the manifest's emitted env var. The\n * runtime read (via `entry.schema`, if provided) is unchanged —\n * overrides only affect what the konfig module writes into the\n * Deployment's `env` array.\n */\n readonly literals?: LiteralMembersOpts<M>\n /**\n * Override every secret member's namespace for this bind. Useful when\n * the bundle is consumed across multiple k8s namespaces (e.g. prod /\n * staging / local) without redeclaring each contract. Recurses into\n * nested `Environment` members.\n *\n * When passed as a string literal, the literal flows into each\n * `DeclaredSecret.ref`'s brand so `secretEnvForPod` can enforce\n * cross-namespace coherence on hand-spliced env entries.\n */\n readonly namespace?: Ns\n}\n\n/**\n * `secrets` flips between required and optional based on whether `M`\n * actually contains any secrets. A bundle of literals/downwards only\n * has nothing to bind, so `secrets` stays optional. A bundle with even\n * one `Secret` (directly or nested) forces the caller to supply\n * every secret member — and for each member, either a `backend` or a\n * `source` (see `SecretMemberOptions`).\n */\nexport type BindEnvironmentInput<\n M extends Readonly<Record<string, EnvMember>>,\n Ns extends string = string\n> =\n & _BindEnvironmentInputBase<M, Ns>\n & (HasSecrets<M> extends true ? { readonly secrets: SecretMembersOpts<M> }\n : { readonly secrets?: SecretMembersOpts<M> })\n\ninterface _BindLiteralInput {\n readonly entry: LiteralEntry<string, unknown>\n readonly override?: unknown\n}\nconst _bindLiteral = (input: _BindLiteralInput): DeclaredLiteral<string, unknown> => {\n const hasOverride = input.override !== undefined\n const value = hasOverride ? input.override : input.entry.value\n const serialized = hasOverride\n ? input.entry.serialize(input.override)\n : input.entry.serialized\n return {\n envName: input.entry.envName,\n value,\n envVar: { name: input.entry.envName, value: serialized }\n }\n}\n\ninterface _BindDownwardInput {\n readonly entry: DownwardEntry<string>\n}\nconst _bindDownward = (input: _BindDownwardInput): DeclaredDownward<string> => ({\n envName: input.entry.envName,\n fieldPath: input.entry.fieldPath,\n envVar: {\n name: input.entry.envName,\n valueFrom: { fieldRef: { fieldPath: input.entry.fieldPath } }\n }\n})\n\ntype _AnyValuesLayer = Layer.Layer<unknown, RenderError, Manifest.RenderServices>\n\ninterface _BindAcc {\n readonly declared: Record<string, unknown>\n readonly envVars: EnvVar[]\n readonly manifests: Manifest.Manifest<unknown>[]\n readonly valuesLayers: _AnyValuesLayer[]\n}\n\ninterface _DispatchInput {\n readonly memberKey: string\n readonly entry: EnvMember\n readonly secretsOpts: Record<string, unknown> | undefined\n readonly literalsOpts: Record<string, unknown> | undefined\n readonly namespace: string | undefined\n readonly acc: _BindAcc\n}\n\nconst _handleSecret = (input: _DispatchInput): void => {\n const memberOpts = unsafeCoerce<SecretMemberOptions<string, string> | undefined>(\n input.secretsOpts?.[input.memberKey],\n \"SecretMembersOpts<M> shape — runtime key lookup against the typed input\"\n )\n const secret = unsafeCoerce<SecretEntry<string, string, Readonly<Record<string, string>>>>(\n input.entry,\n \"Match.tag('Secret') narrowed entry to SecretEntry; the helper-level signature is the general SecretEntry shape\"\n )\n const d = bindSecret({\n secret,\n backend: memberOpts?.backend,\n source: memberOpts?.source,\n labels: memberOpts?.labels,\n annotations: memberOpts?.annotations,\n namespace: input.namespace\n })\n input.acc.declared[input.memberKey] = d\n input.acc.envVars.push(...d.envVars)\n if (d.manifest !== undefined) input.acc.manifests.push(d.manifest)\n if (d.layer !== undefined) {\n input.acc.valuesLayers.push(\n unsafeCoerce<_AnyValuesLayer>(\n d.layer,\n \"DeclaredSecret.layer is Layer<Provide<SecretValues, N>, ...>; widen to unknown for the heterogeneous Layer.mergeAll\"\n )\n )\n }\n}\n\nconst _handleLiteral = (input: _DispatchInput): void => {\n const literal = unsafeCoerce<LiteralEntry<string, unknown>>(\n input.entry,\n \"Match.tag('Literal') narrowed entry to LiteralEntry<string, unknown>\"\n )\n const d = _bindLiteral({ entry: literal, override: input.literalsOpts?.[input.memberKey] })\n input.acc.declared[input.memberKey] = d\n input.acc.envVars.push(d.envVar)\n}\n\nconst _handleDownward = (input: _DispatchInput): void => {\n const downward = unsafeCoerce<DownwardEntry<string>>(\n input.entry,\n \"Match.tag('Downward') narrowed entry to DownwardEntry<string>\"\n )\n const d = _bindDownward({ entry: downward })\n input.acc.declared[input.memberKey] = d\n input.acc.envVars.push(d.envVar)\n}\n\nconst _handleEnvironment = (input: _DispatchInput): void => {\n const subEnv = unsafeCoerce<AnyEnvironment>(\n input.entry,\n \"Match.tag('Environment') narrowed entry to a nested Environment\"\n )\n const sub = bindEnvironment({\n env: subEnv,\n secrets: unsafeCoerce<SecretMembersOpts<Readonly<Record<string, EnvMember>>>>(\n input.secretsOpts?.[input.memberKey] ?? {},\n \"sub-record from SecretMembersOpts<M> — type is checked at the outer call site\"\n ),\n literals: unsafeCoerce<LiteralMembersOpts<Readonly<Record<string, EnvMember>>>>(\n input.literalsOpts?.[input.memberKey] ?? {},\n \"sub-record from LiteralMembersOpts<M> — type is checked at the outer call site\"\n ),\n namespace: input.namespace\n })\n input.acc.declared[input.memberKey] = sub.members\n input.acc.envVars.push(...sub.envVars)\n input.acc.manifests.push(...sub.manifests)\n input.acc.valuesLayers.push(\n unsafeCoerce<_AnyValuesLayer>(\n sub.valuesLayer,\n \"valuesLayer aggregate over the recursive merge\"\n )\n )\n}\n\nconst _dispatch = (input: _DispatchInput): void =>\n Match.value(input.entry._kind).pipe(\n Match.when(\"Secret\", () => _handleSecret(input)),\n Match.when(\"Literal\", () => _handleLiteral(input)),\n Match.when(\"Downward\", () => _handleDownward(input)),\n Match.when(\"Environment\", () => _handleEnvironment(input)),\n Match.exhaustive\n )\n\nexport const bindEnvironment = <\n const M extends Readonly<Record<string, EnvMember>>,\n const Ns extends string = string\n>(\n input: BindEnvironmentInput<M, Ns>\n): DeclaredEnvironment<M, Ns> => {\n const { env } = input\n const acc: _BindAcc = {\n declared: {},\n envVars: [],\n manifests: [],\n valuesLayers: []\n }\n const secretsOpts = unsafeCoerce<Record<string, unknown> | undefined>(\n input.secrets,\n \"discriminated union from BindEnvironmentInput; iterate keys at runtime\"\n )\n const literalsOpts = unsafeCoerce<Record<string, unknown> | undefined>(\n input.literals,\n \"discriminated union from BindEnvironmentInput; iterate keys at runtime\"\n )\n\n for (const memberKey of Object.keys(env.members)) {\n const entry = unsafeCoerce<EnvMember>(\n env.members[memberKey],\n \"env.members values are EnvMember by construction\"\n )\n _dispatch({\n memberKey,\n entry,\n secretsOpts,\n literalsOpts,\n namespace: input.namespace,\n acc\n })\n }\n\n const valuesLayer = unsafeCoerce<_AnyValuesLayer>(\n acc.valuesLayers.length === 0\n ? Layer.empty\n : Layer.mergeAll(acc.valuesLayers[0]!, ...acc.valuesLayers.slice(1)),\n \"merged Layer over a heterogeneous list of per-secret value layers\"\n )\n\n return {\n envVars: acc.envVars,\n manifests: acc.manifests,\n members: unsafeCoerce<{ readonly [K in keyof M]: DeclaredMember<M[K], Ns> }>(\n acc.declared,\n \"declared populated by iterating env.members; each key maps to its DeclaredMember<M[K], Ns>\"\n ),\n valuesLayer\n }\n}\n","import type { Manifest } from \"@konfig.ts/core\"\nimport type { SecretSource } from \"@konfig.ts/env\"\nimport { Data } from \"effect\"\n\nexport type BackendTag =\n | \"Sops\"\n | \"Sops.passthrough\"\n | \"SealedSecrets\"\n | \"ExternalSecrets\"\n | \"NativeSecret\"\n\nexport interface BackendEmitInput<N extends string, K extends string> {\n readonly name: N\n readonly namespace: string\n readonly keys: ReadonlyArray<K>\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly source?: SecretSource<K, Manifest.RenderServices>\n}\n\nexport interface SecretBackend<\n N extends string,\n K extends string,\n RequiresSource extends boolean = boolean\n> {\n readonly _tag: BackendTag\n readonly requiresSource: RequiresSource\n readonly emit: (input: BackendEmitInput<N, K>) => Manifest.Manifest<unknown>\n}\n\nexport class BackendSourceMissing extends Data.TaggedError(\"BackendSourceMissing\")<{\n readonly backend: BackendTag\n readonly secret: string\n}> {\n get message(): string {\n return `backend \"${this.backend}\" requires a source but none was provided for secret \"${this.secret}\"`\n }\n}\n","import { Manifest, RenderError } from \"@konfig.ts/core\"\nimport type { SecretSource } from \"@konfig.ts/env\"\nimport { Effect, Redacted } from \"effect\"\nimport type { Secret as K8sSecret } from \"./.generated/k8s-types\"\nimport { type BackendEmitInput, BackendSourceMissing, type SecretBackend } from \"./backend\"\n\nexport interface NativeSecretOptions {\n readonly type?: string\n readonly immutable?: boolean\n readonly silenceWarning?: boolean\n}\n\ninterface _EmitInput<N extends string, K extends string> {\n readonly base: BackendEmitInput<N, K>\n readonly opts: NativeSecretOptions\n readonly source: SecretSource<K, Manifest.RenderServices>\n}\n\nconst _emit = <N extends string, K extends string>(\n input: _EmitInput<N, K>\n): Manifest.Manifest<K8sSecret> =>\n Manifest.make<K8sSecret>((_ctx) =>\n Effect.gen(function*() {\n if (input.opts.silenceWarning !== true) {\n yield* Effect.logWarning(\n `NativeSecret backend emits a plaintext Secret with stringData on disk for \"${input.base.namespace}/${input.base.name}\". Pass { silenceWarning: true } to suppress, or switch to ExternalSecrets / SealedSecrets / Sops for production.`\n )\n }\n const resolved = yield* input.source.resolve.pipe(\n Effect.mapError(\n (cause) =>\n new RenderError({\n message: `NativeSecret(${input.base.namespace}/${input.base.name}): source failed for key \"${cause.key}\"`,\n cause\n })\n )\n )\n const stringData: Record<string, string> = {}\n for (const key of input.base.keys) {\n stringData[key] = Redacted.value(resolved[key])\n }\n const out: K8sSecret = {\n apiVersion: \"v1\",\n kind: \"Secret\",\n metadata: {\n name: input.base.name,\n namespace: input.base.namespace,\n labels: input.base.labels,\n annotations: input.base.annotations\n },\n type: input.opts.type,\n stringData,\n immutable: input.opts.immutable\n }\n return out\n })\n )\n\nexport const NativeSecret = {\n backend: <N extends string, K extends string>(\n opts?: NativeSecretOptions\n ): SecretBackend<N, K, true> => {\n const resolvedOpts = opts ?? {}\n return {\n _tag: \"NativeSecret\",\n requiresSource: true,\n emit: (input: BackendEmitInput<N, K>) => {\n if (input.source === undefined) {\n throw new BackendSourceMissing({ backend: \"NativeSecret\", secret: input.name })\n }\n return _emit({ base: input, opts: resolvedOpts, source: input.source })\n }\n }\n }\n}\n","import { Manifest, type SecretRef, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type { IngressBackend as K8sIngressBackend } from \"kubernetes-types/networking/v1\"\nimport type {\n Ingress as K8sIngress,\n IngressRule as K8sIngressRule,\n IngressTLS as K8sIngressTLS,\n Service as K8sService,\n ServicePort as K8sServicePort\n} from \"./.generated/k8s-types\"\nimport type { ContainerSpec } from \"./container\"\nimport type { ServicePortSpec } from \"./ports\"\nimport type { Selector } from \"./selector\"\n\n/**\n * Strict input for a `Service`. `selector` and `ports` are required:\n * a Service with no selector has no endpoints, and one with no ports\n * is meaningless. ServicePort needs at minimum a `port`; the upstream\n * `K8sServicePort` only marks `port` as required — names/protocol\n * defaults match kube-apiserver behaviour.\n */\nexport interface ServiceInput {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly selector: Readonly<Record<string, string>>\n readonly ports: ReadonlyArray<K8sServicePort>\n readonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\"\n readonly clusterIP?: string\n readonly sessionAffinity?: string\n readonly publishNotReadyAddresses?: boolean\n readonly externalTrafficPolicy?: string\n readonly internalTrafficPolicy?: string\n}\n\n/**\n * Strongly-typed Service input bound to a container's declared port-name\n * union. `selector` and `ports` are required; `ports[i].targetPort`\n * accepts a bare number or `Port.ref(name)` referencing a name declared\n * on `forContainer`. `NoInfer` locks `Ports` to `forContainer`, so the\n * port list is validated against that union rather than inferred from.\n */\nexport interface ServiceFromContainerInput<Ports extends string> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly selector: Readonly<Record<string, string>>\n readonly forContainer: ContainerSpec<Ports>\n readonly ports: ReadonlyArray<ServicePortSpec<NoInfer<Ports>>>\n readonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\"\n readonly clusterIP?: string\n readonly sessionAffinity?: string\n readonly publishNotReadyAddresses?: boolean\n readonly externalTrafficPolicy?: string\n readonly internalTrafficPolicy?: string\n}\n\n/**\n * Service built from a `Selector`. The selector's labels populate\n * `spec.selector` — drift versus the matching Deployment is impossible\n * once both consume the same `podSet`.\n */\nexport interface ServiceFromPodSetInput<L extends Readonly<Record<string, string>>> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly podSet: Selector<L>\n readonly ports: ReadonlyArray<K8sServicePort>\n readonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\"\n readonly clusterIP?: string\n readonly sessionAffinity?: string\n readonly publishNotReadyAddresses?: boolean\n readonly externalTrafficPolicy?: string\n readonly internalTrafficPolicy?: string\n}\n\nexport const Service = {\n make: (input: ServiceInput): Manifest.Manifest<K8sService> => {\n const resource: K8sService = {\n apiVersion: \"v1\",\n kind: \"Service\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n selector: input.selector,\n type: input.type,\n ports: unsafeCoerce(\n input.ports,\n \"input.ports is the user-typed Service spec; K8s ServicePort allows the same fields\"\n ),\n clusterIP: input.clusterIP,\n sessionAffinity: input.sessionAffinity,\n publishNotReadyAddresses: input.publishNotReadyAddresses,\n externalTrafficPolicy: input.externalTrafficPolicy,\n internalTrafficPolicy: input.internalTrafficPolicy\n }\n }\n return Manifest.make<K8sService>(() => Effect.succeed(resource))\n },\n fromContainer: <Ports extends string>(\n input: ServiceFromContainerInput<Ports>\n ): Manifest.Manifest<K8sService> =>\n Service.make({\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations,\n selector: input.selector,\n ports: unsafeCoerce<ReadonlyArray<K8sServicePort>>(\n input.ports,\n \"ServicePortSpec<Ports> structurally matches K8sServicePort; targetPort's PortName<Ports> brand is a phantom — runtime value is the underlying string\"\n ),\n type: input.type,\n clusterIP: input.clusterIP,\n sessionAffinity: input.sessionAffinity,\n publishNotReadyAddresses: input.publishNotReadyAddresses,\n externalTrafficPolicy: input.externalTrafficPolicy,\n internalTrafficPolicy: input.internalTrafficPolicy\n }),\n fromPodSet: <L extends Readonly<Record<string, string>>>(\n input: ServiceFromPodSetInput<L>\n ): Manifest.Manifest<K8sService> =>\n Service.make({\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations,\n selector: input.podSet.labels,\n ports: input.ports,\n type: input.type,\n clusterIP: input.clusterIP,\n sessionAffinity: input.sessionAffinity,\n publishNotReadyAddresses: input.publishNotReadyAddresses,\n externalTrafficPolicy: input.externalTrafficPolicy,\n internalTrafficPolicy: input.internalTrafficPolicy\n })\n}\n\nexport interface IngressTLSInput {\n readonly hosts?: ReadonlyArray<string>\n readonly secretName: SecretRef<string>\n}\n\nexport interface IngressInput {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly ingressClassName?: string\n readonly rules?: ReadonlyArray<K8sIngressRule>\n readonly tls?: ReadonlyArray<IngressTLSInput>\n readonly defaultBackend?: K8sIngressBackend\n}\n\nexport const Ingress = {\n make: (input: IngressInput): Manifest.Manifest<K8sIngress> => {\n const resource: K8sIngress = {\n apiVersion: \"networking.k8s.io/v1\",\n kind: \"Ingress\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n ingressClassName: input.ingressClassName,\n rules: unsafeCoerce(\n input.rules,\n \"user-supplied Ingress rules; widening from our convenience type to the K8s type\"\n ),\n tls: unsafeCoerce<K8sIngressTLS[]>(input.tls, \"Ingress.tls produces K8sIngressTLS with branded secretName\"),\n defaultBackend: unsafeCoerce(input.defaultBackend, \"user-supplied IngressBackend; structural match to K8s type\")\n }\n }\n return Manifest.make<K8sIngress>(() => Effect.succeed(resource))\n },\n /**\n * TLS entry constructor for `Ingress.make({ tls: [...] })`. Takes a\n * branded `SecretRef` so the secret's name can't widen to a raw\n * string at the call site.\n */\n tls: (input: {\n readonly secretName: SecretRef<string>\n readonly hosts?: ReadonlyArray<string>\n }): IngressTLSInput => ({ secretName: input.secretName, hosts: input.hosts })\n}\n","import { Redacted } from \"effect\"\nimport { createHash, type Hash } from \"node:crypto\"\n\nexport interface HashSecretValuesInput {\n readonly values: Readonly<Record<string, Redacted.Redacted<string>>>\n /**\n * Non-secret salt folded into the digest so it is NOT a pure function of the\n * plaintext — this defeats offline brute-force / rainbow-table recovery of\n * low-entropy secrets from the annotation. Use a stable per-workload\n * identifier such as `\"<namespace>/<name>\"`.\n */\n readonly salt: string\n}\n\n// Netstring-frames every field (`<byteLen>:<bytes>,`) before hashing. Plain\n// `key + \"=\" + value + \"\\n\"` concatenation is ambiguous — `{ \"a=b\": \"c\" }` and\n// `{ \"a\": \"b\\nc\" }` would hash identically. Length-prefixing makes each field\n// boundary unforgeable, so distinct records always produce distinct digests.\nconst _frame = (hasher: Hash, value: string): void => {\n const bytes = Buffer.from(value, \"utf8\")\n hasher.update(`${bytes.length}:`)\n hasher.update(bytes)\n hasher.update(\",\")\n}\n\n// Captures values AT BUILD TIME ONLY — rotations between builds need an\n// in-cluster watcher (e.g. Reloader). Redacted.value is inline so plaintext\n// is not bound to a local.\n//\n// NOTE: the returned digest is a change-detection fingerprint, NOT a\n// cryptographic commitment you may safely publish for a low-entropy secret.\n// It is salted (so it is not a bare sha256 of the plaintext) and emitted at\n// full width (no truncation), but it must not be treated as secret-safe.\nexport const hashSecretValues = (input: HashSecretValuesInput): string => {\n const hasher = createHash(\"sha256\")\n _frame(hasher, \"konfig/secret-values-hash/v1\")\n _frame(hasher, input.salt)\n const keys = Object.keys(input.values).sort()\n for (const key of keys) {\n _frame(hasher, key)\n _frame(hasher, Redacted.value(input.values[key]!))\n }\n return hasher.digest(\"hex\")\n}\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type { PersistentVolumeSpec as K8sPersistentVolumeSpec } from \"kubernetes-types/core/v1\"\nimport type {\n NetworkPolicyEgressRule as K8sNetworkPolicyEgressRule,\n NetworkPolicyIngressRule as K8sNetworkPolicyIngressRule\n} from \"kubernetes-types/networking/v1\"\nimport type {\n ClusterRole as K8sClusterRole,\n ClusterRoleBinding as K8sClusterRoleBinding,\n NetworkPolicy as K8sNetworkPolicy,\n PersistentVolume as K8sPersistentVolume,\n PersistentVolumeClaim as K8sPersistentVolumeClaim,\n Role as K8sRole,\n RoleBinding as K8sRoleBinding\n} from \"./.generated/k8s-types\"\nimport type { Selector } from \"./selector\"\n\ninterface NamespacedMeta {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\ninterface ClusterMeta {\n readonly name: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\n/**\n * Standard k8s PV access modes. Constrained to the four documented\n * values so a typo (`\"ReadWriteonce\"`) is a compile-time error.\n */\nexport type PersistentVolumeAccessMode =\n | \"ReadWriteOnce\"\n | \"ReadOnlyMany\"\n | \"ReadWriteMany\"\n | \"ReadWriteOncePod\"\n\nexport type PersistentVolumeReclaimPolicy = \"Retain\" | \"Recycle\" | \"Delete\"\n\nexport type PersistentVolumeMode = \"Filesystem\" | \"Block\"\n\n/**\n * Strict input shape for a `PersistentVolume.spec`. Upstream\n * `kubernetes-types` types every field as optional (because the\n * OpenAPI generator emits the entire union), which makes invalid\n * specs (no capacity, no accessModes, no volume source) compile.\n * The fields the kube-apiserver actually requires are required here.\n *\n * Volume-source fields (`hostPath`, `csi`, `nfs`, `local`, etc.) are\n * inherited from the upstream `PersistentVolumeSpec` via `Omit` so\n * users can use whichever source they need. \"At least one source\"\n * isn't enforced statically (TS unions over 20+ variants would be\n * unwieldy) — the kube-apiserver rejects a spec with no source.\n */\nexport interface PersistentVolumeSpecInput extends\n Omit<\n K8sPersistentVolumeSpec,\n \"capacity\" | \"accessModes\" | \"persistentVolumeReclaimPolicy\" | \"volumeMode\" | \"claimRef\"\n >\n{\n readonly capacity: { readonly storage: string }\n readonly accessModes: ReadonlyArray<PersistentVolumeAccessMode>\n readonly persistentVolumeReclaimPolicy?: PersistentVolumeReclaimPolicy\n readonly volumeMode?: PersistentVolumeMode\n readonly claimRef?: { readonly namespace: string; readonly name: string }\n}\n\nexport interface PersistentVolumeInput extends ClusterMeta {\n readonly spec: PersistentVolumeSpecInput\n}\n\nexport const PersistentVolume = {\n make: (input: PersistentVolumeInput): Manifest.Manifest<K8sPersistentVolume> =>\n Manifest.make<K8sPersistentVolume>(() =>\n Effect.succeed({\n apiVersion: \"v1\",\n kind: \"PersistentVolume\",\n metadata: {\n name: input.name,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: unsafeCoerce<K8sPersistentVolume[\"spec\"]>(\n input.spec,\n \"user-supplied PV spec; structural match to the K8s type\"\n )\n })\n )\n}\n\n/**\n * Strict input shape for a `PersistentVolumeClaim.spec`. Same\n * rationale as `PersistentVolumeSpecInput` — accessModes + a storage\n * request are the fields the apiserver requires.\n */\nexport interface PersistentVolumeClaimSpecInput {\n readonly accessModes: ReadonlyArray<PersistentVolumeAccessMode>\n readonly resources: { readonly requests: { readonly storage: string } }\n readonly storageClassName?: string\n readonly volumeMode?: PersistentVolumeMode\n readonly volumeName?: string\n readonly selector?: { readonly matchLabels?: Readonly<Record<string, string>> }\n}\n\nexport interface PersistentVolumeClaimInput extends NamespacedMeta {\n readonly spec: PersistentVolumeClaimSpecInput\n}\n\nexport const PersistentVolumeClaim = {\n make: (input: PersistentVolumeClaimInput): Manifest.Manifest<K8sPersistentVolumeClaim> =>\n Manifest.make<K8sPersistentVolumeClaim>(() =>\n Effect.succeed({\n apiVersion: \"v1\",\n kind: \"PersistentVolumeClaim\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: unsafeCoerce<K8sPersistentVolumeClaim[\"spec\"]>(\n input.spec,\n \"user-supplied PVC spec; structural match to the K8s type\"\n )\n })\n )\n}\n\nexport interface NetworkPolicyInput extends NamespacedMeta {\n readonly spec: K8sNetworkPolicy[\"spec\"]\n}\n\n/**\n * Peer rule for `NetworkPolicy.fromPodSet`. A peer is either a typed\n * `Selector` (matched as `podSelector.matchLabels`), a `namespaceSelector`,\n * or a CIDR block.\n */\nexport interface NetworkPolicyPeer {\n readonly podSet?: Selector<Readonly<Record<string, string>>>\n readonly namespaceSelector?: { readonly matchLabels?: Readonly<Record<string, string>> }\n readonly ipBlock?: { readonly cidr: string; readonly except?: ReadonlyArray<string> }\n}\n\nexport interface NetworkPolicyIngressRule {\n readonly from?: ReadonlyArray<NetworkPolicyPeer>\n readonly ports?: K8sNetworkPolicyIngressRule[\"ports\"]\n}\n\nexport interface NetworkPolicyEgressRule {\n readonly to?: ReadonlyArray<NetworkPolicyPeer>\n readonly ports?: K8sNetworkPolicyEgressRule[\"ports\"]\n}\n\n/**\n * NetworkPolicy built from typed `Selector`s. `podSet` drives\n * `spec.podSelector`; ingress/egress peer rules accept further selectors\n * via `from[].podSet` / `to[].podSet`. Peer selectors need not match the\n * owning selector — the typing ties this NetworkPolicy's selection to a\n * single source of truth and lets peers be independently typed.\n */\nexport interface NetworkPolicyFromPodSetInput<L extends Readonly<Record<string, string>>> extends NamespacedMeta {\n readonly podSet: Selector<L>\n readonly policyTypes?: ReadonlyArray<\"Ingress\" | \"Egress\">\n readonly ingress?: ReadonlyArray<NetworkPolicyIngressRule>\n readonly egress?: ReadonlyArray<NetworkPolicyEgressRule>\n}\n\nconst _lowerPeer = (peer: NetworkPolicyPeer): {\n readonly podSelector?: { readonly matchLabels?: Readonly<Record<string, string>> }\n readonly namespaceSelector?: { readonly matchLabels?: Readonly<Record<string, string>> }\n readonly ipBlock?: { readonly cidr: string; readonly except?: ReadonlyArray<string> }\n} => ({\n ...(peer.podSet !== undefined ? { podSelector: { matchLabels: peer.podSet.labels } } : {}),\n ...(peer.namespaceSelector !== undefined ? { namespaceSelector: peer.namespaceSelector } : {}),\n ...(peer.ipBlock !== undefined ? { ipBlock: peer.ipBlock } : {})\n})\n\nexport const NetworkPolicy = {\n make: (input: NetworkPolicyInput): Manifest.Manifest<K8sNetworkPolicy> =>\n Manifest.make<K8sNetworkPolicy>(() =>\n Effect.succeed({\n apiVersion: \"networking.k8s.io/v1\",\n kind: \"NetworkPolicy\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: input.spec\n })\n ),\n fromPodSet: <L extends Readonly<Record<string, string>>>(\n input: NetworkPolicyFromPodSetInput<L>\n ): Manifest.Manifest<K8sNetworkPolicy> => {\n const ingress = input.ingress?.map((rule) => ({\n from: rule.from?.map(_lowerPeer),\n ports: rule.ports\n }))\n const egress = input.egress?.map((rule) => ({\n to: rule.to?.map(_lowerPeer),\n ports: rule.ports\n }))\n return NetworkPolicy.make({\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations,\n spec: unsafeCoerce<K8sNetworkPolicy[\"spec\"]>(\n {\n podSelector: { matchLabels: input.podSet.labels },\n policyTypes: input.policyTypes,\n ingress,\n egress\n },\n \"konfig peers carry readonly arrays; upstream NetworkPolicySpec is mutable but the runtime shape matches\"\n )\n })\n }\n}\n\nexport interface ClusterRoleInput extends ClusterMeta {\n readonly rules?: K8sClusterRole[\"rules\"]\n readonly aggregationRule?: K8sClusterRole[\"aggregationRule\"]\n}\n\nexport const ClusterRole = {\n make: (input: ClusterRoleInput): Manifest.Manifest<K8sClusterRole> =>\n Manifest.make<K8sClusterRole>(() =>\n Effect.succeed({\n apiVersion: \"rbac.authorization.k8s.io/v1\",\n kind: \"ClusterRole\",\n metadata: {\n name: input.name,\n labels: input.labels,\n annotations: input.annotations\n },\n rules: input.rules,\n aggregationRule: input.aggregationRule\n })\n )\n}\n\nexport interface ClusterRoleBindingInput extends ClusterMeta {\n readonly roleRef: K8sClusterRoleBinding[\"roleRef\"]\n readonly subjects?: K8sClusterRoleBinding[\"subjects\"]\n}\n\nexport const ClusterRoleBinding = {\n make: (input: ClusterRoleBindingInput): Manifest.Manifest<K8sClusterRoleBinding> =>\n Manifest.make<K8sClusterRoleBinding>(() =>\n Effect.succeed({\n apiVersion: \"rbac.authorization.k8s.io/v1\",\n kind: \"ClusterRoleBinding\",\n metadata: {\n name: input.name,\n labels: input.labels,\n annotations: input.annotations\n },\n roleRef: input.roleRef,\n subjects: input.subjects\n })\n )\n}\n\nexport interface RoleInput extends NamespacedMeta {\n readonly rules?: K8sRole[\"rules\"]\n}\n\nexport const Role = {\n make: (input: RoleInput): Manifest.Manifest<K8sRole> =>\n Manifest.make<K8sRole>(() =>\n Effect.succeed({\n apiVersion: \"rbac.authorization.k8s.io/v1\",\n kind: \"Role\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n rules: input.rules\n })\n )\n}\n\nexport interface RoleBindingInput extends NamespacedMeta {\n readonly roleRef: K8sRoleBinding[\"roleRef\"]\n readonly subjects?: K8sRoleBinding[\"subjects\"]\n}\n\nexport const RoleBinding = {\n make: (input: RoleBindingInput): Manifest.Manifest<K8sRoleBinding> =>\n Manifest.make<K8sRoleBinding>(() =>\n Effect.succeed({\n apiVersion: \"rbac.authorization.k8s.io/v1\",\n kind: \"RoleBinding\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n roleRef: input.roleRef,\n subjects: input.subjects\n })\n )\n}\n","import { brand } from \"@konfig.ts/core\"\nimport type { ConfigMapRef, PvcRef, SecretRef } from \"@konfig.ts/core\"\n\n/**\n * Branded volume name — a string carrying the literal `N` in its\n * phantom. Constructed by the volume factories\n * (`Volume.empty`, `Volume.fromSecret`, …) and `Volume.mountRef`. Lets\n * `VolumeMount<Mounts>` and `Pod` constrain a container's\n * `volumeMounts[i].name` to volumes that the pod actually declares.\n */\ndeclare const VolumeNameBrand: unique symbol\nexport type VolumeName<N extends string> = string & {\n readonly [VolumeNameBrand]: N\n}\n\nconst _volumeName = <const N extends string>(name: N): VolumeName<N> => brand<VolumeName<N>>(name)\n\nexport interface Volume<N extends string = string> {\n readonly name: VolumeName<N>\n readonly secret?: {\n readonly secretName: string\n readonly optional?: boolean\n readonly defaultMode?: number\n }\n readonly configMap?: {\n readonly name: string\n readonly optional?: boolean\n readonly defaultMode?: number\n readonly items?: ReadonlyArray<{ readonly key: string; readonly path: string }>\n }\n readonly emptyDir?: { readonly medium?: string; readonly sizeLimit?: string }\n readonly persistentVolumeClaim?: {\n readonly claimName: PvcRef<string>\n readonly readOnly?: boolean\n }\n readonly hostPath?: { readonly path: string; readonly type?: string }\n}\n\nexport interface EmptyVolumeInput<N extends string> {\n readonly name: N\n readonly medium?: string\n readonly sizeLimit?: string\n}\n\nexport interface VolumeFromSecretInput<N extends string> {\n readonly name: N\n readonly ref: SecretRef<string>\n readonly optional?: boolean\n readonly defaultMode?: number\n}\n\nexport interface VolumeFromConfigMapInput<N extends string> {\n readonly name: N\n readonly ref: ConfigMapRef<string>\n readonly optional?: boolean\n readonly defaultMode?: number\n readonly items?: ReadonlyArray<{ readonly key: string; readonly path: string }>\n}\n\nexport interface VolumeFromPvcInput<N extends string, PvcN extends string> {\n readonly name: N\n readonly claim: PvcRef<PvcN>\n readonly readOnly?: boolean\n}\n\n/**\n * `Volume` value namespace.\n *\n * volumes: [\n * Volume.empty({ name: \"config\" }),\n * Volume.fromSecret({ name: \"tls\", ref: tlsSecret.ref }),\n * Volume.fromConfigMap({ name: \"settings\", ref: cfg.ref }),\n * Volume.fromPvc({ name: \"data\", claim: pvc.ref }),\n * ],\n * volumeMounts: [\n * { name: Volume.mountRef(\"config\"), mountPath: \"/etc/conf\" },\n * ],\n *\n * All four constructors capture the literal `name` in the returned\n * `Volume<N>` brand; `Pod` infers the union and constrains each\n * container's `volumeMounts[i].name` to it.\n */\nexport const Volume = {\n empty: <const N extends string>(input: EmptyVolumeInput<N>): Volume<N> => ({\n name: _volumeName(input.name),\n emptyDir: { medium: input.medium, sizeLimit: input.sizeLimit }\n }),\n fromSecret: <const N extends string>(input: VolumeFromSecretInput<N>): Volume<N> => ({\n name: _volumeName(input.name),\n secret: {\n secretName: input.ref,\n optional: input.optional,\n defaultMode: input.defaultMode\n }\n }),\n fromConfigMap: <const N extends string>(input: VolumeFromConfigMapInput<N>): Volume<N> => ({\n name: _volumeName(input.name),\n configMap: {\n name: input.ref,\n optional: input.optional,\n defaultMode: input.defaultMode,\n items: input.items\n }\n }),\n fromPvc: <const N extends string, const PvcN extends string>(\n input: VolumeFromPvcInput<N, PvcN>\n ): Volume<N> => ({\n name: _volumeName(input.name),\n persistentVolumeClaim: { claimName: input.claim, readOnly: input.readOnly }\n }),\n mountRef: <const N extends string>(name: N): VolumeName<N> => _volumeName(name)\n}\n\n/**\n * Typed container volumeMount. `Mounts` is the union of volume names\n * declared on the surrounding pod; `name` must reference one of them.\n * Bare-number variants don't apply (mounts are always by name).\n */\nexport interface VolumeMount<Mounts extends string = string> {\n readonly name: VolumeName<Mounts>\n readonly mountPath: string\n readonly readOnly?: boolean\n readonly subPath?: string\n readonly subPathExpr?: string\n readonly mountPropagation?: string\n}\n\nexport type VolumeNamesOf<V extends ReadonlyArray<Volume<string>>> = {\n readonly [I in keyof V]: V[I] extends Volume<infer N> ? N : never\n}[number]\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n CronJob as K8sCronJob,\n Deployment as K8sDeployment,\n Job as K8sJob,\n StatefulSet as K8sStatefulSet\n} from \"./.generated/k8s-types\"\nimport type { PodSpecInput } from \"./container\"\nimport type { Selector } from \"./selector\"\n\ninterface WorkloadMeta {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n}\n\ninterface SelectorAndTemplate {\n readonly selector: { readonly matchLabels: Readonly<Record<string, string>> }\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n}\n\nexport interface DeploymentInput extends WorkloadMeta, SelectorAndTemplate {\n readonly replicas?: number\n readonly strategy?: unknown\n readonly revisionHistoryLimit?: number\n readonly progressDeadlineSeconds?: number\n readonly minReadySeconds?: number\n}\n\n/**\n * Deployment built from a `Selector`. The selector's labels become both\n * the Deployment's `spec.selector.matchLabels` and the pod template's\n * `metadata.labels` — coherent by construction. Drift between selector\n * and template (the classic \"service has no endpoints\" footgun) is\n * structurally impossible once both consume the same `podSet`.\n */\nexport interface DeploymentFromPodSetInput<L extends Readonly<Record<string, string>>> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly podSet: Selector<L>\n readonly replicas?: number\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n readonly strategy?: unknown\n readonly revisionHistoryLimit?: number\n readonly progressDeadlineSeconds?: number\n readonly minReadySeconds?: number\n}\n\nexport const Deployment = {\n make: (input: DeploymentInput): Manifest.Manifest<K8sDeployment> => {\n const resource: K8sDeployment = {\n apiVersion: \"apps/v1\",\n kind: \"Deployment\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n replicas: input.replicas,\n selector: input.selector,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n ),\n strategy: unsafeCoerce(\n input.strategy,\n \"DeploymentStrategy is escape-hatch unknown; lift to K8s type for serialization\"\n ),\n revisionHistoryLimit: input.revisionHistoryLimit,\n progressDeadlineSeconds: input.progressDeadlineSeconds,\n minReadySeconds: input.minReadySeconds\n }\n }\n return Manifest.make<K8sDeployment>(() => Effect.succeed(resource))\n },\n fromPodSet: <L extends Readonly<Record<string, string>>>(\n input: DeploymentFromPodSetInput<L>\n ): Manifest.Manifest<K8sDeployment> =>\n Deployment.make({\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations,\n replicas: input.replicas,\n selector: { matchLabels: input.podSet.labels },\n template: {\n metadata: {\n // podSet labels are spread LAST so a colliding caller-supplied\n // template label can never shadow a selector label — that would\n // desync the pod template from `spec.selector` and strand the\n // Deployment with zero matching endpoints.\n labels: { ...input.template.metadata?.labels, ...input.podSet.labels },\n annotations: input.template.metadata?.annotations\n },\n spec: input.template.spec\n },\n strategy: input.strategy,\n revisionHistoryLimit: input.revisionHistoryLimit,\n progressDeadlineSeconds: input.progressDeadlineSeconds,\n minReadySeconds: input.minReadySeconds\n })\n}\n\nexport interface StatefulSetInput extends WorkloadMeta, SelectorAndTemplate {\n readonly replicas?: number\n readonly serviceName: string\n readonly volumeClaimTemplates?: ReadonlyArray<unknown>\n readonly podManagementPolicy?: string\n readonly updateStrategy?: unknown\n}\n\nexport const StatefulSet = {\n make: (input: StatefulSetInput): Manifest.Manifest<K8sStatefulSet> => {\n const resource: K8sStatefulSet = {\n apiVersion: \"apps/v1\",\n kind: \"StatefulSet\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n replicas: input.replicas,\n selector: input.selector,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n ),\n serviceName: input.serviceName,\n volumeClaimTemplates: unsafeCoerce(\n input.volumeClaimTemplates,\n \"StatefulSet volumeClaimTemplates is escape-hatch unknown; lift to K8s type\"\n ),\n podManagementPolicy: input.podManagementPolicy,\n updateStrategy: unsafeCoerce(input.updateStrategy, \"StatefulSetUpdateStrategy is escape-hatch unknown\")\n }\n }\n return Manifest.make<K8sStatefulSet>(() => Effect.succeed(resource))\n }\n}\n\nexport interface JobInput extends WorkloadMeta {\n readonly parallelism?: number\n readonly completions?: number\n readonly backoffLimit?: number\n readonly activeDeadlineSeconds?: number\n readonly ttlSecondsAfterFinished?: number\n readonly suspend?: boolean\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n}\n\nexport const Job = {\n make: (input: JobInput): Manifest.Manifest<K8sJob> => {\n const resource: K8sJob = {\n apiVersion: \"batch/v1\",\n kind: \"Job\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n parallelism: input.parallelism,\n completions: input.completions,\n backoffLimit: input.backoffLimit,\n activeDeadlineSeconds: input.activeDeadlineSeconds,\n ttlSecondsAfterFinished: input.ttlSecondsAfterFinished,\n suspend: input.suspend,\n template: unsafeCoerce(\n input.template,\n \"konfig PodSpecInput is structurally a K8s PodTemplateSpec body; brand-checked fields lower at construction\"\n )\n }\n }\n return Manifest.make<K8sJob>(() => Effect.succeed(resource))\n }\n}\n\nexport interface CronJobInput extends WorkloadMeta {\n readonly schedule: string\n readonly concurrencyPolicy?: string\n readonly successfulJobsHistoryLimit?: number\n readonly failedJobsHistoryLimit?: number\n readonly startingDeadlineSeconds?: number\n readonly suspend?: boolean\n readonly jobTemplate: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: {\n readonly template: {\n readonly metadata?: {\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n }\n readonly spec: PodSpecInput\n }\n readonly backoffLimit?: number\n readonly activeDeadlineSeconds?: number\n readonly ttlSecondsAfterFinished?: number\n }\n }\n}\n\nexport const CronJob = {\n make: (input: CronJobInput): Manifest.Manifest<K8sCronJob> => {\n const resource: K8sCronJob = {\n apiVersion: \"batch/v1\",\n kind: \"CronJob\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: input.labels,\n annotations: input.annotations\n },\n spec: {\n schedule: input.schedule,\n concurrencyPolicy: input.concurrencyPolicy,\n successfulJobsHistoryLimit: input.successfulJobsHistoryLimit,\n failedJobsHistoryLimit: input.failedJobsHistoryLimit,\n startingDeadlineSeconds: input.startingDeadlineSeconds,\n suspend: input.suspend,\n jobTemplate: unsafeCoerce(\n input.jobTemplate,\n \"konfig CronJob jobTemplate is structurally a K8s JobTemplateSpec body\"\n )\n }\n }\n return Manifest.make<K8sCronJob>(() => Effect.succeed(resource))\n }\n}\n","import { Manifest, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n Deployment as K8sDeployment,\n NetworkPolicy as K8sNetworkPolicy,\n Service as K8sService\n} from \"./.generated/k8s-types\"\nimport { Service, type ServiceFromPodSetInput } from \"./network\"\nimport { NetworkPolicy, type NetworkPolicyFromPodSetInput } from \"./policy\"\nimport type { Selector } from \"./selector\"\nimport { Deployment, type DeploymentFromPodSetInput } from \"./workload\"\n\n/**\n * `PodSet.define` input. Drives a coherent Deployment + Service +\n * (optional) NetworkPolicy from a single `Selector` — every resource\n * derives its selector from `podSet`, so the trio cannot drift.\n */\nexport interface DefinePodSetInput<L extends Readonly<Record<string, string>>> {\n readonly podSet: Selector<L>\n readonly deployment: Omit<DeploymentFromPodSetInput<L>, \"podSet\">\n readonly service?: Omit<ServiceFromPodSetInput<L>, \"podSet\">\n readonly netPol?: Omit<NetworkPolicyFromPodSetInput<L>, \"podSet\">\n}\n\ntype PodSetOutput =\n | readonly [K8sDeployment, K8sService]\n | readonly [K8sDeployment, K8sService, K8sNetworkPolicy]\n | readonly [K8sDeployment, K8sNetworkPolicy]\n | readonly [K8sDeployment]\n\n/**\n * `PodSet` value namespace.\n *\n * const trio = PodSet.define({\n * podSet: redisCachePods,\n * deployment: { ... },\n * service: { ... },\n * netPol: { ... },\n * });\n *\n * Umbrella over `Deployment.fromPodSet`, `Service.fromPodSet`, and\n * `NetworkPolicy.fromPodSet` — emits whichever subset of the trio the\n * input specifies, all rooted at one `Selector`.\n */\nexport const PodSet = {\n define: <L extends Readonly<Record<string, string>>>(\n input: DefinePodSetInput<L>\n ): Manifest.Manifest<PodSetOutput> => {\n const deployment = Deployment.fromPodSet({ podSet: input.podSet, ...input.deployment })\n const service = input.service !== undefined\n ? Service.fromPodSet({ podSet: input.podSet, ...input.service })\n : undefined\n const netPol = input.netPol !== undefined\n ? NetworkPolicy.fromPodSet({ podSet: input.podSet, ...input.netPol })\n : undefined\n\n return Manifest.make<PodSetOutput>((ctx) =>\n Effect.gen(function*() {\n const d = yield* deployment.render(ctx)\n const s = service !== undefined ? yield* service.render(ctx) : undefined\n const n = netPol !== undefined ? yield* netPol.render(ctx) : undefined\n const reason =\n \"tuple element types are statically known per branch; the array literal is widened by TS, the brand-free runtime shape matches the typed tuple\"\n if (s !== undefined && n !== undefined) {\n return unsafeCoerce<readonly [K8sDeployment, K8sService, K8sNetworkPolicy]>([d, s, n], reason)\n }\n if (s !== undefined) return unsafeCoerce<readonly [K8sDeployment, K8sService]>([d, s], reason)\n if (n !== undefined) return unsafeCoerce<readonly [K8sDeployment, K8sNetworkPolicy]>([d, n], reason)\n return unsafeCoerce<readonly [K8sDeployment]>([d], reason)\n })\n )\n }\n}\n","import { unsafeCoerce } from \"@konfig.ts/core\"\n\n/**\n * Selector — one source of truth for \"this pod set.\"\n *\n * `Selector<L>` wraps a literal label record and brands it. Resources\n * that *select* pods — Deployment.selector, Service.selector,\n * NetworkPolicy.podSelector, HPA target — take the bundle directly via\n * `Deployment.fromPodSet` / `Service.fromPodSet` / `NetworkPolicy.fromPodSet`\n * so a drift across three resources (the classic \"service has no\n * endpoints / netpol denies everything\" bug) becomes a compile error.\n *\n * `Workload.web` already keeps these labels coherent internally; the\n * Selector is the win when users go off-script: StatefulSet, DaemonSet,\n * cross-namespace selectors, or wiring a NetworkPolicy from app A to\n * peer pods B.\n */\ndeclare const SelectorBrand: unique symbol\n\nexport interface Selector<L extends Readonly<Record<string, string>>> {\n readonly [SelectorBrand]: L\n readonly labels: L\n}\n\n/**\n * `Selector` value namespace.\n *\n * const apiPods = Selector.make({ app: \"api\", tier: \"web\" });\n */\nexport const Selector = {\n make: <const L extends Readonly<Record<string, string>>>(labels: L): Selector<L> =>\n unsafeCoerce<Selector<L>>(\n { labels },\n \"SelectorBrand is a unique-symbol phantom — no runtime value; runtime shape is { labels }\"\n )\n}\n\nexport type SelectorLabels<S> = S extends Selector<infer L> ? L : never\n","import type { Manifest, SecretRef } from \"@konfig.ts/core\"\nimport { Manifest as M, unsafeCoerce } from \"@konfig.ts/core\"\nimport { Effect } from \"effect\"\nimport type {\n CronJob as K8sCronJob,\n Deployment as K8sDeployment,\n Ingress as K8sIngress,\n IngressRule as K8sIngressRule,\n Service as K8sService,\n ServiceAccount as K8sServiceAccount,\n ServicePort as K8sServicePort\n} from \"./.generated/k8s-types\"\nimport type { ContainerInput, ContainerSpec } from \"./container\"\nimport { Ingress, type IngressTLSInput, Service } from \"./network\"\nimport type { ServicePortSpec } from \"./ports\"\nimport type { Volume } from \"./volume\"\nimport { CronJob, Deployment } from \"./workload\"\n\n/**\n * Union of port names declared by every `ContainerSpec` in `Cs`. Raw\n * `ContainerInput` entries (no `Container.define`) contribute `never`,\n * so untyped containers don't widen the result — they just don't add\n * any named-port options to the Service. With every container untyped,\n * the union collapses to `never` and `targetPort` is effectively\n * `number`-only, matching Kubernetes' behaviour when no port is named.\n */\ntype _PortNamesOfContainers<Cs extends ReadonlyArray<ContainerInput>> = {\n readonly [K in keyof Cs]: Cs[K] extends ContainerSpec<infer P, string> ? P : never\n}[number]\n\n/**\n * Reloader integration shorthand. Two complementary rotation models:\n *\n * - *Build-time* rotation (re-render → new hash → rolling update). konfig\n * does NOT stamp this automatically; it ships `hashSecretValues` as a\n * helper you attach yourself — feed it your resolved secret values and\n * place the digest into `deployment.podAnnotations`, so a value change\n * flips the pod template and triggers a rollout.\n * - *Runtime* rotation via Stakater's Reloader (operator watches mounted\n * Secrets/ConfigMaps and patches the workload to restart pods on change),\n * selected by the option below.\n *\n * Pick:\n *\n * - `\"off\"` (default) — no Reloader annotation. Pair with a build-time\n * `hashSecretValues` annotation if you accept the redeploy-on-edit model.\n * - `\"stakater\"` — emit `reloader.stakater.com/auto: \"true\"`. Reloader\n * watches every Secret/ConfigMap referenced by the pod spec.\n * - `\"stakater-strict\"` — emit `reloader.stakater.com/auto: \"true\"`\n * plus `reloader.stakater.com/match: \"true\"`, restricting watch\n * to objects with the matching annotation set on them.\n * - `{ secrets, configMaps }` — explicit per-resource lists, emitted\n * as `secret.reloader.stakater.com/reload` /\n * `configmap.reloader.stakater.com/reload` (comma-joined).\n *\n * See packages/k8s/README.md for the trade-off between build-time\n * hashes and runtime reloader.\n */\nexport type ReloaderOption =\n | \"off\"\n | \"stakater\"\n | \"stakater-strict\"\n | {\n readonly secrets?: ReadonlyArray<string>\n readonly configMaps?: ReadonlyArray<string>\n }\n\nconst _reloaderAnnotations = (\n opt: ReloaderOption | undefined\n): Readonly<Record<string, string>> => {\n if (opt === undefined || opt === \"off\") return {}\n if (opt === \"stakater\") return { \"reloader.stakater.com/auto\": \"true\" }\n if (opt === \"stakater-strict\") {\n return {\n \"reloader.stakater.com/auto\": \"true\",\n \"reloader.stakater.com/match\": \"true\"\n }\n }\n const out: Record<string, string> = {}\n if (opt.secrets && opt.secrets.length > 0) {\n out[\"secret.reloader.stakater.com/reload\"] = opt.secrets.join(\",\")\n }\n if (opt.configMaps && opt.configMaps.length > 0) {\n out[\"configmap.reloader.stakater.com/reload\"] = opt.configMaps.join(\",\")\n }\n return out\n}\n\ninterface WebInput<Cs extends ReadonlyArray<ContainerInput>> {\n readonly name: string\n readonly namespace: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n /** Pod-restart-on-rotation integration. See `ReloaderOption`. */\n readonly reloader?: ReloaderOption\n readonly deployment: {\n readonly replicas?: number\n readonly containers: Cs\n readonly volumes?: ReadonlyArray<Volume>\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n readonly serviceAccountName?: string\n readonly podLabels?: Readonly<Record<string, string>>\n readonly podAnnotations?: Readonly<Record<string, string>>\n }\n readonly service: {\n readonly ports: ReadonlyArray<ServicePortSpec<NoInfer<_PortNamesOfContainers<Cs>>>>\n readonly type?: \"ClusterIP\" | \"NodePort\" | \"LoadBalancer\"\n }\n readonly ingress?: {\n readonly ingressClassName?: string\n readonly rules?: ReadonlyArray<K8sIngressRule>\n readonly tls?: ReadonlyArray<IngressTLSInput>\n readonly annotations?: Readonly<Record<string, string>>\n }\n}\n\nexport const web = <const Cs extends ReadonlyArray<ContainerInput>>(\n input: WebInput<Cs>\n): Manifest.Manifest<\n readonly [K8sDeployment, K8sService] | readonly [K8sDeployment, K8sService, K8sIngress]\n> => {\n const selectorLabels = { app: input.name }\n // selectorLabels are spread LAST so a colliding user pod label can never\n // override the `app` selector — that would desync the pod template from\n // `spec.selector` and leave the Service with zero endpoints.\n const podLabels = { ...input.deployment.podLabels, ...selectorLabels }\n\n const reloaderAnns = _reloaderAnnotations(input.reloader)\n const deployment = Deployment.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: { ...input.annotations, ...reloaderAnns },\n replicas: input.deployment.replicas,\n selector: { matchLabels: selectorLabels },\n template: {\n metadata: { labels: podLabels, annotations: input.deployment.podAnnotations },\n spec: {\n containers: input.deployment.containers,\n volumes: input.deployment.volumes,\n imagePullSecrets: input.deployment.imagePullSecrets,\n serviceAccountName: input.deployment.serviceAccountName\n }\n }\n })\n\n const service = Service.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations,\n selector: selectorLabels,\n type: input.service.type ?? \"ClusterIP\",\n ports: unsafeCoerce<ReadonlyArray<K8sServicePort>>(\n input.service.ports,\n \"ServicePortSpec<Ports> structurally matches K8sServicePort; the PortName<Ports> brand on targetPort is a phantom whose runtime value is the underlying string\"\n )\n })\n\n if (input.ingress === undefined) {\n return M.make((ctx) => Effect.all([deployment.render(ctx), service.render(ctx)], { concurrency: \"unbounded\" }))\n }\n\n const ingress = Ingress.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: { ...input.annotations, ...input.ingress.annotations },\n ingressClassName: input.ingress.ingressClassName,\n rules: input.ingress.rules,\n tls: input.ingress.tls\n })\n\n return M.make((ctx) =>\n Effect.all([deployment.render(ctx), service.render(ctx), ingress.render(ctx)], {\n concurrency: \"unbounded\"\n })\n )\n}\n\ninterface CronInput {\n readonly name: string\n readonly namespace: string\n readonly schedule: string\n readonly labels?: Readonly<Record<string, string>>\n readonly annotations?: Readonly<Record<string, string>>\n readonly concurrencyPolicy?: \"Allow\" | \"Forbid\" | \"Replace\"\n readonly successfulJobsHistoryLimit?: number\n readonly failedJobsHistoryLimit?: number\n readonly containers: ReadonlyArray<ContainerInput>\n readonly volumes?: ReadonlyArray<Volume>\n readonly imagePullSecrets?: ReadonlyArray<{ readonly name: SecretRef<string> }>\n readonly restartPolicy?: \"OnFailure\" | \"Never\"\n}\n\nexport const cron = (\n input: CronInput\n): Manifest.Manifest<readonly [K8sServiceAccount, K8sCronJob]> => {\n const selectorLabels = { app: input.name }\n\n const sa: Manifest.Manifest<K8sServiceAccount> = M.make<K8sServiceAccount>(() =>\n Effect.succeed({\n apiVersion: \"v1\",\n kind: \"ServiceAccount\",\n metadata: {\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations\n }\n })\n )\n\n const cronJob = CronJob.make({\n name: input.name,\n namespace: input.namespace,\n labels: { ...selectorLabels, ...input.labels },\n annotations: input.annotations,\n schedule: input.schedule,\n concurrencyPolicy: input.concurrencyPolicy,\n successfulJobsHistoryLimit: input.successfulJobsHistoryLimit,\n failedJobsHistoryLimit: input.failedJobsHistoryLimit,\n jobTemplate: {\n spec: {\n template: {\n metadata: { labels: selectorLabels },\n spec: {\n containers: input.containers,\n volumes: input.volumes,\n imagePullSecrets: input.imagePullSecrets,\n serviceAccountName: input.name,\n restartPolicy: input.restartPolicy ?? \"OnFailure\"\n }\n }\n }\n }\n })\n\n return M.make((ctx) => Effect.all([sa.render(ctx), cronJob.render(ctx)], { concurrency: \"unbounded\" }))\n}\n","export * as K8s from \"./.generated/k8s-types\"\nexport {\n Container,\n type ContainerInput,\n type ContainerSpec,\n type DefineContainerInput,\n type DefinedPod,\n type DefinePodInput,\n Pod,\n type PodSpecInput\n} from \"./container\"\nexport {\n type ContainerPort,\n type ContainerProtocol,\n type ExecAction,\n type GrpcAction,\n type HttpGetAction,\n type HttpHeader,\n type NamesOf,\n Port,\n type PortInput,\n type PortName,\n type ProbeTarget,\n type ServicePortSpec,\n type TcpSocketAction\n} from \"./ports\"\n\nexport {\n type ConfigMapEnvInput,\n EnvVar,\n type EnvVarSource,\n type RawEnvInput,\n type SecretEnvForPodInput,\n type SecretEnvInput,\n type ValueEnvInput\n} from \"./env\"\nexport {\n ConfigMap,\n type ConfigMapInput,\n type ConfigMapManifest,\n Namespace,\n type NamespaceInput,\n type NamespaceManifest,\n type SecretInput,\n type SecretManifest,\n ServiceAccount,\n type ServiceAccountInput,\n type ServiceAccountManifest\n} from \"./identity\"\nimport { Environment as _EnvironmentContract, runtime as envRuntime, Secret as _SecretContract } from \"@konfig.ts/env\"\nimport { bindEnvironment } from \"./environmentBind\"\nimport { Secret as _SecretIdentity } from \"./identity\"\nimport { bindSecret } from \"./secretBind\"\n\n/**\n * `Secret` value namespace — merges the env-contracts side (`define`)\n * with the K8s side (`make`, `bind`, identity helpers). Importing\n * `Secret` from `@konfig.ts/k8s` gives you the full surface:\n *\n * Secret.define({ name, namespace, env }) — env contract (from @konfig.ts/env)\n * Secret.make({ name, namespace, stringData }) — K8s Secret manifest\n * Secret.bind({ secret, backend, source }) — env-to-manifest binder\n */\nexport const Secret = { ..._SecretContract, ..._SecretIdentity, bind: bindSecret }\n\n/**\n * `Environment` value namespace — merges `define` (env-contracts) with\n * `bind` + `runtime` (K8s). The same `Environment` symbol carries the\n * declaration, the manifest binder, and the runtime decoder.\n */\nexport const Environment = {\n ..._EnvironmentContract,\n bind: bindEnvironment,\n runtime: envRuntime\n}\nexport { type BackendEmitInput, BackendSourceMissing, type BackendTag, type SecretBackend } from \"./backend\"\nexport type {\n BindEnvironmentInput,\n DeclaredDownward,\n DeclaredEnvironment,\n DeclaredLiteral,\n DeclaredMember,\n HasSecrets,\n SecretMemberOptions,\n SecretMemberOptionsFor,\n SecretMembersOpts\n} from \"./environmentBind\"\nexport { NativeSecret, type NativeSecretOptions } from \"./nativeSecret\"\nexport {\n Ingress,\n type IngressInput,\n type IngressTLSInput,\n Service,\n type ServiceFromContainerInput,\n type ServiceFromPodSetInput,\n type ServiceInput\n} from \"./network\"\nexport { hashSecretValues, type HashSecretValuesInput } from \"./podHash\"\nexport {\n ClusterRole,\n ClusterRoleBinding,\n type ClusterRoleBindingInput,\n type ClusterRoleInput,\n NetworkPolicy,\n type NetworkPolicyEgressRule,\n type NetworkPolicyFromPodSetInput,\n type NetworkPolicyIngressRule,\n type NetworkPolicyInput,\n type NetworkPolicyPeer,\n PersistentVolume,\n PersistentVolumeClaim,\n type PersistentVolumeClaimInput,\n type PersistentVolumeInput,\n Role,\n RoleBinding,\n type RoleBindingInput,\n type RoleInput\n} from \"./policy\"\nexport type { ConfigMapRefName, PvcRefName, SecretRefName } from \"./refs\"\nexport { ConfigMapRef, PvcRef, SecretRef, ServiceAccountRef } from \"./refs\"\nexport type { BindSecretInput, DeclaredSecret } from \"./secretBind\"\nexport { Volume } from \"./volume\"\nexport type {\n EmptyVolumeInput,\n VolumeFromConfigMapInput,\n VolumeFromPvcInput,\n VolumeFromSecretInput,\n VolumeMount,\n VolumeName,\n VolumeNamesOf\n} from \"./volume\"\nexport {\n CronJob,\n type CronJobInput,\n Deployment,\n type DeploymentFromPodSetInput,\n type DeploymentInput,\n Job,\n type JobInput,\n StatefulSet,\n type StatefulSetInput\n} from \"./workload\"\n\nexport { type DefinePodSetInput, PodSet } from \"./podSet\"\nexport { Selector } from \"./selector\"\nexport type { SelectorLabels } from \"./selector\"\nexport * as Workload from \"./workloadHelpers\"\n"],"mappings":"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"}
|
package/dist/network.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Manifest, type SecretRef } from "@konfig.ts/core";
|
|
2
|
-
import type { ContainerSpec } from "./container";
|
|
3
|
-
import type { Ingress as K8sIngress, IngressRule as K8sIngressRule, Service as K8sService, ServicePort as K8sServicePort } from "./.generated/k8s-types";
|
|
4
2
|
import type { IngressBackend as K8sIngressBackend } from "kubernetes-types/networking/v1";
|
|
3
|
+
import type { Ingress as K8sIngress, IngressRule as K8sIngressRule, Service as K8sService, ServicePort as K8sServicePort } from "./.generated/k8s-types";
|
|
4
|
+
import type { ContainerSpec } from "./container";
|
|
5
5
|
import type { ServicePortSpec } from "./ports";
|
|
6
6
|
import type { Selector } from "./selector";
|
|
7
7
|
/**
|
package/dist/podSet.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Manifest } from "@konfig.ts/core";
|
|
2
2
|
import type { Deployment as K8sDeployment, NetworkPolicy as K8sNetworkPolicy, Service as K8sService } from "./.generated/k8s-types";
|
|
3
|
+
import { type ServiceFromPodSetInput } from "./network";
|
|
3
4
|
import { type NetworkPolicyFromPodSetInput } from "./policy";
|
|
4
5
|
import type { Selector } from "./selector";
|
|
5
|
-
import { type ServiceFromPodSetInput } from "./network";
|
|
6
6
|
import { type DeploymentFromPodSetInput } from "./workload";
|
|
7
7
|
/**
|
|
8
8
|
* `PodSet.define` input. Drives a coherent Deployment + Service +
|
package/dist/policy.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Manifest } from "@konfig.ts/core";
|
|
2
|
-
import type { ClusterRole as K8sClusterRole, ClusterRoleBinding as K8sClusterRoleBinding, NetworkPolicy as K8sNetworkPolicy, PersistentVolume as K8sPersistentVolume, PersistentVolumeClaim as K8sPersistentVolumeClaim, Role as K8sRole, RoleBinding as K8sRoleBinding } from "./.generated/k8s-types";
|
|
3
2
|
import type { PersistentVolumeSpec as K8sPersistentVolumeSpec } from "kubernetes-types/core/v1";
|
|
4
3
|
import type { NetworkPolicyEgressRule as K8sNetworkPolicyEgressRule, NetworkPolicyIngressRule as K8sNetworkPolicyIngressRule } from "kubernetes-types/networking/v1";
|
|
4
|
+
import type { ClusterRole as K8sClusterRole, ClusterRoleBinding as K8sClusterRoleBinding, NetworkPolicy as K8sNetworkPolicy, PersistentVolume as K8sPersistentVolume, PersistentVolumeClaim as K8sPersistentVolumeClaim, Role as K8sRole, RoleBinding as K8sRoleBinding } from "./.generated/k8s-types";
|
|
5
5
|
import type { Selector } from "./selector";
|
|
6
6
|
interface NamespacedMeta {
|
|
7
7
|
readonly name: string;
|
package/dist/refs.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { type ConfigMapRef as CMRef, type PvcRef as PRef, type
|
|
1
|
+
import { type ConfigMapRef as CMRef, type PvcRef as PRef, type SecretRef as SRef, type ServiceAccountRef as SARef } from "@konfig.ts/core";
|
|
2
2
|
export type SecretRef<N extends string = string, K extends string = string, Ns extends string = string> = SRef<N, K, Ns>;
|
|
3
3
|
export type ConfigMapRef<N extends string = string, K extends string = string> = CMRef<N, K>;
|
|
4
4
|
export type ServiceAccountRef<N extends string = string> = SARef<N>;
|
|
5
5
|
export type PvcRef<N extends string = string> = PRef<N>;
|
|
6
|
-
export type { ConfigMapRefKeys, ConfigMapRefName, PvcRefName, SecretRefKeys, SecretRefName
|
|
6
|
+
export type { ConfigMapRefKeys, ConfigMapRefName, PvcRefName, SecretRefKeys, SecretRefName } from "@konfig.ts/core";
|
|
7
7
|
export type { SecretRefNamespace } from "@konfig.ts/core";
|
|
8
8
|
export declare const SecretRef: {
|
|
9
9
|
of: <N extends string, K extends string = string, Ns extends string = string>(name: N) => SecretRef<N, K, Ns>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@konfig.ts/k8s",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.8",
|
|
4
4
|
"description": "Kubernetes resource builders (workloads, network, identity, policy, volume, env) for konfig.ts.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "David Stahl-Gruber",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
"LICENSE"
|
|
35
35
|
],
|
|
36
36
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
37
|
+
"node": ">=22"
|
|
38
38
|
},
|
|
39
39
|
"publishConfig": {
|
|
40
40
|
"access": "public"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
|
43
|
-
"build": "tsdown ./src/index.ts --format=esm --target=
|
|
43
|
+
"build": "tsdown ./src/index.ts --format=esm --target=node22 --sourcemap --clean --no-dts && tsc -p tsconfig.build.json",
|
|
44
44
|
"check": "tsc -p tsconfig.check.json --noEmit",
|
|
45
45
|
"test": "vitest run",
|
|
46
46
|
"lint": "oxlint",
|
|
@@ -50,18 +50,18 @@
|
|
|
50
50
|
"postpack": "node ../../scripts/prepack-exports.mjs restore"
|
|
51
51
|
},
|
|
52
52
|
"dependencies": {
|
|
53
|
-
"@konfig.ts/core": "0.0.
|
|
54
|
-
"@konfig.ts/env": "0.0.
|
|
53
|
+
"@konfig.ts/core": "0.0.8",
|
|
54
|
+
"@konfig.ts/env": "0.0.8",
|
|
55
55
|
"kubernetes-types": "~1.30.0"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"effect": "4.0.0-beta.
|
|
58
|
+
"effect": "4.0.0-beta.98"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
|
-
"@effect/platform-node": "4.0.0-beta.
|
|
62
|
-
"@effect/vitest": "4.0.0-beta.
|
|
61
|
+
"@effect/platform-node": "4.0.0-beta.98",
|
|
62
|
+
"@effect/vitest": "4.0.0-beta.98",
|
|
63
63
|
"@types/bun": "^1.3.6",
|
|
64
|
-
"effect": "4.0.0-beta.
|
|
64
|
+
"effect": "4.0.0-beta.98",
|
|
65
65
|
"fast-check": "^4.7.0",
|
|
66
66
|
"typescript": "^5.8.3",
|
|
67
67
|
"vitest": "^4.0.18"
|