@intentius/chant 0.30.0 → 0.31.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -23,6 +23,15 @@ export interface GenerateResult {
|
|
|
23
23
|
file: string;
|
|
24
24
|
error: string;
|
|
25
25
|
}>;
|
|
26
|
+
/**
|
|
27
|
+
* Additional generated files, keyed by filename, produced by the optional
|
|
28
|
+
* {@link GeneratePipelineConfig.generateExtraArtifacts} hook. They come out
|
|
29
|
+
* of the same parse a lexicon's types and registry come out of, which is the
|
|
30
|
+
* point: an artifact derived here cannot drift from the types, the way a
|
|
31
|
+
* hand-maintained table beside them can (chant #1074's operation surface is
|
|
32
|
+
* the first of these).
|
|
33
|
+
*/
|
|
34
|
+
extraArtifacts?: Record<string, string>;
|
|
26
35
|
}
|
|
27
36
|
/**
|
|
28
37
|
* A parsed result with enough structure for the pipeline to count stats.
|
|
@@ -62,6 +71,13 @@ export interface GeneratePipelineConfig<T extends ParsedResult> {
|
|
|
62
71
|
generateTypes: (results: T[], naming: NamingStrategy) => string;
|
|
63
72
|
/** Generate runtime index with factory exports. */
|
|
64
73
|
generateRuntimeIndex: (results: T[], naming: NamingStrategy) => string;
|
|
74
|
+
/**
|
|
75
|
+
* Optional extra artifacts from the same parsed results — filename → content.
|
|
76
|
+
* Used when a lexicon needs a second derived table alongside the registry and
|
|
77
|
+
* the types, and needs it to come from the same pass so the three cannot
|
|
78
|
+
* skew.
|
|
79
|
+
*/
|
|
80
|
+
generateExtraArtifacts?: (results: T[], naming: NamingStrategy) => Record<string, string>;
|
|
65
81
|
/** Optional pre-parse hook (patches, overlays, extra resources, etc.). */
|
|
66
82
|
augmentSchemas?: (schemas: Map<string, Buffer>, opts: GenerateOptions, log: (msg: string) => void) => Promise<AugmentResult<T>>;
|
|
67
83
|
/** Optional post-parse hook (add synthetic resources, fallbacks, etc.). */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAI/C,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/codegen/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -52,6 +52,23 @@ export interface ResolvedClusterTarget {
|
|
|
52
52
|
/** Where the target came from. */
|
|
53
53
|
source: "bound" | "ambient";
|
|
54
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* How the resolver learns which context is ambient. The default shells
|
|
57
|
+
* `kubectl config current-context`; the k8s lexicon's typed API client
|
|
58
|
+
* (chant #1074) supplies one that reads the parsed kubeconfig instead, so a
|
|
59
|
+
* client that never needs the `kubectl` binary does not acquire a dependency
|
|
60
|
+
* on it just to check the binding. Both answer the same question, so the
|
|
61
|
+
* refusal semantics below are identical either way.
|
|
62
|
+
*/
|
|
63
|
+
export type AmbientContextReader = () => Promise<string | undefined>;
|
|
64
|
+
/** Options for {@link resolveClusterTarget}. */
|
|
65
|
+
export interface ResolveClusterTargetOptions {
|
|
66
|
+
/**
|
|
67
|
+
* Override how the ambient context is read. Defaults to
|
|
68
|
+
* `kubectl config current-context`.
|
|
69
|
+
*/
|
|
70
|
+
ambientContext?: AmbientContextReader;
|
|
71
|
+
}
|
|
55
72
|
/**
|
|
56
73
|
* Resolve the kubectl context an environment should be observed/applied
|
|
57
74
|
* against, reading `k8s.profiles.<environment>.context` from `chant.config.ts`
|
|
@@ -70,7 +87,7 @@ export interface ResolvedClusterTarget {
|
|
|
70
87
|
* {@link ClusterBindingMismatchError} — a loud refusal instead of quietly
|
|
71
88
|
* reading the wrong cluster.
|
|
72
89
|
*/
|
|
73
|
-
export declare function resolveClusterTarget(config: Record<string, unknown>, environment: string, lexiconName: string): Promise<ResolvedClusterTarget>;
|
|
90
|
+
export declare function resolveClusterTarget(config: Record<string, unknown>, environment: string, lexiconName: string, options?: ResolveClusterTargetOptions): Promise<ResolvedClusterTarget>;
|
|
74
91
|
/**
|
|
75
92
|
* What a failed `kubectl get` actually proved. Shared by the k8s and gcp
|
|
76
93
|
* lexicons, which read through the same kubectl path and used to collapse every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"kubectl-context.d.ts","sourceRoot":"","sources":["../src/kubectl-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;aAElC,WAAW,EAAE,MAAM;aACnB,eAAe,EAAE,MAAM;aACvB,cAAc,EAAE,MAAM;gBAFtB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM;CAWzC;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"kubectl-context.d.ts","sourceRoot":"","sources":["../src/kubectl-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAItD,wFAAwF;AACxF,MAAM,WAAW,iBAAiB;IAChC,yDAAyD;IACzD,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wFAAwF;AACxF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC9C;AAED;;;;;;GAMG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;aAElC,WAAW,EAAE,MAAM;aACnB,eAAe,EAAE,MAAM;aACvB,cAAc,EAAE,MAAM;gBAFtB,WAAW,EAAE,MAAM,EACnB,eAAe,EAAE,MAAM,EACvB,cAAc,EAAE,MAAM;CAWzC;AAED,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kCAAkC;IAClC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;CAC7B;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,MAAM,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;AAarE,gDAAgD;AAChD,MAAM,WAAW,2BAA2B;IAC1C;;;OAGG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;CACvC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,2BAAgC,GACxC,OAAO,CAAC,qBAAqB,CAAC,CAmBhC;AAID;;;;;GAKG;AACH,MAAM,MAAM,kBAAkB;AAC5B,kFAAkF;AAChF;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE;AACpB,4DAA4D;GAC1D;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAmBrE;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,CAuCvE"}
|
package/package.json
CHANGED
package/src/codegen/generate.ts
CHANGED
|
@@ -27,6 +27,15 @@ export interface GenerateResult {
|
|
|
27
27
|
properties: number;
|
|
28
28
|
enums: number;
|
|
29
29
|
warnings: Array<{ file: string; error: string }>;
|
|
30
|
+
/**
|
|
31
|
+
* Additional generated files, keyed by filename, produced by the optional
|
|
32
|
+
* {@link GeneratePipelineConfig.generateExtraArtifacts} hook. They come out
|
|
33
|
+
* of the same parse a lexicon's types and registry come out of, which is the
|
|
34
|
+
* point: an artifact derived here cannot drift from the types, the way a
|
|
35
|
+
* hand-maintained table beside them can (chant #1074's operation surface is
|
|
36
|
+
* the first of these).
|
|
37
|
+
*/
|
|
38
|
+
extraArtifacts?: Record<string, string>;
|
|
30
39
|
}
|
|
31
40
|
|
|
32
41
|
/**
|
|
@@ -68,6 +77,14 @@ export interface GeneratePipelineConfig<T extends ParsedResult> {
|
|
|
68
77
|
/** Generate runtime index with factory exports. */
|
|
69
78
|
generateRuntimeIndex: (results: T[], naming: NamingStrategy) => string;
|
|
70
79
|
|
|
80
|
+
/**
|
|
81
|
+
* Optional extra artifacts from the same parsed results — filename → content.
|
|
82
|
+
* Used when a lexicon needs a second derived table alongside the registry and
|
|
83
|
+
* the types, and needs it to come from the same pass so the three cannot
|
|
84
|
+
* skew.
|
|
85
|
+
*/
|
|
86
|
+
generateExtraArtifacts?: (results: T[], naming: NamingStrategy) => Record<string, string>;
|
|
87
|
+
|
|
71
88
|
/** Optional pre-parse hook (patches, overlays, extra resources, etc.). */
|
|
72
89
|
augmentSchemas?: (
|
|
73
90
|
schemas: Map<string, Buffer>,
|
|
@@ -161,6 +178,13 @@ export async function generatePipeline<T extends ParsedResult>(
|
|
|
161
178
|
log("Generating runtime index...");
|
|
162
179
|
const indexTS = config.generateRuntimeIndex(results, naming);
|
|
163
180
|
|
|
181
|
+
let extraArtifacts: Record<string, string> | undefined;
|
|
182
|
+
if (config.generateExtraArtifacts) {
|
|
183
|
+
log("Generating extra artifacts...");
|
|
184
|
+
extraArtifacts = config.generateExtraArtifacts(results, naming);
|
|
185
|
+
log(`Generated ${Object.keys(extraArtifacts).length} extra artifact(s)`);
|
|
186
|
+
}
|
|
187
|
+
|
|
164
188
|
// Count stats
|
|
165
189
|
let resourceCount = 0;
|
|
166
190
|
let propertyCount = 0;
|
|
@@ -179,6 +203,7 @@ export async function generatePipeline<T extends ParsedResult>(
|
|
|
179
203
|
properties: propertyCount,
|
|
180
204
|
enums: enumCount,
|
|
181
205
|
warnings,
|
|
206
|
+
...(extraArtifacts ? { extraArtifacts } : {}),
|
|
182
207
|
};
|
|
183
208
|
}
|
|
184
209
|
|
package/src/kubectl-context.ts
CHANGED
|
@@ -72,8 +72,18 @@ export interface ResolvedClusterTarget {
|
|
|
72
72
|
source: "bound" | "ambient";
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* How the resolver learns which context is ambient. The default shells
|
|
77
|
+
* `kubectl config current-context`; the k8s lexicon's typed API client
|
|
78
|
+
* (chant #1074) supplies one that reads the parsed kubeconfig instead, so a
|
|
79
|
+
* client that never needs the `kubectl` binary does not acquire a dependency
|
|
80
|
+
* on it just to check the binding. Both answer the same question, so the
|
|
81
|
+
* refusal semantics below are identical either way.
|
|
82
|
+
*/
|
|
83
|
+
export type AmbientContextReader = () => Promise<string | undefined>;
|
|
84
|
+
|
|
75
85
|
/** Reads `kubectl config current-context`. Returns undefined if unset or kubectl fails. */
|
|
76
|
-
|
|
86
|
+
const currentAmbientContext: AmbientContextReader = async () => {
|
|
77
87
|
try {
|
|
78
88
|
const { stdout } = await execAsync("kubectl config current-context");
|
|
79
89
|
const trimmed = stdout.trim();
|
|
@@ -81,6 +91,15 @@ async function currentAmbientContext(): Promise<string | undefined> {
|
|
|
81
91
|
} catch {
|
|
82
92
|
return undefined;
|
|
83
93
|
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
/** Options for {@link resolveClusterTarget}. */
|
|
97
|
+
export interface ResolveClusterTargetOptions {
|
|
98
|
+
/**
|
|
99
|
+
* Override how the ambient context is read. Defaults to
|
|
100
|
+
* `kubectl config current-context`.
|
|
101
|
+
*/
|
|
102
|
+
ambientContext?: AmbientContextReader;
|
|
84
103
|
}
|
|
85
104
|
|
|
86
105
|
/**
|
|
@@ -105,6 +124,7 @@ export async function resolveClusterTarget(
|
|
|
105
124
|
config: Record<string, unknown>,
|
|
106
125
|
environment: string,
|
|
107
126
|
lexiconName: string,
|
|
127
|
+
options: ResolveClusterTargetOptions = {},
|
|
108
128
|
): Promise<ResolvedClusterTarget> {
|
|
109
129
|
const k8sConfig = config.k8s as K8sConfigShape | undefined;
|
|
110
130
|
const bound = k8sConfig?.profiles?.[environment]?.context;
|
|
@@ -118,7 +138,7 @@ export async function resolveClusterTarget(
|
|
|
118
138
|
return { source: "ambient" };
|
|
119
139
|
}
|
|
120
140
|
|
|
121
|
-
const ambient = await currentAmbientContext();
|
|
141
|
+
const ambient = await (options.ambientContext ?? currentAmbientContext)();
|
|
122
142
|
if (ambient && ambient !== bound) {
|
|
123
143
|
throw new ClusterBindingMismatchError(environment, bound, ambient);
|
|
124
144
|
}
|