UNPKG

@eclipse-emfcloud/modelserver-client

Version:

Typescript rest client to interact with an EMF.cloud modelserver

279 lines 15.4 kB
"use strict"; 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