@truefoundry/tfy-infra-engine 0.1.2 → 0.1.3-canary.4058145

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 CHANGED
@@ -53,7 +53,8 @@ console.log('Aggregate Hash:', result.manifest.aggregateHash);
53
53
  - **Pure transformer**: Accepts pre-resolved `Template` objects -- no I/O for fetching
54
54
  - **JSON Schema validation**: Validate inputs against JSON Schema Draft-07 using AJV with `useDefaults`, `allErrors`, and `discriminator` support
55
55
  - **Handlebars templating**: 7 built-in helpers for HCL generation
56
- - **HCL formatting**: Automatic formatting with `tofu fmt`
56
+ - **HCL formatting**: Optional formatting with `tofu fmt` for output readability
57
+ - **Format-independent canonical hashing**: Deterministic SHA-256 hashes via `canonical_hash.sh` regardless of formatting, comments, or whitespace. The script is available for external callers (e.g., bash scripts using Terraform directly)
57
58
  - **Deterministic output**: Byte-identical output for identical inputs
58
59
  - **Integrity verification**: Zone-based file ownership, `@tfy-status` headers, JSON Manifest, and drift detection
59
60
  - **Four-operation API**: `install`, `verify`, `upgrade`, and `hashOnly`
@@ -99,15 +100,21 @@ if (!result.driftReport.valid) {
99
100
 
100
101
  ### `engine.upgrade(envelope, currentFiles, previousManifest)`
101
102
 
102
- Update platform files to new template versions. Performs pre-upgrade drift detection and source mismatch blocking.
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).
103
104
 
104
105
  ```typescript
105
106
  const result = await engine.upgrade(envelope, currentFiles, previousManifest);
107
+
106
108
  if (result.sourceBlocked) {
107
- console.log('Upgrade blocked: template source mismatch');
108
- } else if (!result.driftReport.valid) {
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
109
114
  console.log('Pre-upgrade drift detected');
110
115
  }
116
+
117
+ // result.files always contains newly rendered files, even when sourceBlocked
111
118
  ```
112
119
 
113
120
  ### `engine.hashOnly(envelope)`
