Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Added

- Support for newline-delimited JSON (NDJSON) input. Multiple JSON values in a single input are now parsed as a multi-document branch, matching the existing YAML multi-document behaviour.

### Fixed

- Strip leading "v" from version output for consistency across build methods (Docker vs Homebrew).
Expand Down
45 changes: 35 additions & 10 deletions parsing/json/json_reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,36 +18,61 @@ func newJSONReader(options parsing.ReaderOptions) (parsing.Reader, error) {
type jsonReader struct{}

// Read reads a value from a byte slice.
// When the input contains multiple JSON values (NDJSON), they are returned
// as a branch-marked slice, mirroring the YAML multi-document behaviour.
func (j *jsonReader) Read(data []byte) (*model.Value, error) {
decoder := json.NewDecoder(bytes.NewReader(data))
decoder.UseNumber()

var results []*model.Value

for decoder.More() {
v, err := j.decodeValue(decoder)
if err != nil {
return nil, err
}
results = append(results, v)
}

switch len(results) {
case 0:
return model.NewNullValue(), nil
case 1:
return results[0], nil
default:
slice := model.NewSliceValue()
slice.MarkAsBranch()
for _, v := range results {
if err := slice.Append(v); err != nil {
return nil, err
}
}
return slice, nil
}
}

func (j *jsonReader) decodeValue(decoder *json.Decoder) (*model.Value, error) {
t, err := decoder.Token()
if err != nil {
return nil, err
}

var res *model.Value

switch t {
case jsonOpenObject:
res, err = j.decodeObject(decoder)
res, err := j.decodeObject(decoder)
if err != nil {
return nil, fmt.Errorf("could not decode object: %w", err)
}
return res, nil
case jsonOpenArray:
res, err = j.decodeArray(decoder)
res, err := j.decodeArray(decoder)
if err != nil {
return nil, fmt.Errorf("could not decode array: %w", err)
}
return res, nil
default:
res, err = j.decodeToken(decoder, t)
if err != nil {
return nil, err
}
return j.decodeToken(decoder, t)
}

return res, nil
}

func (j *jsonReader) decodeObject(decoder *json.Decoder) (*model.Value, error) {
Expand Down
Loading
Loading