@truefoundry/tfy-infra-engine 0.0.0-canary.6233945
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/README.md +287 -0
- package/dist/index.d.mts +589 -0
- package/dist/index.d.ts +589 -0
- package/dist/index.js +1155 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1109 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +59 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,589 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Engine error codes for programmatic error handling.
|
|
3
|
+
*/
|
|
4
|
+
declare enum EngineErrorCode {
|
|
5
|
+
TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
|
|
6
|
+
NETWORK_ERROR = "NETWORK_ERROR",
|
|
7
|
+
GITHUB_NOT_FOUND = "GITHUB_NOT_FOUND",
|
|
8
|
+
GITHUB_RATE_LIMITED = "GITHUB_RATE_LIMITED",
|
|
9
|
+
FILE_NOT_FOUND = "FILE_NOT_FOUND",
|
|
10
|
+
HTTPS_AUTH_FAILED = "HTTPS_AUTH_FAILED",
|
|
11
|
+
SCHEMA_INVALID = "SCHEMA_INVALID",
|
|
12
|
+
INPUT_VALIDATION_FAILED = "INPUT_VALIDATION_FAILED",
|
|
13
|
+
TEMPLATE_JSON_NOT_FOUND = "TEMPLATE_JSON_NOT_FOUND",
|
|
14
|
+
TEMPLATE_JSON_INVALID = "TEMPLATE_JSON_INVALID",
|
|
15
|
+
TEMPLATE_SYNTAX_ERROR = "TEMPLATE_SYNTAX_ERROR",
|
|
16
|
+
TOFU_NOT_FOUND = "TOFU_NOT_FOUND",
|
|
17
|
+
TOFU_FMT_FAILED = "TOFU_FMT_FAILED",
|
|
18
|
+
CACHE_ERROR = "CACHE_ERROR",
|
|
19
|
+
ENVELOPE_VALIDATION_FAILED = "ENVELOPE_VALIDATION_FAILED",
|
|
20
|
+
MANIFEST_PARSE_ERROR = "MANIFEST_PARSE_ERROR"
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Custom error class for engine errors.
|
|
24
|
+
* Provides structured error information including error code, cause, and details.
|
|
25
|
+
*/
|
|
26
|
+
declare class EngineError extends Error {
|
|
27
|
+
readonly code: EngineErrorCode;
|
|
28
|
+
readonly details?: Record<string, unknown>;
|
|
29
|
+
constructor(message: string, code: EngineErrorCode, cause?: Error, details?: Record<string, unknown>);
|
|
30
|
+
/**
|
|
31
|
+
* Create a string representation including error code.
|
|
32
|
+
*/
|
|
33
|
+
toString(): string;
|
|
34
|
+
/**
|
|
35
|
+
* Convert error to JSON-serializable object.
|
|
36
|
+
*/
|
|
37
|
+
toJSON(): Record<string, unknown>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* JSON Schema type definitions.
|
|
42
|
+
*
|
|
43
|
+
* CHANGE (008): All Zod-based converter functions and zod-to-json-schema
|
|
44
|
+
* import removed. Only the JSONSchema7 type interface remains.
|
|
45
|
+
* Templates provide JSON Schema directly via template.json.
|
|
46
|
+
*/
|
|
47
|
+
/**
|
|
48
|
+
* JSON Schema Draft-07 type.
|
|
49
|
+
*/
|
|
50
|
+
interface JSONSchema7 {
|
|
51
|
+
$schema?: string;
|
|
52
|
+
$ref?: string;
|
|
53
|
+
type?: string;
|
|
54
|
+
properties?: Record<string, JSONSchema7>;
|
|
55
|
+
required?: string[];
|
|
56
|
+
default?: unknown;
|
|
57
|
+
description?: string;
|
|
58
|
+
items?: JSONSchema7;
|
|
59
|
+
additionalProperties?: boolean | JSONSchema7;
|
|
60
|
+
oneOf?: JSONSchema7[];
|
|
61
|
+
anyOf?: JSONSchema7[];
|
|
62
|
+
allOf?: JSONSchema7[];
|
|
63
|
+
enum?: unknown[];
|
|
64
|
+
const?: unknown;
|
|
65
|
+
pattern?: string;
|
|
66
|
+
minimum?: number;
|
|
67
|
+
maximum?: number;
|
|
68
|
+
minLength?: number;
|
|
69
|
+
maxLength?: number;
|
|
70
|
+
discriminator?: {
|
|
71
|
+
propertyName: string;
|
|
72
|
+
};
|
|
73
|
+
[key: string]: unknown;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Core type definitions for the HCL templating engine.
|
|
78
|
+
*
|
|
79
|
+
* These interfaces define the data model for templates, schemas, rendering,
|
|
80
|
+
* and the integrity engine (zone classification, file headers, manifests,
|
|
81
|
+
* drift reports, and the four-operation API).
|
|
82
|
+
*
|
|
83
|
+
* CHANGE (008): TemplateSchema, InputDefinition, OutputDefinition removed.
|
|
84
|
+
* Replaced by TemplateMetadata + JSONSchema7. sideOutputs removed from results.
|
|
85
|
+
*
|
|
86
|
+
* References:
|
|
87
|
+
* - specs/004-infra-integrity-engine/contracts/engine-api.ts
|
|
88
|
+
* - specs/004-infra-integrity-engine/data-model.md
|
|
89
|
+
* - specs/008-json-schema-engine/data-model.md
|
|
90
|
+
*/
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* File ownership zone classification.
|
|
94
|
+
* (FR-001, FR-002)
|
|
95
|
+
*/
|
|
96
|
+
type Zone = 'platform' | 'user';
|
|
97
|
+
/**
|
|
98
|
+
* Drift finding classification.
|
|
99
|
+
* (FR-015, FR-028, FR-042)
|
|
100
|
+
*/
|
|
101
|
+
type DriftType = 'content_drift' | 'metadata_inconsistency' | 'source_mismatch' | 'missing_file' | 'unexpected_file';
|
|
102
|
+
/**
|
|
103
|
+
* Structured metadata embedded in every Platform Zone file as HCL comments.
|
|
104
|
+
* (FR-025)
|
|
105
|
+
*
|
|
106
|
+
* Serialized format (R-001):
|
|
107
|
+
* ```hcl
|
|
108
|
+
* # @tfy-status:begin
|
|
109
|
+
* # {"managed":true,"source":"...","version":"...","intent_id":"...","content_hash":"sha256:..."}
|
|
110
|
+
* # @tfy-status:end
|
|
111
|
+
* ```
|
|
112
|
+
*
|
|
113
|
+
* Note: JSON field names use snake_case (intent_id, content_hash) for HCL
|
|
114
|
+
* convention consistency. TypeScript interface uses camelCase.
|
|
115
|
+
*/
|
|
116
|
+
interface TfyStatusHeader {
|
|
117
|
+
/** Always true for Platform Zone files */
|
|
118
|
+
managed: boolean;
|
|
119
|
+
/** Template origin URI (e.g., "tfy-registry/aws/eks-core") */
|
|
120
|
+
source: string;
|
|
121
|
+
/** Template semver tag (e.g., "v2.4.1") */
|
|
122
|
+
version: string;
|
|
123
|
+
/** Cluster identity — same value for all files in a cluster */
|
|
124
|
+
intentId: string;
|
|
125
|
+
/** SHA-256 of file content excluding the header ("sha256:<hex>") */
|
|
126
|
+
contentHash: string;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* A single entry in the engine's output file map.
|
|
130
|
+
* (FR-039, FR-040)
|
|
131
|
+
*/
|
|
132
|
+
interface FileEntry {
|
|
133
|
+
/** Full file content (includes @tfy-status header for platform files) */
|
|
134
|
+
content: string;
|
|
135
|
+
/** File ownership zone */
|
|
136
|
+
zone: Zone;
|
|
137
|
+
/** Parsed header metadata (present only for platform zone files) */
|
|
138
|
+
header?: TfyStatusHeader;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Zone-tagged file map — the engine's standard output format.
|
|
142
|
+
* Keys are relative file paths.
|
|
143
|
+
* (FR-021, FR-039)
|
|
144
|
+
*/
|
|
145
|
+
type FileMap = Map<string, FileEntry>;
|
|
146
|
+
/**
|
|
147
|
+
* The engine's input configuration.
|
|
148
|
+
*
|
|
149
|
+
* CHANGE (006): `template` field accepts a resolved `Template` object
|
|
150
|
+
* instead of a URI string. The caller is responsible for fetching
|
|
151
|
+
* and constructing the Template before calling the engine.
|
|
152
|
+
* (FR-031, FR-032)
|
|
153
|
+
*/
|
|
154
|
+
interface Envelope {
|
|
155
|
+
/** Resolved template (caller fetches, engine consumes) */
|
|
156
|
+
template: Template;
|
|
157
|
+
/** Input values to pass to template */
|
|
158
|
+
inputs: Record<string, unknown>;
|
|
159
|
+
/** Optional rendering options */
|
|
160
|
+
options?: RenderOptions;
|
|
161
|
+
/** Cluster identity — propagated to file headers and Manifest (FR-031) */
|
|
162
|
+
intentId: string;
|
|
163
|
+
/** Filename prefix for Platform Zone files (default: "tfy_") */
|
|
164
|
+
platformPrefix?: string;
|
|
165
|
+
}
|
|
166
|
+
/**
|
|
167
|
+
* Options for rendering operations.
|
|
168
|
+
*
|
|
169
|
+
* CHANGE (006): Removed `noCache`, `cacheDir`, `timeout` — these were
|
|
170
|
+
* resolver options that no longer apply to the pure engine.
|
|
171
|
+
*/
|
|
172
|
+
interface RenderOptions {
|
|
173
|
+
/** Skip tofu fmt formatting (default: false) */
|
|
174
|
+
skipFormat?: boolean;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Metadata about a template, sourced from the "template" key in template.json.
|
|
178
|
+
*/
|
|
179
|
+
interface TemplateMetadata {
|
|
180
|
+
/** Template name */
|
|
181
|
+
name: string;
|
|
182
|
+
/** Human-readable description */
|
|
183
|
+
description?: string;
|
|
184
|
+
/** Template version (semver) */
|
|
185
|
+
version: string;
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* A remote template package containing source files and schema.
|
|
189
|
+
*
|
|
190
|
+
* CHANGE (008): Replaced `schema: TemplateSchema` with `metadata` + `jsonSchema`.
|
|
191
|
+
* Metadata comes from template.json "template" key; schema from "schema" key.
|
|
192
|
+
*/
|
|
193
|
+
interface Template {
|
|
194
|
+
/** Template metadata from template.json → "template" key */
|
|
195
|
+
metadata: TemplateMetadata;
|
|
196
|
+
/** JSON Schema Draft-07 from template.json → "schema" key */
|
|
197
|
+
jsonSchema: JSONSchema7;
|
|
198
|
+
/** Map of output paths to HBS content (rendered via Handlebars) */
|
|
199
|
+
files: Map<string, string>;
|
|
200
|
+
/** Map of output paths to static content (copied verbatim, no rendering) */
|
|
201
|
+
staticFiles: Map<string, string>;
|
|
202
|
+
/** Template source URI */
|
|
203
|
+
source: string;
|
|
204
|
+
/** Resolved version info */
|
|
205
|
+
version: VersionInfo;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Version information for a template.
|
|
209
|
+
*/
|
|
210
|
+
interface VersionInfo {
|
|
211
|
+
/** Semantic version (e.g., "0.1.0") */
|
|
212
|
+
semver: string;
|
|
213
|
+
/** API version directory from the URI path (e.g., "v1"), for display/logging */
|
|
214
|
+
apiVersion?: string;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Per-file entry in the Manifest.
|
|
219
|
+
* (FR-035)
|
|
220
|
+
*/
|
|
221
|
+
interface ManifestFileEntry {
|
|
222
|
+
/** Relative file path */
|
|
223
|
+
path: string;
|
|
224
|
+
/** SHA-256 content hash, header-agnostic ("sha256:<hex>") */
|
|
225
|
+
hash: string;
|
|
226
|
+
/** File size in bytes */
|
|
227
|
+
size: number;
|
|
228
|
+
/** Template origin for this file */
|
|
229
|
+
source: string;
|
|
230
|
+
/** Template semver for this file */
|
|
231
|
+
version: string;
|
|
232
|
+
/** File ownership zone */
|
|
233
|
+
zone: Zone;
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Manifest (State Passport) — JSON format.
|
|
237
|
+
* (FR-007, FR-033, FR-034, FR-036)
|
|
238
|
+
*/
|
|
239
|
+
interface Manifest {
|
|
240
|
+
/** Format version discriminator */
|
|
241
|
+
manifestVersion: '1.0';
|
|
242
|
+
/** Cluster identity (matches envelope.intentId) */
|
|
243
|
+
intentId: string;
|
|
244
|
+
/** ISO-8601 generation timestamp */
|
|
245
|
+
generatedAt: string;
|
|
246
|
+
/** Primary template origin URI */
|
|
247
|
+
templateSource: string;
|
|
248
|
+
/** Primary template semver */
|
|
249
|
+
templateVersion: string;
|
|
250
|
+
/** Aggregate Platform Hash ("sha256:<hex>") */
|
|
251
|
+
aggregateHash: string;
|
|
252
|
+
/** Engine metadata */
|
|
253
|
+
engine: {
|
|
254
|
+
version: string;
|
|
255
|
+
formatted: boolean;
|
|
256
|
+
};
|
|
257
|
+
/** Resolved input values used during generation (005) */
|
|
258
|
+
inputs: Record<string, unknown>;
|
|
259
|
+
/** Filename prefix for Platform Zone files (005) */
|
|
260
|
+
platformPrefix: string;
|
|
261
|
+
/** Per-file entries, sorted lexicographically by path */
|
|
262
|
+
files: ManifestFileEntry[];
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* A single drift finding.
|
|
266
|
+
* (FR-042)
|
|
267
|
+
*/
|
|
268
|
+
interface DriftEntry {
|
|
269
|
+
/** File path (relative) */
|
|
270
|
+
path: string;
|
|
271
|
+
/** Classification of the finding */
|
|
272
|
+
type: DriftType;
|
|
273
|
+
/** Human-readable description of the mismatch */
|
|
274
|
+
details: string;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Quick counts for CLI display and telemetry.
|
|
278
|
+
*/
|
|
279
|
+
interface DriftSummary {
|
|
280
|
+
/** Total Platform Zone files checked */
|
|
281
|
+
totalFiles: number;
|
|
282
|
+
/** Files with content_drift */
|
|
283
|
+
driftedFiles: number;
|
|
284
|
+
/** Files with metadata_inconsistency */
|
|
285
|
+
inconsistentFiles: number;
|
|
286
|
+
/** Files in Manifest but not found */
|
|
287
|
+
missingFiles: number;
|
|
288
|
+
/** Platform-prefixed files not in Manifest */
|
|
289
|
+
unexpectedFiles: number;
|
|
290
|
+
/** Files with source_mismatch */
|
|
291
|
+
sourceMismatches: number;
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Structured drift report from Verify and Upgrade operations.
|
|
295
|
+
* (FR-041, FR-043)
|
|
296
|
+
*/
|
|
297
|
+
interface DriftReport {
|
|
298
|
+
/** True if no drift entries (all files match) */
|
|
299
|
+
valid: boolean;
|
|
300
|
+
/** Aggregate hash comparison */
|
|
301
|
+
aggregateHash: {
|
|
302
|
+
expected: string;
|
|
303
|
+
actual: string;
|
|
304
|
+
};
|
|
305
|
+
/** Per-file findings (a file may appear multiple times with different types) */
|
|
306
|
+
entries: DriftEntry[];
|
|
307
|
+
/** Quick counts for display/telemetry */
|
|
308
|
+
summary: DriftSummary;
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* Result of the Install operation.
|
|
312
|
+
* (FR-012)
|
|
313
|
+
*
|
|
314
|
+
* CHANGE (008): sideOutputs removed — templates own all Terraform output via .hbs files.
|
|
315
|
+
*/
|
|
316
|
+
interface InstallResult {
|
|
317
|
+
/** Zone-tagged file map (platform + user boilerplate files) */
|
|
318
|
+
files: FileMap;
|
|
319
|
+
/** Initial Manifest */
|
|
320
|
+
manifest: Manifest;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Result of the Upgrade operation.
|
|
324
|
+
* (FR-014, FR-015, FR-016)
|
|
325
|
+
*
|
|
326
|
+
* CHANGE (008): sideOutputs removed — templates own all Terraform output via .hbs files.
|
|
327
|
+
*/
|
|
328
|
+
interface UpgradeResult {
|
|
329
|
+
/** New zone-tagged file map */
|
|
330
|
+
files: FileMap;
|
|
331
|
+
/** Updated Manifest */
|
|
332
|
+
manifest: Manifest;
|
|
333
|
+
/** Pre-upgrade drift analysis */
|
|
334
|
+
driftReport: DriftReport;
|
|
335
|
+
/**
|
|
336
|
+
* True if the upgrade was blocked due to source mismatch (FR-028).
|
|
337
|
+
* When true, `files` and `manifest` reflect the CURRENT state (not upgraded).
|
|
338
|
+
*/
|
|
339
|
+
sourceBlocked: boolean;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Result of the Verify operation.
|
|
343
|
+
* (FR-015, FR-041)
|
|
344
|
+
*/
|
|
345
|
+
interface VerifyResult {
|
|
346
|
+
/** Full drift analysis */
|
|
347
|
+
driftReport: DriftReport;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Result of the Hash-Only operation.
|
|
351
|
+
* (FR-022, FR-023)
|
|
352
|
+
*/
|
|
353
|
+
interface HashOnlyResult {
|
|
354
|
+
/** Aggregate Platform Hash ("sha256:<hex>") */
|
|
355
|
+
aggregateHash: string;
|
|
356
|
+
/** Template source used */
|
|
357
|
+
templateSource: string;
|
|
358
|
+
/** Template version used */
|
|
359
|
+
templateVersion: string;
|
|
360
|
+
/** Number of Platform Zone files that would be generated */
|
|
361
|
+
fileCount: number;
|
|
362
|
+
}
|
|
363
|
+
/**
|
|
364
|
+
* Options for resolver operations.
|
|
365
|
+
*/
|
|
366
|
+
interface ResolverOptions {
|
|
367
|
+
/** Request timeout in ms */
|
|
368
|
+
timeout?: number;
|
|
369
|
+
/** Number of retries */
|
|
370
|
+
retries?: number;
|
|
371
|
+
/** Skip cache lookup */
|
|
372
|
+
noCache?: boolean;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Interface for fetching templates from different sources.
|
|
376
|
+
*/
|
|
377
|
+
interface Resolver {
|
|
378
|
+
/** Check if resolver handles this URI scheme */
|
|
379
|
+
canResolve(uri: string): boolean;
|
|
380
|
+
/** Fetch template from source */
|
|
381
|
+
resolve(uri: string, options?: ResolverOptions): Promise<Template>;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* The HCL Engine public API.
|
|
385
|
+
*
|
|
386
|
+
* CHANGE (006): Narrowed to four core operations. Removed:
|
|
387
|
+
* - getSchema(uri) — caller reads template.schema directly
|
|
388
|
+
* - validate(uri, inputs) — caller uses exported validateInputs()
|
|
389
|
+
* - clearCache(uri?) — caching is caller's concern
|
|
390
|
+
* - EngineConfig — deleted entirely (all fields were resolver-related)
|
|
391
|
+
*
|
|
392
|
+
* (FR-037, FR-038, FR-024)
|
|
393
|
+
*/
|
|
394
|
+
interface HclEngine {
|
|
395
|
+
/**
|
|
396
|
+
* Install: Generate all files for a new cluster.
|
|
397
|
+
* Input: Envelope with intentId, resolved Template, and inputs.
|
|
398
|
+
* Output: Zone-tagged file map + initial Manifest.
|
|
399
|
+
* (FR-012, FR-025, FR-039)
|
|
400
|
+
*/
|
|
401
|
+
install(envelope: Envelope): Promise<InstallResult>;
|
|
402
|
+
/**
|
|
403
|
+
* Upgrade: Update an existing cluster to new templates.
|
|
404
|
+
* Input: Envelope + current file map (from disk) + previous Manifest.
|
|
405
|
+
* Output: New file map + new Manifest + drift report.
|
|
406
|
+
* (FR-014, FR-015, FR-016, FR-027, FR-028, FR-047)
|
|
407
|
+
*/
|
|
408
|
+
upgrade(envelope: Envelope, currentFiles: FileMap, previousManifest: Manifest): Promise<UpgradeResult>;
|
|
409
|
+
/**
|
|
410
|
+
* Verify: Check integrity of existing files against a Manifest.
|
|
411
|
+
* Input: Current file map (from disk) + previous Manifest.
|
|
412
|
+
* Output: Drift report only (no file generation).
|
|
413
|
+
* (FR-015, FR-041, FR-047)
|
|
414
|
+
*/
|
|
415
|
+
verify(currentFiles: FileMap, previousManifest: Manifest): Promise<VerifyResult>;
|
|
416
|
+
/**
|
|
417
|
+
* Hash-Only: Calculate expected aggregate hash without full generation.
|
|
418
|
+
* Input: Envelope (same as install).
|
|
419
|
+
* Output: Aggregate Platform Hash + metadata.
|
|
420
|
+
* (FR-022, FR-023)
|
|
421
|
+
*/
|
|
422
|
+
hashOnly(envelope: Envelope): Promise<HashOnlyResult>;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* Template JSON structure validation using AJV.
|
|
427
|
+
*
|
|
428
|
+
* Validates the top-level structure of template.json against the
|
|
429
|
+
* templateJsonSchema (JSON Schema Draft-07) defined in template-json-schema.ts.
|
|
430
|
+
*
|
|
431
|
+
* Reference: R-006, data-model.md validator.ts
|
|
432
|
+
*/
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* Result of validating a template.json file.
|
|
436
|
+
*/
|
|
437
|
+
interface TemplateJsonResult {
|
|
438
|
+
metadata: TemplateMetadata;
|
|
439
|
+
jsonSchema: JSONSchema7;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Validate the structure of a parsed template.json file.
|
|
443
|
+
*
|
|
444
|
+
* Checks:
|
|
445
|
+
* - Data is an object with "template" and "schema" keys
|
|
446
|
+
* - template.name is a non-empty string
|
|
447
|
+
* - template.version is a semver string (x.y.z)
|
|
448
|
+
* - template.description is an optional string
|
|
449
|
+
* - schema is a non-null object with type: "object" and properties
|
|
450
|
+
*
|
|
451
|
+
* @param data - Parsed JSON content from template.json
|
|
452
|
+
* @returns Validated metadata and JSON Schema
|
|
453
|
+
* @throws EngineError with TEMPLATE_JSON_INVALID on failure
|
|
454
|
+
*/
|
|
455
|
+
declare function validateTemplateJson(data: unknown): TemplateJsonResult;
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* AJV-based JSON Schema input validation.
|
|
459
|
+
*
|
|
460
|
+
* Provides:
|
|
461
|
+
* - createInputValidator(): Compiles a JSON Schema into an AJV validator
|
|
462
|
+
* - validateAndApplyDefaults(): Validates inputs + applies defaults in one pass
|
|
463
|
+
* - validateJsonSchemaStructure(): Asserts root type: "object" + properties key
|
|
464
|
+
*
|
|
465
|
+
* Local $ref pointers (e.g., "#/components/schemas/...") are supported natively
|
|
466
|
+
* by AJV and resolved automatically during schema compilation.
|
|
467
|
+
*
|
|
468
|
+
* CHANGE (008): New module replacing hand-rolled validateInputs() and applyDefaults().
|
|
469
|
+
*
|
|
470
|
+
* Reference: R-001, R-007, R-010
|
|
471
|
+
*/
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Validate that a JSON Schema has the required structure for template inputs.
|
|
475
|
+
* Must be an object with type: "object" and a properties key.
|
|
476
|
+
*
|
|
477
|
+
* @param schema - Schema to validate
|
|
478
|
+
* @throws EngineError if structure is invalid
|
|
479
|
+
*/
|
|
480
|
+
declare function validateJsonSchemaStructure(schema: JSONSchema7): void;
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* JSON Schema (Draft-07) for template.json files.
|
|
484
|
+
*
|
|
485
|
+
* This is the source of truth for template.json validation.
|
|
486
|
+
* Used by validator.ts via AJV for runtime validation.
|
|
487
|
+
*
|
|
488
|
+
* Validates:
|
|
489
|
+
* - "template" key: name (required, non-empty), version (semver, required), description (optional string)
|
|
490
|
+
* - "schema" key: must be a JSON Schema object with type: "object" and a properties key
|
|
491
|
+
*
|
|
492
|
+
* Note: No additionalProperties: false at root level — extra top-level keys are allowed
|
|
493
|
+
* for forward compatibility.
|
|
494
|
+
*/
|
|
495
|
+
|
|
496
|
+
declare const templateJsonSchema: JSONSchema7;
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* Check if tofu is available in the system.
|
|
500
|
+
*
|
|
501
|
+
* @returns true if tofu is available
|
|
502
|
+
*/
|
|
503
|
+
declare function isTofuAvailable(): Promise<boolean>;
|
|
504
|
+
|
|
505
|
+
/**
|
|
506
|
+
* Zone classification for file ownership.
|
|
507
|
+
*
|
|
508
|
+
* Classifies files as Platform Zone or User Zone based on filename prefix.
|
|
509
|
+
* Reference: R-007, FR-001, FR-002
|
|
510
|
+
*/
|
|
511
|
+
|
|
512
|
+
/**
|
|
513
|
+
* Default platform filename prefix.
|
|
514
|
+
*/
|
|
515
|
+
declare const DEFAULT_PREFIX = "tfy_";
|
|
516
|
+
/**
|
|
517
|
+
* Classify a file as Platform Zone or User Zone based on its filename.
|
|
518
|
+
*
|
|
519
|
+
* Rules (R-007):
|
|
520
|
+
* 1. Only the basename matters (not the directory path).
|
|
521
|
+
* 2. The prefix check is case-sensitive.
|
|
522
|
+
* 3. The Manifest file itself (manifest.json) is classified as Platform Zone.
|
|
523
|
+
* 4. Files without .tf extension that have the prefix are still Platform Zone.
|
|
524
|
+
* 5. The prefix is configurable per envelope/configuration.
|
|
525
|
+
*
|
|
526
|
+
* @param filePath - Relative or absolute file path
|
|
527
|
+
* @param prefix - Platform Zone filename prefix (default: "tfy_")
|
|
528
|
+
* @returns Zone classification ("platform" or "user")
|
|
529
|
+
*/
|
|
530
|
+
declare function classifyFile(filePath: string, prefix?: string): Zone;
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* @tfy-status header processing: parse, strip, inject.
|
|
534
|
+
*
|
|
535
|
+
* The header is a structured metadata block embedded as Terraform comment lines
|
|
536
|
+
* at the top of every Platform Zone file.
|
|
537
|
+
*
|
|
538
|
+
* Format (R-001):
|
|
539
|
+
* ```hcl
|
|
540
|
+
* # @tfy-status:begin
|
|
541
|
+
* # {"managed":true,"source":"...","version":"...","intent_id":"...","content_hash":"sha256:..."}
|
|
542
|
+
* # @tfy-status:end
|
|
543
|
+
* ```
|
|
544
|
+
*
|
|
545
|
+
* Reference: R-001, R-002, R-010, FR-044 through FR-046
|
|
546
|
+
*/
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Parse a @tfy-status header from file content.
|
|
550
|
+
* Returns undefined if no valid header is found.
|
|
551
|
+
* (FR-044)
|
|
552
|
+
*
|
|
553
|
+
* @param content - File content possibly containing a header
|
|
554
|
+
* @returns Parsed header or undefined
|
|
555
|
+
*/
|
|
556
|
+
declare function parseHeader(content: string): TfyStatusHeader | undefined;
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* HCL Engine implementation — four-operation integrity API.
|
|
560
|
+
*
|
|
561
|
+
* Operations:
|
|
562
|
+
* - install(envelope): Generate all files for a new cluster
|
|
563
|
+
* - upgrade(envelope, currentFiles, previousManifest): Update to new templates
|
|
564
|
+
* - verify(currentFiles, previousManifest): Check integrity
|
|
565
|
+
* - hashOnly(envelope): Calculate expected aggregate hash
|
|
566
|
+
*
|
|
567
|
+
* Reference: R-006, FR-037, FR-038, plan.md Operation Pipelines
|
|
568
|
+
*/
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* Create a new HCL engine instance.
|
|
572
|
+
*
|
|
573
|
+
* @returns Engine instance
|
|
574
|
+
*
|
|
575
|
+
* @example
|
|
576
|
+
* ```typescript
|
|
577
|
+
* import { createEngine } from '@truefoundry/tfy-infra-engine';
|
|
578
|
+
*
|
|
579
|
+
* const engine = createEngine();
|
|
580
|
+
* const result = await engine.install({
|
|
581
|
+
* template, // pre-resolved Template object
|
|
582
|
+
* inputs: { cluster_name: 'prod' },
|
|
583
|
+
* intentId: 'cluster-prod-001',
|
|
584
|
+
* });
|
|
585
|
+
* ```
|
|
586
|
+
*/
|
|
587
|
+
declare function createEngine(): HclEngine;
|
|
588
|
+
|
|
589
|
+
export { DEFAULT_PREFIX, type DriftReport, type DriftType, EngineError, EngineErrorCode, type Envelope, type FileEntry, type FileMap, type HashOnlyResult, type InstallResult, type JSONSchema7, type Manifest, type Resolver, type ResolverOptions, type Template, type UpgradeResult, type VerifyResult, type VersionInfo, classifyFile, createEngine, isTofuAvailable, parseHeader, templateJsonSchema, validateJsonSchemaStructure, validateTemplateJson };
|