json

package
v0.5.14 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 9, 2026 License: MIT Imports: 6 Imported by: 0

README

JSON Codec for JSON Patch Operations

The json codec implements the standard JSON encoding/decoding for JSON Patch operations as defined in RFC 6902, with full support for extended operations and JSON Predicate.

🎯 Key Features: 100% json-joy compatibility, modern struct-based API, high-performance JSON v2 integration.

Operations use clean struct literals, for example:

// New struct-based API ✅
{Op: "add", Path: "/foo/bar", Value: 123}

// JSON representation
{"op": "add", "path": "/foo/bar", "value": 123}

Features

  • Complete json-joy compatibility - 100% functional compatibility with TypeScript implementation
  • All 47 operation types supported - JSON Patch (RFC6902) + JSON Predicate + JSON Patch Extended
  • High-performance optimizations - Uses JSON v2 for better type preservation and performance
  • Zero-allocation hot paths - Optimized for common operation patterns
  • Comprehensive TypeScript documentation - Every function includes original TypeScript code references

Usage

Basic Usage with Struct API
import (
    "github.com/kaptinlin/jsonpatch"
    "github.com/kaptinlin/jsonpatch/codec/json"
)

// Create operations using clean struct syntax
operations := []jsonpatch.Operation{
    {Op: "test", Path: "/foo", Value: "bar"},
    {Op: "replace", Path: "/foo", Value: "baz"},
    {Op: "inc", Path: "/counter", Inc: 5},
    {Op: "str_ins", Path: "/text", Pos: 0, Str: "Hello "},
}

// Apply directly using main API (recommended)
result, err := jsonpatch.ApplyPatch(doc, operations)
if err != nil {
    // handle error
}

// Advanced: Use codec directly for custom workflows
decoder := json.NewDecoder(json.Options{
    CreateMatcher: func(pattern string, ignoreCase bool) func(string) bool {
        // Custom regex implementation for security
        return customRegexMatcher(pattern, ignoreCase)
    },
})

// Convert struct operations to Op instances  
ops, err := json.DecodeOperations(operations, decoder.Options())
if err != nil {
    // handle error
}

// Encode Op instances back to JSON
encoded, err := json.EncodeJSON(ops)
if err != nil {
    // handle error
}
Using Decoder and Encoder Classes
import (
    "github.com/kaptinlin/jsonpatch/codec/json"
)

// Using Decoder (matches TypeScript Decoder class)
options := json.JsonPatchOptions{}
decoder := json.NewDecoder(options)
ops, err := decoder.Decode(patch)
if err != nil {
    // handle error
}

// Using Encoder (matches TypeScript Encoder class)
encoder := json.NewEncoder()
operations, err := encoder.Encode(ops)
if err != nil {
    // handle error
}

// Encode to JSON bytes
jsonBytes, err := encoder.EncodeJSON(ops)
if err != nil {
    // handle error
}

Supported Operations

This codec supports all JSON Patch+ operations with complete TypeScript compatibility:

Core JSON Patch (RFC 6902)
  • add - Add a value to the document
  • remove - Remove a value from the document
  • replace - Replace a value in the document
  • move - Move a value within the document
  • copy - Copy a value within the document
  • test - Test that a value is as expected
JSON Predicate Operations
  • defined - Test if path exists in document
  • undefined - Test if path does not exist in document
  • contains - Test if string contains substring
  • starts - Test if string starts with prefix
  • ends - Test if string ends with suffix
  • matches - Test if string matches regex pattern (requires CreateMatcher)
  • type - Test value type (string, number, boolean, object, integer, array, null)
  • in - Test if value is in array
  • less - Test if number is less than value
  • more - Test if number is greater than value
  • and - Logical AND of multiple predicates
  • or - Logical OR of multiple predicates
  • not - Logical NOT of multiple predicates
Extended Operations
  • str_ins - Insert string at position
  • str_del - Delete string at position
  • flip - Flip boolean value
  • inc - Increment number value
  • split - Split object at specified position
  • merge - Merge objects
  • extend - Extend object with properties
Additional Test Operations
  • test_type - Test value type with array support
  • test_string - Test string at specific position
  • test_string_len - Test string length

TypeScript Compatibility

This implementation maintains 100% compatibility with the json-joy TypeScript implementation:

  • Identical operation semantics - All operations behave exactly like TypeScript
  • Compatible error handling - Error types and messages match TypeScript
  • Same JSON format - Generated JSON is identical to TypeScript output
  • Matching API design - Function signatures mirror TypeScript interfaces

