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