@eclipse-emfcloud/modelserver-client
Version:
Typescript rest client to interact with an EMF.cloud modelserver
279 lines • 15.4 kB
JavaScript
;
var __rest = (this && this.__rest) || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ModelServerClientV2 = void 0;
/********************************************************************************
* Copyright (c) 2022-2023 STMicroelectronics and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0, or the MIT License which is
* available at https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: EPL-2.0 OR MIT
*******************************************************************************/
const axios_1 = __importDefault(require("axios"));
const fast_json_patch_1 = require("fast-json-patch");
const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
const model_server_client_api_v1_1 = require("./model-server-client-api-v1");
const model_server_client_api_v2_1 = require("./model-server-client-api-v2");
const model_server_message_1 = require("./model-server-message");
const model_server_paths_1 = require("./model-server-paths");
const command_model_1 = require("./model/command-model");
const diagnostic_1 = require("./model/diagnostic");
const type_util_1 = require("./utils/type-util");
/**
* A client to interact with a model server.
*/
class ModelServerClientV2 {
constructor() {
this.openSockets = new Map();
this.defaultFormat = model_server_client_api_v2_1.FORMAT_JSON_V2;
}
initialize(baseUrl, defaultFormat = model_server_client_api_v2_1.FORMAT_JSON_V2) {
this._baseUrl = baseUrl.clone();
this.defaultFormat = defaultFormat;
this.restClient = axios_1.default.create(this.getAxiosConfig(baseUrl));
}
getAxiosConfig(baseURL) {
return { baseURL: baseURL.toString() };
}
get(modeluri, formatOrGuard, format) {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString(), format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
}
format = formatOrGuard !== null && formatOrGuard !== void 0 ? formatOrGuard : this.defaultFormat;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString(), format } }), model_server_message_1.MessageDataMapper.asObject);
}
getAll(formatOrGuard) {
let modelMapper;
let format = this.defaultFormat;
if (!formatOrGuard) {
modelMapper = (model) => mapModel(model);
}
else if (typeof formatOrGuard === 'string') {
format = formatOrGuard;
modelMapper = (model) => mapModel(model, undefined, true);
}
else {
modelMapper = (model) => mapModel(model, formatOrGuard);
}
const messageMapper = (message) => model_server_message_1.MessageDataMapper.asModelArray(message).map(modelMapper);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { format } }), messageMapper);
}
getModelUris() {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_URIS), model_server_message_1.MessageDataMapper.asURIArray);
}
getElementById(modeluri, elementid, formatOrGuard, format) {
format = format !== null && format !== void 0 ? format : this.defaultFormat;
if (formatOrGuard) {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementid, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
}
format = formatOrGuard;
}
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementid, format } }), model_server_message_1.MessageDataMapper.asObject);
}
getElementByName(modeluri, elementname, formatOrGuard, format) {
format = format !== null && format !== void 0 ? format : this.defaultFormat;
if (formatOrGuard) {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementname, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
}
format = formatOrGuard;
}
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementname, format } }), model_server_message_1.MessageDataMapper.asObject);
}
create(modeluri, model, formatOrGuard, format) {
format = format !== null && format !== void 0 ? format : this.defaultFormat;
if (formatOrGuard) {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.post(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(model), {
params: { modeluri: modeluri.toString(), format }
}), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
}
format = formatOrGuard;
}
return this.process(this.restClient.post(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(model), {
params: { modeluri: modeluri.toString(), format }
}), model_server_message_1.MessageDataMapper.asObject);
}
update(modeluri, model, formatOrGuard, format) {
format = format !== null && format !== void 0 ? format : this.defaultFormat;
if (formatOrGuard) {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(model), {
params: { modeluri: modeluri.toString(), format }
}), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
}
format = formatOrGuard;
}
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(model), {
params: { modeluri: modeluri.toString(), format }
}), model_server_message_1.MessageDataMapper.asObject);
}
delete(modeluri) {
return this.process(this.restClient.delete(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.isSuccess);
}
close(modeluri) {
return this.process(this.restClient.post(model_server_paths_1.ModelServerPaths.CLOSE, undefined, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.isSuccess);
}
save(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.SAVE, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.isSuccess);
}
saveAll() {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.SAVE_ALL), model_server_message_1.MessageDataMapper.isSuccess);
}
validate(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.VALIDATION, { params: { modeluri: modeluri.toString() } }), response => model_server_message_1.MessageDataMapper.as(response, diagnostic_1.Diagnostic.is));
}
getValidationConstraints(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.VALIDATION_CONSTRAINTS, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.asString);
}
getTypeSchema(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.asString);
}
getUiSchema(schemaname) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.UI_SCHEMA, { params: { schemaname } }), model_server_message_1.MessageDataMapper.asString);
}
configureServer(configuration) {
var _a;
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE, {
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: (_a = configuration.uiSchemaFolder) === null || _a === void 0 ? void 0 : _a.toString()
}), model_server_message_1.MessageDataMapper.isSuccess);
}
ping() {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.SERVER_PING), model_server_message_1.MessageDataMapper.isSuccess);
}
edit(modeluri, patchOrCommand, format = this.defaultFormat) {
let patchMessage;
if (patchOrCommand instanceof command_model_1.ModelServerCommand) {
patchMessage = {
type: 'modelserver.emfcommand',
data: patchOrCommand
};
}
else {
// Operation[] and ModelPatch[] are treated in the same way; we don't need to distinguish both cases
const fullPatch = Array.isArray(patchOrCommand) ? patchOrCommand : [patchOrCommand];
patchMessage = {
type: 'modelserver.patch',
data: fullPatch
};
if (fullPatch.length === 0) {
// No-op
return Promise.resolve({
success: true,
patchModel: (oldModel, copy, _modeluri) => (copy ? (0, fast_json_patch_1.deepClone)(oldModel) : oldModel),
patch: []
});
}
}
return this.process(this.restClient.patch(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(patchMessage), {
params: { modeluri: modeluri.toString(), format: format }
}), model_server_message_1.MessageDataMapper.patchModel);
}
undo(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.UNDO, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.patchModel);
}
redo(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.REDO, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.patchModel);
}
send(modeluri, message) {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.send(JSON.stringify(message));
}
}
subscribe(modeluri, listener, options = {}) {
if (this.isSocketOpen(modeluri)) {
const errorMsg = `${modeluri.toString()} : Cannot open new socket, already subscribed!'`;
console.warn(errorMsg);
if (options.errorWhenUnsuccessful) {
throw new Error(errorMsg);
}
}
const path = this.createSubscriptionPath(modeluri, options);
this.doSubscribe(listener, modeluri, path);
return listener;
}
unsubscribe(modeluri) {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.close();
this.openSockets.delete(modeluri.toString());
}
}
createSubscriptionPath(modeluri, options) {
const paramOptions = __rest(options, []);
const subscriptionUri = this._baseUrl.clone();
subscriptionUri.protocol('ws');
subscriptionUri.segment(model_server_paths_1.ModelServerPaths.SUBSCRIPTION);
subscriptionUri.addQuery('modeluri', modeluri);
subscriptionUri.addQuery('format', options.format || this.defaultFormat);
Object.entries(paramOptions).forEach(entry => subscriptionUri.addQuery(entry[0], entry[1]));
subscriptionUri.removeQuery('errorWhenUnsuccessful');
return subscriptionUri;
}
doSubscribe(listener, modeluri, path) {
const socket = new isomorphic_ws_1.default(path.toString() /* .trim() */);
socket.onopen = event => { var _a; return (_a = listener.onOpen) === null || _a === void 0 ? void 0 : _a.call(listener, modeluri, event); };
socket.onclose = event => { var _a; return (_a = listener.onClose) === null || _a === void 0 ? void 0 : _a.call(listener, modeluri, event); };
socket.onerror = event => { var _a; return (_a = listener.onError) === null || _a === void 0 ? void 0 : _a.call(listener, modeluri, event); };
socket.onmessage = event => { var _a; return (_a = listener.onMessage) === null || _a === void 0 ? void 0 : _a.call(listener, modeluri, event); };
this.openSockets.set(modeluri.toString(), socket);
}
isSocketOpen(modeluri) {
return this.openSockets.get(modeluri.toString()) !== undefined;
}
async process(request, mapper) {
var _a;
try {
const response = await request;
if (response.data.type === 'error') {
throw new model_server_client_api_v1_1.ModelServerError(response.data);
}
return mapper(response.data);
}
catch (error) {
if (axios_1.default.isAxiosError(error)) {
const message = ((_a = error.response) === null || _a === void 0 ? void 0 : _a.data) ? error.response.data : error.message;
throw new model_server_client_api_v1_1.ModelServerError(message, error.code);
}
else {
throw error;
}
}
}
}
exports.ModelServerClientV2 = ModelServerClientV2;
function mapModel(model, guard, toString = false) {
const { modeluri, content } = model;
if (guard) {
return { modeluri, content: (0, type_util_1.asType)(content, guard) };
}
else if (toString) {
return { modeluri, content: (0, type_util_1.asString)(content) };
}
return { modeluri, content: (0, type_util_1.asObject)(content) };
}
//# sourceMappingURL=model-server-client-v2.js.map