Performance Optimizations

  • JSON v2 integration - Uses github.com/go-json-experiment/json for better type preservation
  • Pre-allocated slices - Avoids memory reallocations in hot paths
  • Zero-allocation type checking - Fast operation type detection
  • Optimized path handling - Uses github.com/kaptinlin/jsonpointer for efficient JSON Pointer operations
  • Bulk operation processing - Efficient handling of operation arrays

Architecture

The codec follows the layered architecture pattern from rules.md:

codec/json/
├── types.go      # Core type definitions and helpers
├── decode.go     # JSON to Op conversion (matches decode.ts)  
├── encode.go     # Op to JSON conversion (matches encode.ts)
├── decoder.go    # Decoder class (matches Decoder.ts)
├── encoder.go    # Encoder class (matches Encoder.ts)
└── index.go      # Package exports (matches index.ts)

Every function includes complete TypeScript original code references for maintainability and compatibility verification.

Documentation

Overview

Package json implements JSON codec for JSON Patch operations. It provides encoding and decoding for JSON Patch operations with full RFC 6902 support.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrOpMissingOpField indicates operation is missing 'op' field.
	ErrOpMissingOpField = errors.New("operation missing 'op' field")
	// ErrOpMissingPathField indicates operation is missing 'path' field.
	ErrOpMissingPathField = errors.New("operation missing 'path' field")
	// ErrInvalidPointer indicates an invalid JSON pointer.
	ErrInvalidPointer = errors.New("invalid pointer")
	// ErrCodecOpUnknown indicates unknown operation.
	ErrCodecOpUnknown = errors.New("unknown operation")
)

Base operation errors.

View Source
var (
	// ErrAddOpMissingValue indicates add operation is missing 'value' field.
	ErrAddOpMissingValue = errors.New("add operation missing 'value' field")
	// ErrReplaceOpMissingValue indicates replace operation is missing 'value' field.
	ErrReplaceOpMissingValue = errors.New("replace operation missing 'value' field")
	// ErrMissingValueField indicates a missing value field.
	ErrMissingValueField = errors.New("missing value field")
	// ErrMoveOpMissingFrom indicates move operation is missing 'from' field.
	ErrMoveOpMissingFrom = errors.New("move operation missing 'from' field")
	// ErrCopyOpMissingFrom indicates copy operation is missing 'from' field.
	ErrCopyOpMissingFrom = errors.New("copy operation missing 'from' field")
)

Core operation errors.

View Source
var (
	// ErrIncOpMissingInc indicates inc operation is missing 'inc' field.
	ErrIncOpMissingInc = errors.New("inc operation missing 'inc' field")
	// ErrIncOpInvalidType indicates inc operation 'inc' field must be a number.
	ErrIncOpInvalidType = errors.New("inc operation 'inc' field must be a number")
	// ErrStrInsOpMissingPos indicates str_ins operation is missing 'pos' field.
	ErrStrInsOpMissingPos = errors.New("str_ins operation missing 'pos' field")
	// ErrStrInsOpMissingStr indicates str_ins operation is missing 'str' field.
	ErrStrInsOpMissingStr = errors.New("str_ins operation missing 'str' field")
	// ErrStrDelOpMissingPos indicates str_del operation is missing 'pos' field.
	ErrStrDelOpMissingPos = errors.New("str_del operation missing 'pos' field")
	// ErrStrDelOpMissingFields indicates str_del operation is missing 'str' or 'len' field.
	ErrStrDelOpMissingFields = errors.New("str_del operation missing 'str' or 'len' field")
	// ErrSplitOpMissingPos indicates split operation is missing 'pos' field.
	ErrSplitOpMissingPos = errors.New("split operation missing 'pos' field")
	// ErrValueNotObject indicates value is not an object.
	ErrValueNotObject = errors.New("value is not an object")
)

Extended operation errors.