@@ -145,15 +152,15 @@ if (!result.valid) {
145
152
  // inputs now has defaults applied in-place
146
153
  ```
147
154
 
148
- ### Template JSON Validation
155
+ ### Bundle Validation
149
156
 
150
- Validate the top-level structure of a `template.json` file:
157
+ Validate the top-level structure of a `bundle.json` file:
151
158
 
152
159
  ```typescript
153
- import { validateTemplateJson } from '@truefoundry/tfy-infra-engine';
160
+ import { validateBundle } from '@truefoundry/tfy-infra-engine';
154
161
 
155
- const parsed = JSON.parse(fs.readFileSync('template.json', 'utf-8'));
156
- const { metadata, jsonSchema } = validateTemplateJson(parsed);
162
+ const parsed = JSON.parse(fs.readFileSync('bundle.json', 'utf-8'));
163
+ const { metadata, jsonSchema } = validateBundle(parsed);
157
164
  // metadata: { name, version, description? }
158
165
  // jsonSchema: the raw JSON Schema object
159
166
  ```
@@ -268,11 +275,11 @@ try {
268
275
  case EngineErrorCode.INPUT_VALIDATION_FAILED:
269
276
  console.log('Invalid inputs:', error.details);
270
277
  break;
271
- case EngineErrorCode.TEMPLATE_JSON_NOT_FOUND:
272
- console.log('template.json not found in template directory');
278
+ case EngineErrorCode.BUNDLE_NOT_FOUND:
279
+ console.log('bundle.json not found in template directory');
273
280
  break;
274
- case EngineErrorCode.TEMPLATE_JSON_INVALID:
275
- console.log('template.json has invalid structure:', error.message);
281
+ case EngineErrorCode.BUNDLE_INVALID:
282
+ console.log('bundle.json has invalid structure:', error.message);
276
283
  break;
277
284
  case EngineErrorCode.TOFU_NOT_FOUND:
278
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
- TEMPLATE_JSON_NOT_FOUND = "TEMPLATE_JSON_NOT_FOUND",
14
- TEMPLATE_JSON_INVALID = "TEMPLATE_JSON_INVALID",
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 template.json.
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 "template" key in template.json.
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 template.json "template" key; schema from "schema" key.
189
+ * Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
192
190
  */
193
191
  interface Template {
194
- /** Template metadata from template.json → "template" key */
192
+ /** Template metadata from bundle.json → "metadata" key */
195
193
  metadata: TemplateMetadata;
196
- /** JSON Schema Draft-07 from template.json → "schema" key */
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
- * Template JSON structure validation using AJV.
424
+ * Bundle structure validation using AJV.
427
425
  *
428
- * Validates the top-level structure of template.json against the
429
- * templateJsonSchema (JSON Schema Draft-07) defined in template-json-schema.ts.
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 template.json file.
433
+ * Result of validating a bundle.
436
434
  */
437
- interface TemplateJsonResult {
435
+ interface BundleValidationResult {
438
436
  metadata: TemplateMetadata;
439
437
  jsonSchema: JSONSchema7;
440
438
  }
441
439
  /**
442
- * Validate the structure of a parsed template.json file.
440
+ * Validate the structure of a parsed bundle.
443
441
  *
444
442
  * 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
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 template.json
449
+ * @param data - Parsed JSON content from a bundle
452
450
  * @returns Validated metadata and JSON Schema
453
- * @throws EngineError with TEMPLATE_JSON_INVALID on failure
451
+ * @throws EngineError with BUNDLE_INVALID on failure
454
452
  */
455
- declare function validateTemplateJson(data: unknown): TemplateJsonResult;
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 template.json files.
481
+ * JSON Schema (Draft-07) for bundle.json files.
484
482
  *
485
- * This is the source of truth for template.json validation.
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
- * - "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
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 extra top-level keys are allowed
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 templateJsonSchema: JSONSchema7;
494
+ declare const bundleSchema: JSONSchema7;
497
495
 
498
496
  /**
499
497
  * Check if tofu is available in the system.
@@ -529,6 +527,47 @@ declare const DEFAULT_PREFIX = "tfy_";
529
527
  */
530
528
  declare function classifyFile(filePath: string, prefix?: string): Zone;
531
529
 
530
+ /**
531
+ * Format-independent canonical hashing via external shell script.
532
+ *
533
+ * Delegates to `scripts/canonical_hash.sh` which canonicalizes HCL content
534
+ * (stripping headers, comments, whitespace, and normalizing trailing commas)
535
+ * then computes a SHA-256 hash. Uses spawnSync to keep the entire call graph
536
+ * synchronous.
537
+ *
538
+ * Reference: R-003, R-010
539
+ */
540
+ /**
541
+ * Get the absolute path to the canonical_hash.sh script.
542
+ *
543
+ * Resolves by walking up from the current module's directory to find the
544
+ * package root, then appending `scripts/canonical_hash.sh`. The result is
545
+ * cached after first resolution.
546
+ *
547
+ * Works in all environments:
548
+ * - Dev/test: __dirname = src/integrity -> walk up 2 levels
549
+ * - tsup CJS: __dirname = dist -> walk up 1 level
550
+ * - tsup ESM: __dirname shimmed by esbuild -> walk up 1 level
551
+ */
552
+ declare function getCanonicalHashScriptPath(): string;
553
+ /**
554
+ * Compute a format-independent canonical hash of HCL content.
555
+ *
556
+ * The shell script handles the full pipeline: strip @tfy-status header,
557
+ * strip carriage returns, canonicalize via AWK 4-state machine, then SHA-256.
558
+ *
559
+ * If the script fails for any reason (not found, timeout, bad exit code,
560
+ * malformed output), falls back to a raw SHA-256 of the header-stripped
561
+ * content and logs a warning.
562
+ *
563
+ * @param content - Raw file content (may include @tfy-status header)
564
+ * @param options - Optional timeout in milliseconds (default: 10000)
565
+ * @returns Hash string in format "sha256:<64-hex-chars>"
566
+ */
567
+ declare function canonicalHash(content: string, options?: {
568
+ timeout?: number;
569
+ }): string;
570
+
532
571
  /**
533
572
  * @tfy-status header processing: parse, strip, inject.
534
573
  *
@@ -586,4 +625,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
586
625
  */
587
626
  declare function createEngine(): HclEngine;
588
627
 
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 };
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
- TEMPLATE_JSON_NOT_FOUND = "TEMPLATE_JSON_NOT_FOUND",
14
- TEMPLATE_JSON_INVALID = "TEMPLATE_JSON_INVALID",
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 template.json.
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 "template" key in template.json.
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 template.json "template" key; schema from "schema" key.
189
+ * Metadata comes from bundle.json "metadata" key; schema from "jsonSchema" key.
192
190
  */
193
191
  interface Template {
194
- /** Template metadata from template.json → "template" key */
192
+ /** Template metadata from bundle.json → "metadata" key */
195
193
  metadata: TemplateMetadata;
196
- /** JSON Schema Draft-07 from template.json → "schema" key */
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
- * Template JSON structure validation using AJV.
424
+ * Bundle structure validation using AJV.
427
425
  *
428
- * Validates the top-level structure of template.json against the
429
- * templateJsonSchema (JSON Schema Draft-07) defined in template-json-schema.ts.
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 template.json file.
433
+ * Result of validating a bundle.
436
434
  */
437
- interface TemplateJsonResult {
435
+ interface BundleValidationResult {
438
436
  metadata: TemplateMetadata;
439
437
  jsonSchema: JSONSchema7;
440
438
  }
441
439
  /**
442
- * Validate the structure of a parsed template.json file.
440
+ * Validate the structure of a parsed bundle.
443
441
  *
444
442
  * 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
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 template.json
449
+ * @param data - Parsed JSON content from a bundle
452
450
  * @returns Validated metadata and JSON Schema
453
- * @throws EngineError with TEMPLATE_JSON_INVALID on failure
451
+ * @throws EngineError with BUNDLE_INVALID on failure
454
452
  */
455
- declare function validateTemplateJson(data: unknown): TemplateJsonResult;
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 template.json files.
481
+ * JSON Schema (Draft-07) for bundle.json files.
484
482
  *
485
- * This is the source of truth for template.json validation.
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
- * - "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
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 extra top-level keys are allowed
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 templateJsonSchema: JSONSchema7;
494
+ declare const bundleSchema: JSONSchema7;
497
495
 
498
496
  /**
499
497
  * Check if tofu is available in the system.
@@ -529,6 +527,47 @@ declare const DEFAULT_PREFIX = "tfy_";
529
527
  */
530
528
  declare function classifyFile(filePath: string, prefix?: string): Zone;
531
529
 
530
+ /**
531
+ * Format-independent canonical hashing via external shell script.
532
+ *
533
+ * Delegates to `scripts/canonical_hash.sh` which canonicalizes HCL content
534
+ * (stripping headers, comments, whitespace, and normalizing trailing commas)
535
+ * then computes a SHA-256 hash. Uses spawnSync to keep the entire call graph
536
+ * synchronous.
537
+ *
538
+ * Reference: R-003, R-010
539
+ */
540
+ /**
541
+ * Get the absolute path to the canonical_hash.sh script.
542
+ *
543
+ * Resolves by walking up from the current module's directory to find the
544
+ * package root, then appending `scripts/canonical_hash.sh`. The result is
545
+ * cached after first resolution.
546
+ *
547
+ * Works in all environments:
548
+ * - Dev/test: __dirname = src/integrity -> walk up 2 levels
549
+ * - tsup CJS: __dirname = dist -> walk up 1 level
550
+ * - tsup ESM: __dirname shimmed by esbuild -> walk up 1 level
551
+ */
552
+ declare function getCanonicalHashScriptPath(): string;
553
+ /**
554
+ * Compute a format-independent canonical hash of HCL content.
555
+ *
556
+ * The shell script handles the full pipeline: strip @tfy-status header,
557
+ * strip carriage returns, canonicalize via AWK 4-state machine, then SHA-256.
558
+ *
559
+ * If the script fails for any reason (not found, timeout, bad exit code,
560
+ * malformed output), falls back to a raw SHA-256 of the header-stripped
561
+ * content and logs a warning.
562
+ *
563
+ * @param content - Raw file content (may include @tfy-status header)
564
+ * @param options - Optional timeout in milliseconds (default: 10000)
565
+ * @returns Hash string in format "sha256:<64-hex-chars>"
566
+ */
567
+ declare function canonicalHash(content: string, options?: {
568
+ timeout?: number;
569
+ }): string;
570
+
532
571
  /**
533
572
  * @tfy-status header processing: parse, strip, inject.
534
573
  *
@@ -586,4 +625,4 @@ declare function parseHeader(content: string): TfyStatusHeader | undefined;
586
625
  */
587
626
  declare function createEngine(): HclEngine;
588
627
 
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 };
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 };