npm package: @origints/yaml
Description: YAML parsing for Origins with anchor/alias/tag preservation.
Latest version: 0.3.2

# @origints/yaml

> YAML parsing for Origins with anchor/alias/tag preservation and full lineage tracking.

---

## Features

- Parse single or multi-document YAML streams
- Preserve anchors, aliases, and custom tags
- Full source location tracking for every node
- Navigation API with type-safe extraction
- JSON conversion with customizable options
- Integrates with Origins transform registry

---

## Installation

```bash
npm install @origints/yaml @origints/core
```

---

## Usage with Planner

### Extract values from a YAML config file

```ts
import { Planner, loadFile, run } from '@origints/core'
import { parseYaml } from '@origints/yaml'

const plan = new Planner()
  .in(loadFile('config.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) =>
    out
      .add('host', $.get('database').get('host').string())
      .add('port', $.get('database').get('port').number())
  )
  .compile()

const result = await run(plan, { readFile, registry })
// result.value: { host: 'localhost', port: 5432 }
```

### Extract nested structures

```ts
// config.yaml:
// app:
//   name: MyApp
//   settings:
//     theme: dark
//     language: en

const plan = new Planner()
  .in(loadFile('config.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) =>
    out
      .add('appName', $.get('app').get('name').string())
      .add('theme', $.get('app').get('settings').get('theme').string())
      .add('lang', $.get('app').get('settings').get('language').string())
  )
  .compile()
```

### Extract arrays

```ts
// users.yaml:
// users:
//   - name: Alice
//     role: admin
//   - name: Bob
//     role: user

const plan = new Planner()
  .in(loadFile('users.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) =>
    out
      .add(
        'names',
        $.get('users').array(u => u.get('name').string())
      )
      .add(
        'roles',
        $.get('users').array(u => u.get('role').string())
      )
  )
  .compile()

const result = await run(plan, { readFile, registry })
// result.value: { names: ['Alice', 'Bob'], roles: ['admin', 'user'] }
```

### Convenience collection methods

For simple sequences of scalars, use `strings()` or `numbers()` instead of `array()`:

```ts
// config.yaml:
// tags:
//   - dev
//   - staging
//   - prod
// ports:
//   - 3000
//   - 3001
//   - 3002

const plan = new Planner()
  .in(loadFile('config.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) =>
    out
      .add('tags', $.get('tags').strings())
      .add('ports', $.get('ports').numbers())
  )
  .compile()

const result = await run(plan, { readFile, registry })
// result.value: { tags: ['dev', 'staging', 'prod'], ports: [3000, 3001, 3002] }
```

### Multi-document YAML

```ts
import { parseYamlAll } from '@origints/yaml'

const plan = new Planner()
  .in(loadFile('multi.yaml'))
  .mapIn(parseYamlAll())
  .emit((out, $) =>
    out.add(
      'names',
      $.array(doc => doc.get('name').string())
    )
  )
  .compile()
```

### Combine YAML with other sources

```ts
const plan = new Planner()
  .in(loadFile('defaults.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) =>
    out.add('host', $.get('host').string()).add('port', $.get('port').number())
  )
  .in(loadFile('overrides.yaml'))
  .mapIn(parseYaml())
  .emit((out, $) => out.addIfEmpty('host', $.get('host').string()))
  .compile()
```

### Standalone usage (without Planner)

```ts
import { parseYamlImpl, toJson, YamlNode } from '@origints/yaml'

const node = parseYamlImpl.execute(yamlString) as YamlNode

// Navigate with Result types
const name = node.get('name')
if (name.ok) {
  console.log(name.value.asString().value)
}

// Or convert to JSON
const json = toJson(node)
if (json.ok) {
  console.log(json.value)
}
```

---

## API

| Export                             | Description                                       |
| ---------------------------------- | ------------------------------------------------- |
| `parseYaml(options?)`              | Create a transform AST for single-document YAML   |
| `parseYamlAll(options?)`           | Create a transform AST for multi-document YAML    |
| `parseYamlImpl`                    | Sync transform implementation (string input)      |
| `parseYamlAsyncImpl`               | Async transform implementation (string or stream) |
| `parseYamlAllImpl`                 | Async multi-document implementation               |
| `registerYamlTransforms(registry)` | Register all YAML transforms with a registry      |
| `YamlNode`                         | Navigable wrapper around parsed YAML              |
| `toJson(node, options?)`           | Convert YamlNode to JSON                          |
| `toJsonValue(node)`                | Convert YamlNode to JSON with defaults            |
| `ok`, `fail`, `formatYamlPath`     | Result helpers                                    |

---

## License

MIT