View Source
var (
	// ErrTypeOpMissingValue indicates type operation is missing string 'value' field.
	ErrTypeOpMissingValue = errors.New("type operation missing string 'value' field")
	// ErrTestTypeOpMissingType indicates test_type operation is missing 'type' field.
	ErrTestTypeOpMissingType = errors.New("test_type operation missing 'type' field")
	// ErrTestStringOpMissingStr indicates test_string operation is missing 'str' field.
	ErrTestStringOpMissingStr = errors.New("test_string operation missing 'str' field")
	// ErrTestStringLenOpMissingLen indicates test_string_len operation is missing 'len' field.
	ErrTestStringLenOpMissingLen = errors.New("test_string_len operation missing 'len' field")
	// ErrContainsOpMissingValue indicates contains operation is missing 'value' field.
	ErrContainsOpMissingValue = errors.New("contains operation missing 'value' field")
	// ErrEndsOpMissingValue indicates ends operation is missing 'value' field.
	ErrEndsOpMissingValue = errors.New("ends operation missing 'value' field")
	// ErrStartsOpMissingValue indicates starts operation is missing 'value' field.
	ErrStartsOpMissingValue = errors.New("starts operation missing 'value' field")
	// ErrMatchesOpMissingValue indicates matches operation is missing 'value' field.
	ErrMatchesOpMissingValue = errors.New("matches operation missing 'value' field")
	// ErrLessOpMissingValue indicates less operation is missing 'value' field.
	ErrLessOpMissingValue = errors.New("less operation missing 'value' field")
	// ErrMoreOpMissingValue indicates more operation is missing 'value' field.
	ErrMoreOpMissingValue = errors.New("more operation missing 'value' field")
	// ErrInvalidType indicates an invalid type.
	ErrInvalidType = errors.New("invalid type")
	// ErrEmptyTypeList indicates an empty type list.
	ErrEmptyTypeList = errors.New("empty type list")
)

Predicate operation errors.

View Source
var (
	// ErrAndOpMissingApply indicates and operation is missing 'apply' field.
	ErrAndOpMissingApply = errors.New("and operation missing 'apply' field")
	// ErrOrOpMissingApply indicates or operation is missing 'apply' field.
	ErrOrOpMissingApply = errors.New("or operation missing 'apply' field")
	// ErrNotOpMissingApply indicates not operation is missing 'apply' field.
	ErrNotOpMissingApply = errors.New("not operation missing 'apply' field")
	// ErrNotOpRequiresOperand indicates not operation requires at least one operand.
	ErrNotOpRequiresOperand = errors.New("not operation requires at least one operand")
	// ErrNotOpRequiresValidOperand indicates not operation requires a valid predicate operand.
	ErrNotOpRequiresValidOperand = errors.New("not operation requires a valid predicate operand")
)

Composite operation errors.

Functions

func Decode

func Decode(operations []map[string]any, options internal.JSONPatchOptions) ([]internal.Op, error)

Decode converts JSON operations to Op instances.

func DecodeJSON

func DecodeJSON(data []byte, options internal.JSONPatchOptions) ([]internal.Op, error)

DecodeJSON converts JSON bytes to Op instances.

func DecodeOperations added in v0.5.0

func DecodeOperations(operations []internal.Operation, options internal.JSONPatchOptions) ([]internal.Op, error)

DecodeOperations converts Operation structs to Op instances.

func Encode

func Encode(ops []internal.Op) ([]internal.Operation, error)

Encode converts operations to JSON format.

func EncodeJSON

func EncodeJSON(ops []internal.Op) ([]byte, error)

EncodeJSON converts operations to JSON bytes.

func OperationToOp

func OperationToOp(operation map[string]any, options internal.JSONPatchOptions) (internal.Op, error)

OperationToOp converts a JSON operation map to an Op instance.

func OperationToPredicateOp

func OperationToPredicateOp(operation map[string]any, options internal.JSONPatchOptions) (internal.Op, error)

OperationToPredicateOp converts a JSON operation map to a PredicateOp instance.

Types

type Decoder

type Decoder struct {
	// contains filtered or unexported fields
}

Decoder provides JSON patch decoding with configurable options.

func NewDecoder

func NewDecoder(options internal.JSONPatchOptions) *Decoder

NewDecoder creates a new Decoder with the given options.

func (*Decoder) Decode

func (d *Decoder) Decode(patch []map[string]any) ([]internal.Op, error)

Decode decodes a JSON patch array to operations.

type Encoder

type Encoder struct{}

Encoder provides JSON patch encoding functionality.

func NewEncoder

func NewEncoder() *Encoder

NewEncoder creates a new Encoder instance.

func (*Encoder) Encode

func (e *Encoder) Encode(ops []internal.Op) ([]internal.Operation, error)

Encode encodes operations to JSON format.

func (*Encoder) EncodeJSON

func (e *Encoder) EncodeJSON(ops []internal.Op) ([]byte, error)

EncodeJSON encodes operations to JSON bytes.

type Operation

type Operation = internal.Operation

Operation is a JSON Patch operation in JSON format.

type PatchOptions added in v0.4.3

type PatchOptions = internal.JSONPatchOptions

PatchOptions configures JSON Patch decoding.

Directories

Path Synopsis
Package tests provides test data and automated codec tests for the JSON codec.
Package tests provides test data and automated codec tests for the JSON codec.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL