Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

597 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

JsonRecast

JsonRecast Logo

Editable JSON AST with visitor traversal and formatting-preserving printing.

Latest Version ci build Documentation Code Coverage PHPStan Downloads

Windows macOS Linux

Edit JSON content without noisy diffs

  • Update JSON content programmatically and keep the original indentation, spacing, and key order intact.
  • Transform documents with visitors, inspired by nikic/PHP-Parser, with path awareness built in.
  • The printed output differs from the input only where you made changes; nothing else is reformatted.

Installation

composer require boundwize/jsonrecast

Example

Say we want to bump a dependency, add a new one, and remove an entry in composer.json. With JsonRecast, a single visitor does all three:

Demo of JsonRecast bumping a dependency, adding a new one, and removing an entry in composer.json while preserving the original formatting, including non-standard alignment

<?php

use Boundwize\JsonRecast\JsonRecast;
use Boundwize\JsonRecast\Node\NodeJson;
use Boundwize\JsonRecast\Node\ObjectItemNode;
use Boundwize\JsonRecast\Node\ObjectNode;
use Boundwize\JsonRecast\Node\StringNode;
use Boundwize\JsonRecast\NodePath\NodeJsonPath;
use Boundwize\JsonRecast\NodeVisitor\NodeJsonVisitor;
use Boundwize\JsonRecast\NodeVisitor\NodeJsonVisitorAbstract;

$document = JsonRecast::parse(file_get_contents('composer.json'));

$result = JsonRecast::traverse($document, new class extends NodeJsonVisitorAbstract {
    public function enterNode(NodeJson $node, NodeJsonPath $path): null|NodeJson|int
    {
        // ~ bump monolog to ^3.6
        if ($node instanceof ObjectItemNode && $path->matches(['require']) && $node->key->value === 'monolog/monolog') {
            $node->value = new StringNode('^3.6');

            return $node;
        }

        // + add guzzle under "require"
        if ($node instanceof ObjectNode && $path->matches(['require'])) {
            $node->set('guzzlehttp/guzzle', new StringNode('^7.8'));

            return $node;
        }

        // − drop the root "minimum-stability" entry
        if ($node instanceof ObjectItemNode && $path->isRoot() && $node->key->value === 'minimum-stability') {
            return NodeJsonVisitor::REMOVE_NODE;
        }

        return null;
    }
});

// update the file with original formatting preserved
file_put_contents('composer.json', JsonRecast::print($result));

Anything the visitor didn't touch keeps its original indentation, key order, and alignment.

Documentation

Documentation is available online, with source files kept in this repository:

About

🌳 A PHP JSON parser that turns JSON into an editable AST, supports visitor-based traversal, and prints changes back while preserving the original formatting.

Resources

Contributing

Stars

4 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages