react-hcl 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -0
- package/dist/blocks.d.ts +125 -0
- package/dist/cli.d.ts +22 -0
- package/dist/cli.js +210971 -0
- package/dist/components/data-source.d.ts +21 -0
- package/dist/components/index.d.ts +8 -0
- package/dist/components/locals.d.ts +12 -0
- package/dist/components/module.d.ts +24 -0
- package/dist/components/output.d.ts +18 -0
- package/dist/components/provider.d.ts +19 -0
- package/dist/components/resource.d.ts +21 -0
- package/dist/components/terraform.d.ts +15 -0
- package/dist/components/variable.d.ts +21 -0
- package/dist/conflict.d.ts +29 -0
- package/dist/generator.d.ts +36 -0
- package/dist/hcl-serializer.d.ts +144 -0
- package/dist/hcl-validator.d.ts +14 -0
- package/dist/helpers/tf.d.ts +27 -0
- package/dist/hooks/use-ref.d.ts +79 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.js +320 -0
- package/dist/jsx-runtime.d.ts +40 -0
- package/dist/jsx-runtime.js +23 -0
- package/dist/renderer.d.ts +12 -0
- package/package.json +52 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DataSource component — produces a DataSourceBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `type` and `name` as block labels, passes remaining props as HCL attributes.
|
|
5
|
+
* Special props `ref` and `children` are excluded from attributes:
|
|
6
|
+
* - `ref`: reserved for useRef (Step 8)
|
|
7
|
+
* - `children`: if string, stored as `innerText`
|
|
8
|
+
*
|
|
9
|
+
* Usage in TSX:
|
|
10
|
+
* <DataSource type="aws_ami" name="latest" most_recent={true} />
|
|
11
|
+
* → data "aws_ami" "latest" { most_recent = true }
|
|
12
|
+
*/
|
|
13
|
+
import type { DataSourceBlock } from "../blocks";
|
|
14
|
+
export declare function DataSource(props: {
|
|
15
|
+
type: string;
|
|
16
|
+
name: string;
|
|
17
|
+
ref?: any;
|
|
18
|
+
children?: string | string[];
|
|
19
|
+
attributes?: Record<string, any>;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}): DataSourceBlock;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DataSource } from "./data-source";
|
|
2
|
+
export { Locals } from "./locals";
|
|
3
|
+
export { Module } from "./module";
|
|
4
|
+
export { Output } from "./output";
|
|
5
|
+
export { Provider } from "./provider";
|
|
6
|
+
export { Resource } from "./resource";
|
|
7
|
+
export { Terraform } from "./terraform";
|
|
8
|
+
export { Variable } from "./variable";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Locals component — produces a LocalsBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* All props become HCL attributes (there is no name label for locals blocks).
|
|
5
|
+
* The `children` prop is excluded as it's a JSX-internal prop.
|
|
6
|
+
*
|
|
7
|
+
* Usage in TSX:
|
|
8
|
+
* <Locals environment="prod" project_name="my-app" />
|
|
9
|
+
* → locals { environment = "prod"\n project_name = "my-app" }
|
|
10
|
+
*/
|
|
11
|
+
import type { LocalsBlock } from "../blocks";
|
|
12
|
+
export declare function Locals(props: Record<string, any>): LocalsBlock;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module component — produces a ModuleBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `name` as the block label, passes remaining props as HCL attributes.
|
|
5
|
+
* Reserved props `ref` and `children` are excluded from attributes:
|
|
6
|
+
* - `ref`: reserved for useRef — resolves to module.<name>.<output>
|
|
7
|
+
* - `children`: if string, stored as `innerText` for raw HCL body output
|
|
8
|
+
*
|
|
9
|
+
* Special handling for `depends_on` and `providers`:
|
|
10
|
+
* - `depends_on`: ref proxies are resolved to raw("module.name") / raw("type.name")
|
|
11
|
+
* - `providers`: ref proxies are resolved to raw("type.alias") with attribute() wrapper
|
|
12
|
+
*
|
|
13
|
+
* Usage in TSX:
|
|
14
|
+
* <Module name="vpc" source="terraform-aws-modules/vpc/aws" version="~> 5.0" cidr="10.0.0.0/16" />
|
|
15
|
+
* → module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0" cidr = "10.0.0.0/16" }
|
|
16
|
+
*/
|
|
17
|
+
import type { ModuleBlock } from "../blocks";
|
|
18
|
+
export declare function Module(props: {
|
|
19
|
+
name: string;
|
|
20
|
+
ref?: any;
|
|
21
|
+
children?: string | string[];
|
|
22
|
+
attributes?: Record<string, any>;
|
|
23
|
+
[key: string]: any;
|
|
24
|
+
}): ModuleBlock;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Output component — produces an OutputBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `name` as the block label, passes remaining props (value, description, sensitive, etc.)
|
|
5
|
+
* as HCL attributes.
|
|
6
|
+
*
|
|
7
|
+
* Usage in TSX:
|
|
8
|
+
* <Output name="vpc_id" value="aws_vpc.main.id" />
|
|
9
|
+
* → output "vpc_id" { value = "aws_vpc.main.id" }
|
|
10
|
+
*/
|
|
11
|
+
import type { OutputBlock } from "../blocks";
|
|
12
|
+
export declare function Output(props: {
|
|
13
|
+
name: string;
|
|
14
|
+
value: any;
|
|
15
|
+
description?: string;
|
|
16
|
+
sensitive?: boolean;
|
|
17
|
+
[key: string]: any;
|
|
18
|
+
}): OutputBlock;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider component — produces a ProviderBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `type` as the block label, passes remaining props as HCL attributes.
|
|
5
|
+
* Special props `ref` is excluded from attributes (reserved for useRef).
|
|
6
|
+
* If both `ref` and `alias` are provided, the alias is stored on the ref metadata
|
|
7
|
+
* so that references resolve to `<type>.<alias>`.
|
|
8
|
+
*
|
|
9
|
+
* Usage in TSX:
|
|
10
|
+
* <Provider type="aws" region="ap-northeast-1" />
|
|
11
|
+
* → provider "aws" { region = "ap-northeast-1" }
|
|
12
|
+
*/
|
|
13
|
+
import type { ProviderBlock } from "../blocks";
|
|
14
|
+
export declare function Provider(props: {
|
|
15
|
+
type: string;
|
|
16
|
+
ref?: any;
|
|
17
|
+
alias?: string;
|
|
18
|
+
[key: string]: any;
|
|
19
|
+
}): ProviderBlock;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resource component — produces a ResourceBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `type` and `name` as block labels, passes remaining props as HCL attributes.
|
|
5
|
+
* Special props `ref` and `children` are excluded from attributes:
|
|
6
|
+
* - `ref`: reserved for useRef (Step 8)
|
|
7
|
+
* - `children`: if string, stored as `innerText` for raw HCL body output (Step 10)
|
|
8
|
+
*
|
|
9
|
+
* Usage in TSX:
|
|
10
|
+
* <Resource type="aws_vpc" name="main" cidr_block="10.0.0.0/16" />
|
|
11
|
+
* → resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" }
|
|
12
|
+
*/
|
|
13
|
+
import type { ResourceBlock } from "../blocks";
|
|
14
|
+
export declare function Resource(props: {
|
|
15
|
+
type: string;
|
|
16
|
+
name: string;
|
|
17
|
+
ref?: any;
|
|
18
|
+
children?: string | string[];
|
|
19
|
+
attributes?: Record<string, any>;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}): ResourceBlock;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terraform component — produces a TerraformBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* All props become HCL attributes. Supports `children` as raw HCL text (innerText)
|
|
5
|
+
* for nested blocks like `backend "s3" { ... }` that need verbatim HCL.
|
|
6
|
+
*
|
|
7
|
+
* Usage in TSX:
|
|
8
|
+
* <Terraform required_version=">= 1.0" />
|
|
9
|
+
* → terraform { required_version = ">= 1.0" }
|
|
10
|
+
*/
|
|
11
|
+
import type { TerraformBlock } from "../blocks";
|
|
12
|
+
export declare function Terraform(props: {
|
|
13
|
+
children?: string | string[];
|
|
14
|
+
[key: string]: any;
|
|
15
|
+
}): TerraformBlock;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Variable component — produces a VariableBlock for the Block[] IR pipeline.
|
|
3
|
+
*
|
|
4
|
+
* Extracts `name` as the block label.
|
|
5
|
+
* The `type` prop is automatically wrapped with raw() so that HCL outputs `type = string`
|
|
6
|
+
* (unquoted) rather than `type = "string"` (quoted). This lets users write naturally:
|
|
7
|
+
* <Variable name="env" type="string" />
|
|
8
|
+
*
|
|
9
|
+
* Usage in TSX:
|
|
10
|
+
* <Variable name="environment" type="string" default="dev" />
|
|
11
|
+
* → variable "environment" { type = string\n default = "dev" }
|
|
12
|
+
*/
|
|
13
|
+
import type { VariableBlock } from "../blocks";
|
|
14
|
+
export declare function Variable(props: {
|
|
15
|
+
name: string;
|
|
16
|
+
type?: string;
|
|
17
|
+
default?: any;
|
|
18
|
+
description?: string;
|
|
19
|
+
sensitive?: boolean;
|
|
20
|
+
[key: string]: any;
|
|
21
|
+
}): VariableBlock;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Conflict detection for Terraform blocks.
|
|
3
|
+
*
|
|
4
|
+
* Validates that the collected Block[] does not contain duplicates that would
|
|
5
|
+
* produce invalid Terraform configuration. This runs after render() and before
|
|
6
|
+
* generate() in the CLI pipeline.
|
|
7
|
+
*
|
|
8
|
+
* Conflict rules (from design doc §5.2):
|
|
9
|
+
* - Resource: duplicate type + name → error
|
|
10
|
+
* - DataSource: duplicate type + name → error
|
|
11
|
+
* - Resource vs DataSource with same type + name → allowed
|
|
12
|
+
* - Variable: duplicate name → error
|
|
13
|
+
* - Output: duplicate name → error
|
|
14
|
+
* - Locals: multiple blocks → allowed
|
|
15
|
+
* - Provider: same type with different alias → allowed; same type + alias → error
|
|
16
|
+
* - Terraform: more than one block → error
|
|
17
|
+
* - Module: duplicate name → error
|
|
18
|
+
*/
|
|
19
|
+
import type { Block } from "./blocks";
|
|
20
|
+
export declare class ConflictError extends Error {
|
|
21
|
+
constructor(message: string);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Detect conflicts in a list of blocks and throw ConflictError if any are found.
|
|
25
|
+
*
|
|
26
|
+
* Checks each block type independently. For provider blocks, alias is extracted
|
|
27
|
+
* from attributes (absence of alias is treated as empty string for grouping).
|
|
28
|
+
*/
|
|
29
|
+
export declare function detectConflicts(blocks: Block[]): void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HCL code generator — converts Block[] intermediate representation into a Terraform .tf file string.
|
|
3
|
+
*
|
|
4
|
+
* This module is the final stage of the pipeline:
|
|
5
|
+
* JSX components → Block[] (IR) → generate() → HCL string
|
|
6
|
+
*
|
|
7
|
+
* Output formatting rules:
|
|
8
|
+
* - Each block is rendered as: <header> {\n<body>\n}
|
|
9
|
+
* - Blocks are separated by a single blank line (\n\n)
|
|
10
|
+
* - The output always ends with a trailing newline
|
|
11
|
+
* - If a block has `innerText`, it is used as-is as the body (no attribute serialization)
|
|
12
|
+
* - Otherwise, attributes are serialized via serializeHCLAttributes() from hcl-serializer.ts
|
|
13
|
+
* - Empty attribute blocks produce: <header> {\n}
|
|
14
|
+
*/
|
|
15
|
+
import type { Block } from "./blocks";
|
|
16
|
+
/**
|
|
17
|
+
* Generates a complete Terraform .tf file string from an array of Block objects.
|
|
18
|
+
*
|
|
19
|
+
* @param blocks - Array of Block IR objects to render
|
|
20
|
+
* @returns A string of valid HCL with blocks separated by blank lines, ending with a newline
|
|
21
|
+
*
|
|
22
|
+
* Example:
|
|
23
|
+
* generate([
|
|
24
|
+
* { blockType: "resource", type: "aws_vpc", name: "main", attributes: { cidr_block: "10.0.0.0/16" } },
|
|
25
|
+
* { blockType: "resource", type: "aws_subnet", name: "public", attributes: { cidr_block: "10.0.1.0/24" } },
|
|
26
|
+
* ])
|
|
27
|
+
* →
|
|
28
|
+
* resource "aws_vpc" "main" {
|
|
29
|
+
* cidr_block = "10.0.0.0/16"
|
|
30
|
+
* }
|
|
31
|
+
*
|
|
32
|
+
* resource "aws_subnet" "public" {
|
|
33
|
+
* cidr_block = "10.0.1.0/24"
|
|
34
|
+
* }
|
|
35
|
+
*/
|
|
36
|
+
export declare function generate(blocks: Block[]): string;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HCL attribute serializer — converts JavaScript objects into HCL attribute syntax.
|
|
3
|
+
*
|
|
4
|
+
* This module handles the serialization of key-value attribute pairs inside HCL blocks.
|
|
5
|
+
* It distinguishes between two HCL syntactic forms:
|
|
6
|
+
*
|
|
7
|
+
* 1. Attribute syntax: key = value (uses `=` sign)
|
|
8
|
+
* 2. Block syntax: key { ... } (no `=` sign, used for nested blocks)
|
|
9
|
+
*
|
|
10
|
+
* The serializer automatically determines which syntax to use based on:
|
|
11
|
+
* - Explicit BlockHCL marker → always block syntax
|
|
12
|
+
* - Key name in BLOCK_WHITELIST + plain object value → block syntax
|
|
13
|
+
* - Plain object value (not in whitelist) → attribute syntax with `=` (e.g. tags = { ... })
|
|
14
|
+
* - Array of plain objects → repeated block syntax (e.g. multiple ingress { } blocks)
|
|
15
|
+
* - Primitive values (string, number, boolean) and arrays of primitives → attribute syntax
|
|
16
|
+
*
|
|
17
|
+
* Three marker types represent the HCL value categories:
|
|
18
|
+
* - RawHCL: outputs a string value without quotes (for Terraform references like var.foo)
|
|
19
|
+
* - BlockHCL: block syntax for a nested object (key { ... }, no `=`)
|
|
20
|
+
* - AttributeHCL: attribute syntax for a nested object (key = { ... }, with `=`)
|
|
21
|
+
*
|
|
22
|
+
* All three are user-facing — users can explicitly wrap values with raw(), block(), or attribute().
|
|
23
|
+
* When no marker is specified, the serializer auto-classifies plain objects:
|
|
24
|
+
* - Key in BLOCK_WHITELIST → auto block()
|
|
25
|
+
* - Otherwise → auto attribute()
|
|
26
|
+
* Explicit markers always take precedence over auto-classification.
|
|
27
|
+
*
|
|
28
|
+
* Formatting:
|
|
29
|
+
* - Simple attributes are aligned by padding key names to the same width
|
|
30
|
+
* - Block entries are separated from simple attributes by a blank line
|
|
31
|
+
* - Indentation increases by 2 spaces per nesting level (default starts at 2)
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* RawHCL — marker type for unquoted HCL expressions.
|
|
35
|
+
*
|
|
36
|
+
* In HCL, some values must not be quoted (e.g. variable references, function calls):
|
|
37
|
+
* vpc_id = aws_vpc.main.id ← raw (no quotes)
|
|
38
|
+
* name = "my-vpc" ← string (quoted)
|
|
39
|
+
*
|
|
40
|
+
* Usage: raw("aws_vpc.main.id") produces a RawHCL value that serializes without quotes.
|
|
41
|
+
* Also implements toString() so it can be used in template literals.
|
|
42
|
+
*
|
|
43
|
+
* Identified at runtime via a global Symbol key (Symbol.for).
|
|
44
|
+
* Global symbols are used because esbuild bundles inline this module, creating separate
|
|
45
|
+
* copies in the bundle and the CLI process. Symbol.for() ensures both copies share the
|
|
46
|
+
* same Symbol identity, so isRawHCL() works across the bundle boundary.
|
|
47
|
+
*/
|
|
48
|
+
declare const RAW_HCL_SYMBOL: unique symbol;
|
|
49
|
+
export type RawHCL = {
|
|
50
|
+
[RAW_HCL_SYMBOL]: true;
|
|
51
|
+
value: string;
|
|
52
|
+
toString(): string;
|
|
53
|
+
};
|
|
54
|
+
/** Creates a RawHCL marker. The value string is emitted as-is (no quoting). */
|
|
55
|
+
export declare function raw(value: string): RawHCL;
|
|
56
|
+
/** Type guard for RawHCL values. Checks for the private Symbol key. */
|
|
57
|
+
export declare function isRawHCL(v: unknown): v is RawHCL;
|
|
58
|
+
/**
|
|
59
|
+
* BlockHCL — marker type to force block syntax for a nested object.
|
|
60
|
+
*
|
|
61
|
+
* By default, a plain object value is rendered as attribute syntax: key = { ... }
|
|
62
|
+
* Wrapping it with block() forces block syntax: key { ... } (no `=`)
|
|
63
|
+
*
|
|
64
|
+
* This is needed when the key name is not in BLOCK_WHITELIST but should still
|
|
65
|
+
* use block syntax (e.g. custom nested blocks in provider-specific resources).
|
|
66
|
+
*
|
|
67
|
+
* Identified at runtime via a global Symbol key (Symbol.for).
|
|
68
|
+
* See RAW_HCL_SYMBOL for why global symbols are necessary.
|
|
69
|
+
*/
|
|
70
|
+
declare const BLOCK_HCL_SYMBOL: unique symbol;
|
|
71
|
+
export type BlockHCL = {
|
|
72
|
+
[BLOCK_HCL_SYMBOL]: true;
|
|
73
|
+
value: Record<string, any>;
|
|
74
|
+
};
|
|
75
|
+
/** Creates a BlockHCL marker wrapping a plain object to force block syntax. */
|
|
76
|
+
export declare function block(value: Record<string, any>): BlockHCL;
|
|
77
|
+
/** Type guard for BlockHCL values. Checks for the private Symbol key. */
|
|
78
|
+
export declare function isBlockHCL(v: unknown): v is BlockHCL;
|
|
79
|
+
/**
|
|
80
|
+
* AttributeHCL — marker type for attribute syntax with nested objects.
|
|
81
|
+
*
|
|
82
|
+
* Represents `key = { ... }` syntax (with `=`), as opposed to BlockHCL's `key { ... }`.
|
|
83
|
+
*
|
|
84
|
+
* Can be used explicitly to force attribute syntax even for BLOCK_WHITELIST keys:
|
|
85
|
+
* { lifecycle: attribute({ prevent_destroy: true }) }
|
|
86
|
+
* → lifecycle = { prevent_destroy = true } (attribute syntax forced)
|
|
87
|
+
*
|
|
88
|
+
* When no marker is specified, plain objects not in the whitelist are auto-wrapped
|
|
89
|
+
* as AttributeHCL during the classification phase.
|
|
90
|
+
*
|
|
91
|
+
* Identified at runtime via a global Symbol key (Symbol.for).
|
|
92
|
+
* See RAW_HCL_SYMBOL for why global symbols are necessary.
|
|
93
|
+
*/
|
|
94
|
+
declare const ATTRIBUTE_HCL_SYMBOL: unique symbol;
|
|
95
|
+
export type AttributeHCL = {
|
|
96
|
+
[ATTRIBUTE_HCL_SYMBOL]: true;
|
|
97
|
+
value: Record<string, any>;
|
|
98
|
+
};
|
|
99
|
+
/** Creates an AttributeHCL marker wrapping a plain object to force attribute syntax (key = { ... }). */
|
|
100
|
+
export declare function attribute(value: Record<string, any>): AttributeHCL;
|
|
101
|
+
/** Type guard for AttributeHCL values. Checks for the private Symbol key. */
|
|
102
|
+
export declare function isAttributeHCL(v: unknown): v is AttributeHCL;
|
|
103
|
+
/**
|
|
104
|
+
* Serializes a Record of attributes into indented HCL lines.
|
|
105
|
+
*
|
|
106
|
+
* @param attrs - Key-value pairs to serialize
|
|
107
|
+
* @param indent - Current indentation level in spaces (default: 2)
|
|
108
|
+
* @returns Multi-line string of HCL attributes (without enclosing braces)
|
|
109
|
+
*
|
|
110
|
+
* Processing order:
|
|
111
|
+
* 1. Entries are partitioned into simple attributes and block entries
|
|
112
|
+
* 2. Simple attributes are rendered first, with keys aligned (padded to max key length)
|
|
113
|
+
* 3. Block entries follow, separated from simple attrs by a blank line
|
|
114
|
+
*
|
|
115
|
+
* Entry classification (explicit markers take precedence over auto-classification):
|
|
116
|
+
* - AttributeHCL (explicit) → attribute syntax (key = { ... }), overrides whitelist
|
|
117
|
+
* - BlockHCL (explicit) → block syntax (key { ... })
|
|
118
|
+
* - Whitelisted key + plain object → auto block() (key { ... })
|
|
119
|
+
* - Plain object (not whitelisted) → auto attribute() (key = { ... })
|
|
120
|
+
* - Array of objects → repeated blocks (key { } key { })
|
|
121
|
+
* - Everything else → simple attribute (key = value)
|
|
122
|
+
*
|
|
123
|
+
* Example output (indent=2):
|
|
124
|
+
* cidr_block = "10.0.0.0/16"
|
|
125
|
+
* enable_dns_hostnames = true
|
|
126
|
+
*
|
|
127
|
+
* lifecycle {
|
|
128
|
+
* create_before_destroy = true
|
|
129
|
+
* }
|
|
130
|
+
*/
|
|
131
|
+
export declare function serializeHCLAttributes(attrs: Record<string, any>, indent?: number): string;
|
|
132
|
+
/**
|
|
133
|
+
* Adjusts indentation of a multi-line HCL string.
|
|
134
|
+
*
|
|
135
|
+
* 1. Strips leading and trailing blank lines
|
|
136
|
+
* 2. Computes the minimum indentation across non-empty lines
|
|
137
|
+
* 3. Re-indents all lines to the target indentation level
|
|
138
|
+
*
|
|
139
|
+
* @param text - Raw multi-line string (e.g. from JSX children)
|
|
140
|
+
* @param targetIndent - Desired indentation in number of spaces (default: 2)
|
|
141
|
+
* @returns Re-indented string
|
|
142
|
+
*/
|
|
143
|
+
export declare function adjustIndent(text: string, targetIndent?: number): string;
|
|
144
|
+
export {};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HCL validator for innerText content.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the raw HCL body in a dummy resource block and parses it with hcl2-parser
|
|
5
|
+
* to detect syntax errors before emitting invalid Terraform.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Validates an innerText HCL string by wrapping it in a dummy resource block
|
|
9
|
+
* and parsing with hcl2-parser.
|
|
10
|
+
*
|
|
11
|
+
* @param hclText - The raw HCL body text (already indented)
|
|
12
|
+
* @throws Error if the HCL is syntactically invalid
|
|
13
|
+
*/
|
|
14
|
+
export declare function validateInnerTextHCL(hclText: string): void;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terraform expression helpers — provides shorthand functions for referencing
|
|
3
|
+
* Terraform variables and locals inside JSX attributes.
|
|
4
|
+
*
|
|
5
|
+
* These helpers return RawHCL values, which the HCL serializer outputs without
|
|
6
|
+
* quotes. This allows JSX attributes to contain Terraform expressions like
|
|
7
|
+
* `var.environment` or `local.common_tags` directly.
|
|
8
|
+
*
|
|
9
|
+
* Usage in TSX:
|
|
10
|
+
* <Resource type="aws_instance" name="web"
|
|
11
|
+
* instance_type={tf.var("instance_type")}
|
|
12
|
+
* tags={tf.local("common_tags")}
|
|
13
|
+
* />
|
|
14
|
+
*
|
|
15
|
+
* Output:
|
|
16
|
+
* resource "aws_instance" "web" {
|
|
17
|
+
* instance_type = var.instance_type
|
|
18
|
+
* tags = local.common_tags
|
|
19
|
+
* }
|
|
20
|
+
*/
|
|
21
|
+
import { type RawHCL } from "../hcl-serializer";
|
|
22
|
+
export declare const tf: {
|
|
23
|
+
/** tf.var("name") → var.name */
|
|
24
|
+
var(name: string): RawHCL;
|
|
25
|
+
/** tf.local("name") → local.name */
|
|
26
|
+
local(name: string): RawHCL;
|
|
27
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* useRef hook — creates a Proxy-based reference object for cross-resource references.
|
|
3
|
+
*
|
|
4
|
+
* In Terraform, resources often reference each other:
|
|
5
|
+
* vpc_id = aws_vpc.main.id
|
|
6
|
+
*
|
|
7
|
+
* useRef() returns a Proxy that:
|
|
8
|
+
* 1. Stores metadata (__refMeta) set by Resource/DataSource/Provider/Module components
|
|
9
|
+
* 2. Returns RawHCL values on property access (e.g. ref.id → raw("aws_vpc.main.id"))
|
|
10
|
+
* 3. Supports nested access (ref.outputs.vpc_id → raw("data.terraform_remote_state.x.outputs.vpc_id"))
|
|
11
|
+
* 4. Provides special __dependsOnValue (type.name format for depends_on)
|
|
12
|
+
* 5. Provides special __providerValue (type.alias format for provider references)
|
|
13
|
+
*
|
|
14
|
+
* Stateful hook store:
|
|
15
|
+
* useRef() uses a global hookStore to return the same proxy across multiple render passes.
|
|
16
|
+
* resetHookState(clear?) resets the hook index (and optionally clears the store).
|
|
17
|
+
* This enables 2-pass rendering: pass 1 collects ref metadata, pass 2 resolves references.
|
|
18
|
+
*
|
|
19
|
+
* The ref lifecycle (inside a component):
|
|
20
|
+
* function App() {
|
|
21
|
+
* const vpcRef = useRef();
|
|
22
|
+
* return (
|
|
23
|
+
* <>
|
|
24
|
+
* <Resource ref={vpcRef} type="aws_vpc" name="main" /> // registers metadata
|
|
25
|
+
* <Resource vpc_id={vpcRef.id} /> // lazy RawHCL, resolved at serialization
|
|
26
|
+
* </>
|
|
27
|
+
* );
|
|
28
|
+
* }
|
|
29
|
+
*/
|
|
30
|
+
import type { RawHCL } from "../hcl-serializer";
|
|
31
|
+
/**
|
|
32
|
+
* Metadata stored on a ref after a component registers it.
|
|
33
|
+
* Set by Resource, DataSource, Provider, or Module when they receive a `ref` prop.
|
|
34
|
+
*/
|
|
35
|
+
export type RefMeta = {
|
|
36
|
+
blockType: "resource" | "data" | "provider" | "module";
|
|
37
|
+
type: string;
|
|
38
|
+
name: string;
|
|
39
|
+
alias?: string;
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The Proxy-based ref object returned by useRef().
|
|
43
|
+
* Property access returns RawHCL or nested RefProxy for chained access.
|
|
44
|
+
*/
|
|
45
|
+
export type RefProxy = {
|
|
46
|
+
__refMeta?: RefMeta;
|
|
47
|
+
__dependsOnValue: RawHCL;
|
|
48
|
+
__providerValue: RawHCL;
|
|
49
|
+
[key: string]: any;
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Resets the hook state between render passes.
|
|
53
|
+
* @param clear If true, clears the store entirely (used before pass 1).
|
|
54
|
+
* If false/omitted, only resets the index (used before pass 2).
|
|
55
|
+
*/
|
|
56
|
+
export declare function resetHookState(clear?: boolean): void;
|
|
57
|
+
/**
|
|
58
|
+
* Returns the current hook store (for validation after rendering).
|
|
59
|
+
*/
|
|
60
|
+
export declare function getHookStore(): RefProxy[];
|
|
61
|
+
/**
|
|
62
|
+
* Creates a ref Proxy object for tracking Terraform resource references.
|
|
63
|
+
*
|
|
64
|
+
* Stateful: returns the same proxy on repeated calls within a render cycle
|
|
65
|
+
* (identified by hookIndex). This enables 2-pass rendering where pass 1
|
|
66
|
+
* collects metadata and pass 2 resolves references using the same proxies.
|
|
67
|
+
*
|
|
68
|
+
* Usage (inside a component function):
|
|
69
|
+
* function App() {
|
|
70
|
+
* const vpcRef = useRef();
|
|
71
|
+
* return (
|
|
72
|
+
* <>
|
|
73
|
+
* <Resource type="aws_vpc" name="main" ref={vpcRef} cidr_block="10.0.0.0/16" />
|
|
74
|
+
* <Resource type="aws_subnet" name="sub" vpc_id={vpcRef.id} />
|
|
75
|
+
* </>
|
|
76
|
+
* );
|
|
77
|
+
* }
|
|
78
|
+
*/
|
|
79
|
+
export declare function useRef(): RefProxy;
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public API entry point for the react-hcl package.
|
|
3
|
+
*
|
|
4
|
+
* This module re-exports all user-facing components and utilities.
|
|
5
|
+
* Users import from "react-hcl" in their TSX files:
|
|
6
|
+
*
|
|
7
|
+
* import { Resource, Fragment } from "react-hcl";
|
|
8
|
+
*
|
|
9
|
+
* As more components are added (Data, Variable, Output, Provider, etc.),
|
|
10
|
+
* they should be exported from here.
|
|
11
|
+
*/
|
|
12
|
+
export { DataSource } from "./components/data-source";
|
|
13
|
+
export { Locals } from "./components/locals";
|
|
14
|
+
export { Module } from "./components/module";
|
|
15
|
+
export { Output } from "./components/output";
|
|
16
|
+
export { Provider } from "./components/provider";
|
|
17
|
+
export { Resource } from "./components/resource";
|
|
18
|
+
export { Terraform } from "./components/terraform";
|
|
19
|
+
export { Variable } from "./components/variable";
|
|
20
|
+
export { block, raw } from "./hcl-serializer";
|
|
21
|
+
export { tf } from "./helpers/tf";
|
|
22
|
+
export { useRef } from "./hooks/use-ref";
|
|
23
|
+
export { Fragment } from "./jsx-runtime";
|