@eclipse-emfcloud/modelserver-client
Version:
Typescript rest client to interact with an EMF.cloud modelserver
215 lines • 8.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Operations = exports.removeObject = exports.removeValue = exports.removeValueAt = exports.deleteElement = exports.add = exports.create = exports.replace = void 0;
const base_model_1 = require("../model/base-model");
const type_util_1 = require("./type-util");
// Json Patch Operation types
const REPLACE = 'replace';
const ADD = 'add';
const REMOVE = 'remove';
//
// Functions to generate Json Patch operations, specific to the ModelServer syntax.
// These operations can only be used with the model server, as they use a custom
// syntax to define the Path attribute, which relies on the ModelURI and Object $id.
//
/**
* Create a ReplaceOperation, to change the value of a property of the specified object.
* @param modeluri the uri of the model to edit
* @param object the object to edit
* @param feature the property to edit
* @param value the value to set
* @returns The Json Patch ReplaceOperation to set the property.
*/
function replace(modeluri, object, feature, value) {
return {
op: REPLACE,
path: getPropertyPath(modeluri, object, feature),
value: value
};
}
exports.replace = replace;
/**
* Create an AddOperation, to create a new object of the specified type, in the specified parent.
* @param modeluri the uri of the model to edit
* @param parent the parent in which the new element should be created
* @param feature the property of the parent in which the new element should be added
* @param $type the type of element to create
* @param attributes the attributes to initialize for the new element
* @returns The Json Patch AddOperation to create the element.
*/
function create(modeluri, parent, feature, $type, attributes) {
return {
op: ADD,
path: getPropertyPath(modeluri, parent, feature),
value: Object.assign({ $type: $type }, attributes)
};
}
exports.create = create;
/**
* Create an AddOperation, to add an existing object of the specified type, in the specified parent.
* @param modeluri the uri of the model to edit
* @param parent the parent in which the element should be added
* @param feature the property of the parent in which the element should be added
* @param value the element to add
* @returns The Json Patch AddOperation to add the element in the parent.
*/
function add(modeluri, parent, feature, value) {
return {
op: ADD,
path: getPropertyPath(modeluri, parent, feature),
value: {
$type: value.$type,
$id: getObjectPath(modeluri, value)
}
};
}
exports.add = add;
/**
* Create a RemoveOperation, to delete an object from the model.
* @param modeluri the uri of the model to edit
* @param object the object to remove from the model
* @returns The Json Patch RemoveOperation to remove the element.
*/
function deleteElement(modeluri, object) {
return {
op: REMOVE,
path: getObjectPath(modeluri, object)
};
}
exports.deleteElement = deleteElement;
/**
* Create a RemoveOperation, to remove a value from a list.
* @param modeluri the uri of the model to edit
* @param object the object from which a value will be removed
* @param feature the property from which a value will be removed
* @param index the index of the value to remove
*/
function removeValueAt(modeluri, object, feature, index) {
return {
op: REMOVE,
path: getPropertyPath(modeluri, object, feature, index)
};
}
exports.removeValueAt = removeValueAt;
/**
* Create a RemoveOperation, to remove a value from a list.
* @param modeluri the uri of the model to edit
* @param object the object from which a value will be removed
* @param feature the property from which a value will be removed
* @param value the value to remove
*/
function removeValue(modeluri, object, feature, value) {
const index = findIndex(object, feature, value);
if (index >= 0) {
return removeValueAt(modeluri, object, feature, index);
}
return undefined;
}
exports.removeValue = removeValue;
/**
* Create a RemoveOperation, to delete an object from the model.
* @param modeluri the uri of the model to edit
* @param objectToRemove the object to delete from the model
*/
function removeObject(modeluri, objectToRemove) {
return {
op: REMOVE,
path: getObjectPath(modeluri, objectToRemove)
};
}
exports.removeObject = removeObject;
/**
* Return the custom Json Path for this object. The result is a path that
* can be used to define Json Patch operations. It uses object ids ($id
* attribute) and ModelURI, which are not standard Json Patch concepts.
* As such, operations using this path will only work with the ModelServer.
* They won't work with a standard Json Patch library.
* @param modeluri The URI of the model to edit.
* @param object The object.
* @returns the custom Json Path for this object.
*/
function getObjectPath(modeluri, object) {
const id = base_model_1.ModelServerReferenceDescriptionV2.is(object) ? object.$ref : object.$id;
return modeluri.clone().fragment(id).toString();
}
/**
* Return the custom Json Path for this property. The result is a path that
* can be used to define Json Patch operations. It uses object ids ($id
* attribute) and ModelURI, which are not standard Json Patch concepts.
* As such, operations using this path will only work with the ModelServer.
* They won't work with a standard Json Patch library.
* @param modeluri The URI of the model to edit.
* @param object The object.
* @param feature The name of the property to edit.
* @param index An optional index, for list properties.
* @returns the custom Json Path to edit this property.
*/
function getPropertyPath(modeluri, object, feature, index) {
const indexSuffix = index === undefined ? '' : `/${index}`;
return `${getObjectPath(modeluri, object)}/${feature}${indexSuffix}`;
}
function findIndex(object, feature, value) {
const propertyValue = object[feature];
if (Array.isArray(propertyValue)) {
return propertyValue.indexOf(value);
}
return -1;
}
/**
* Utility functions for working with JSON Patch operations.
*/
var Operations;
(function (Operations) {
/**
* Tests is the given object is a Json Patch {@link Operation}
* @param object the object to test
* @returns true if the object is an Operation, false otherwise.
*/
function isOperation(object) {
if (type_util_1.AnyObject.is(object)) {
return ('op' in object &&
typeof object.op === 'string' && //
'path' in object &&
typeof object.path === 'string');
}
else {
return false;
}
}
Operations.isOperation = isOperation;
/**
* Tests is the given object is a Json Patch (Which is an array of {@link Operation Operations})
* @param object the object to test
* @returns true if the object is a Json Patch, false otherwise.
*/
function isPatch(object) {
return Array.isArray(object) && (object.length === 0 || isOperation(object[0]));
}
Operations.isPatch = isPatch;
function isAdd(op, typeGuard) {
if (typeof typeGuard === 'function') {
return (op === null || op === void 0 ? void 0 : op.op) === ADD && (!typeGuard || typeGuard(op.value));
}
if (!typeGuard) {
return (op === null || op === void 0 ? void 0 : op.op) === ADD;
}
return (op === null || op === void 0 ? void 0 : op.op) === ADD && typeof op.value === typeGuard;
}
Operations.isAdd = isAdd;
function isReplace(op, typeGuard) {
if (typeof typeGuard === 'function') {
return (op === null || op === void 0 ? void 0 : op.op) === REPLACE && (!typeGuard || typeGuard(op.value));
}
if (!typeGuard) {
return (op === null || op === void 0 ? void 0 : op.op) === REPLACE;
}
return (op === null || op === void 0 ? void 0 : op.op) === REPLACE && typeof op.value === typeGuard;
}
Operations.isReplace = isReplace;
/** Type guard testing whether an operation is a remove operation. */
function isRemove(op) {
return (op === null || op === void 0 ? void 0 : op.op) === REMOVE;
}
Operations.isRemove = isRemove;
})(Operations = exports.Operations || (exports.Operations = {}));
//# sourceMappingURL=patch-utils.js.map