1.0.6 โ€ข Published 5 months ago

@openanime/hcl-unmarshal v1.0.6

Weekly downloads
-
License
MIT
Repository
-
Last release
5 months ago

hcl-unmarshal

A zero-dependency TypeScript library for parsing HashiCorp Configuration Language (HCL) v1 into plain JavaScript objects. Works out-of-the-box in Node.js, modern browsers, and React Native.


๐Ÿ” Features

  • Full HCL v1 support
    Labels, blocks, nested blocks
    Scalar assignments, maps, nested arrays
    Heredoc / multiline strings
  • Pure JS/TS implementation
    No native modules, no WebAssemblyโ€”just install and import
  • Accurate recursive-descent parser
    Faithfully reproduces HCLโ€™s AST shape as JSON
  • Built-in TypeScript definitions
    Type-safe imports & IntelliSense support

๐Ÿš€ Installation

npm i @openanime/hcl-unmarshal
# or
pnpm i @openanime/hcl-unmarshal

๐Ÿ’ก Quick Start

import { hclToJson } from '@openanime/hcl-unmarshal';

const hcl = `
variable "env" {
  default = "production"
}

resource "aws_s3_bucket" "my_bucket" {
  bucket = "my-app-data"
  acl    = "private"

  tags = ["app", "data"]
}
`;

console.log(JSON.stringify(hclToJson(hcl)));

Result:

{
    "variable": [
        {
            "env": [
                {
                    "default": "production"
                }
            ]
        }
    ],
    "resource": [
        {
            "aws_s3_bucket": [
                {
                    "my_bucket": [
                        {
                            "bucket": "my-app-data",
                            "acl": "private",
                            "tags": ["app", "data"]
                        }
                    ]
                }
            ]
        }
    ]
}

๐Ÿ“š API

hclToJson(input: string): Record<string, any>

Parses an HCL string (v1) into a nested JS object/array structure.

  • input: full HCL document as a single string
  • returns: a JSON-compatible object reflecting your HCL blocks, labels, and values

๐Ÿ› ๏ธ Examples

1. Variables & Maps

const hcl = `
variable "region" {
  type    = string
  default = "us-west-2"
}

variable "tags" {
  type    = map(string)
  default = {
    Env  = "prod"
    Team = "devops"
  }
}
`;

console.log(JSON.stringify(hclToJson(hcl)));

Result:

{
    "variable": [
        {
            "region": [
                {
                    "type": "string",
                    "default": "us-west-2"
                }
            ]
        },
        {
            "tags": [
                {
                    "type": "map(string)",
                    "default": {
                        "Env": "prod",
                        "Team": "devops"
                    }
                }
            ]
        }
    ]
}

2. Resource with Nested Blocks & Lists

const hcl = `
resource "aws_instance" "web" {
  ami  = "ami-123"
  tags = ["web", "prod"]

  network_interface {
    device_index = 0
    network_id   = "net-abc"
  }
}
`;

console.log(JSON.stringify(hclToJson(hcl));

Result:

{
    "resource": [
        {
            "aws_instance": [
                {
                    "web": [
                        {
                            "ami": "ami-123",
                            "tags": ["web", "prod"],
                            "network_interface": [
                                {
                                    "device_index": 0,
                                    "network_id": "net-abc"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

3. Locals with Nested Arrays & Objects

const hcl = `
locals {
  servers = [
    {
      name = "frontend"
      port = 80
    },
    {
      name = "backend"
      port = 8080
    }
  ]
}
`;

console.log(JSON.stringify(hclToJson(hcl)));

Result:

{
    "locals": [
        {
            "servers": [
                {
                    "name": "frontend",
                    "port": 80
                },
                {
                    "name": "backend",
                    "port": 8080
                }
            ]
        }
    ]
}

๐Ÿง‘โ€๐Ÿ’ป Development

  1. Clone the repo
  2. Install dependencies

    pnpm i
  3. Build

    pnpm build
  4. Test

    pnpx jest

๐Ÿค Contributing

Contributions welcome! Please open issues or pull requests for bugs, feature requests, or improvements.


๐Ÿ“œ License

Distributed under the MIT License. See LICENSE for details.