@homedev/hcl
v1.1.9
Published
hcl parser and serializer
Readme
@homedev/hcl
Small HCL parser and serializer for Terraform-style documents, block trees, literal values, function calls, traversal expressions, and provider metadata helpers.
import { parse, stringify, updateRequiredProvider } from '@homedev/hcl'
const document = parse(`
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
`)
updateRequiredProvider(document, 'hashicorp/aws', '>= 6.0.0')
console.log(stringify(document))Install
bun add @homedev/hcl
# or
npm install @homedev/hclCore usage
import { parse, stringify } from '@homedev/hcl'
const document = parse('service "api" { port = 8080 }')
const hcl = stringify(document, { align: true })
console.log(hcl)Public API
Parsing and serialization
parse(source: string, filePath?: string): HclDocumentParses an HCL source string into an in-memory document tree. The optionalfilePathis stored on the document for later save/load workflows.stringify(document: HclDocument, options?: StringifyOptions): stringSerializes a parsed document back to formatted HCL.StringifyOptionsindentation?: string— default is two spaces (" ")align?: boolean— default istrue; aligns assignment operators across adjacent attributes
AST types
HclDocumentHclAttribute<T = HclValue>HclBlockHclCommentHclFunctionHclTraversalHclObjectHclValueHclTargetHclBodyItemHclScalar
Object metadata helpers
markObjectBlankLine(object: HclObject, key: string): voidMarks a key so serializer output keeps a blank line before the next object-valued field.hasObjectBlankLine(object: HclObject, key: string): booleanChecks whether the key was marked for blank-line grouping.
File helpers
save(document: HclDocument, filePath?: string): Promise<void>Writes the formatted HCL for a document to disk. IffilePathis omitted, it usesdocument.filePath.load(filePath: string): Promise<HclDocument | null>load(filePaths: string[]): Promise<HclDocument[]>load(options: LoadFirstOptions): Promise<HclDocument | null>load(options: LoadWhereOptions): Promise<HclDocument[]>load(options: LoadOptions): Promise<HclDocument[]>LoadOptions,LoadFirstOptions, andLoadWhereOptionsReads one file, many files, or folder-based HCL inputs. Supported load options include:paths?: string[]folder?: stringpattern?: stringfirst?: (document: HclDocument) => booleanwhere?: (document: HclDocument) => booleanerror?: (error: Error, filePath: string) => void
Body and lookup helpers
bodyItem(from: HclNullableTarget, desc: HclEntityDesc): HclBodyItem | undefinedbodyItems<T extends HclBodyItem>(from: HclNullableTarget, desc: HclEntityDesc): T[]block(from: HclNullableTarget, type: string): HclBlock | undefinedblocks(from: HclNullableTarget, type: string): HclBlock[]attribute<T extends HclValue>(from: HclNullableTarget, name: string): HclAttribute<T> | undefinedattributes<T extends HclValue>(from: HclNullableTarget, name: string): HclAttribute<T>[]addBlock(to: HclTarget, block: HclBlock): HclBlockaddAttribute<T extends HclValue>(to: HclTarget, attribute: HclAttribute<T>): HclAttribute<T>addComment(comment: string, to: HclTarget): voidaddBlankLine(to: HclTarget): void
Terraform and provider helpers
terraformBlock(document: HclDocument): HclBlock | undefinedrequiredProvidersBlock(document: HclDocument): HclBlock | undefinedcloudBlock(document: HclDocument): HclBlock | undefinedworkspacesBlock(document: HclDocument): HclBlock | undefinedproviderBlocks(document: HclDocument, name?: string): HclBlock[]localBlocks(document: HclDocument): HclBlock[]local(document: HclDocument, name: string): HclAttribute | undefinedrequiredProviders(document: HclDocument, normalizeSource?: boolean): Record<string, HclRequiredProvider>requiredProviderBySource(document: HclDocument, source: string | HclSource): HclAttribute<HclRequiredProvider> | undefinedrequiredProvider(document: HclDocument, nameOrSource: string | HclSource): HclAttribute<HclRequiredProvider> | undefinedupdateRequiredProvider(document: HclDocument, source: string | HclSource, version?: string | null): HclAttribute<HclRequiredProvider>parseProviderSource(source: HclSource | string): HclSourceParses a provider source such ashashicorp/awsorexample/acme/eksinto{ prefix?, domain, name }.serializeProviderSource(source: HclSource | string): stringSerializes a normalized provider source back to the canonical HCL string form.compareSources(a: HclSource | string, b: HclSource | string): booleanCompares two provider sources after normalization.
Document builders
create(body: HclDocument['body'] = []): HclDocumentCreates an empty document or one seeded with a prebuilt body.toBlock(type: string, value: Record<string, HclValue>, labels: string[] = []): HclBlockCreates a block from a plain JavaScript object.updateAttribute<T extends HclValue>(to: HclTarget, name: string, value: T): HclAttribute<T>Creates or updates an attribute in a document or block.
Example: working with providers
import { parse, requiredProvider, stringify, updateRequiredProvider } from '@homedev/hcl'
const document = parse('terraform { required_providers { aws = { source = "hashicorp/aws" } } }')
updateRequiredProvider(document, 'aws', '~> 5.0')
console.log(stringify(document))
console.log(requiredProvider(document, 'aws')?.value)Run locally
bun test
bun run play