json-joy
Version:
Collection of libraries for building collaborative editing apps.
278 lines (277 loc) • 7.26 kB
TypeScript
import type { Path } from '@jsonjoy.com/json-pointer';
import type { OpType } from '../../opcodes';
export type Operation = JsonPatchOperation | PredicateOperation | JsonPatchExtendedOperation;
export interface OperationBase {
readonly op: OpType;
readonly path: string | Path;
}
export type JsonPatchOperation = OperationAdd | OperationRemove | OperationReplace | OperationMove | OperationCopy | OperationTest;
/**
* JSON Patch add (or replace) operation.
*
* Below example sets __"foo"__ key of an object to `"bar"` value:
*
* ```ts
* const operation: OperationAdd = {
* op: 'add',
* path: '/foo',
* value: 'bar',
* };
* ```
*
* @category JSON Patch
*/
export interface OperationAdd<T = unknown> extends OperationBase {
readonly op: 'add';
readonly value: T;
}
/**
* @category JSON Patch
*/
export interface OperationRemove<T = unknown> extends OperationBase {
readonly op: 'remove';
/** Value which was remove, for ability to reverse operations. */
readonly oldValue?: T;
}
/**
* @category JSON Patch
*/
export interface OperationReplace<V = unknown, O = unknown> extends OperationBase {
readonly op: 'replace';
readonly value: V;
readonly oldValue?: O;
}
/**
* @category JSON Patch
*/
export interface OperationCopy extends OperationBase {
readonly op: 'copy';
readonly from: string;
}
/**
* @category JSON Patch
*/
export interface OperationMove extends OperationBase {
readonly op: 'move';
readonly from: string;
}
/**
* Tests that value at `path` strictly equals `value`. If `not` is set to `true`
* inverts the condition to test for value not being strictly equal.
*
* @category JSON Patch
*/
export interface OperationTest<T = unknown> extends OperationBase {
readonly op: 'test';
readonly value: T;
readonly not?: boolean;
}
export type PredicateOperation = FirstOrderPredicateOperation | SecondOrderPredicateOperation;
export type FirstOrderPredicateOperation = OperationTest | OperationDefined | OperationUndefined | OperationTestType | OperationTestString | OperationTestStringLen | OperationContains | OperationEnds | OperationStarts | OperationIn | OperationLess | OperationMore | OperationMatches | OperationType;
export type SecondOrderPredicateOperation = OperationAnd | OperationNot | OperationOr;
export type JsTypes = 'string' | 'number' | 'boolean' | 'object';
export type JsonPatchTypes = JsTypes | 'integer' | 'array' | 'null';
/**
* Tests is the target value exists in the document, fails otherwise.
*
* @category JSON Predicate
*/
export interface OperationDefined extends OperationBase {
readonly op: 'defined';
}
/**
* Opposite of "defined" operation.
*
* @category JSON Predicate
*/
export interface OperationUndefined extends OperationBase {
readonly op: 'undefined';
}
/**
* Tests is the target is of any of the given types.
*
* @category JSON Patch Extended
*/
export interface OperationTestType extends OperationBase {
readonly op: 'test_type';
readonly type: JsonPatchTypes[];
}
/**
* @category JSON Patch Extended
*/
export interface OperationTestString extends OperationBase {
readonly op: 'test_string';
readonly not?: boolean;
readonly pos: number;
readonly str: string;
}
/**
* Fails if string is shorter than `len` characters.
*
* @category JSON Patch Extended
*/
export interface OperationTestStringLen extends OperationBase {
readonly op: 'test_string_len';
readonly not?: boolean;
readonly len: number;
}
/**
* @category JSON Predicate
*/
export interface OperationContains extends OperationBase {
readonly op: 'contains';
readonly value: string;
readonly ignore_case?: boolean;
}
/**
* @category JSON Predicate
*/
export interface OperationMatches extends OperationBase {
readonly op: 'matches';
readonly value: string;
readonly ignore_case?: boolean;
}
/**
* @category JSON Predicate
*/
export interface OperationEnds extends OperationBase {
readonly op: 'ends';
readonly value: string;
readonly ignore_case?: boolean;
}
/**
* @category JSON Predicate
*/
export interface OperationStarts extends OperationBase {
readonly op: 'starts';
readonly value: string;
readonly ignore_case?: boolean;
}
/**
* @category JSON Predicate
*/
export interface OperationType extends OperationBase {
readonly op: 'type';
readonly value: JsonPatchTypes;
}
/**
* @category JSON Predicate
*/
export interface OperationIn extends OperationBase {
readonly op: 'in';
readonly value: unknown[];
}
/**
* @category JSON Predicate
*/
export interface OperationLess extends OperationBase {
readonly op: 'less';
readonly value: number;
}
/**
* @category JSON Predicate
*/
export interface OperationMore extends OperationBase {
readonly op: 'more';
readonly value: number;
}
/**
* @category JSON Predicate
*/
export interface OperationAnd extends OperationBase {
readonly op: 'and';
readonly apply: PredicateOperation[];
}
/**
* @category JSON Predicate
*/
export interface OperationNot extends OperationBase {
readonly op: 'not';
readonly apply: PredicateOperation[];
}
/**
* @category JSON Predicate
*/
export interface OperationOr extends OperationBase {
readonly op: 'or';
readonly apply: PredicateOperation[];
}
export type JsonPatchExtendedOperation = OperationStrIns | OperationStrDel | OperationFlip | OperationInc | OperationSplit | OperationMerge | OperationExtend;
/**
* Inserts a `value` string into a string at position `pos`.
*
* @category JSON Patch Extended
*/
export interface OperationStrIns extends OperationBase {
readonly op: 'str_ins';
readonly pos: number;
readonly str: string;
}
/**
* Removes `len` number of characters from a string starting at position `pos`.
*
* @category JSON Patch Extended
*/
export interface OperationStrDel1 extends OperationBase {
readonly op: 'str_del';
readonly pos: number;
readonly str: string;
}
/**
* @category JSON Patch Extended
*/
export interface OperationStrDel2 extends OperationBase {
readonly op: 'str_del';
readonly pos: number;
readonly len: number;
}
/**
* @category JSON Patch Extended
*/
export interface OperationStrDel extends OperationBase {
readonly op: 'str_del';
readonly pos: number;
readonly str?: string;
readonly len?: number;
}
/**
* Flips boolean value to the opposite one.
*
* @category JSON Patch Extended
*/
export interface OperationFlip extends OperationBase {
readonly op: 'flip';
}
/**
* Increments a number by a specified value `inc`.
*
* @category JSON Patch Extended
*/
export interface OperationInc extends OperationBase {
readonly op: 'inc';
readonly inc: number;
}
/**
* @category JSON Patch Extended
*/
export interface OperationSplit extends OperationBase {
readonly op: 'split';
pos: number;
props?: object;
}
/**
* @category JSON Patch Extended
*/
export interface OperationMerge extends OperationBase {
readonly op: 'merge';
pos: number;
props?: object;
}
/**
* @category JSON Patch Extended
*/
export interface OperationExtend extends OperationBase {
readonly op: 'extend';
props: Record<string, unknown>;
deleteNull?: boolean;
}