@truefoundry/tfy-infra-engine 0.1.3 → 0.1.4
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 +18 -12
- package/dist/index.d.mts +29 -31
- package/dist/index.d.ts +29 -31
- package/dist/index.js +38 -48
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -45
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -100,15 +100,21 @@ if (!result.driftReport.valid) {
|
|
|
100
100
|
|
|
101
101
|
### `engine.upgrade(envelope, currentFiles, previousManifest)`
|
|
102
102
|
|
|
103
|
-
Update platform files to new template versions.
|
|
103
|
+
Update platform files to new template versions. Always renders new files and returns a pre-upgrade drift report. The `sourceBlocked` flag indicates a template source mismatch -- callers enforce blocking policy (FR-029).
|
|
104
104
|
|
|
105
105
|
```typescript
|
|
106
106
|
const result = await engine.upgrade(envelope, currentFiles, previousManifest);
|
|
107
|
+
|
|
107
108
|
if (result.sourceBlocked) {
|
|
108
|
-
|
|
109
|
-
|
|
109
|
+
// Template source changed -- caller decides whether to proceed
|
|
110
|
+
console.log('Source mismatch detected');
|
|
111
|
+
}
|
|
112
|
+
if (!result.driftReport.valid) {
|
|
113
|
+
// Managed files were modified since last render
|
|
110
114
|
console.log('Pre-upgrade drift detected');
|
|
111
115
|
}
|
|
116
|
+
|
|
117
|
+
// result.files always contains newly rendered files, even when sourceBlocked
|
|
112
118
|
```
|
|
113
119
|
|
|
114
120
|
### `engine.hashOnly(envelope)`
|
|
@@ -146,15 +152,15 @@ if (!result.valid) {
|
|
|
146
152
|
// inputs now has defaults applied in-place
|
|
147
153
|
```
|
|
148
154
|
|
|
149
|
-
###
|
|
155
|
+
### Bundle Validation
|
|
150
156
|
|
|
151
|
-
Validate the top-level structure of a `
|
|
157
|
+
Validate the top-level structure of a `bundle.json` file:
|
|
152
158
|
|
|
153
159
|
```typescript
|
|
154
|
-
import {
|
|
160
|
+
import { validateBundle } from '@truefoundry/tfy-infra-engine';
|
|
155
161
|
|
|
156
|
-
const parsed = JSON.parse(fs.readFileSync('
|
|
157
|
-
const { metadata, jsonSchema } =
|
|
162
|
+
const parsed = JSON.parse(fs.readFileSync('bundle.json', 'utf-8'));
|
|
163
|
+
const { metadata, jsonSchema } = validateBundle(parsed);
|
|
158
164
|
// metadata: { name, version, description? }
|
|
159
165
|
// jsonSchema: the raw JSON Schema object
|
|
160
166
|
```
|
|
@@ -269,11 +275,11 @@ try {
|
|
|
269
275
|
case EngineErrorCode.INPUT_VALIDATION_FAILED:
|
|
270
276
|
console.log('Invalid inputs:', error.details);
|
|
271
277
|
break;
|
|
272
|
-
case EngineErrorCode.
|
|
273
|
-
console.log('
|
|
278
|
+
case EngineErrorCode.BUNDLE_NOT_FOUND:
|
|
279
|
+
console.log('bundle.json not found in template directory');
|
|
274
280
|
break;
|
|
275
|
-
case EngineErrorCode.
|
|
276
|
-
console.log('
|
|
281
|
+
case EngineErrorCode.BUNDLE_INVALID:
|
|
282
|
+
console.log('bundle.json has invalid structure:', error.message);
|
|
277
283
|
break;
|
|
278
284
|
case EngineErrorCode.TOFU_NOT_FOUND:
|
|
279
285
|
console.log('Install OpenTofu or use skipFormat option');
|
package/dist/index.d.mts
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
declare enum EngineErrorCode {
|
|
5
5
|
TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
|
|
6
6
|
NETWORK_ERROR = "NETWORK_ERROR",
|
|
7
|
-
GITHUB_NOT_FOUND = "GITHUB_NOT_FOUND",
|
|
8
|
-
GITHUB_RATE_LIMITED = "GITHUB_RATE_LIMITED",
|
|
9
7
|
FILE_NOT_FOUND = "FILE_NOT_FOUND",
|
|
10
8
|
HTTPS_AUTH_FAILED = "HTTPS_AUTH_FAILED",
|
|
11
9
|
SCHEMA_INVALID = "SCHEMA_INVALID",
|
|
12
10
|
INPUT_VALIDATION_FAILED = "INPUT_VALIDATION_FAILED",
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
BUNDLE_NOT_FOUND = "BUNDLE_NOT_FOUND",
|
|
12
|
+
BUNDLE_INVALID = "BUNDLE_INVALID",
|
|
15
13
|
TEMPLATE_SYNTAX_ERROR = "TEMPLATE_SYNTAX_ERROR",
|
|
16
14
|
TOFU_NOT_FOUND = "TOFU_NOT_FOUND",
|
|
17
15
|
TOFU_FMT_FAILED = "TOFU_FMT_FAILED",
|
|
@@ -42,7 +40,7 @@ declare class EngineError extends Error {
|
|
|
42
40
|
*
|
|
43
41
|
* CHANGE (008): All Zod-based converter functions and zod-to-json-schema
|
|
44
42
|
* import removed. Only the JSONSchema7 type interface remains.
|
|
45
|
-
* Templates provide JSON Schema directly via
|
|
43
|
+
* Templates provide JSON Schema directly via bundle.json.
|
|
46
44
|
*/
|
|
47
45
|
/**
|
|
48
46
|
* JSON Schema Draft-07 type.
|
|
@@ -174,7 +172,7 @@ interface RenderOptions {
|
|
|
174
172
|
skipFormat?: boolean;
|
|
175
173
|
}
|
|
176
174
|
/**
|
|
177
|
-
* Metadata about a template, sourced from the "
|
|
175
|
+
* Metadata about a template, sourced from the "metadata" key in bundle.json.
|
|
178
176
|
*/
|
|
179
177
|
interface TemplateMetadata {
|
|
180
178
|
/** Template name */
|
|
@@ -188,12 +186,12 @@ interface TemplateMetadata {
|
|
|
188
186
|
* A remote template package containing source files and schema.
|
|
189
187
|
*
|
|
190
188
|
* CHANGE (008): Replaced `schema: TemplateSchema` with `metadata` + `jsonSchema`.
|
|
191
|
-
* Metadata comes from
|
|
189
|
+
* Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
|
|
192
190
|
*/
|
|
193
191
|
interface Template {
|
|
194
|
-
/** Template metadata from
|
|
192
|
+
/** Template metadata from bundle.json → "metadata" key */
|
|
195
193
|
metadata: TemplateMetadata;
|
|
196
|
-
/** JSON Schema Draft-07 from
|
|
194
|
+
/** JSON Schema Draft-07 from bundle.json → "jsonSchema" key */
|
|
197
195
|
jsonSchema: JSONSchema7;
|
|
198
196
|
/** Map of output paths to HBS content (rendered via Handlebars) */
|
|
199
197
|
files: Map<string, string>;
|
|
@@ -423,36 +421,36 @@ interface HclEngine {
|
|
|
423
421
|
}
|
|
424
422
|
|
|
425
423
|
/**
|
|
426
|
-
*
|
|
424
|
+
* Bundle structure validation using AJV.
|
|
427
425
|
*
|
|
428
|
-
* Validates the top-level structure of
|
|
429
|
-
*
|
|
426
|
+
* Validates the top-level structure of a bundle against the
|
|
427
|
+
* bundleSchema (JSON Schema Draft-07) defined in bundle-schema.ts.
|
|
430
428
|
*
|
|
431
429
|
* Reference: R-006, data-model.md validator.ts
|
|
432
430
|
*/
|
|
433
431
|
|
|
434
432
|
/**
|
|
435
|
-
* Result of validating a
|
|
433
|
+
* Result of validating a bundle.
|
|
436
434
|
*/
|
|
437
|
-
interface
|
|
435
|
+
interface BundleValidationResult {
|
|
438
436
|
metadata: TemplateMetadata;
|
|
439
437
|
jsonSchema: JSONSchema7;
|
|
440
438
|
}
|
|
441
439
|
/**
|
|
442
|
-
* Validate the structure of a parsed
|
|
440
|
+
* Validate the structure of a parsed bundle.
|
|
443
441
|
*
|
|
444
442
|
* Checks:
|
|
445
|
-
* - Data is an object with "
|
|
446
|
-
* -
|
|
447
|
-
* -
|
|
448
|
-
* -
|
|
449
|
-
* -
|
|
443
|
+
* - Data is an object with "metadata" and "jsonSchema" keys
|
|
444
|
+
* - metadata.name is a non-empty string
|
|
445
|
+
* - metadata.version is a semver string (x.y.z)
|
|
446
|
+
* - metadata.description is an optional string
|
|
447
|
+
* - jsonSchema is a non-null object with type: "object" and properties
|
|
450
448
|
*
|
|
451
|
-
* @param data - Parsed JSON content from
|
|
449
|
+
* @param data - Parsed JSON content from a bundle
|
|
452
450
|
* @returns Validated metadata and JSON Schema
|
|
453
|
-
* @throws EngineError with
|
|
451
|
+
* @throws EngineError with BUNDLE_INVALID on failure
|
|
454
452
|
*/
|
|
455
|
-
declare function
|
|
453
|
+
declare function validateBundle(data: unknown): BundleValidationResult;
|
|
456
454
|
|
|
457
455
|
/**
|
|
458
456
|
* AJV-based JSON Schema input validation.
|
|
@@ -480,20 +478,20 @@ declare function validateTemplateJson(data: unknown): TemplateJsonResult;
|
|
|
480
478
|
declare function validateJsonSchemaStructure(schema: JSONSchema7): void;
|
|
481
479
|
|
|
482
480
|
/**
|
|
483
|
-
* JSON Schema (Draft-07) for
|
|
481
|
+
* JSON Schema (Draft-07) for bundle.json files.
|
|
484
482
|
*
|
|
485
|
-
* This is the source of truth for
|
|
483
|
+
* This is the source of truth for bundle structure validation.
|
|
486
484
|
* Used by validator.ts via AJV for runtime validation.
|
|
487
485
|
*
|
|
488
486
|
* Validates:
|
|
489
|
-
* - "
|
|
490
|
-
* - "
|
|
487
|
+
* - "metadata" key: name (required, non-empty), version (semver, required), description (optional string)
|
|
488
|
+
* - "jsonSchema" key: must be a JSON Schema object with type: "object" and a properties key
|
|
491
489
|
*
|
|
492
|
-
* Note: No additionalProperties: false at root level
|
|
493
|
-
* for forward compatibility.
|
|
490
|
+
* Note: No additionalProperties: false at root level -- extra top-level keys are allowed
|
|
491
|
+
* for forward compatibility (e.g., uiSchema, files, staticFiles, version).
|
|
494
492
|
*/
|
|
495
493
|
|
|
496
|
-
declare const
|
|
494
|
+
declare const bundleSchema: JSONSchema7;
|
|
497
495
|
|
|
498
496
|
/**
|
|
499
497
|
* Check if tofu is available in the system.
|
|
@@ -627,4 +625,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
|
|
|
627
625
|
*/
|
|
628
626
|
declare function createEngine(): HclEngine;
|
|
629
627
|
|
|
630
|
-
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, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader,
|
|
628
|
+
export { type BundleValidationResult, 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 TemplateMetadata, type UpgradeResult, type VerifyResult, type VersionInfo, bundleSchema, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, validateBundle, validateJsonSchemaStructure };
|
package/dist/index.d.ts
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
declare enum EngineErrorCode {
|
|
5
5
|
TEMPLATE_NOT_FOUND = "TEMPLATE_NOT_FOUND",
|
|
6
6
|
NETWORK_ERROR = "NETWORK_ERROR",
|
|
7
|
-
GITHUB_NOT_FOUND = "GITHUB_NOT_FOUND",
|
|
8
|
-
GITHUB_RATE_LIMITED = "GITHUB_RATE_LIMITED",
|
|
9
7
|
FILE_NOT_FOUND = "FILE_NOT_FOUND",
|
|
10
8
|
HTTPS_AUTH_FAILED = "HTTPS_AUTH_FAILED",
|
|
11
9
|
SCHEMA_INVALID = "SCHEMA_INVALID",
|
|
12
10
|
INPUT_VALIDATION_FAILED = "INPUT_VALIDATION_FAILED",
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
BUNDLE_NOT_FOUND = "BUNDLE_NOT_FOUND",
|
|
12
|
+
BUNDLE_INVALID = "BUNDLE_INVALID",
|
|
15
13
|
TEMPLATE_SYNTAX_ERROR = "TEMPLATE_SYNTAX_ERROR",
|
|
16
14
|
TOFU_NOT_FOUND = "TOFU_NOT_FOUND",
|
|
17
15
|
TOFU_FMT_FAILED = "TOFU_FMT_FAILED",
|
|
@@ -42,7 +40,7 @@ declare class EngineError extends Error {
|
|
|
42
40
|
*
|
|
43
41
|
* CHANGE (008): All Zod-based converter functions and zod-to-json-schema
|
|
44
42
|
* import removed. Only the JSONSchema7 type interface remains.
|
|
45
|
-
* Templates provide JSON Schema directly via
|
|
43
|
+
* Templates provide JSON Schema directly via bundle.json.
|
|
46
44
|
*/
|
|
47
45
|
/**
|
|
48
46
|
* JSON Schema Draft-07 type.
|
|
@@ -174,7 +172,7 @@ interface RenderOptions {
|
|
|
174
172
|
skipFormat?: boolean;
|
|
175
173
|
}
|
|
176
174
|
/**
|
|
177
|
-
* Metadata about a template, sourced from the "
|
|
175
|
+
* Metadata about a template, sourced from the "metadata" key in bundle.json.
|
|
178
176
|
*/
|
|
179
177
|
interface TemplateMetadata {
|
|
180
178
|
/** Template name */
|
|
@@ -188,12 +186,12 @@ interface TemplateMetadata {
|
|
|
188
186
|
* A remote template package containing source files and schema.
|
|
189
187
|
*
|
|
190
188
|
* CHANGE (008): Replaced `schema: TemplateSchema` with `metadata` + `jsonSchema`.
|
|
191
|
-
* Metadata comes from
|
|
189
|
+
* Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
|
|
192
190
|
*/
|
|
193
191
|
interface Template {
|
|
194
|
-
/** Template metadata from
|
|
192
|
+
/** Template metadata from bundle.json → "metadata" key */
|
|
195
193
|
metadata: TemplateMetadata;
|
|
196
|
-
/** JSON Schema Draft-07 from
|
|
194
|
+
/** JSON Schema Draft-07 from bundle.json → "jsonSchema" key */
|
|
197
195
|
jsonSchema: JSONSchema7;
|
|
198
196
|
/** Map of output paths to HBS content (rendered via Handlebars) */
|
|
199
197
|
files: Map<string, string>;
|
|
@@ -423,36 +421,36 @@ interface HclEngine {
|
|
|
423
421
|
}
|
|
424
422
|
|
|
425
423
|
/**
|
|
426
|
-
*
|
|
424
|
+
* Bundle structure validation using AJV.
|
|
427
425
|
*
|
|
428
|
-
* Validates the top-level structure of
|
|
429
|
-
*
|
|
426
|
+
* Validates the top-level structure of a bundle against the
|
|
427
|
+
* bundleSchema (JSON Schema Draft-07) defined in bundle-schema.ts.
|
|
430
428
|
*
|
|
431
429
|
* Reference: R-006, data-model.md validator.ts
|
|
432
430
|
*/
|
|
433
431
|
|
|
434
432
|
/**
|
|
435
|
-
* Result of validating a
|
|
433
|
+
* Result of validating a bundle.
|
|
436
434
|
*/
|
|
437
|
-
interface
|
|
435
|
+
interface BundleValidationResult {
|
|
438
436
|
metadata: TemplateMetadata;
|
|
439
437
|
jsonSchema: JSONSchema7;
|
|
440
438
|
}
|
|
441
439
|
/**
|
|
442
|
-
* Validate the structure of a parsed
|
|
440
|
+
* Validate the structure of a parsed bundle.
|
|
443
441
|
*
|
|
444
442
|
* Checks:
|
|
445
|
-
* - Data is an object with "
|
|
446
|
-
* -
|
|
447
|
-
* -
|
|
448
|
-
* -
|
|
449
|
-
* -
|
|
443
|
+
* - Data is an object with "metadata" and "jsonSchema" keys
|
|
444
|
+
* - metadata.name is a non-empty string
|
|
445
|
+
* - metadata.version is a semver string (x.y.z)
|
|
446
|
+
* - metadata.description is an optional string
|
|
447
|
+
* - jsonSchema is a non-null object with type: "object" and properties
|
|
450
448
|
*
|
|
451
|
-
* @param data - Parsed JSON content from
|
|
449
|
+
* @param data - Parsed JSON content from a bundle
|
|
452
450
|
* @returns Validated metadata and JSON Schema
|
|
453
|
-
* @throws EngineError with
|
|
451
|
+
* @throws EngineError with BUNDLE_INVALID on failure
|
|
454
452
|
*/
|
|
455
|
-
declare function
|
|
453
|
+
declare function validateBundle(data: unknown): BundleValidationResult;
|
|
456
454
|
|
|
457
455
|
/**
|
|
458
456
|
* AJV-based JSON Schema input validation.
|
|
@@ -480,20 +478,20 @@ declare function validateTemplateJson(data: unknown): TemplateJsonResult;
|
|
|
480
478
|
declare function validateJsonSchemaStructure(schema: JSONSchema7): void;
|
|
481
479
|
|
|
482
480
|
/**
|
|
483
|
-
* JSON Schema (Draft-07) for
|
|
481
|
+
* JSON Schema (Draft-07) for bundle.json files.
|
|
484
482
|
*
|
|
485
|
-
* This is the source of truth for
|
|
483
|
+
* This is the source of truth for bundle structure validation.
|
|
486
484
|
* Used by validator.ts via AJV for runtime validation.
|
|
487
485
|
*
|
|
488
486
|
* Validates:
|
|
489
|
-
* - "
|
|
490
|
-
* - "
|
|
487
|
+
* - "metadata" key: name (required, non-empty), version (semver, required), description (optional string)
|
|
488
|
+
* - "jsonSchema" key: must be a JSON Schema object with type: "object" and a properties key
|
|
491
489
|
*
|
|
492
|
-
* Note: No additionalProperties: false at root level
|
|
493
|
-
* for forward compatibility.
|
|
490
|
+
* Note: No additionalProperties: false at root level -- extra top-level keys are allowed
|
|
491
|
+
* for forward compatibility (e.g., uiSchema, files, staticFiles, version).
|
|
494
492
|
*/
|
|
495
493
|
|
|
496
|
-
declare const
|
|
494
|
+
declare const bundleSchema: JSONSchema7;
|
|
497
495
|
|
|
498
496
|
/**
|
|
499
497
|
* Check if tofu is available in the system.
|
|
@@ -627,4 +625,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
|
|
|
627
625
|
*/
|
|
628
626
|
declare function createEngine(): HclEngine;
|
|
629
627
|
|
|
630
|
-
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, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader,
|
|
628
|
+
export { type BundleValidationResult, 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 TemplateMetadata, type UpgradeResult, type VerifyResult, type VersionInfo, bundleSchema, canonicalHash, classifyFile, createEngine, getCanonicalHashScriptPath, isTofuAvailable, parseHeader, validateBundle, validateJsonSchemaStructure };
|
package/dist/index.js
CHANGED
|
@@ -33,15 +33,15 @@ __export(index_exports, {
|
|
|
33
33
|
DEFAULT_PREFIX: () => DEFAULT_PREFIX,
|
|
34
34
|
EngineError: () => EngineError,
|
|
35
35
|
EngineErrorCode: () => EngineErrorCode,
|
|
36
|
+
bundleSchema: () => bundleSchema,
|
|
36
37
|
canonicalHash: () => canonicalHash,
|
|
37
38
|
classifyFile: () => classifyFile,
|
|
38
39
|
createEngine: () => createEngine,
|
|
39
40
|
getCanonicalHashScriptPath: () => getCanonicalHashScriptPath,
|
|
40
41
|
isTofuAvailable: () => isTofuAvailable,
|
|
41
42
|
parseHeader: () => parseHeader,
|
|
42
|
-
|
|
43
|
-
validateJsonSchemaStructure: () => validateJsonSchemaStructure
|
|
44
|
-
validateTemplateJson: () => validateTemplateJson
|
|
43
|
+
validateBundle: () => validateBundle,
|
|
44
|
+
validateJsonSchemaStructure: () => validateJsonSchemaStructure
|
|
45
45
|
});
|
|
46
46
|
module.exports = __toCommonJS(index_exports);
|
|
47
47
|
|
|
@@ -49,14 +49,12 @@ module.exports = __toCommonJS(index_exports);
|
|
|
49
49
|
var EngineErrorCode = /* @__PURE__ */ ((EngineErrorCode2) => {
|
|
50
50
|
EngineErrorCode2["TEMPLATE_NOT_FOUND"] = "TEMPLATE_NOT_FOUND";
|
|
51
51
|
EngineErrorCode2["NETWORK_ERROR"] = "NETWORK_ERROR";
|
|
52
|
-
EngineErrorCode2["GITHUB_NOT_FOUND"] = "GITHUB_NOT_FOUND";
|
|
53
|
-
EngineErrorCode2["GITHUB_RATE_LIMITED"] = "GITHUB_RATE_LIMITED";
|
|
54
52
|
EngineErrorCode2["FILE_NOT_FOUND"] = "FILE_NOT_FOUND";
|
|
55
53
|
EngineErrorCode2["HTTPS_AUTH_FAILED"] = "HTTPS_AUTH_FAILED";
|
|
56
54
|
EngineErrorCode2["SCHEMA_INVALID"] = "SCHEMA_INVALID";
|
|
57
55
|
EngineErrorCode2["INPUT_VALIDATION_FAILED"] = "INPUT_VALIDATION_FAILED";
|
|
58
|
-
EngineErrorCode2["
|
|
59
|
-
EngineErrorCode2["
|
|
56
|
+
EngineErrorCode2["BUNDLE_NOT_FOUND"] = "BUNDLE_NOT_FOUND";
|
|
57
|
+
EngineErrorCode2["BUNDLE_INVALID"] = "BUNDLE_INVALID";
|
|
60
58
|
EngineErrorCode2["TEMPLATE_SYNTAX_ERROR"] = "TEMPLATE_SYNTAX_ERROR";
|
|
61
59
|
EngineErrorCode2["TOFU_NOT_FOUND"] = "TOFU_NOT_FOUND";
|
|
62
60
|
EngineErrorCode2["TOFU_FMT_FAILED"] = "TOFU_FMT_FAILED";
|
|
@@ -101,12 +99,12 @@ var EngineError = class _EngineError extends Error {
|
|
|
101
99
|
// src/schema/validator.ts
|
|
102
100
|
var import_ajv = __toESM(require("ajv"));
|
|
103
101
|
|
|
104
|
-
// src/schema/
|
|
105
|
-
var
|
|
102
|
+
// src/schema/bundle-schema.ts
|
|
103
|
+
var bundleSchema = {
|
|
106
104
|
$schema: "http://json-schema.org/draft-07/schema#",
|
|
107
105
|
type: "object",
|
|
108
106
|
properties: {
|
|
109
|
-
|
|
107
|
+
metadata: {
|
|
110
108
|
type: "object",
|
|
111
109
|
properties: {
|
|
112
110
|
name: { type: "string", minLength: 1 },
|
|
@@ -116,7 +114,7 @@ var templateJsonSchema = {
|
|
|
116
114
|
required: ["name", "version"],
|
|
117
115
|
additionalProperties: false
|
|
118
116
|
},
|
|
119
|
-
|
|
117
|
+
jsonSchema: {
|
|
120
118
|
type: "object",
|
|
121
119
|
description: "JSON Schema Draft-07 defining template inputs",
|
|
122
120
|
properties: {
|
|
@@ -127,7 +125,7 @@ var templateJsonSchema = {
|
|
|
127
125
|
required: ["type", "properties"]
|
|
128
126
|
}
|
|
129
127
|
},
|
|
130
|
-
required: ["
|
|
128
|
+
required: ["metadata", "jsonSchema"]
|
|
131
129
|
};
|
|
132
130
|
|
|
133
131
|
// src/schema/validator.ts
|
|
@@ -136,54 +134,51 @@ var ajv = new import_ajv.default({
|
|
|
136
134
|
strict: false,
|
|
137
135
|
validateSchema: false
|
|
138
136
|
});
|
|
139
|
-
var validate = ajv.compile(
|
|
140
|
-
function
|
|
137
|
+
var validate = ajv.compile(bundleSchema);
|
|
138
|
+
function validateBundle(data) {
|
|
141
139
|
if (!data || typeof data !== "object" || Array.isArray(data)) {
|
|
142
|
-
throw new EngineError(
|
|
143
|
-
"template.json must be a JSON object",
|
|
144
|
-
"TEMPLATE_JSON_INVALID" /* TEMPLATE_JSON_INVALID */
|
|
145
|
-
);
|
|
140
|
+
throw new EngineError("bundle must be a JSON object", "BUNDLE_INVALID" /* BUNDLE_INVALID */);
|
|
146
141
|
}
|
|
147
142
|
const valid = validate(data);
|
|
148
143
|
if (!valid) {
|
|
149
144
|
const message = formatAjvErrors(validate.errors ?? []);
|
|
150
|
-
throw new EngineError(message, "
|
|
145
|
+
throw new EngineError(message, "BUNDLE_INVALID" /* BUNDLE_INVALID */);
|
|
151
146
|
}
|
|
152
147
|
const record = data;
|
|
153
|
-
const
|
|
148
|
+
const metadataBlock = record["metadata"];
|
|
154
149
|
const metadata = {
|
|
155
|
-
name:
|
|
156
|
-
version:
|
|
157
|
-
...
|
|
150
|
+
name: metadataBlock["name"],
|
|
151
|
+
version: metadataBlock["version"],
|
|
152
|
+
...metadataBlock["description"] !== void 0 ? { description: metadataBlock["description"] } : {}
|
|
158
153
|
};
|
|
159
|
-
const jsonSchema = record["
|
|
154
|
+
const jsonSchema = record["jsonSchema"];
|
|
160
155
|
return { metadata, jsonSchema };
|
|
161
156
|
}
|
|
162
157
|
function formatAjvErrors(errors) {
|
|
163
158
|
const first = errors[0];
|
|
164
159
|
if (!first) {
|
|
165
|
-
return "
|
|
160
|
+
return "bundle validation failed";
|
|
166
161
|
}
|
|
167
162
|
const path = first.instancePath || "";
|
|
168
163
|
if (first.keyword === "required") {
|
|
169
164
|
const prop = first.params["missingProperty"];
|
|
170
|
-
return `
|
|
165
|
+
return `bundle must have a "${prop}" key`;
|
|
171
166
|
}
|
|
172
167
|
if (first.keyword === "type") {
|
|
173
168
|
const expected = first.params["type"];
|
|
174
|
-
return `
|
|
169
|
+
return `bundle${path ? ` "${dotPath(path)}"` : ""} must be ${expected}`;
|
|
175
170
|
}
|
|
176
|
-
if (first.keyword === "pattern" && path === "/
|
|
177
|
-
return `
|
|
171
|
+
if (first.keyword === "pattern" && path === "/metadata/version") {
|
|
172
|
+
return `bundle "metadata.version" must be semver format (x.y.z)`;
|
|
178
173
|
}
|
|
179
|
-
if (first.keyword === "minLength" && path === "/
|
|
180
|
-
return `
|
|
174
|
+
if (first.keyword === "minLength" && path === "/metadata/name") {
|
|
175
|
+
return `bundle "metadata.name" must be a non-empty string`;
|
|
181
176
|
}
|
|
182
177
|
if (first.keyword === "const") {
|
|
183
178
|
const expected = first.params["allowedValue"];
|
|
184
|
-
return `
|
|
179
|
+
return `bundle "${dotPath(path)}" must be ${JSON.stringify(expected)}`;
|
|
185
180
|
}
|
|
186
|
-
return `
|
|
181
|
+
return `bundle validation failed at ${path || "/"}: ${first.message ?? "unknown error"}`;
|
|
187
182
|
}
|
|
188
183
|
function dotPath(jsonPointer) {
|
|
189
184
|
return jsonPointer.replace(/^\//, "").replace(/\//g, ".");
|
|
@@ -701,7 +696,7 @@ function computeAggregateHash(files) {
|
|
|
701
696
|
}
|
|
702
697
|
|
|
703
698
|
// src/render/manifest.ts
|
|
704
|
-
var ENGINE_VERSION = "0.1.
|
|
699
|
+
var ENGINE_VERSION = "0.1.4";
|
|
705
700
|
function generateManifest(opts) {
|
|
706
701
|
const { files, template, inputs, formatted, intentId, platformPrefix = "tfy_" } = opts;
|
|
707
702
|
const manifestFiles = [];
|
|
@@ -1006,8 +1001,11 @@ var HclEngineImpl = class {
|
|
|
1006
1001
|
/**
|
|
1007
1002
|
* Upgrade: Update an existing cluster to new templates.
|
|
1008
1003
|
*
|
|
1009
|
-
* Pipeline: validate envelope → drift detection (FR-028) →
|
|
1010
|
-
*
|
|
1004
|
+
* Pipeline: validate envelope → drift detection (FR-028) → validate inputs →
|
|
1005
|
+
* render → format → hash + manifest.
|
|
1006
|
+
*
|
|
1007
|
+
* The engine always renders new files regardless of source mismatch.
|
|
1008
|
+
* Callers (CLI/Server) enforce blocking policy via `sourceBlocked` flag (FR-029).
|
|
1011
1009
|
*/
|
|
1012
1010
|
async upgrade(envelope, currentFiles, previousManifest) {
|
|
1013
1011
|
const validatedEnvelope = this.validateEnvelopeOrThrow(envelope);
|
|
@@ -1016,14 +1014,6 @@ var HclEngineImpl = class {
|
|
|
1016
1014
|
const incomingSource = validatedEnvelope.template.source;
|
|
1017
1015
|
const driftReport = buildDriftReport(currentFiles, previousManifest, prefix, incomingSource);
|
|
1018
1016
|
const sourceBlocked = driftReport.summary.sourceMismatches > 0;
|
|
1019
|
-
if (sourceBlocked) {
|
|
1020
|
-
return {
|
|
1021
|
-
files: currentFiles,
|
|
1022
|
-
manifest: previousManifest,
|
|
1023
|
-
driftReport,
|
|
1024
|
-
sourceBlocked: true
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
1017
|
const { renderedFiles, template, formatted, inputsWithDefaults } = await this.renderPipeline(
|
|
1028
1018
|
validatedEnvelope,
|
|
1029
1019
|
options
|
|
@@ -1036,7 +1026,7 @@ var HclEngineImpl = class {
|
|
|
1036
1026
|
formatted,
|
|
1037
1027
|
prefix
|
|
1038
1028
|
);
|
|
1039
|
-
return { files: fileMap, manifest, driftReport, sourceBlocked
|
|
1029
|
+
return { files: fileMap, manifest, driftReport, sourceBlocked };
|
|
1040
1030
|
}
|
|
1041
1031
|
/**
|
|
1042
1032
|
* Verify: Check integrity of existing files against a Manifest.
|
|
@@ -1195,14 +1185,14 @@ function createEngine() {
|
|
|
1195
1185
|
DEFAULT_PREFIX,
|
|
1196
1186
|
EngineError,
|
|
1197
1187
|
EngineErrorCode,
|
|
1188
|
+
bundleSchema,
|
|
1198
1189
|
canonicalHash,
|
|
1199
1190
|
classifyFile,
|
|
1200
1191
|
createEngine,
|
|
1201
1192
|
getCanonicalHashScriptPath,
|
|
1202
1193
|
isTofuAvailable,
|
|
1203
1194
|
parseHeader,
|
|
1204
|
-
|
|
1205
|
-
validateJsonSchemaStructure
|
|
1206
|
-
validateTemplateJson
|
|
1195
|
+
validateBundle,
|
|
1196
|
+
validateJsonSchemaStructure
|
|
1207
1197
|
});
|
|
1208
1198
|
//# sourceMappingURL=index.js.map
|