Socket
Socket
Sign inDemoInstall

@eclipse-emfcloud/modelserver-client

Package Overview
Dependencies
10
Maintainers
8
Versions
40
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.8.0-next.9611b89d to 0.8.0-next.97b0990.90

lib/utils/index.d.ts

8

lib/index.js
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {

@@ -10,3 +14,3 @@ if (k2 === undefined) k2 = k;

var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p);
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};

@@ -13,0 +17,0 @@ Object.defineProperty(exports, "__esModule", { value: true });

@@ -11,5 +11,6 @@ /********************************************************************************

*******************************************************************************/
import URI from 'urijs';
import { Model, ModelServerMessage } from './model-server-message';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { Model, ModelServerMessage } from './model-server-message';
import { SubscriptionListener } from './subscription-listener';

@@ -31,3 +32,3 @@ import { AnyObject, TypeGuard } from './utils/type-util';

*/
initialize(baseUrl: string, defaultFormat?: string): void | Promise<void>;
initialize(baseUrl: URI, defaultFormat?: string): void | Promise<void>;
/**

@@ -58,3 +59,3 @@ * Retrieves all available {@link Model}s of the current workspace as plain JSON objects.

*/
get(modeluri: string): Promise<AnyObject>;
get(modeluri: URI): Promise<AnyObject>;
/**

@@ -68,3 +69,3 @@ * Retrieves the {@link Model} for a given URI as typed JSON object

*/
get<M>(modeluri: string, typeGuard: TypeGuard<M>): Promise<M>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -77,3 +78,3 @@ * Retrieves the {@link Model} for a given URI in string representation derived from a given format (e.g. 'xml' or 'json').

*/
get(modeluri: string, format: string): Promise<string>;
get(modeluri: URI, format: string): Promise<string>;
/**

@@ -83,3 +84,3 @@ * Retrieves the URIs of all available {@link Model}s of the current workspace.

*/
getModelUris(): Promise<string[]>;
getModelUris(): Promise<URI[]>;
/**

@@ -92,3 +93,3 @@ * Retrieves a specific model (sub)element by its `id` as plain JSON object.

*/
getElementById(modeluri: string, elementid: string): Promise<AnyObject>;
getElementById(modeluri: URI, elementid: string): Promise<AnyObject>;
/**

@@ -103,3 +104,3 @@ * Retrieves a specific model (sub)element by its `id` as typed JSON object.

*/
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -113,3 +114,3 @@ * Retrieves a specific model (sub)element by its `id` in string representation derived from a given format (e.g. 'xml' or 'json').

*/
getElementById(modeluri: string, elementid: string, format: string): Promise<string>;
getElementById(modeluri: URI, elementid: string, format: string): Promise<string>;
/**

@@ -122,3 +123,3 @@ * Retrieves a specific model (sub)element by its `name` as plain JSON object.

*/
getElementByName(modeluri: string, elementname: string): Promise<AnyObject>;
getElementByName(modeluri: URI, elementname: string): Promise<AnyObject>;
/**

@@ -133,3 +134,3 @@ * Retrieves a specific model (sub)element by its `name` as typed JSON object.

*/
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
/**

@@ -143,3 +144,3 @@ * Retrieves a specific model (sub)element by its `name` in string representation derived from a given format (e.g. 'xml' or 'json').

*/
getElementByName(modeluri: string, elementname: string, format: string): Promise<string>;
getElementByName(modeluri: URI, elementname: string, format: string): Promise<string>;
/**

@@ -150,3 +151,3 @@ * Deletes the {@link Model} with the given URI from the current workspace.

*/
delete(modeluri: string): Promise<boolean>;
delete(modeluri: URI): Promise<boolean>;
/**

@@ -157,3 +158,3 @@ * Closes (i.e. unloads) the model with the given URI from the current workspace. This discards all dirty changes.

*/
close(modeluri: string): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;
/**

@@ -165,3 +166,3 @@ * Creates a new model object with the given URI and content object in the current workspace.

*/
create(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
/**

@@ -176,3 +177,3 @@ * Creates a new model object with the given URI and content object in the current workspace.

*/
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -186,3 +187,3 @@ * Creates a new model object with the given URI and content string in the current workspace.

*/
create(modeluri: string, model: string, format: string): Promise<string>;
create(modeluri: URI, model: string, format: string): Promise<string>;
/**

@@ -195,3 +196,3 @@ * Updates an existing model with the given URI with the given content in the current workspace.

*/
update(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
update(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
/**

@@ -207,3 +208,3 @@ * Updates an existing model with the given URI with the given content in the current workspace.

*/
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -217,3 +218,3 @@ * Updates an existing model with the given URI with the given content string in the current workspace.

*/
update(modeluri: string, model: string, format: string): Promise<AnyObject>;
update(modeluri: URI, model: string, format: string): Promise<AnyObject>;
/**

@@ -224,3 +225,3 @@ * Persists all `dirty` changes for the model with the given URI.

*/
save(modeluri: string): Promise<boolean>;
save(modeluri: URI): Promise<boolean>;
/**

@@ -236,3 +237,3 @@ * Saves (i.e. persists the dirty changes of) all models that are loaded in the current workspace.

*/
validate(modeluri: string): Promise<Diagnostic>;
validate(modeluri: URI): Promise<Diagnostic>;
/**

@@ -243,3 +244,3 @@ * Retrieves the EMF validation constraints for the model with the given URI

*/
getValidationConstraints(modeluri: string): Promise<string>;
getValidationConstraints(modeluri: URI): Promise<string>;
/**

@@ -252,3 +253,3 @@ * Retrieves the JSON schema representation of the Ecore model with the given URI.

*/
getTypeSchema(modeluri: string): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;
/**

@@ -278,3 +279,3 @@ * Retrieves the JSONForms UI schema for the given EClass literal.

*/
edit(modeluri: string, command: ModelServerCommand): Promise<boolean>;
edit(modeluri: URI, command: ModelServerCommand): Promise<boolean>;
/**

@@ -285,3 +286,3 @@ * Can be used to undo the latest edit change (i.e. command execution) for the model with the given URI.

*/
undo(modeluri: string): Promise<string>;
undo(modeluri: URI): Promise<string>;
/**

@@ -292,3 +293,3 @@ * Can be used to redo the latest edit change (i.e. command execution) for the model with the given URI.

*/
redo(modeluri: string): Promise<string>;
redo(modeluri: URI): Promise<string>;
/**

@@ -300,10 +301,10 @@ * Can be used to subscribe for model server notifications for the model with the given URI. For subscription communication

*/
subscribe(modeluri: string, options?: SubscriptionOptions): void;
subscribe(modeluri: URI, options?: SubscriptionOptions): void;
/**
* Can be used to send arbitrary {@link ModelServerMessage}s to the model server via a subscription channel.
* @param modelUri The URI of the subscribed model.
* @param modeluri The URI of the subscribed model.
* @param message The model server message that should be sent.
* @returns A boolean indicating whether the message submission was successful.
*/
send(modelUri: string, message: ModelServerMessage): boolean;
send(modeluri: URI, message: ModelServerMessage): boolean;
/**

@@ -314,6 +315,6 @@ * Can be used to unsubscribe from model server notifications for the model with the given URI.

*/
unsubscribe(modelUri: string): boolean;
unsubscribe(modeluri: URI): boolean;
}
export declare namespace ModelServerClientApiV1 {
const API_ENDPOINT = "/api/v1";
const API_ENDPOINT = "api/v1";
}

@@ -337,4 +338,4 @@ /**

export interface ServerConfiguration {
workspaceRoot: string;
uiSchemaFolder?: string;
workspaceRoot: URI;
uiSchemaFolder?: URI;
}

@@ -341,0 +342,0 @@ /**

@@ -7,3 +7,3 @@ "use strict";

(function (ModelServerClientApiV1) {
ModelServerClientApiV1.API_ENDPOINT = '/api/v1';
ModelServerClientApiV1.API_ENDPOINT = 'api/v1';
})(ModelServerClientApiV1 = exports.ModelServerClientApiV1 || (exports.ModelServerClientApiV1 = {}));

@@ -10,0 +10,0 @@ /**

@@ -12,2 +12,3 @@ /********************************************************************************

import { Operation } from 'fast-json-patch';
import URI from 'urijs';
import { ModelServerElement } from './model/base-model';

@@ -33,5 +34,5 @@ import { ModelServerCommand } from './model/command-model';

/** JSON formats supported by the V2 client API. */
export declare type JsonFormat = 'json' | 'json-v2';
export type JsonFormat = 'json' | 'json-v2';
/** Message formats supported by the V2 client API. */
export declare type Format = string;
export type Format = string;
/**

@@ -51,2 +52,11 @@ * Additional subscription options supported by API v2 model subscriptions.

/**
* A union type that represents all Patches or Commands supported by the model server:
* - Operation
* - Operation[] (Json Patch)
* - ModelPatch
* - ModelPatch[]
* - ModelServerCommand
*/
export type PatchOrCommand = Operation | Operation[] | ModelPatch | ModelPatch[] | ModelServerCommand;
/**
* Basic client API to interact with a model server that conforms to the Modelserver API Version 2.

@@ -58,3 +68,3 @@ */

* The given base url should point to the location of the model server API entry point.
* (e.g. `http://localhost:8081/api/v1/`). Once the initialization is completed the client is expected
* (e.g. `http://localhost:8081/api/v2/`). Once the initialization is completed the client is expected
* to be ready and should be able to handle REST requests to & responses from the model server.

@@ -66,3 +76,3 @@ * Any requests to the model server before the client has been initialized are expected to fail (i.e. throw an error)

*/
initialize(baseUrl: string, defaultFormat?: Format): void | Promise<void>;
initialize(baseUrl: URI, defaultFormat?: Format): void | Promise<void>;
/**

@@ -74,35 +84,47 @@ * Retrieves all available models of the current workspace.

getAll(format: Format): Promise<Model<string>[]>;
get(modeluri: string, format?: Format): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getModelUris(): Promise<string[]>;
getElementById(modeluri: string, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName(modeluri: string, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
delete(modeluri: string): Promise<boolean>;
close(modeluri: string): Promise<boolean>;
create(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
save(modeluri: string): Promise<boolean>;
get(modeluri: URI, format?: Format): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getModelUris(): Promise<URI[]>;
getElementById(modeluri: URI, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName(modeluri: URI, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
delete(modeluri: URI): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;
create(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
save(modeluri: URI): Promise<boolean>;
saveAll(): Promise<boolean>;
validate(modeluri: string): Promise<Diagnostic>;
getValidationConstraints(modeluri: string): Promise<string>;
getTypeSchema(modeluri: string): Promise<string>;
validate(modeluri: URI): Promise<Diagnostic>;
getValidationConstraints(modeluri: URI): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;
getUiSchema(schemaname: string): Promise<string>;
configureServer(configuration: ServerConfiguration): Promise<boolean>;
ping(): Promise<boolean>;
edit(modeluri: string, patch: Operation | Operation[], format?: Format): Promise<ModelUpdateResult>;
edit(modeluri: string, command: ModelServerCommand, format?: Format): Promise<ModelUpdateResult>;
undo(modeluri: string): Promise<ModelUpdateResult>;
redo(modeluri: string): Promise<ModelUpdateResult>;
subscribe(modeluri: string, listener: SubscriptionListener, options?: SubscriptionOptionsV2): SubscriptionListener;
send(modelUri: string, message: ModelServerMessage): void;
unsubscribe(modelUri: string): void;
edit(modeluri: URI, patchOrCommand: PatchOrCommand, format?: Format): Promise<ModelUpdateResult>;
undo(modeluri: URI): Promise<ModelUpdateResult>;
redo(modeluri: URI): Promise<ModelUpdateResult>;
subscribe(modeluri: URI, listener: SubscriptionListener, options?: SubscriptionOptionsV2): SubscriptionListener;
send(modeluri: URI, message: ModelServerMessage): void;
unsubscribe(modeluri: URI): void;
}
export declare namespace ModelServerClientApiV2 {
const API_ENDPOINT = "/api/v2";
const API_ENDPOINT = "api/v2";
}
/**
* A patch affecting a specific model.
*/
export interface ModelPatch {
/**
* The uri of the patched model.
*/
modelUri: string;
/**
* The patch describing the changes applied to the model.
*/
patch: Operation[];
}
/**
* Result sent to client after requesting a model update.

@@ -124,5 +146,8 @@ */

* the original model unchanged.
* @param modeluri the uri of the model to patch. This can be used when the model is split in multiple
* resources, to identify the patch to apply. The modeluri should correspond to the oldModel object.
* It can be omitted when patching the main model (or in single-model cases).
* @return the patched model.
*/
patchModel?(oldModel: ModelServerElement, copy?: boolean): ModelServerElement;
patchModel?(oldModel: ModelServerElement, copy?: boolean, modeluri?: URI): ModelServerElement;
/**

@@ -133,3 +158,10 @@ * The Json Patch describing the changes that were applied to the model. Only present if

patch?: Operation[];
/**
* The list of Json Patches describing the changes that were applied to the models. Only present if
* the edit request was successful.
*
* The list contains one entry per modified model. Unmodified models will not contain any entry.
*/
allPatches?: ModelPatch[];
}
//# sourceMappingURL=model-server-client-api-v2.d.ts.map

@@ -18,4 +18,4 @@ "use strict";

(function (ModelServerClientApiV2) {
ModelServerClientApiV2.API_ENDPOINT = '/api/v2';
ModelServerClientApiV2.API_ENDPOINT = 'api/v2';
})(ModelServerClientApiV2 = exports.ModelServerClientApiV2 || (exports.ModelServerClientApiV2 = {}));
//# sourceMappingURL=model-server-client-api-v2.js.map
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {

@@ -17,6 +21,9 @@ if (k2 === undefined) k2 = k;

var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });

@@ -35,2 +42,3 @@ /********************************************************************************

const fast_json_patch_1 = __importStar(require("fast-json-patch"));
const urijs_1 = __importDefault(require("urijs"));
const _1 = require(".");

@@ -40,3 +48,8 @@ const model_server_client_api_v2_1 = require("./model-server-client-api-v2");

let client;
const baseUrl = `http://localhost:8081${model_server_client_api_v2_1.ModelServerClientApiV2.API_ENDPOINT}`;
const baseUrl = new urijs_1.default({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: model_server_client_api_v2_1.ModelServerClientApiV2.API_ENDPOINT
});
const testUndoRedo = async (modeluri, originalModel, patchedModel) => {

@@ -47,10 +60,10 @@ // Expected: originalModel === undoModel === patchedUndoModel

const undoModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
chai_1.expect(undoModel).to.deep.equal(originalModel);
(0, chai_1.expect)(undoModel).to.deep.equal(originalModel);
const patchedUndoModel = undoPatch.patchModel(patchedModel, true);
chai_1.expect(patchedUndoModel).to.deep.equal(originalModel);
(0, chai_1.expect)(patchedUndoModel).to.deep.equal(originalModel);
const redoPatch = await client.redo(modeluri);
const redoModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
chai_1.expect(redoModel).to.deep.equal(patchedModel);
(0, chai_1.expect)(redoModel).to.deep.equal(patchedModel);
const patchedRedoModel = redoPatch.patchModel(patchedUndoModel, true);
chai_1.expect(patchedRedoModel).to.deep.equal(patchedModel);
(0, chai_1.expect)(patchedRedoModel).to.deep.equal(patchedModel);
// Restore initial state

@@ -65,32 +78,32 @@ await client.undo(modeluri);

it('edit with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const patch = _1.replace(modeluri, machine, 'name', newName);
const patch = (0, _1.replace)(modeluri, machine, 'name', newName);
await client.edit(modeluri, patch);
const model = await client.get(modeluri);
chai_1.expect(model.name).to.be.equal(newName);
(0, chai_1.expect)(model.name).to.be.equal(newName);
await testUndoRedo(modeluri, machine, model);
});
it('create with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
const newWorkflowName = 'New Test Workflow';
const initialWorkflowsCount = originalModel.workflows.length;
const patch = _1.create(modeluri, originalModel, 'workflows', 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow', { name: newWorkflowName });
const patch = (0, _1.create)(modeluri, originalModel, 'workflows', 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow', { name: newWorkflowName });
await client.edit(modeluri, patch);
const patchedModel = await client.get(modeluri);
const workflows = patchedModel.workflows;
chai_1.expect(workflows.length).to.be.equal(initialWorkflowsCount + 1);
(0, chai_1.expect)(workflows.length).to.be.equal(initialWorkflowsCount + 1);
const newWorkflow = patchedModel.workflows[initialWorkflowsCount];
chai_1.expect(newWorkflow.name).to.be.equal(newWorkflowName);
chai_1.expect(newWorkflow).to.have.property('$id');
chai_1.expect(newWorkflow.$id).to.be.a('string');
(0, chai_1.expect)(newWorkflow.name).to.be.equal(newWorkflowName);
(0, chai_1.expect)(newWorkflow).to.have.property('$id');
(0, chai_1.expect)(newWorkflow.$id).to.be.a('string');
await testUndoRedo(modeluri, originalModel, patchedModel);
});
it('add with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const initialModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
// Add a second workflow to the model; we'll use it to move a Task from a workflow to the other
const createWorkflow = _1.create(modeluri, initialModel, 'workflows', 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow', { name: 'New Workflow' });
const createWorkflow = (0, _1.create)(modeluri, initialModel, 'workflows', 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow', { name: 'New Workflow' });
await client.edit(modeluri, createWorkflow);

@@ -100,3 +113,3 @@ const originalModel = await client.get(modeluri, _1.ModelServerObjectV2.is);

const targetWF = originalModel.workflows[1];
const patch = _1.add(modeluri, targetWF, 'nodes', sourceWF.nodes[0]);
const patch = (0, _1.add)(modeluri, targetWF, 'nodes', sourceWF.nodes[0]);
await client.edit(modeluri, patch);

@@ -106,34 +119,34 @@ const patchedModel = await client.get(modeluri);

const patchedTargetWF = patchedModel.workflows[1];
chai_1.expect(patchedSourceWF.nodes).to.be.undefined;
chai_1.expect(patchedTargetWF.nodes).to.be.an('array').of.length(1);
chai_1.expect(patchedTargetWF.nodes[0].name).to.be.equal(sourceWF.nodes[0].name); // Node was moved
(0, chai_1.expect)(patchedSourceWF.nodes).to.be.undefined;
(0, chai_1.expect)(patchedTargetWF.nodes).to.be.an('array').of.length(1);
(0, chai_1.expect)(patchedTargetWF.nodes[0].name).to.be.equal(sourceWF.nodes[0].name); // Node was moved
await testUndoRedo(modeluri, originalModel, patchedModel);
});
it('delete with patch - index based', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
const parentWorkflow = originalModel.workflows[0];
chai_1.expect(parentWorkflow.nodes).to.be.an('array').that.is.not.empty;
const patch = _1.removeValueAt(modeluri, parentWorkflow, 'nodes', 0);
(0, chai_1.expect)(parentWorkflow.nodes).to.be.an('array').that.is.not.empty;
const patch = (0, _1.removeValueAt)(modeluri, parentWorkflow, 'nodes', 0);
await client.edit(modeluri, patch);
const patchedModel = await client.get(modeluri);
const patchedParentWorkflow = patchedModel.workflows[0];
chai_1.expect(patchedParentWorkflow.nodes).to.be.undefined;
(0, chai_1.expect)(patchedParentWorkflow.nodes).to.be.undefined;
await testUndoRedo(modeluri, originalModel, patchedModel);
});
it('delete with patch - object', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, _1.ModelServerObjectV2.is);
const parentWorkflow = originalModel.workflows[0];
chai_1.expect(parentWorkflow.nodes).to.be.an('array').that.is.not.empty;
(0, chai_1.expect)(parentWorkflow.nodes).to.be.an('array').that.is.not.empty;
const valueToRemove = parentWorkflow.nodes[0];
const patch = _1.removeObject(modeluri, valueToRemove);
const patch = (0, _1.removeObject)(modeluri, valueToRemove);
await client.edit(modeluri, patch);
const patchedModel = await client.get(modeluri);
const patchedParentWorkflow = patchedModel.workflows[0];
chai_1.expect(patchedParentWorkflow.nodes).to.be.undefined;
(0, chai_1.expect)(patchedParentWorkflow.nodes).to.be.undefined;
await testUndoRedo(modeluri, originalModel, patchedModel);
});
it('edit with command', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -143,3 +156,3 @@ const originalModel = await client.get(modeluri, _1.ModelServerObjectV2.is);

eClass: originalModel.$type,
$ref: `SuperBrewer3000.coffee#${originalModel.$id}`
$ref: urijs_1.default.build({ path: 'SuperBrewer3000.coffee', fragment: originalModel.$id })
};

@@ -149,25 +162,25 @@ const command = new _1.SetCommand(owner, 'name', [newName]);

const model = await client.get(modeluri);
chai_1.expect(model.name).to.be.equal(newName);
(0, chai_1.expect)(model.name).to.be.equal(newName);
await testUndoRedo(modeluri, originalModel, model);
});
it('incremental patch update', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const patch = _1.replace(modeluri, machine, 'name', newName);
const patch = (0, _1.replace)(modeluri, machine, 'name', newName);
const updateResult = await client.edit(modeluri, patch);
chai_1.expect(updateResult.success).to.be.true;
chai_1.expect(updateResult.patchModel).to.not.be.undefined;
chai_1.expect(updateResult.patch).to.not.be.undefined;
(0, chai_1.expect)(updateResult.success).to.be.true;
(0, chai_1.expect)(updateResult.patchModel).to.not.be.undefined;
(0, chai_1.expect)(updateResult.patch).to.not.be.undefined;
// Patch a copy of the model (machine), to make sure the original model is
// unchanged. We'll need it later to check undo/redo behavior.
const patchedMachine = updateResult.patchModel(machine, true);
chai_1.expect(patchedMachine.name).to.be.equal(newName);
(0, chai_1.expect)(patchedMachine.name).to.be.equal(newName);
// Check that the incremental update is consistent with the server version of the model
const newMachine = await client.get(modeluri, _1.ModelServerObjectV2.is);
chai_1.expect(newMachine).to.deep.equal(patchedMachine);
(0, chai_1.expect)(newMachine).to.deep.equal(patchedMachine);
await testUndoRedo(modeluri, machine, patchedMachine);
});
it('subscribe to changes', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -177,3 +190,3 @@ const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);

eClass: machine.$type,
$ref: `SuperBrewer3000.coffee#${machine.$id}`
$ref: urijs_1.default.build({ path: 'SuperBrewer3000.coffee', fragment: machine.$id })
};

@@ -195,9 +208,9 @@ const command = new _1.SetCommand(owner, 'name', [newName]);

const patch = notification.patch;
chai_1.expect(notification.modelUri).to.be.equal(modeluri);
chai_1.expect(patch.length).to.be.equal(1);
(0, chai_1.expect)(notification.modeluri.toString()).to.be.equal(modeluri.toString());
(0, chai_1.expect)(patch.length).to.be.equal(1);
const operation = patch[0];
chai_1.expect(_1.Operations.isReplace(operation, 'string')).to.be.equal(true);
chai_1.expect(operation.path).to.be.equal('/name');
(0, chai_1.expect)(_1.Operations.isReplace(operation, 'string')).to.be.equal(true);
(0, chai_1.expect)(operation.path).to.be.equal('/name');
if (_1.Operations.isReplace(operation, 'string')) {
chai_1.expect(operation.value).to.be.equal(newName);
(0, chai_1.expect)(operation.value).to.be.equal(newName);
}

@@ -208,3 +221,3 @@ await client.undo(modeluri);

it('subscribe to incremental updates', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -214,3 +227,3 @@ const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);

eClass: machine.$type,
$ref: `SuperBrewer3000.coffee#${machine.$id}`
$ref: urijs_1.default.build({ path: 'SuperBrewer3000.coffee', fragment: machine.$id })
};

@@ -237,3 +250,3 @@ const command = new _1.SetCommand(owner, 'name', [newName]);

// from the model server.
chai_1.expect(incrementalPatchedModel).to.deep.equal(patchedModel);
(0, chai_1.expect)(incrementalPatchedModel).to.deep.equal(patchedModel);
await client.undo(modeluri);

@@ -243,6 +256,6 @@ client.unsubscribe(modeluri);

it('pure Json Patch changes', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const patchedMachine = fast_json_patch_1.deepClone(machine);
const patchedMachine = (0, fast_json_patch_1.deepClone)(machine);
// Directly change the model

@@ -255,11 +268,11 @@ patchedMachine.name = newName;

const model = await client.get(modeluri);
chai_1.expect(model.name).to.be.equal(newName);
chai_1.expect(model.children[1].processor.clockSpeed).to.be.equal(6);
(0, chai_1.expect)(model.name).to.be.equal(newName);
(0, chai_1.expect)(model.children[1].processor.clockSpeed).to.be.equal(6);
await testUndoRedo(modeluri, machine, model);
});
it('clear list with "remove" patch operation', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const initialWorkflowsSize = machine.workflows.length;
chai_1.expect(initialWorkflowsSize).to.not.be.equal(0);
(0, chai_1.expect)(initialWorkflowsSize).to.not.be.equal(0);
const patch = [

@@ -274,10 +287,10 @@ {

const newWorkflows = model.workflows;
chai_1.expect(newWorkflows).to.be.undefined;
(0, chai_1.expect)(newWorkflows).to.be.undefined;
await testUndoRedo(modeluri, machine, model);
});
it('unset value with "remove" patch operation', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const initialValue = machine.children[1].processor.thermalDesignPower;
chai_1.expect(initialValue).to.not.be.oneOf([undefined, 0]);
(0, chai_1.expect)(initialValue).to.not.be.oneOf([undefined, 0]);
const patch = [

@@ -292,7 +305,53 @@ {

const newValue = model.children[1].processor.thermalDesignPower;
chai_1.expect(newValue).to.be.oneOf([undefined, 0]); // Should be === 0, but default values are not converted to Json at the moment; so we also expect 'undefined'
(0, chai_1.expect)(newValue).to.be.oneOf([undefined, 0]); // Should be === 0, but default values are not converted to Json at the moment; so we also expect 'undefined'
await testUndoRedo(modeluri, machine, model);
});
it('check all patch replies', async () => {
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const patchedMachine = (0, fast_json_patch_1.deepClone)(machine);
// Directly change the model
patchedMachine.name = newName;
patchedMachine.children[1].processor.clockSpeed = 6;
// Generate patch by diffing the original model and the patched one
const patch = fast_json_patch_1.default.compare(machine, patchedMachine);
const result = await client.edit(modeluri, patch);
(0, chai_1.expect)(result.success).to.be.true;
(0, chai_1.expect)(result.patch).to.not.be.undefined;
(0, chai_1.expect)(result.allPatches).to.not.be.undefined;
(0, chai_1.expect)(result.allPatches).to.be.an('array').of.length(1);
// Patch the main resource
const updatedMachineMainPatch = result.patchModel(machine, true);
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineMainPatch);
// Patch the first resource
const updatedMachineFirstPatch = result.patchModel(machine, true, new urijs_1.default(result.allPatches[0].modelUri));
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineFirstPatch);
await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);
});
it('test model patches', async () => {
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);
const patchedMachine = (0, fast_json_patch_1.deepClone)(machine);
// Directly change the model
patchedMachine.name = newName;
patchedMachine.children[1].processor.clockSpeed = 6;
// Generate patches by diffing the original model and the patched one
const patch = fast_json_patch_1.default.compare(machine, patchedMachine);
const result = await client.edit(modeluri, patch);
(0, chai_1.expect)(result.success).to.be.true;
(0, chai_1.expect)(result.patch).to.not.be.undefined;
(0, chai_1.expect)(result.allPatches).to.not.be.undefined;
(0, chai_1.expect)(result.allPatches).to.be.an('array').of.length(1);
// Patch the main resource
const updatedMachineMainPatch = result.patchModel(machine, true);
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineMainPatch);
// Patch the first resource
const updatedMachineFirstPatch = result.patchModel(machine, true, new urijs_1.default(result.allPatches[0].modelUri));
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineFirstPatch);
await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);
});
});
});
//# sourceMappingURL=model-server-client-v2-integration.spec.js.map
/********************************************************************************
* Copyright (c) 2022 STMicroelectronics and others.
* Copyright (c) 2022-2023 STMicroelectronics and others.
*

@@ -12,9 +12,8 @@ * This program and the accompanying materials are made available under the

import { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { Operation } from 'fast-json-patch';
import WebSocket from 'isomorphic-ws';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import URI from 'urijs';
import { ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
import { Format, ModelServerClientApiV2, ModelUpdateResult } from './model-server-client-api-v2';
import { Format, ModelServerClientApiV2, ModelUpdateResult, PatchOrCommand } from './model-server-client-api-v2';
import { MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { Diagnostic } from './model/diagnostic';
import { SubscriptionListener } from './subscription-listener';

@@ -28,43 +27,41 @@ import { AnyObject, TypeGuard } from './utils/type-util';

protected openSockets: Map<string, WebSocket>;
protected _baseUrl: string;
protected _baseUrl: URI;
protected defaultFormat: Format;
initialize(baseUrl: string, defaultFormat?: Format): void | Promise<void>;
protected getAxiosConfig(baseURL: string): AxiosRequestConfig | undefined;
get(modeluri: string, format?: Format): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
initialize(baseUrl: URI, defaultFormat?: Format): void | Promise<void>;
protected getAxiosConfig(baseURL: URI): AxiosRequestConfig | undefined;
get(modeluri: URI, format?: Format): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getAll(): Promise<Model[]>;
getAll<M>(typeGuard: TypeGuard<M>): Promise<Model<M>[]>;
getAll(format: Format): Promise<Model<string>[]>;
getModelUris(): Promise<string[]>;
getElementById(modeluri: string, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementByName(modeluri: string, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
create(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
delete(modeluri: string): Promise<boolean>;
close(modeluri: string): Promise<boolean>;
save(modeluri: string): Promise<boolean>;
getModelUris(): Promise<URI[]>;
getElementById(modeluri: URI, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementByName(modeluri: URI, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
create(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
delete(modeluri: URI): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;
save(modeluri: URI): Promise<boolean>;
saveAll(): Promise<boolean>;
validate(modeluri: string): Promise<Diagnostic>;
getValidationConstraints(modeluri: string): Promise<string>;
getTypeSchema(modeluri: string): Promise<string>;
validate(modeluri: URI): Promise<Diagnostic>;
getValidationConstraints(modeluri: URI): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;
getUiSchema(schemaname: string): Promise<string>;
configureServer(configuration: ServerConfiguration): Promise<boolean>;
ping(): Promise<boolean>;
edit(modeluri: string, patch: Operation): Promise<ModelUpdateResult>;
edit(modeluri: string, patch: Operation[]): Promise<ModelUpdateResult>;
edit(modeluri: string, command: ModelServerCommand): Promise<ModelUpdateResult>;
undo(modeluri: string): Promise<ModelUpdateResult>;
redo(modeluri: string): Promise<ModelUpdateResult>;
send(modelUri: string, message: ModelServerMessage): void;
subscribe(modeluri: string, listener: SubscriptionListener, options?: SubscriptionOptions): SubscriptionListener;
unsubscribe(modeluri: string): void;
protected createSubscriptionPath(modeluri: string, options: SubscriptionOptions): string;
protected doSubscribe(listener: SubscriptionListener, modelUri: string, path: string): void;
protected isSocketOpen(modelUri: string): boolean;
edit(modeluri: URI, patchOrCommand: PatchOrCommand, format?: string): Promise<ModelUpdateResult>;
undo(modeluri: URI): Promise<ModelUpdateResult>;
redo(modeluri: URI): Promise<ModelUpdateResult>;
send(modeluri: URI, message: ModelServerMessage): void;
subscribe(modeluri: URI, listener: SubscriptionListener, options?: SubscriptionOptions): SubscriptionListener;
unsubscribe(modeluri: URI): void;
protected createSubscriptionPath(modeluri: URI, options: SubscriptionOptions): URI;
protected doSubscribe(listener: SubscriptionListener, modeluri: URI, path: URI): void;
protected isSocketOpen(modeluri: URI): boolean;
protected process<T>(request: Promise<AxiosResponse<ModelServerMessage>>, mapper: MessageDataMapper<T>): Promise<T>;
}
//# sourceMappingURL=model-server-client-v2.d.ts.map
"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) {

@@ -8,3 +19,3 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

/********************************************************************************
* Copyright (c) 2022 STMicroelectronics and others.
* Copyright (c) 2022-2023 STMicroelectronics and others.
*

@@ -19,5 +30,4 @@ * This program and the accompanying materials are made available under the

const axios_1 = __importDefault(require("axios"));
const fast_json_patch_1 = require("fast-json-patch");
const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
const command_model_1 = require("./model/command-model");
const diagnostic_1 = require("./model/diagnostic");
const model_server_client_api_v1_1 = require("./model-server-client-api-v1");

@@ -27,2 +37,4 @@ const model_server_client_api_v2_1 = require("./model-server-client-api-v2");

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");

@@ -38,3 +50,3 @@ /**

initialize(baseUrl, defaultFormat = model_server_client_api_v2_1.FORMAT_JSON_V2) {
this._baseUrl = baseUrl;
this._baseUrl = baseUrl.clone();
this.defaultFormat = defaultFormat;

@@ -44,3 +56,3 @@ this.restClient = axios_1.default.create(this.getAxiosConfig(baseUrl));

getAxiosConfig(baseURL) {
return { baseURL };
return { baseURL: baseURL.toString() };
}

@@ -50,6 +62,6 @@ get(modeluri, formatOrGuard, format) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { modeluri, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
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, format } }), model_server_message_1.MessageDataMapper.asObject);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString(), format } }), model_server_message_1.MessageDataMapper.asObject);
}

@@ -73,3 +85,3 @@ getAll(formatOrGuard) {

getModelUris() {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_URIS), model_server_message_1.MessageDataMapper.asStringArray);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_URIS), model_server_message_1.MessageDataMapper.asURIArray);
}

@@ -81,7 +93,7 @@ getElementById(modeluri, elementid, formatOrGuard, format) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementid, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
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, elementid, format } }), model_server_message_1.MessageDataMapper.asObject);
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);
}

@@ -93,7 +105,7 @@ getElementByName(modeluri, elementname, formatOrGuard, format) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementname, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
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, elementname, format } }), model_server_message_1.MessageDataMapper.asObject);
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);
}

@@ -105,7 +117,11 @@ create(modeluri, model, formatOrGuard, format) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.post(model_server_paths_1.ModelServerPaths.MODEL_CRUD, type_util_1.encodeRequestBody(format)(model), { params: { modeluri, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
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, type_util_1.encodeRequestBody(format)(model), { params: { modeluri, format } }), model_server_message_1.MessageDataMapper.asObject);
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);
}

@@ -117,16 +133,20 @@ update(modeluri, model, formatOrGuard, format) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.MODEL_CRUD, type_util_1.encodeRequestBody(format)(model), { params: { modeluri, format } }), msg => model_server_message_1.MessageDataMapper.as(msg, typeGuard));
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, type_util_1.encodeRequestBody(format)(model), { params: { modeluri, format } }), model_server_message_1.MessageDataMapper.asObject);
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 } }), model_server_message_1.MessageDataMapper.isSuccess);
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 } }), model_server_message_1.MessageDataMapper.isSuccess);
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 } }), model_server_message_1.MessageDataMapper.isSuccess);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.SAVE, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.isSuccess);
}

@@ -137,9 +157,9 @@ saveAll() {

validate(modeluri) {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.VALIDATION, { params: { modeluri } }), response => model_server_message_1.MessageDataMapper.as(response, diagnostic_1.Diagnostic.is));
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 } }), model_server_message_1.MessageDataMapper.asString);
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 } }), model_server_message_1.MessageDataMapper.asString);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA, { params: { modeluri: modeluri.toString() } }), model_server_message_1.MessageDataMapper.asString);
}

@@ -150,6 +170,7 @@ getUiSchema(schemaname) {

configureServer(configuration) {
let { workspaceRoot, uiSchemaFolder } = configuration;
workspaceRoot = workspaceRoot.replace('file://', '');
uiSchemaFolder = uiSchemaFolder === null || uiSchemaFolder === void 0 ? void 0 : uiSchemaFolder.replace('file://', '');
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE, { workspaceRoot, uiSchemaFolder }), model_server_message_1.MessageDataMapper.isSuccess);
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);
}

@@ -159,3 +180,3 @@ ping() {

}
edit(modeluri, patchOrCommand) {
edit(modeluri, patchOrCommand, format = this.defaultFormat) {
let patchMessage;

@@ -169,2 +190,3 @@ if (patchOrCommand instanceof command_model_1.ModelServerCommand) {

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];

@@ -175,17 +197,25 @@ patchMessage = {

};
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, type_util_1.encodeRequestBody(this.defaultFormat)(patchMessage), {
params: { modeluri, format: this.defaultFormat }
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 } }), model_server_message_1.MessageDataMapper.patchModel);
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 } }), model_server_message_1.MessageDataMapper.patchModel);
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);
send(modeluri, message) {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.send(message);
openSocket.send(JSON.stringify(message));
}

@@ -195,6 +225,6 @@ }

if (this.isSocketOpen(modeluri)) {
const errorMsg = `${modeluri} : Cannot open new socket, already subscribed!'`;
const errorMsg = `${modeluri.toString()} : Cannot open new socket, already subscribed!'`;
console.warn(errorMsg);
if (options.errorWhenUnsuccessful) {
throw new Error('errorMsg');
throw new Error(errorMsg);
}

@@ -207,28 +237,29 @@ }

unsubscribe(modeluri) {
const openSocket = this.openSockets.get(modeluri);
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.close();
this.openSockets.delete(modeluri);
this.openSockets.delete(modeluri.toString());
}
}
createSubscriptionPath(modeluri, options) {
const queryParams = new URLSearchParams();
queryParams.append('modeluri', modeluri);
if (!options.format) {
options.format = this.defaultFormat;
}
Object.entries(options).forEach(entry => queryParams.append(entry[0], entry[1]));
queryParams.delete('errorWhenUnsuccessful');
return `${this._baseUrl}/${model_server_paths_1.ModelServerPaths.SUBSCRIPTION}?${queryParams.toString()}`.replace(/^(http|https):\/\//i, 'ws://');
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.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, socket);
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) !== undefined;
isSocketOpen(modeluri) {
return this.openSockets.get(modeluri.toString()) !== undefined;
}

@@ -245,3 +276,3 @@ async process(request, mapper) {

catch (error) {
if (isAxiosError(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;

@@ -257,15 +288,12 @@ throw new model_server_client_api_v1_1.ModelServerError(message, error.code);

exports.ModelServerClientV2 = ModelServerClientV2;
function isAxiosError(error) {
return error !== undefined && error instanceof Error && 'isAxiosError' in error && error['isAxiosError'];
}
function mapModel(model, guard, toString = false) {
const { modelUri, content } = model;
const { modeluri, content } = model;
if (guard) {
return { modelUri, content: type_util_1.asType(content, guard) };
return { modeluri, content: (0, type_util_1.asType)(content, guard) };
}
else if (toString) {
return { modelUri, content: type_util_1.asString(content) };
return { modeluri, content: (0, type_util_1.asString)(content) };
}
return { modelUri, content: type_util_1.asObject(content) };
return { modeluri, content: (0, type_util_1.asObject)(content) };
}
//# sourceMappingURL=model-server-client-v2.js.map

@@ -20,2 +20,3 @@ "use strict";

const sinon_1 = require("sinon");
const urijs_1 = __importDefault(require("urijs"));
const model_server_client_api_v2_1 = require("./model-server-client-api-v2");

@@ -26,3 +27,8 @@ const model_server_client_v2_1 = require("./model-server-client-v2");

let client;
const baseUrl = `http://localhost:8081${model_server_client_api_v2_1.ModelServerClientApiV2.API_ENDPOINT}`;
const baseUrl = new urijs_1.default({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: model_server_client_api_v2_1.ModelServerClientApiV2.API_ENDPOINT
});
beforeEach(() => {

@@ -38,4 +44,16 @@ client = new model_server_client_v2_1.ModelServerClientV2();

const axios = client['restClient'];
chai_1.expect(axios.defaults.baseURL).to.be.equal(baseUrl);
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});
it('test createSubscriptionPath without trailing slash', () => {
client = new model_server_client_v2_1.ModelServerClientV2();
client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath'](new urijs_1.default('foo'), {});
(0, chai_1.expect)(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
});
it('test createSubscriptionPath with trailing slash', () => {
client = new model_server_client_v2_1.ModelServerClientV2();
client.initialize(new urijs_1.default(`${baseUrl}/`));
const subscriptionPath = client['createSubscriptionPath'](new urijs_1.default('foo'), {});
(0, chai_1.expect)(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
});
describe('test requests', () => {

@@ -48,8 +66,8 @@ it('getAll', done => {

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2 });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI });
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI });
done();

@@ -62,6 +80,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_URIS);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_URIS);
done();

@@ -71,3 +89,3 @@ });

it('getElementById', done => {
const modeluri = 'my/uri.model';
const modeluri = new urijs_1.default('my/uri.model');
const elementid = 'myElement';

@@ -78,8 +96,8 @@ client.getElementById(modeluri, elementid);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, elementid, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, elementid, modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, elementid, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, elementid, modeluri: modeluri.toString() });
done();

@@ -89,3 +107,3 @@ });

it('getElementByName', done => {
const modeluri = 'my/uri.model';
const modeluri = new urijs_1.default('my/uri.model');
const elementname = 'myElement';

@@ -96,8 +114,8 @@ client.getElementByName(modeluri, elementname);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, elementname, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, elementname, modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, elementname, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, elementname, modeluri: modeluri.toString() });
done();

@@ -107,10 +125,10 @@ });

it('delete', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
client.delete(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('delete');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('delete');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
done();

@@ -120,10 +138,10 @@ });

it('close', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
client.close(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('post');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.CLOSE);
(0, chai_1.expect)(request.config.method).to.be.equal('post');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.CLOSE);
done();

@@ -133,3 +151,3 @@ });

it('create', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -141,9 +159,9 @@ const data = JSON.stringify(model);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('post');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data }));
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('post');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data }));
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, modeluri: modeluri.toString() });
done();

@@ -153,3 +171,3 @@ });

it('update', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -161,9 +179,9 @@ const data = JSON.stringify(model);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('put');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data }));
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('put');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data }));
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_XMI, modeluri: modeluri.toString() });
done();

@@ -173,10 +191,10 @@ });

it('save', done => {
const modeluri = 'save/me/please';
const modeluri = new urijs_1.default('save/me/please');
client.save(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE);
done();

@@ -189,6 +207,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE_ALL);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE_ALL);
done();

@@ -198,10 +216,10 @@ });

it('validate', done => {
const modeluri = 'validate/me/please';
const modeluri = new urijs_1.default('validate/me/please');
client.validate(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION);
done();

@@ -211,10 +229,10 @@ });

it('getValidationConstraints', done => {
const modeluri = 'validate/me/please';
const modeluri = new urijs_1.default('validate/me/please');
client.getValidationConstraints(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION_CONSTRAINTS);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION_CONSTRAINTS);
done();

@@ -224,10 +242,10 @@ });

it('getTypeSchema', done => {
const modeluri = 'my/model/uri';
const modeluri = new urijs_1.default('my/model/uri');
client.getTypeSchema(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA);
done();

@@ -241,6 +259,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ schemaname });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UI_SCHEMA);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ schemaname });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UI_SCHEMA);
done();

@@ -251,4 +269,4 @@ });

const configuration = {
workspaceRoot: 'myRoot',
uiSchemaFolder: 'mySchemaFolder'
workspaceRoot: new urijs_1.default('myRoot'),
uiSchemaFolder: new urijs_1.default('mySchemaFolder')
};

@@ -258,7 +276,10 @@ client.configureServer(configuration);

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('put');
chai_1.expect(request.config.data).to.equal(JSON.stringify(configuration));
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE);
(0, chai_1.expect)(request.config.method).to.be.equal('put');
(0, chai_1.expect)(request.config.data).to.equal(JSON.stringify({
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder.toString()
}));
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE);
done();

@@ -271,6 +292,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_PING);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_PING);
done();

@@ -280,3 +301,3 @@ });

it('edit', done => {
const modeluri = 'edit/me/please';
const modeluri = new urijs_1.default('edit/me/please');
const patch = [

@@ -296,7 +317,7 @@ {

const request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('patch');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data: expected }));
chai_1.expect(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('patch');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data: expected }));
(0, chai_1.expect)(request.config.params).to.include({ format: model_server_client_api_v2_1.FORMAT_JSON_V2, modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
done();

@@ -306,10 +327,10 @@ });

it('undo', done => {
const modeluri = 'undo/me/please';
const modeluri = new urijs_1.default('undo/me/please');
client.undo(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UNDO);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UNDO);
done();

@@ -319,10 +340,10 @@ });

it('redo', done => {
const modeluri = 'redo/me/please';
const modeluri = new urijs_1.default('redo/me/please');
client.redo(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.REDO);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.include({ modeluri: modeluri.toString() });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.REDO);
done();

@@ -333,3 +354,3 @@ });

describe('test responses', () => {
it('ping ', done => {
it('ping', done => {
const expectedMsg = {

@@ -339,3 +360,3 @@ data: '',

};
const onFulfilled = sinon_1.spy();
const onFulfilled = (0, sinon_1.spy)();
client.ping().then(onFulfilled);

@@ -348,9 +369,9 @@ moxios_1.default.wait(async () => {

});
assert_1.strictEqual(onFulfilled.getCall(0).args[0], true);
(0, assert_1.strictEqual)(onFulfilled.getCall(0).args[0], true);
done();
});
});
it('ping ', done => {
it('getAll', done => {
const model1 = {
modelUri: 'path/to/model1',
modeluri: 'path/to/model1',
content: {

@@ -361,3 +382,3 @@ name: 'coffee'

const model2 = {
modelUri: 'path/to/model2',
modeluri: 'path/to/model2',
content: {

@@ -369,8 +390,8 @@ name: 'coffee'

data: {
[model1.modelUri]: model1.content,
[model2.modelUri]: model2.content
[model1.modeluri.toString()]: model1.content,
[model2.modeluri.toString()]: model2.content
},
type: 'success'
};
const onFulfilled = sinon_1.spy();
const onFulfilled = (0, sinon_1.spy)();
client.getAll().then(onFulfilled);

@@ -384,3 +405,4 @@ moxios_1.default.wait(async () => {

const result = onFulfilled.getCall(0).args[0];
chai_1.expect(result).to.deep.include.members([model2, model1]);
(0, chai_1.expect)(result).to.be.an('array').of.length(2);
(0, chai_1.expect)(result).to.deep.include.members([model1, model2]);
done();

@@ -387,0 +409,0 @@ });

/********************************************************************************
* Copyright (c) 2021-2022 STMicroelectronics and others.
* Copyright (c) 2021-2023 STMicroelectronics and others.
*

@@ -13,6 +13,7 @@ * This program and the accompanying materials are made available under the

import WebSocket from 'isomorphic-ws';
import URI from 'urijs';
import { ModelServerClientApiV1, ModelServerError, ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
import { Mapper, MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { ModelServerClientApiV1, ModelServerError, ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
import { Mapper, MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { SubscriptionListener } from './subscription-listener';

@@ -26,44 +27,44 @@ import { AnyObject, TypeGuard } from './utils/type-util';

protected openSockets: Map<string, WebSocket>;
protected _baseUrl: string;
protected _baseUrl: URI;
protected defaultFormat: string;
initialize(baseUrl: string): void | Promise<void>;
protected getAxisConfig(baseURL: string): AxiosRequestConfig | undefined;
get(modeluri: string): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>): Promise<M>;
get(modeluri: string, format: string): Promise<string>;
initialize(baseUrl: URI): void | Promise<void>;
protected getAxisConfig(baseURL: URI): AxiosRequestConfig | undefined;
get(modeluri: URI): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>): Promise<M>;
get(modeluri: URI, format: string): Promise<string>;
getAll(): Promise<Model[]>;
getAll<M>(typeGuard: TypeGuard<M>): Promise<Model<M>[]>;
getAll(format: string): Promise<Model<string>[]>;
getModelUris(): Promise<string[]>;
getElementById(modeluri: string, elementid: string): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById(modeluri: string, elementid: string, format: string): Promise<string>;
getElementByName(modeluri: string, elementname: string): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName(modeluri: string, elementname: string, format: string): Promise<string>;
create(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: string, model: AnyObject | string, format: string): Promise<string>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: string, model: AnyObject | string, format: string): Promise<AnyObject>;
delete(modeluri: string): Promise<boolean>;
close(modeluri: string): Promise<boolean>;
save(modeluri: string): Promise<boolean>;
getModelUris(): Promise<URI[]>;
getElementById(modeluri: URI, elementid: string): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById(modeluri: URI, elementid: string, format: string): Promise<string>;
getElementByName(modeluri: URI, elementname: string): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName(modeluri: URI, elementname: string, format: string): Promise<string>;
create(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: URI, model: AnyObject | string, format: string): Promise<string>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format: string): Promise<AnyObject>;
delete(modeluri: URI): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;
save(modeluri: URI): Promise<boolean>;
saveAll(): Promise<boolean>;
validate(modeluri: string): Promise<Diagnostic>;
getValidationConstraints(modeluri: string): Promise<string>;
getTypeSchema(modeluri: string): Promise<string>;
validate(modeluri: URI): Promise<Diagnostic>;
getValidationConstraints(modeluri: URI): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;
getUiSchema(schemaname: string): Promise<string>;
configureServer(configuration: ServerConfiguration): Promise<boolean>;
ping(): Promise<boolean>;
edit(modeluri: string, command: ModelServerCommand): Promise<boolean>;
undo(modeluri: string): Promise<string>;
redo(modeluri: string): Promise<string>;
send(modelUri: string, message: ModelServerMessage): boolean;
subscribe(modeluri: string, options?: SubscriptionOptions): void;
unsubscribe(modeluri: string): boolean;
protected createSubscriptionPath(modeluri: string, options: SubscriptionOptions): string;
protected doSubscribe(listener: SubscriptionListener, modelUri: string, path: string): void;
protected isSocketOpen(modelUri: string): boolean;
edit(modeluri: URI, command: ModelServerCommand): Promise<boolean>;
undo(modeluri: URI): Promise<string>;
redo(modeluri: URI): Promise<string>;
send(modeluri: URI, message: ModelServerMessage): boolean;
subscribe(modeluri: URI, options?: SubscriptionOptions): void;
unsubscribe(modeluri: URI): boolean;
protected createSubscriptionPath(modeluri: URI, options: SubscriptionOptions): URI;
protected doSubscribe(listener: SubscriptionListener, modeluri: URI, path: URI): void;
protected isSocketOpen(modeluri: URI): boolean;
protected process<T>(request: Promise<AxiosResponse<ModelServerMessage>>, mapper: MessageDataMapper<T>): Promise<T>;

@@ -70,0 +71,0 @@ protected processMessageAsData<M>(request: Promise<AxiosResponse<M>>): Promise<M>;

@@ -19,3 +19,3 @@ "use strict";

/********************************************************************************
* Copyright (c) 2021-2022 STMicroelectronics and others.
* Copyright (c) 2021-2023 STMicroelectronics and others.
*

@@ -31,6 +31,6 @@ * This program and the accompanying materials are made available under the

const isomorphic_ws_1 = __importDefault(require("isomorphic-ws"));
const diagnostic_1 = require("./model/diagnostic");
const model_server_client_api_v1_1 = require("./model-server-client-api-v1");
const model_server_message_1 = require("./model-server-message");
const model_server_paths_1 = require("./model-server-paths");
const diagnostic_1 = require("./model/diagnostic");
const type_util_1 = require("./utils/type-util");

@@ -46,7 +46,7 @@ /**

initialize(baseUrl) {
this._baseUrl = baseUrl;
this._baseUrl = baseUrl.clone();
this.restClient = axios_1.default.create(this.getAxisConfig(baseUrl));
}
getAxisConfig(baseURL) {
return { baseURL };
return { baseURL: baseURL.toString() };
}

@@ -75,3 +75,3 @@ get(modeluri, formatOrGuard) {

getModelUris() {
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_URIS), model_server_message_1.MessageDataMapper.asStringArray);
return this.process(this.restClient.get(model_server_paths_1.ModelServerPaths.MODEL_URIS), model_server_message_1.MessageDataMapper.asURIArray);
}

@@ -123,6 +123,7 @@ getElementById(modeluri, elementid, formatOrGuard) {

configureServer(configuration) {
let { workspaceRoot, uiSchemaFolder } = configuration;
workspaceRoot = workspaceRoot.replace('file://', '');
uiSchemaFolder = uiSchemaFolder === null || uiSchemaFolder === void 0 ? void 0 : uiSchemaFolder.replace('file://', '');
return this.process(this.restClient.put(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE, { workspaceRoot, uiSchemaFolder }), model_server_message_1.MessageDataMapper.isSuccess);
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);
}

@@ -141,4 +142,4 @@ ping() {

}
send(modelUri, message) {
const openSocket = this.openSockets.get(modelUri);
send(modeluri, message) {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {

@@ -152,7 +153,7 @@ openSocket.send(JSON.stringify(message));

if (!options.listener) {
const errorMsg = `${modeluri} : Cannot subscribe. No listener is present!'`;
const errorMsg = `${modeluri.toString()} : Cannot subscribe. No listener is present!'`;
throw new Error(errorMsg);
}
if (this.isSocketOpen(modeluri)) {
const errorMsg = `${modeluri} : Cannot open new socket, already subscribed!'`;
const errorMsg = `${modeluri.toString()} : Cannot open new socket, already subscribed!'`;
console.warn(errorMsg);

@@ -167,6 +168,6 @@ if (options.errorWhenUnsuccessful) {

unsubscribe(modeluri) {
const openSocket = this.openSockets.get(modeluri);
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.close();
this.openSockets.delete(modeluri);
this.openSockets.delete(modeluri.toString());
return true;

@@ -179,24 +180,24 @@ }

const { listener } = options, paramOptions = __rest(options, ["listener"]);
const queryParams = new URLSearchParams();
queryParams.append('modeluri', modeluri);
if (!options.format) {
options.format = this.defaultFormat;
}
Object.entries(paramOptions).forEach(entry => queryParams.append(entry[0], entry[1]));
queryParams.delete('errorWhenUnsuccessful');
return `${this._baseUrl}${model_server_paths_1.ModelServerPaths.SUBSCRIPTION}?${queryParams.toString()}`.replace(/^(http|https):\/\//i, 'ws://');
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.trim());
socket.onopen = event => listener.onOpen(modelUri, event);
doSubscribe(listener, modeluri, path) {
const socket = new isomorphic_ws_1.default(path.toString() /* .trim() */);
socket.onopen = event => listener.onOpen(modeluri, event);
socket.onclose = event => {
listener.onClose(modelUri, event);
this.openSockets.delete(modelUri);
listener.onClose(modeluri, event);
this.openSockets.delete(modeluri.toString());
};
socket.onerror = event => listener.onError(modelUri, event);
socket.onmessage = event => listener.onMessage(modelUri, event);
this.openSockets.set(modelUri, socket);
socket.onerror = event => listener.onError(modeluri, event);
socket.onmessage = event => listener.onMessage(modeluri, event);
this.openSockets.set(modeluri.toString(), socket);
}
isSocketOpen(modelUri) {
return this.openSockets.get(modelUri) !== undefined;
isSocketOpen(modeluri) {
return this.openSockets.get(modeluri.toString()) !== undefined;
}

@@ -226,3 +227,3 @@ async process(request, mapper) {

catch (error) {
if (isAxiosError(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;

@@ -238,5 +239,2 @@ throw new model_server_client_api_v1_1.ModelServerError(message, error.code);

exports.ModelServerClient = ModelServerClient;
function isAxiosError(error) {
return error !== undefined && error instanceof Error && 'isAxiosError' in error && error['isAxiosError'];
}
/**

@@ -259,11 +257,11 @@ * Creates a modelserver message data mapper that maps the response either to a generic JSON object, a specific typed object or string.

function mapModel(model, guard, toString = false) {
const { modelUri, content } = model;
const { modeluri, content } = model;
if (guard) {
return { modelUri, content: type_util_1.asType(content, guard) };
return { modeluri, content: (0, type_util_1.asType)(content, guard) };
}
else if (toString) {
return { modelUri, content: type_util_1.asString(content) };
return { modeluri, content: (0, type_util_1.asString)(content) };
}
return { modelUri, content: type_util_1.asObject(content) };
return { modeluri, content: (0, type_util_1.asObject)(content) };
}
//# sourceMappingURL=model-server-client.js.map

@@ -20,9 +20,15 @@ "use strict";

const sinon_1 = require("sinon");
const command_model_1 = require("./model/command-model");
const urijs_1 = __importDefault(require("urijs"));
const model_server_client_1 = require("./model-server-client");
const model_server_client_api_v1_1 = require("./model-server-client-api-v1");
const model_server_paths_1 = require("./model-server-paths");
const command_model_1 = require("./model/command-model");
describe('tests for ModelServerClient', () => {
let client;
const baseUrl = `http://localhost:8081${model_server_client_api_v1_1.ModelServerClientApiV1.API_ENDPOINT}`;
const baseUrl = new urijs_1.default({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: model_server_client_api_v1_1.ModelServerClientApiV1.API_ENDPOINT
});
beforeEach(() => {

@@ -38,4 +44,16 @@ client = new model_server_client_1.ModelServerClient();

const axios = client['restClient'];
chai_1.expect(axios.defaults.baseURL).to.be.equal(baseUrl);
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});
it('test createSubscriptionPath without trailing slash', () => {
client = new model_server_client_1.ModelServerClient();
client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath'](new urijs_1.default('foo'), {});
(0, chai_1.expect)(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo&format=json');
});
it('test createSubscriptionPath with trailing slash', () => {
client = new model_server_client_1.ModelServerClient();
client.initialize(new urijs_1.default(`${baseUrl}/`));
const subscriptionPath = client['createSubscriptionPath'](new urijs_1.default('foo'), {});
(0, chai_1.expect)(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo&format=json');
});
describe('test requests', () => {

@@ -48,8 +66,8 @@ it('getAll', done => {

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: 'json' });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: 'json' });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: 'xml' });
(0, chai_1.expect)(request.config.params).to.include({ format: 'xml' });
done();

@@ -62,6 +80,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_URIS);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_URIS);
done();

@@ -71,3 +89,3 @@ });

it('getElementById', done => {
const modeluri = 'my/uri.model';
const modeluri = new urijs_1.default('my/uri.model');
const elementid = 'myElement';

@@ -78,8 +96,8 @@ client.getElementById(modeluri, elementid);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: 'json', elementid, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: 'json', elementid, modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: 'xml', elementid, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: 'xml', elementid, modeluri });
done();

@@ -89,3 +107,3 @@ });

it('getElementByName', done => {
const modeluri = 'my/uri.model';
const modeluri = new urijs_1.default('my/uri.model');
const elementname = 'myElement';

@@ -96,8 +114,8 @@ client.getElementByName(modeluri, elementname);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ format: 'json', elementname, modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ format: 'json', elementname, modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_ELEMENT);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: 'xml', elementname, modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: 'xml', elementname, modeluri });
done();

@@ -107,10 +125,10 @@ });

it('delete', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
client.delete(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('delete');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('delete');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
done();

@@ -120,10 +138,10 @@ });

it('close', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
client.close(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('post');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.CLOSE);
(0, chai_1.expect)(request.config.method).to.be.equal('post');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.CLOSE);
done();

@@ -133,3 +151,3 @@ });

it('create', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -141,9 +159,9 @@ const data = JSON.stringify(model);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('post');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data }));
chai_1.expect(request.config.params).to.include({ format: 'json', modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('post');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data }));
(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: 'xml', modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: 'xml', modeluri });
done();

@@ -153,3 +171,3 @@ });

it('update', done => {
const modeluri = 'delete/me/please';
const modeluri = new urijs_1.default('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -161,9 +179,9 @@ const data = JSON.stringify(model);

let request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('patch');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data }));
chai_1.expect(request.config.params).to.include({ format: 'json', modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
(0, chai_1.expect)(request.config.method).to.be.equal('patch');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data }));
(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.MODEL_CRUD);
request = moxios_1.default.requests.at(1);
chai_1.expect(request.config.params).to.include({ format: 'xml', modeluri });
(0, chai_1.expect)(request.config.params).to.include({ format: 'xml', modeluri });
done();

@@ -173,10 +191,10 @@ });

it('save', done => {
const modeluri = 'save/me/please';
const modeluri = new urijs_1.default('save/me/please');
client.save(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE);
done();

@@ -189,6 +207,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE_ALL);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SAVE_ALL);
done();

@@ -198,10 +216,10 @@ });

it('validate', done => {
const modeluri = 'validate/me/please';
const modeluri = new urijs_1.default('validate/me/please');
client.validate(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION);
done();

@@ -211,10 +229,10 @@ });

it('getValidationConstraints', done => {
const modeluri = 'validate/me/please';
const modeluri = new urijs_1.default('validate/me/please');
client.getValidationConstraints(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION_CONSTRAINTS);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.VALIDATION_CONSTRAINTS);
done();

@@ -224,10 +242,10 @@ });

it('getTypeSchema', done => {
const modeluri = 'my/model/uri';
const modeluri = new urijs_1.default('my/model/uri');
client.getTypeSchema(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.TYPE_SCHEMA);
done();

@@ -241,6 +259,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.include({ schemaname });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UI_SCHEMA);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.include({ schemaname });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UI_SCHEMA);
done();

@@ -251,4 +269,4 @@ });

const configuration = {
workspaceRoot: 'myRoot',
uiSchemaFolder: 'mySchemaFolder'
workspaceRoot: new urijs_1.default('myRoot'),
uiSchemaFolder: new urijs_1.default('mySchemaFolder')
};

@@ -258,7 +276,10 @@ client.configureServer(configuration);

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('put');
chai_1.expect(request.config.data).to.equal(JSON.stringify(configuration));
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE);
(0, chai_1.expect)(request.config.method).to.be.equal('put');
(0, chai_1.expect)(request.config.data).to.equal(JSON.stringify({
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder.toString()
}));
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_CONFIGURE);
done();

@@ -271,6 +292,6 @@ });

const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.undefined;
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_PING);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.SERVER_PING);
done();

@@ -280,3 +301,3 @@ });

it('edit', done => {
const modeluri = 'edit/me/please';
const modeluri = new urijs_1.default('edit/me/please');
const command = new command_model_1.SetCommand({

@@ -289,7 +310,7 @@ eClass: 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow',

const request = moxios_1.default.requests.at(0);
chai_1.expect(request.config.method).to.be.equal('patch');
chai_1.expect(request.config.data).to.be.equal(JSON.stringify({ data: command }));
chai_1.expect(request.config.params).to.include({ format: 'json', modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.EDIT);
(0, chai_1.expect)(request.config.method).to.be.equal('patch');
(0, chai_1.expect)(request.config.data).to.be.equal(JSON.stringify({ data: command }));
(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.EDIT);
done();

@@ -299,10 +320,10 @@ });

it('undo', done => {
const modeluri = 'undo/me/please';
const modeluri = new urijs_1.default('undo/me/please');
client.undo(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UNDO);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.UNDO);
done();

@@ -312,10 +333,10 @@ });

it('redo', done => {
const modeluri = 'redo/me/please';
const modeluri = new urijs_1.default('redo/me/please');
client.redo(modeluri);
moxios_1.default.wait(() => {
const request = moxios_1.default.requests.mostRecent();
chai_1.expect(request.config.method).to.be.equal('get');
chai_1.expect(request.config.params).to.be.include({ modeluri });
chai_1.expect(request.config.baseURL).to.be.equal(baseUrl);
chai_1.expect(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.REDO);
(0, chai_1.expect)(request.config.method).to.be.equal('get');
(0, chai_1.expect)(request.config.params).to.be.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl.toString());
(0, chai_1.expect)(request.config.url).to.be.equal(model_server_paths_1.ModelServerPaths.REDO);
done();

@@ -326,3 +347,3 @@ });

describe('test responses', () => {
it('ping ', done => {
it('ping', done => {
const expectedMsg = {

@@ -332,3 +353,3 @@ data: '',

};
const onFulfilled = sinon_1.spy();
const onFulfilled = (0, sinon_1.spy)();
client.ping().then(onFulfilled);

@@ -341,3 +362,3 @@ moxios_1.default.wait(async () => {

});
assert_1.strictEqual(onFulfilled.getCall(0).args[0], true);
(0, assert_1.strictEqual)(onFulfilled.getCall(0).args[0], true);
done();

@@ -348,3 +369,3 @@ });

const model1 = {
modelUri: 'path/to/model1',
modeluri: 'file:/path/to/model1',
content: {

@@ -355,3 +376,3 @@ name: 'coffee'

const model2 = {
modelUri: 'path/to/model2',
modeluri: 'file:/path/to/model2',
content: {

@@ -363,8 +384,8 @@ name: 'coffee'

data: {
[model1.modelUri]: model1.content,
[model2.modelUri]: model2.content
[model1.modeluri]: model1.content,
[model2.modeluri]: model2.content
},
type: 'success'
};
const onFulfilled = sinon_1.spy();
const onFulfilled = (0, sinon_1.spy)();
client.getAll().then(onFulfilled);

@@ -378,3 +399,4 @@ moxios_1.default.wait(async () => {

const result = onFulfilled.getCall(0).args[0];
chai_1.expect(result).to.deep.include.members([model2, model1]);
(0, chai_1.expect)(result).to.be.an('array').of.length(2);
(0, chai_1.expect)(result).to.deep.include.members([model1, model2]);
done();

@@ -381,0 +403,0 @@ });

@@ -0,1 +1,2 @@

import URI from 'urijs';
import { ModelUpdateResult } from './model-server-client-api-v2';

@@ -54,3 +55,3 @@ import * as Type from './utils/type-util';

/** The uri of the model. */
modelUri: string;
modeluri: string;
/** The model content. */

@@ -66,2 +67,3 @@ content: C;

function is(object: unknown): object is Model;
function toString(model: Model): string;
}

@@ -71,3 +73,3 @@ /**

*/
export declare type Mapper<M, D = unknown> = (message: M) => D;
export type Mapper<M, D = unknown> = (message: M) => D;
/**

@@ -80,3 +82,3 @@ * A Mapper which directly returns the message.

*/
export declare type MessageDataMapper<D = unknown> = (message: ModelServerMessage) => D;
export type MessageDataMapper<D = unknown> = (message: ModelServerMessage) => D;
/**

@@ -114,2 +116,9 @@ * A collection of utility functions to map the `data` property of a {@link ModelServerMessage} to a specific type.

/**
* Maps the {@link ModelServerMessage.data} property of the given message to a URI[].
* @param message The message to map.
* @returns The `data` property as `URI[]`.
* @throws {@link Error} if the 'data' property is not an URI array.
*/
function asURIArray(message: ModelServerMessage): URI[];
/**
* Maps the {@link ModelServerMessage.data} property of the given message to an {@link AnyObject}.

@@ -116,0 +125,0 @@ * @param message The message to map.

"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {

@@ -17,3 +21,3 @@ if (k2 === undefined) k2 = k;

var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);

@@ -91,5 +95,9 @@ return result;

function is(object) {
return Type.AnyObject.is(object) && Type.isString(object, 'modelUri') && Type.isObject(object, 'content');
return Type.AnyObject.is(object) && Type.isString(object, 'modeluri') && Type.isObject(object, 'content');
}
Model.is = is;
function toString(model) {
return JSON.stringify(model, undefined, 2);
}
Model.toString = toString;
})(Model = exports.Model || (exports.Model = {}));

@@ -99,3 +107,4 @@ /**

*/
exports.IdentityMapper = m => m;
const IdentityMapper = m => m;
exports.IdentityMapper = IdentityMapper;
/**

@@ -146,2 +155,12 @@ * A collection of utility functions to map the `data` property of a {@link ModelServerMessage} to a specific type.

/**
* Maps the {@link ModelServerMessage.data} property of the given message to a URI[].
* @param message The message to map.
* @returns The `data` property as `URI[]`.
* @throws {@link Error} if the 'data' property is not an URI array.
*/
function asURIArray(message) {
return Type.asURIArray(message.data);
}
MessageDataMapper.asURIArray = asURIArray;
/**
* Maps the {@link ModelServerMessage.data} property of the given message to an {@link AnyObject}.

@@ -192,10 +211,15 @@ * @param message The message to map.

const patch = data ? data.patch : undefined;
if (patch && patch_utils_1.Operations.isPatch(patch)) {
const allPatches = data ? data.allPatches : undefined;
if (patch || allPatches) {
return {
success: isSuccess(message),
patch,
patchModel: (oldModel, copy) => {
const modelToPatch = copy ? fast_json_patch_1.deepClone(oldModel) : oldModel;
return jsonpatch.applyPatch(modelToPatch, patch).newDocument;
}
patchModel: (oldModel, copy, modeluri) => {
const modelToPatch = copy ? (0, fast_json_patch_1.deepClone)(oldModel) : oldModel;
const patchToApply = modeluri ? getPatch(allPatches, modeluri) : patch_utils_1.Operations.isPatch(patch) ? patch : undefined;
return patchToApply
? jsonpatch.applyPatch(modelToPatch, patchToApply).newDocument
: modelToPatch;
},
allPatches
};

@@ -212,3 +236,7 @@ }

MessageDataMapper.patchModel = patchModel;
function getPatch(patches, modeluri) {
var _a;
return (_a = patches.find(mp => mp.modelUri === modeluri.toString())) === null || _a === void 0 ? void 0 : _a.patch;
}
})(MessageDataMapper = exports.MessageDataMapper || (exports.MessageDataMapper = {}));
//# sourceMappingURL=model-server-message.js.map

@@ -12,2 +12,3 @@ /********************************************************************************

import { Operation } from 'fast-json-patch';
import * as URI from 'urijs';
import { ModelServerObjectV2 } from '.';

@@ -23,3 +24,3 @@ import { CommandExecutionResult } from './model/command-model';

export interface ModelServerNotification {
modelUri: string;
modeluri: URI;
type: string;

@@ -119,3 +120,3 @@ }

*/
export declare type UnknownNotification = ModelServerNotification & ModelServerMessage;
export type UnknownNotification = ModelServerNotification & ModelServerMessage;
export declare namespace UnknownNotification {

@@ -122,0 +123,0 @@ function is(object?: unknown): object is UnknownNotification;

@@ -9,3 +9,3 @@ "use strict";

function is(object) {
return type_util_1.AnyObject.is(object) && type_util_1.isString(object, 'modelUri') && type_util_1.isString(object, 'type');
return type_util_1.AnyObject.is(object) && (0, type_util_1.isObject)(object, 'modeluri') && (0, type_util_1.isString)(object, 'type');
}

@@ -12,0 +12,0 @@ ModelServerNotification.is = is;

@@ -1,2 +0,2 @@

export declare type DataValueType = boolean | number | string;
export type DataValueType = boolean | number | string;
export declare class ModelServerObject {

@@ -3,0 +3,0 @@ readonly eClass: string;

@@ -17,3 +17,3 @@ "use strict";

static is(object) {
return type_util_1.AnyObject.is(object) && type_util_1.isString(object, 'eClass');
return type_util_1.AnyObject.is(object) && (0, type_util_1.isString)(object, 'eClass');
}

@@ -37,3 +37,3 @@ }

static is(object) {
return type_util_1.AnyObject.is(object) && type_util_1.isString(object, '$type');
return type_util_1.AnyObject.is(object) && (0, type_util_1.isString)(object, '$type');
}

@@ -47,3 +47,3 @@ }

static is(object) {
return type_util_1.AnyObject.is(object) && type_util_1.isString(object, '$type') && type_util_1.isString(object, '$id');
return type_util_1.AnyObject.is(object) && (0, type_util_1.isString)(object, '$type') && (0, type_util_1.isString)(object, '$id');
}

@@ -63,3 +63,3 @@ }

static is(object) {
return type_util_1.AnyObject.is(object) && type_util_1.isString(object, '$type') && type_util_1.isString(object, '$ref');
return type_util_1.AnyObject.is(object) && (0, type_util_1.isString)(object, '$type') && (0, type_util_1.isString)(object, '$ref');
}

@@ -66,0 +66,0 @@ }

@@ -54,3 +54,3 @@ import { DataValueType, ModelServerObject, ModelServerReferenceDescription } from './base-model';

static readonly TYPE = "set";
constructor(owner: ModelServerReferenceDescription, feature: string, changedValues: DataValueType[] | ModelServerReferenceDescription[]);
constructor(owner: ModelServerReferenceDescription, feature: string, changedValues: DataValueType[] | ModelServerReferenceDescription[] | ModelServerObject[]);
static is(object?: unknown): object is ModelServerCommand;

@@ -57,0 +57,0 @@ }

@@ -69,3 +69,3 @@ "use strict";

this.feature = feature;
if (model_server_utils_1.isNumberArray(toDelete)) {
if ((0, model_server_utils_1.isNumberArray)(toDelete)) {
this.indices = toDelete;

@@ -91,3 +91,3 @@ }

}
if (model_server_utils_1.isModelServerObjectArray(toAdd)) {
if ((0, model_server_utils_1.isModelServerObjectArray)(toAdd)) {
const objectValues = toAdd.map((o, i) => new base_model_1.ModelServerReferenceDescription(o.eClass, `//@objectsToAdd.${i}`));

@@ -112,5 +112,8 @@ this.objectsToAdd = toAdd;

this.feature = feature;
if (model_server_utils_1.isModelServerReferenceDescriptionArray(changedValues)) {
if ((0, model_server_utils_1.isModelServerReferenceDescriptionArray)(changedValues)) {
this.objectValues = changedValues;
}
else if ((0, model_server_utils_1.isModelServerObjectArray)(changedValues)) {
this.objectsToAdd = changedValues;
}
else {

@@ -117,0 +120,0 @@ this.dataValues = changedValues;

@@ -34,9 +34,9 @@ "use strict";

return (type_util_1.AnyObject.is(object) &&
type_util_1.isNumber(object, 'severity') &&
type_util_1.isString(object, 'message') &&
type_util_1.isString(object, 'source') &&
type_util_1.isNumber(object, 'code') &&
type_util_1.isArray(object, 'data') &&
type_util_1.isArray(object, 'children') &&
type_util_1.isString(object, 'id'));
(0, type_util_1.isNumber)(object, 'severity') &&
(0, type_util_1.isString)(object, 'message') &&
(0, type_util_1.isString)(object, 'source') &&
(0, type_util_1.isNumber)(object, 'code') &&
(0, type_util_1.isArray)(object, 'data') &&
(0, type_util_1.isArray)(object, 'children') &&
(0, type_util_1.isString)(object, 'id'));
}

@@ -43,0 +43,0 @@ Diagnostic.is = is;

@@ -18,9 +18,9 @@ "use strict";

const ok = diagnostic_1.Diagnostic.ok();
chai_1.expect(ok.severity).to.be.equal(diagnostic_1.OK);
chai_1.expect(ok.source).to.be.empty;
chai_1.expect(ok.code).to.be.equal(0);
chai_1.expect(ok.children).to.be.empty;
chai_1.expect(ok.data).to.be.empty;
chai_1.expect(ok.exception).to.be.undefined;
chai_1.expect(ok.message).to.be.equal('OK');
(0, chai_1.expect)(ok.severity).to.be.equal(diagnostic_1.OK);
(0, chai_1.expect)(ok.source).to.be.empty;
(0, chai_1.expect)(ok.code).to.be.equal(0);
(0, chai_1.expect)(ok.children).to.be.empty;
(0, chai_1.expect)(ok.data).to.be.empty;
(0, chai_1.expect)(ok.exception).to.be.undefined;
(0, chai_1.expect)(ok.message).to.be.equal('OK');
});

@@ -30,3 +30,3 @@ describe('merge', () => {

const merged = diagnostic_1.Diagnostic.merge();
chai_1.expect(merged).to.be.eql(diagnostic_1.Diagnostic.ok());
(0, chai_1.expect)(merged).to.be.eql(diagnostic_1.Diagnostic.ok());
});

@@ -36,3 +36,3 @@ it('one arg', () => {

const merged = diagnostic_1.Diagnostic.merge(only);
chai_1.expect(merged).to.be.eql(only);
(0, chai_1.expect)(merged).to.be.eql(only);
});

@@ -44,5 +44,5 @@ it('several args', () => {

const merged = diagnostic_1.Diagnostic.merge(warning, ok, error);
chai_1.expect(merged.severity).to.be.equal(diagnostic_1.ERROR);
chai_1.expect(merged.source).to.be.equal('c');
chai_1.expect(merged.children).to.be.eql([warning, error]);
(0, chai_1.expect)(merged.severity).to.be.equal(diagnostic_1.ERROR);
(0, chai_1.expect)(merged.source).to.be.equal('c');
(0, chai_1.expect)(merged.children).to.be.eql([warning, error]);
});

@@ -53,3 +53,3 @@ });

const worst = diagnostic_1.Diagnostic.worstOf([]);
chai_1.expect(worst).to.be.eql(diagnostic_1.Diagnostic.ok());
(0, chai_1.expect)(worst).to.be.eql(diagnostic_1.Diagnostic.ok());
});

@@ -59,3 +59,3 @@ it('one arg', () => {

const worst = diagnostic_1.Diagnostic.worstOf([only]);
chai_1.expect(worst).to.be.equal(only);
(0, chai_1.expect)(worst).to.be.equal(only);
});

@@ -67,3 +67,3 @@ it('several args', () => {

const worst = diagnostic_1.Diagnostic.worstOf([warning, ok, error]);
chai_1.expect(worst).to.be.equal(error);
(0, chai_1.expect)(worst).to.be.equal(error);
});

@@ -70,0 +70,0 @@ });

import WebSocket from 'isomorphic-ws';
import URI from 'urijs';
import { CloseNotification, DirtyStateNotification, ErrorNotification, FullUpdateNotification, IncrementalUpdateNotification, IncrementalUpdateNotificationV2, ModelServerNotification, UnknownNotification, ValidationNotification } from './model-server-notification';

@@ -9,6 +10,6 @@ /**

export interface SubscriptionListener {
onOpen(modelUri: string, event: WebSocket.Event): void;
onClose(modelUri: string, event: WebSocket.CloseEvent): void;
onError(modelUri: string, event: WebSocket.ErrorEvent): void;
onMessage(modelUri: string, event: WebSocket.MessageEvent): void;
onOpen(modeluri: URI, event: WebSocket.Event): void;
onClose(modeluri: URI, event: WebSocket.CloseEvent): void;
onError(modeluri: URI, event: WebSocket.ErrorEvent): void;
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void;
}

@@ -74,6 +75,6 @@ /**

constructor(notificationListener?: ModelServerNotificationListener);
onOpen(modelUri: string, _event: WebSocket.Event): void;
onClose(modelUri: string, event: WebSocket.CloseEvent): void;
onError(modelUri: string, event: WebSocket.ErrorEvent): void;
onMessage(modelUri: string, event: WebSocket.MessageEvent): void;
onOpen(modeluri: URI, _event: WebSocket.Event): void;
onClose(modeluri: URI, event: WebSocket.CloseEvent): void;
onError(modeluri: URI, event: WebSocket.ErrorEvent): void;
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void;
}

@@ -90,3 +91,3 @@ /**

constructor(notificationListener?: ModelServerNotificationListenerV2);
onMessage(modelUri: string, event: WebSocket.MessageEvent): void;
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void;
}

@@ -93,0 +94,0 @@ /**

@@ -16,5 +16,5 @@ "use strict";

const _1 = require(".");
const model_server_message_1 = require("./model-server-message");
const command_model_1 = require("./model/command-model");
const diagnostic_1 = require("./model/diagnostic");
const model_server_message_1 = require("./model-server-message");
/**

@@ -29,15 +29,15 @@ * Default implementation of {@link SubscriptionListener} that maps received websocket events to the

}
onOpen(modelUri, _event) {
onOpen(modeluri, _event) {
var _a, _b;
(_b = (_a = this.notificationListener).onOpen) === null || _b === void 0 ? void 0 : _b.call(_a, { modelUri, type: model_server_message_1.MessageType.open });
(_b = (_a = this.notificationListener).onOpen) === null || _b === void 0 ? void 0 : _b.call(_a, { modeluri, type: model_server_message_1.MessageType.open });
}
onClose(modelUri, event) {
onClose(modeluri, event) {
var _a, _b;
(_b = (_a = this.notificationListener).onClose) === null || _b === void 0 ? void 0 : _b.call(_a, { modelUri, code: event.code, reason: event.reason, type: model_server_message_1.MessageType.close });
(_b = (_a = this.notificationListener).onClose) === null || _b === void 0 ? void 0 : _b.call(_a, { modeluri, code: event.code, reason: event.reason, type: model_server_message_1.MessageType.close });
}
onError(modelUri, event) {
onError(modeluri, event) {
var _a, _b;
(_b = (_a = this.notificationListener).onError) === null || _b === void 0 ? void 0 : _b.call(_a, { modelUri, error: event.error, type: model_server_message_1.MessageType.error });
(_b = (_a = this.notificationListener).onError) === null || _b === void 0 ? void 0 : _b.call(_a, { modeluri, error: event.error, type: model_server_message_1.MessageType.error });
}
onMessage(modelUri, event) {
onMessage(modeluri, event) {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;

@@ -49,3 +49,3 @@ const message = JSON.parse(event.data.toString());

case model_server_message_1.MessageType.dirtyState: {
(_b = (_a = this.notificationListener).onDirtyStateChanged) === null || _b === void 0 ? void 0 : _b.call(_a, { modelUri, isDirty: model_server_message_1.MessageDataMapper.asBoolean(message), type });
(_b = (_a = this.notificationListener).onDirtyStateChanged) === null || _b === void 0 ? void 0 : _b.call(_a, { modeluri, isDirty: model_server_message_1.MessageDataMapper.asBoolean(message), type });
break;

@@ -55,7 +55,7 @@ }

case model_server_message_1.MessageType.success: {
(_d = (_c = this.notificationListener).onSuccess) === null || _d === void 0 ? void 0 : _d.call(_c, { modelUri, type });
(_d = (_c = this.notificationListener).onSuccess) === null || _d === void 0 ? void 0 : _d.call(_c, { modeluri, type });
break;
}
case model_server_message_1.MessageType.error: {
(_f = (_e = this.notificationListener).onError) === null || _f === void 0 ? void 0 : _f.call(_e, { modelUri, error: model_server_message_1.MessageDataMapper.asString(message), type });
(_f = (_e = this.notificationListener).onError) === null || _f === void 0 ? void 0 : _f.call(_e, { modeluri, error: model_server_message_1.MessageDataMapper.asString(message), type });
break;

@@ -65,3 +65,3 @@ }

(_h = (_g = this.notificationListener).onIncrementalUpdate) === null || _h === void 0 ? void 0 : _h.call(_g, {
modelUri,
modeluri,
result: model_server_message_1.MessageDataMapper.as(message, command_model_1.CommandExecutionResult.is),

@@ -73,11 +73,11 @@ type

case model_server_message_1.MessageType.fullUpdate: {
(_k = (_j = this.notificationListener).onFullUpdate) === null || _k === void 0 ? void 0 : _k.call(_j, { modelUri, model: model_server_message_1.MessageDataMapper.asObject(message), type });
(_k = (_j = this.notificationListener).onFullUpdate) === null || _k === void 0 ? void 0 : _k.call(_j, { modeluri, model: model_server_message_1.MessageDataMapper.asObject(message), type });
break;
}
case model_server_message_1.MessageType.validationResult: {
(_m = (_l = this.notificationListener).onValidation) === null || _m === void 0 ? void 0 : _m.call(_l, { modelUri, diagnostic: model_server_message_1.MessageDataMapper.as(message, diagnostic_1.Diagnostic.is), type });
(_m = (_l = this.notificationListener).onValidation) === null || _m === void 0 ? void 0 : _m.call(_l, { modeluri, diagnostic: model_server_message_1.MessageDataMapper.as(message, diagnostic_1.Diagnostic.is), type });
break;
}
default: {
(_p = (_o = this.notificationListener).onUnknown) === null || _p === void 0 ? void 0 : _p.call(_o, Object.assign(Object.assign({}, message), { modelUri }));
(_p = (_o = this.notificationListener).onUnknown) === null || _p === void 0 ? void 0 : _p.call(_o, Object.assign(Object.assign({}, message), { modeluri }));
}

@@ -101,3 +101,3 @@ }

}
onMessage(modelUri, event) {
onMessage(modeluri, event) {
var _a, _b;

@@ -112,7 +112,7 @@ const message = JSON.parse(event.data.toString());

type: message.type,
modelUri,
modeluri,
patch,
patchModel: (model, copy) => {
const modelToPatch = copy ? fast_json_patch_1.deepClone(model) : model;
return fast_json_patch_1.applyPatch(modelToPatch, patch).newDocument;
const modelToPatch = copy ? (0, fast_json_patch_1.deepClone)(model) : model;
return (0, fast_json_patch_1.applyPatch)(modelToPatch, patch).newDocument;
}

@@ -123,3 +123,3 @@ });

default: {
super.onMessage(modelUri, event);
super.onMessage(modeluri, event);
}

@@ -126,0 +126,0 @@ }

@@ -14,3 +14,3 @@ /********************************************************************************

export declare function isModelServerObjectArray(array: Array<DataValueType | ModelServerObject>): array is ModelServerObject[];
export declare function isModelServerReferenceDescriptionArray(array: Array<DataValueType | ModelServerReferenceDescription>): array is ModelServerReferenceDescription[];
export declare function isModelServerReferenceDescriptionArray(array: Array<DataValueType | ModelServerReferenceDescription | ModelServerObject>): array is ModelServerReferenceDescription[];
//# sourceMappingURL=model-server-utils.d.ts.map

@@ -12,2 +12,3 @@ /********************************************************************************

import { AddOperation, Operation, RemoveOperation, ReplaceOperation } from 'fast-json-patch';
import URI from 'urijs';
import { ModelServerObjectV2, ModelServerReferenceDescriptionV2 } from '../model/base-model';

@@ -30,3 +31,3 @@ import { AnyObject, TypeGuard } from './type-util';

*/
export declare function replace<T>(modeluri: string, object: ModelServerObjectV2, feature: string, value: T): ReplaceOperation<T>;
export declare function replace<T>(modeluri: URI, object: ModelServerObjectV2, feature: string, value: T): ReplaceOperation<T>;
/**

@@ -41,3 +42,3 @@ * Create an AddOperation, to create a new object of the specified type, in the specified parent.

*/
export declare function create(modeluri: string, parent: ModelServerObjectV2, feature: string, $type: string, attributes?: AnyObject): AddOperation<TypeDefinition>;
export declare function create(modeluri: URI, parent: ModelServerObjectV2, feature: string, $type: string, attributes?: AnyObject): AddOperation<TypeDefinition>;
/**

@@ -51,3 +52,3 @@ * Create an AddOperation, to add an existing object of the specified type, in the specified parent.

*/
export declare function add(modeluri: string, parent: ModelServerObjectV2, feature: string, value: ModelServerObjectV2 | ModelServerReferenceDescriptionV2): AddOperation<ModelServerObjectV2>;
export declare function add(modeluri: URI, parent: ModelServerObjectV2, feature: string, value: ModelServerObjectV2 | ModelServerReferenceDescriptionV2): AddOperation<ModelServerObjectV2>;
/**

@@ -59,3 +60,3 @@ * Create a RemoveOperation, to delete an object from the model.

*/
export declare function deleteElement(modeluri: string, object: ModelServerObjectV2): RemoveOperation;
export declare function deleteElement(modeluri: URI, object: ModelServerObjectV2): RemoveOperation;
/**

@@ -68,3 +69,3 @@ * Create a RemoveOperation, to remove a value from a list.

*/
export declare function removeValueAt(modeluri: string, object: ModelServerObjectV2, feature: string, index: number): RemoveOperation;
export declare function removeValueAt(modeluri: URI, object: ModelServerObjectV2, feature: string, index: number): RemoveOperation;
/**

@@ -77,3 +78,3 @@ * Create a RemoveOperation, to remove a value from a list.

*/
export declare function removeValue(modeluri: string, object: ModelServerObjectV2, feature: string, value: AnyObject): RemoveOperation | undefined;
export declare function removeValue(modeluri: URI, object: ModelServerObjectV2, feature: string, value: AnyObject): RemoveOperation | undefined;
/**

@@ -84,3 +85,3 @@ * Create a RemoveOperation, to delete an object from the model.

*/
export declare function removeObject(modeluri: string, objectToRemove: ModelServerObjectV2): RemoveOperation;
export declare function removeObject(modeluri: URI, objectToRemove: ModelServerObjectV2): RemoveOperation;
/**

@@ -87,0 +88,0 @@ * Utility functions for working with JSON Patch operations.

@@ -133,3 +133,3 @@ "use strict";

const id = base_model_1.ModelServerReferenceDescriptionV2.is(object) ? object.$ref : object.$id;
return `${modeluri}#${id}`;
return modeluri.clone().fragment(id).toString();
}

@@ -136,0 +136,0 @@ /**

@@ -11,2 +11,3 @@ /********************************************************************************

*******************************************************************************/
import URI from 'urijs';
import { Format } from '../model-server-client-api-v2';

@@ -19,3 +20,3 @@ import { Model } from '../model-server-message';

*/
export declare type AnyObject = Record<PropertyKey, unknown>;
export type AnyObject = Record<PropertyKey, unknown>;
export declare namespace AnyObject {

@@ -34,3 +35,3 @@ /**

*/
export declare type TypeGuard<T> = (object: unknown) => object is T;
export type TypeGuard<T> = (object: unknown) => object is T;
/**

@@ -100,4 +101,23 @@ * Validates whether the given object as a property of type `string` with the given key.

export declare function asModelArray(object: unknown): Model[];
/**
* Validates whether the given object is a (deferred) instance of an URI object.
* @param object The object that should be validated
* @returns `true` if the object is an instance of URI
*/
export declare function isURI(object: unknown): object is URI;
/**
* Maps the given object to an `URI` object.
* @param obj The object to map
* @returns The object as `URI`
*/
export declare function asURI(obj: unknown): URI;
/**
* Maps the given object to a `string` array.
* @param object The object to map
* @returns The object as `URI` array
* @throws {@link Error} if the given object is not an array
*/
export declare function asURIArray(object: unknown): URI[];
/** Protocol of a message encoder. */
export declare type Encoder<T = unknown> = (object: string | AnyObject) => T | string;
export type Encoder<T = unknown> = (object: string | AnyObject) => T | string;
/**

@@ -104,0 +124,0 @@ * Obtain a message encoder for the request body.

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.encode = exports.encodeRequestBody = exports.asModelArray = exports.asType = exports.asObject = exports.asStringArray = exports.asString = exports.isArray = exports.isObject = exports.isNumber = exports.isBoolean = exports.isString = exports.AnyObject = void 0;
/********************************************************************************

@@ -14,3 +12,10 @@ * Copyright (c) 2021-2022 STMicroelectronics and others.

*******************************************************************************/
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.encode = exports.encodeRequestBody = exports.asURIArray = exports.asURI = exports.isURI = exports.asModelArray = exports.asType = exports.asObject = exports.asStringArray = exports.asString = exports.isArray = exports.isObject = exports.isNumber = exports.isBoolean = exports.isString = exports.AnyObject = void 0;
const urijs_1 = __importDefault(require("urijs"));
const model_server_client_api_v2_1 = require("../model-server-client-api-v2");
const model_server_message_1 = require("../model-server-message");
var AnyObject;

@@ -88,2 +93,15 @@ (function (AnyObject) {

}
if (model_server_message_1.Model.is(object)) {
return model_server_message_1.Model.toString(object);
}
if (Array.isArray(object) && object.every(model_server_message_1.Model.is)) {
return object.map(e => model_server_message_1.Model.toString(e)).toString();
}
if (isURI(object)) {
return asURI(object).toString();
}
if (Array.isArray(object) && object.every(isURI)) {
const uriArray = object.map(e => asURI(e).toString());
return JSON.stringify(uriArray, undefined, 2);
}
return JSON.stringify(object, undefined, 2);

@@ -134,3 +152,3 @@ }

if (AnyObject.is(object)) {
return Object.entries(object).map(entry => ({ modelUri: entry[0], content: entry[1] }));
return Object.entries(object).map(entry => ({ modeluri: entry[0], content: entry[1] }));
}

@@ -141,2 +159,40 @@ throw new Error('Cannot map to Model[]. The given object is no defined or of type "object"!');

/**
* Validates whether the given object is a (deferred) instance of an URI object.
* @param object The object that should be validated
* @returns `true` if the object is an instance of URI
*/
function isURI(object) {
return AnyObject.is(object) && isObject(object, '_parts') && isBoolean(object, '_deferred_build') && isString(object, '_string');
}
exports.isURI = isURI;
/**
* Maps the given object to an `URI` object.
* @param obj The object to map
* @returns The object as `URI`
*/
function asURI(obj) {
if (typeof obj === 'string') {
return new urijs_1.default(obj);
}
// reconstruct if URI object was deferred
if (isURI(obj)) {
return new urijs_1.default(obj._parts);
}
throw new Error('Cannot map to URI. Given parameter is not an URI!');
}
exports.asURI = asURI;
/**
* Maps the given object to a `string` array.
* @param object The object to map
* @returns The object as `URI` array
* @throws {@link Error} if the given object is not an array
*/
function asURIArray(object) {
if (Array.isArray(object)) {
return object.map(asURI);
}
throw new Error('Cannot map to URI[]. Given parameter is not an array!');
}
exports.asURIArray = asURIArray;
/**
* Obtain a message encoder for the request body.

@@ -143,0 +199,0 @@ *

@@ -24,4 +24,4 @@ "use strict";

const object = { eClass: 'Foo', name: 'test', nested: [{ eClass: 'Nested', name: 'inner', tags, emptyArray, nada, emptyObj }] };
const encoded = type_util_1.encode('json')(object);
chai_1.expect(encoded).to.be.equal(encoded);
const encoded = (0, type_util_1.encode)('json')(object);
(0, chai_1.expect)(encoded).to.be.equal(encoded);
});

@@ -31,4 +31,4 @@ it('JSON v1 as JSON v2', () => {

const expected = { $type: 'Foo', name: 'test', nested: [{ $type: 'Nested', name: 'inner', tags, emptyArray, nada, emptyObj }] };
const encoded = type_util_1.encode('json-v2')(object);
chai_1.expect(encoded).to.be.eql(expected);
const encoded = (0, type_util_1.encode)('json-v2')(object);
(0, chai_1.expect)(encoded).to.be.eql(expected);
});

@@ -42,9 +42,9 @@ it('JSON v2 as JSON v1', () => {

};
const encoded = type_util_1.encode('json')(object);
chai_1.expect(encoded).to.be.eql(expected);
const encoded = (0, type_util_1.encode)('json')(object);
(0, chai_1.expect)(encoded).to.be.eql(expected);
});
it('JSON v2 as JSON v2', () => {
const object = { $type: 'Foo', name: 'test', nested: [{ $type: 'Nested', name: 'inner', tags, emptyArray, nada, emptyObj }] };
const encoded = type_util_1.encode('json-v2')(object);
chai_1.expect(encoded).to.be.equal(encoded);
const encoded = (0, type_util_1.encode)('json-v2')(object);
(0, chai_1.expect)(encoded).to.be.equal(encoded);
});

@@ -64,4 +64,4 @@ });

});
const encoded = type_util_1.encode('json')(object);
chai_1.expect(encoded).to.be.equal(encoded);
const encoded = (0, type_util_1.encode)('json')(object);
(0, chai_1.expect)(encoded).to.be.equal(encoded);
});

@@ -75,5 +75,5 @@ it('JSON v1 as JSON v2', () => {

const expected = { $type: 'Foo', name: 'test', nested: { $type: 'Nested', name: 'inner', tags, emptyArray, nada, emptyObj } };
const encoded = type_util_1.encode('json-v2')(object);
chai_1.expect(encoded).to.be.a('string');
chai_1.expect(JSON.parse(encoded)).to.be.eql(expected);
const encoded = (0, type_util_1.encode)('json-v2')(object);
(0, chai_1.expect)(encoded).to.be.a('string');
(0, chai_1.expect)(JSON.parse(encoded)).to.be.eql(expected);
});

@@ -87,5 +87,5 @@ it('JSON v2 as JSON v1', () => {

const expected = { eClass: 'Foo', name: 'test', nested: { eClass: 'Nested', name: 'inner', tags, emptyArray, nada, emptyObj } };
const encoded = type_util_1.encode('json')(object);
chai_1.expect(encoded).to.be.a('string');
chai_1.expect(JSON.parse(encoded)).to.be.eql(expected);
const encoded = (0, type_util_1.encode)('json')(object);
(0, chai_1.expect)(encoded).to.be.a('string');
(0, chai_1.expect)(JSON.parse(encoded)).to.be.eql(expected);
});

@@ -98,4 +98,4 @@ it('JSON v2 as JSON v2', () => {

});
const encoded = type_util_1.encode('json-v2')(object);
chai_1.expect(encoded).to.be.equal(encoded);
const encoded = (0, type_util_1.encode)('json-v2')(object);
(0, chai_1.expect)(encoded).to.be.equal(encoded);
});

@@ -102,0 +102,0 @@ });

@@ -17,3 +17,3 @@ {

"bugs": "https://github.com/eclipse-emfcloud/emfcloud-modelserver-theia/issues",
"version": "0.8.0-next.9611b89d",
"version": "0.8.0-next.97b0990.90+97b0990",
"files": [

@@ -48,10 +48,13 @@ "lib",

"isomorphic-ws": "^4.0.1",
"ws": "^7.4.6"
"urijs": "^1.19.11",
"ws": "^8.5.0"
},
"devDependencies": {
"@types/moxios": "^0.4.14",
"@types/moxios": "0.4.14",
"@types/urijs": "^1.19.19",
"@types/ws": "8.2.2",
"ignore-styles": "^5.0.1",
"moxios": "^0.4.0",
"typescript": "^3.9.2"
"rimraf": "^3.0.2",
"typescript": "^4.6.3"
},

@@ -63,7 +66,7 @@ "scripts": {

"lint": "eslint --ext .ts,.tsx ./src",
"lint:fix": "eslint --fix --ext .ts,.tsx ./src",
"watch": "tsc -w",
"test": "mocha --config ../../configs/.mocharc.json",
"test:ci": "mocha --config ../../configs/.mocharc.ci.json"
}
},
"gitHead": "97b0990564698c437b700e51f16524d4893417fd"
}

@@ -11,5 +11,7 @@ /********************************************************************************

*******************************************************************************/
import URI from 'urijs';
import { MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { SubscriptionListener } from './subscription-listener';

@@ -32,3 +34,3 @@ import { AnyObject, TypeGuard } from './utils/type-util';

*/
initialize(baseUrl: string, defaultFormat?: string): void | Promise<void>;
initialize(baseUrl: URI, defaultFormat?: string): void | Promise<void>;

@@ -61,3 +63,3 @@ /**

*/
get(modeluri: string): Promise<AnyObject>;
get(modeluri: URI): Promise<AnyObject>;
/**

@@ -71,3 +73,3 @@ * Retrieves the {@link Model} for a given URI as typed JSON object

*/
get<M>(modeluri: string, typeGuard: TypeGuard<M>): Promise<M>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -80,3 +82,3 @@ * Retrieves the {@link Model} for a given URI in string representation derived from a given format (e.g. 'xml' or 'json').

*/
get(modeluri: string, format: string): Promise<string>;
get(modeluri: URI, format: string): Promise<string>;

@@ -87,3 +89,3 @@ /**

*/
getModelUris(): Promise<string[]>;
getModelUris(): Promise<URI[]>;

@@ -97,3 +99,3 @@ /**

*/
getElementById(modeluri: string, elementid: string): Promise<AnyObject>;
getElementById(modeluri: URI, elementid: string): Promise<AnyObject>;
/**

@@ -108,3 +110,3 @@ * Retrieves a specific model (sub)element by its `id` as typed JSON object.

*/
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -118,3 +120,3 @@ * Retrieves a specific model (sub)element by its `id` in string representation derived from a given format (e.g. 'xml' or 'json').

*/
getElementById(modeluri: string, elementid: string, format: string): Promise<string>;
getElementById(modeluri: URI, elementid: string, format: string): Promise<string>;

@@ -128,3 +130,3 @@ /**

*/
getElementByName(modeluri: string, elementname: string): Promise<AnyObject>;
getElementByName(modeluri: URI, elementname: string): Promise<AnyObject>;
/**

@@ -139,3 +141,3 @@ * Retrieves a specific model (sub)element by its `name` as typed JSON object.

*/
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
/**

@@ -149,3 +151,3 @@ * Retrieves a specific model (sub)element by its `name` in string representation derived from a given format (e.g. 'xml' or 'json').

*/
getElementByName(modeluri: string, elementname: string, format: string): Promise<string>;
getElementByName(modeluri: URI, elementname: string, format: string): Promise<string>;

@@ -157,3 +159,3 @@ /**

*/
delete(modeluri: string): Promise<boolean>;
delete(modeluri: URI): Promise<boolean>;

@@ -165,3 +167,3 @@ /**

*/
close(modeluri: string): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;

@@ -174,3 +176,3 @@ /**

*/
create(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
/**

@@ -185,3 +187,3 @@ * Creates a new model object with the given URI and content object in the current workspace.

*/
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -195,3 +197,3 @@ * Creates a new model object with the given URI and content string in the current workspace.

*/
create(modeluri: string, model: string, format: string): Promise<string>;
create(modeluri: URI, model: string, format: string): Promise<string>;

@@ -205,3 +207,3 @@ /**

*/
update(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
update(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
/**

@@ -217,3 +219,3 @@ * Updates an existing model with the given URI with the given content in the current workspace.

*/
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
/**

@@ -227,3 +229,3 @@ * Updates an existing model with the given URI with the given content string in the current workspace.

*/
update(modeluri: string, model: string, format: string): Promise<AnyObject>;
update(modeluri: URI, model: string, format: string): Promise<AnyObject>;

@@ -235,3 +237,3 @@ /**

*/
save(modeluri: string): Promise<boolean>;
save(modeluri: URI): Promise<boolean>;

@@ -249,3 +251,3 @@ /**

*/
validate(modeluri: string): Promise<Diagnostic>;
validate(modeluri: URI): Promise<Diagnostic>;

@@ -257,3 +259,3 @@ /**

*/
getValidationConstraints(modeluri: string): Promise<string>;
getValidationConstraints(modeluri: URI): Promise<string>;

@@ -267,3 +269,3 @@ /**

*/
getTypeSchema(modeluri: string): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;

@@ -297,3 +299,3 @@ /**

*/
edit(modeluri: string, command: ModelServerCommand): Promise<boolean>;
edit(modeluri: URI, command: ModelServerCommand): Promise<boolean>;

@@ -305,3 +307,3 @@ /**

*/
undo(modeluri: string): Promise<string>;
undo(modeluri: URI): Promise<string>;

@@ -313,3 +315,3 @@ /**

*/
redo(modeluri: string): Promise<string>;
redo(modeluri: URI): Promise<string>;

@@ -322,11 +324,11 @@ /**

*/
subscribe(modeluri: string, options?: SubscriptionOptions): void;
subscribe(modeluri: URI, options?: SubscriptionOptions): void;
/**
* Can be used to send arbitrary {@link ModelServerMessage}s to the model server via a subscription channel.
* @param modelUri The URI of the subscribed model.
* @param modeluri The URI of the subscribed model.
* @param message The model server message that should be sent.
* @returns A boolean indicating whether the message submission was successful.
*/
send(modelUri: string, message: ModelServerMessage): boolean;
send(modeluri: URI, message: ModelServerMessage): boolean;

@@ -338,7 +340,7 @@ /**

*/
unsubscribe(modelUri: string): boolean;
unsubscribe(modeluri: URI): boolean;
}
export namespace ModelServerClientApiV1 {
export const API_ENDPOINT = '/api/v1';
export const API_ENDPOINT = 'api/v1';
}

@@ -364,4 +366,4 @@

export interface ServerConfiguration {
workspaceRoot: string;
uiSchemaFolder?: string;
workspaceRoot: URI;
uiSchemaFolder?: URI;
}

@@ -368,0 +370,0 @@

@@ -12,2 +12,3 @@ /********************************************************************************

import { Operation } from 'fast-json-patch';
import URI from 'urijs';

@@ -58,2 +59,12 @@ import { ModelServerElement } from './model/base-model';

/**
* A union type that represents all Patches or Commands supported by the model server:
* - Operation
* - Operation[] (Json Patch)
* - ModelPatch
* - ModelPatch[]
* - ModelServerCommand
*/
export type PatchOrCommand = Operation | Operation[] | ModelPatch | ModelPatch[] | ModelServerCommand;
/**
* Basic client API to interact with a model server that conforms to the Modelserver API Version 2.

@@ -65,3 +76,3 @@ */

* The given base url should point to the location of the model server API entry point.
* (e.g. `http://localhost:8081/api/v1/`). Once the initialization is completed the client is expected
* (e.g. `http://localhost:8081/api/v2/`). Once the initialization is completed the client is expected
* to be ready and should be able to handle REST requests to & responses from the model server.

@@ -73,3 +84,3 @@ * Any requests to the model server before the client has been initialized are expected to fail (i.e. throw an error)

*/
initialize(baseUrl: string, defaultFormat?: Format): void | Promise<void>;
initialize(baseUrl: URI, defaultFormat?: Format): void | Promise<void>;

@@ -83,32 +94,32 @@ /**

get(modeluri: string, format?: Format): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
get(modeluri: URI, format?: Format): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getModelUris(): Promise<string[]>;
getModelUris(): Promise<URI[]>;
getElementById(modeluri: string, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementById(modeluri: URI, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName(modeluri: string, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName(modeluri: URI, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
delete(modeluri: string): Promise<boolean>;
delete(modeluri: URI): Promise<boolean>;
close(modeluri: string): Promise<boolean>;
close(modeluri: URI): Promise<boolean>;
create(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
create(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
save(modeluri: string): Promise<boolean>;
save(modeluri: URI): Promise<boolean>;
saveAll(): Promise<boolean>;
validate(modeluri: string): Promise<Diagnostic>;
validate(modeluri: URI): Promise<Diagnostic>;
getValidationConstraints(modeluri: string): Promise<string>;
getValidationConstraints(modeluri: URI): Promise<string>;
getTypeSchema(modeluri: string): Promise<string>;
getTypeSchema(modeluri: URI): Promise<string>;

@@ -121,21 +132,35 @@ getUiSchema(schemaname: string): Promise<string>;

edit(modeluri: string, patch: Operation | Operation[], format?: Format): Promise<ModelUpdateResult>;
edit(modeluri: string, command: ModelServerCommand, format?: Format): Promise<ModelUpdateResult>;
edit(modeluri: URI, patchOrCommand: PatchOrCommand, format?: Format): Promise<ModelUpdateResult>;
undo(modeluri: string): Promise<ModelUpdateResult>;
undo(modeluri: URI): Promise<ModelUpdateResult>;
redo(modeluri: string): Promise<ModelUpdateResult>;
redo(modeluri: URI): Promise<ModelUpdateResult>;
// WebSocket connection
subscribe(modeluri: string, listener: SubscriptionListener, options?: SubscriptionOptionsV2): SubscriptionListener;
subscribe(modeluri: URI, listener: SubscriptionListener, options?: SubscriptionOptionsV2): SubscriptionListener;
send(modelUri: string, message: ModelServerMessage): void;
unsubscribe(modelUri: string): void;
send(modeluri: URI, message: ModelServerMessage): void;
unsubscribe(modeluri: URI): void;
}
export namespace ModelServerClientApiV2 {
export const API_ENDPOINT = '/api/v2';
export const API_ENDPOINT = 'api/v2';
}
/**
* A patch affecting a specific model.
*/
export interface ModelPatch {
/**
* The uri of the patched model.
*/
modelUri: string;
/**
* The patch describing the changes applied to the model.
*/
patch: Operation[];
}
/**
* Result sent to client after requesting a model update.

@@ -158,5 +183,8 @@ */

* the original model unchanged.
* @param modeluri the uri of the model to patch. This can be used when the model is split in multiple
* resources, to identify the patch to apply. The modeluri should correspond to the oldModel object.
* It can be omitted when patching the main model (or in single-model cases).
* @return the patched model.
*/
patchModel?(oldModel: ModelServerElement, copy?: boolean): ModelServerElement;
patchModel?(oldModel: ModelServerElement, copy?: boolean, modeluri?: URI): ModelServerElement;

@@ -168,2 +196,10 @@ /**

patch?: Operation[];
/**
* The list of Json Patches describing the changes that were applied to the models. Only present if
* the edit request was successful.
*
* The list contains one entry per modified model. Unmodified models will not contain any entry.
*/
allPatches?: ModelPatch[];
}

@@ -13,2 +13,3 @@ /********************************************************************************

import jsonpatch, { deepClone, Operation } from 'fast-json-patch';
import URI from 'urijs';

@@ -34,5 +35,10 @@ import {

let client: ModelServerClientV2;
const baseUrl = `http://localhost:8081${ModelServerClientApiV2.API_ENDPOINT}`;
const baseUrl = new URI({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: ModelServerClientApiV2.API_ENDPOINT
});
const testUndoRedo: (modeluri: string, originalModel: any, patchedModel: any) => void = async (
const testUndoRedo: (modeluri: URI, originalModel: any, patchedModel: any) => Promise<void> = async (
modeluri,

@@ -69,3 +75,3 @@ originalModel,

it('edit with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -82,3 +88,3 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

it('create with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, ModelServerObjectV2.is);

@@ -110,3 +116,3 @@ const newWorkflowName = 'New Test Workflow';

it('add with patch', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const initialModel = await client.get(modeluri, ModelServerObjectV2.is);

@@ -142,3 +148,3 @@

it('delete with patch - index based', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, ModelServerObjectV2.is);

@@ -159,3 +165,3 @@

it('delete with patch - object', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const originalModel = await client.get(modeluri, ModelServerObjectV2.is);

@@ -178,3 +184,3 @@

it('edit with command', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -184,3 +190,3 @@ const originalModel = await client.get(modeluri, ModelServerObjectV2.is);

eClass: originalModel.$type,
$ref: `SuperBrewer3000.coffee#${originalModel.$id}`
$ref: URI.build({ path: 'SuperBrewer3000.coffee', fragment: originalModel.$id })
};

@@ -196,3 +202,3 @@ const command = new SetCommand(owner, 'name', [newName]);

it('incremental patch update', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -219,3 +225,3 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

it('subscribe to changes', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -225,3 +231,3 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

eClass: machine.$type,
$ref: `SuperBrewer3000.coffee#${machine.$id}`
$ref: URI.build({ path: 'SuperBrewer3000.coffee', fragment: machine.$id })
};

@@ -249,3 +255,3 @@ const command = new SetCommand(owner, 'name', [newName]);

expect(notification.modelUri).to.be.equal(modeluri);
expect(notification.modeluri.toString()).to.be.equal(modeluri.toString());
expect(patch.length).to.be.equal(1);

@@ -264,3 +270,3 @@ const operation = patch[0];

it('subscribe to incremental updates', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -270,3 +276,3 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

eClass: machine.$type,
$ref: `SuperBrewer3000.coffee#${machine.$id}`
$ref: URI.build({ path: 'SuperBrewer3000.coffee', fragment: machine.$id })
};

@@ -307,3 +313,3 @@ const command = new SetCommand(owner, 'name', [newName]);

it('pure Json Patch changes', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -330,3 +336,3 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

it('clear list with "remove" patch operation', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const machine = await client.get(modeluri, ModelServerObjectV2.is);

@@ -354,3 +360,3 @@

it('unset value with "remove" patch operation', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const machine = await client.get(modeluri, ModelServerObjectV2.is);

@@ -376,3 +382,67 @@

});
it('check all patch replies', async () => {
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, ModelServerObjectV2.is);
const patchedMachine = deepClone(machine);
// Directly change the model
patchedMachine.name = newName;
patchedMachine.children[1].processor.clockSpeed = 6;
// Generate patch by diffing the original model and the patched one
const patch = jsonpatch.compare(machine, patchedMachine);
const result = await client.edit(modeluri, patch);
expect(result.success).to.be.true;
expect(result.patch).to.not.be.undefined;
expect(result.allPatches).to.not.be.undefined;
expect(result.allPatches).to.be.an('array').of.length(1);
// Patch the main resource
const updatedMachineMainPatch = result.patchModel!(machine, true);
expect(patchedMachine).to.deep.equal(updatedMachineMainPatch);
// Patch the first resource
const updatedMachineFirstPatch = result.patchModel!(machine, true, new URI(result.allPatches![0].modelUri));
expect(patchedMachine).to.deep.equal(updatedMachineFirstPatch);
await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);
});
it('test model patches', async () => {
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';
const machine = await client.get(modeluri, ModelServerObjectV2.is);
const patchedMachine = deepClone(machine);
// Directly change the model
patchedMachine.name = newName;
patchedMachine.children[1].processor.clockSpeed = 6;
// Generate patches by diffing the original model and the patched one
const patch = jsonpatch.compare(machine, patchedMachine);
const result = await client.edit(modeluri, patch);
expect(result.success).to.be.true;
expect(result.patch).to.not.be.undefined;
expect(result.allPatches).to.not.be.undefined;
expect(result.allPatches).to.be.an('array').of.length(1);
// Patch the main resource
const updatedMachineMainPatch = result.patchModel!(machine, true);
expect(patchedMachine).to.deep.equal(updatedMachineMainPatch);
// Patch the first resource
const updatedMachineFirstPatch = result.patchModel!(machine, true, new URI(result.allPatches![0].modelUri));
expect(patchedMachine).to.deep.equal(updatedMachineFirstPatch);
await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);
});
});
});

@@ -16,2 +16,3 @@ /********************************************************************************

import { spy } from 'sinon';
import URI from 'urijs';

@@ -26,3 +27,8 @@ import { ServerConfiguration } from './model-server-client-api-v1';

let client: ModelServerClientV2;
const baseUrl = `http://localhost:8081${ModelServerClientApiV2.API_ENDPOINT}`;
const baseUrl = new URI({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: ModelServerClientApiV2.API_ENDPOINT
});

@@ -41,4 +47,16 @@ beforeEach(() => {

const axios = client['restClient'];
expect(axios.defaults.baseURL).to.be.equal(baseUrl);
expect(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});
it('test createSubscriptionPath without trailing slash', () => {
client = new ModelServerClientV2();
client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath'](new URI('foo'), {});
expect(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
});
it('test createSubscriptionPath with trailing slash', () => {
client = new ModelServerClientV2();
client.initialize(new URI(`${baseUrl}/`));
const subscriptionPath = client['createSubscriptionPath'](new URI('foo'), {});
expect(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
});

@@ -54,3 +72,3 @@ describe('test requests', () => {

expect(request.config.params).to.include({ format: FORMAT_JSON_V2 });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -69,3 +87,3 @@ request = moxios.requests.at(1);

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_URIS);

@@ -77,3 +95,3 @@ done();

it('getElementById', done => {
const modeluri = 'my/uri.model';
const modeluri = new URI('my/uri.model');
const elementid = 'myElement';

@@ -87,7 +105,7 @@

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, elementid, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, elementid, modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_ELEMENT);
request = moxios.requests.at(1);
expect(request.config.params).to.include({ format: FORMAT_XMI, elementid, modeluri });
expect(request.config.params).to.include({ format: FORMAT_XMI, elementid, modeluri: modeluri.toString() });
done();

@@ -98,3 +116,3 @@ });

it('getElementByName', done => {
const modeluri = 'my/uri.model';
const modeluri = new URI('my/uri.model');
const elementname = 'myElement';

@@ -108,7 +126,7 @@

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, elementname, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, elementname, modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_ELEMENT);
request = moxios.requests.at(1);
expect(request.config.params).to.include({ format: FORMAT_XMI, elementname, modeluri });
expect(request.config.params).to.include({ format: FORMAT_XMI, elementname, modeluri: modeluri.toString() });
done();

@@ -119,3 +137,3 @@ });

it('delete', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
client.delete(modeluri);

@@ -125,4 +143,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('delete');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -134,3 +152,3 @@ done();

it('close', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
client.close(modeluri);

@@ -140,4 +158,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('post');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.CLOSE);

@@ -149,3 +167,3 @@ done();

it('create', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -160,7 +178,7 @@ const data = JSON.stringify(model);

expect(request.config.data).to.be.equal(JSON.stringify({ data }));
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);
request = moxios.requests.at(1);
expect(request.config.params).to.include({ format: FORMAT_XMI, modeluri });
expect(request.config.params).to.include({ format: FORMAT_XMI, modeluri: modeluri.toString() });
done();

@@ -171,3 +189,3 @@ });

it('update', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -182,7 +200,7 @@ const data = JSON.stringify(model);

expect(request.config.data).to.be.equal(JSON.stringify({ data }));
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);
request = moxios.requests.at(1);
expect(request.config.params).to.include({ format: FORMAT_XMI, modeluri });
expect(request.config.params).to.include({ format: FORMAT_XMI, modeluri: modeluri.toString() });
done();

@@ -193,3 +211,3 @@ });

it('save', done => {
const modeluri = 'save/me/please';
const modeluri = new URI('save/me/please');
client.save(modeluri);

@@ -199,4 +217,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SAVE);

@@ -213,3 +231,3 @@ done();

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SAVE_ALL);

@@ -221,3 +239,3 @@ done();

it('validate', done => {
const modeluri = 'validate/me/please';
const modeluri = new URI('validate/me/please');
client.validate(modeluri);

@@ -227,4 +245,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.VALIDATION);

@@ -236,3 +254,3 @@ done();

it('getValidationConstraints', done => {
const modeluri = 'validate/me/please';
const modeluri = new URI('validate/me/please');
client.getValidationConstraints(modeluri);

@@ -242,4 +260,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.VALIDATION_CONSTRAINTS);

@@ -251,3 +269,3 @@ done();

it('getTypeSchema', done => {
const modeluri = 'my/model/uri';
const modeluri = new URI('my/model/uri');
client.getTypeSchema(modeluri);

@@ -257,4 +275,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.TYPE_SCHEMA);

@@ -272,3 +290,3 @@ done();

expect(request.config.params).to.include({ schemaname });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.UI_SCHEMA);

@@ -281,4 +299,4 @@ done();

const configuration: ServerConfiguration = {
workspaceRoot: 'myRoot',
uiSchemaFolder: 'mySchemaFolder'
workspaceRoot: new URI('myRoot'),
uiSchemaFolder: new URI('mySchemaFolder')
};

@@ -289,5 +307,10 @@ client.configureServer(configuration);

expect(request.config.method).to.be.equal('put');
expect(request.config.data).to.equal(JSON.stringify(configuration));
expect(request.config.data).to.equal(
JSON.stringify({
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder!.toString()
})
);
expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SERVER_CONFIGURE);

@@ -304,3 +327,3 @@ done();

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SERVER_PING);

@@ -312,3 +335,3 @@ done();

it('edit', done => {
const modeluri = 'edit/me/please';
const modeluri = new URI('edit/me/please');
const patch: Operation[] = [

@@ -331,4 +354,4 @@ {

expect(request.config.data).to.be.equal(JSON.stringify({ data: expected }));
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.include({ format: FORMAT_JSON_V2, modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -340,3 +363,3 @@ done();

it('undo', done => {
const modeluri = 'undo/me/please';
const modeluri = new URI('undo/me/please');
client.undo(modeluri);

@@ -346,4 +369,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.be.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.be.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.UNDO);

@@ -355,3 +378,3 @@ done();

it('redo', done => {
const modeluri = 'redo/me/please';
const modeluri = new URI('redo/me/please');
client.redo(modeluri);

@@ -361,4 +384,4 @@ moxios.wait(() => {

expect(request.config.method).to.be.equal('get');
expect(request.config.params).to.be.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.params).to.be.include({ modeluri: modeluri.toString() });
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.REDO);

@@ -371,3 +394,3 @@ done();

describe('test responses', () => {
it('ping ', done => {
it('ping', done => {
const expectedMsg: ModelServerMessage = {

@@ -390,5 +413,5 @@ data: '',

it('ping ', done => {
it('getAll', done => {
const model1: Model = {
modelUri: 'path/to/model1',
modeluri: 'path/to/model1',
content: {

@@ -399,3 +422,3 @@ name: 'coffee'

const model2: Model = {
modelUri: 'path/to/model2',
modeluri: 'path/to/model2',
content: {

@@ -407,4 +430,4 @@ name: 'coffee'

data: {
[model1.modelUri]: model1.content,
[model2.modelUri]: model2.content
[model1.modeluri.toString()]: model1.content,
[model2.modeluri.toString()]: model2.content
},

@@ -422,3 +445,4 @@ type: 'success'

const result = onFulfilled.getCall(0).args[0];
expect(result).to.deep.include.members([model2, model1]);
expect(result).to.be.an('array').of.length(2);
expect(result).to.deep.include.members([model1, model2]);
done();

@@ -425,0 +449,0 @@ });

/********************************************************************************
* Copyright (c) 2022 STMicroelectronics and others.
* Copyright (c) 2022-2023 STMicroelectronics and others.
*

@@ -11,12 +11,13 @@ * This program and the accompanying materials are made available under the

*******************************************************************************/
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { Operation } from 'fast-json-patch';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import { deepClone } from 'fast-json-patch';
import WebSocket from 'isomorphic-ws';
import URI from 'urijs';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { ModelServerError, ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
import { Format, FORMAT_JSON_V2, ModelServerClientApiV2, ModelUpdateResult } from './model-server-client-api-v2';
import { Format, FORMAT_JSON_V2, ModelServerClientApiV2, ModelUpdateResult, PatchOrCommand } from './model-server-client-api-v2';
import { MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { ModelServerPaths } from './model-server-paths';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { SubscriptionListener } from './subscription-listener';

@@ -31,7 +32,7 @@ import { AnyObject, asObject, asString, asType, encodeRequestBody, TypeGuard } from './utils/type-util';

protected openSockets: Map<string, WebSocket> = new Map();
protected _baseUrl: string;
protected _baseUrl: URI;
protected defaultFormat: Format = FORMAT_JSON_V2;
initialize(baseUrl: string, defaultFormat: Format = FORMAT_JSON_V2): void | Promise<void> {
this._baseUrl = baseUrl;
initialize(baseUrl: URI, defaultFormat: Format = FORMAT_JSON_V2): void | Promise<void> {
this._baseUrl = baseUrl.clone();
this.defaultFormat = defaultFormat;

@@ -41,17 +42,21 @@ this.restClient = axios.create(this.getAxiosConfig(baseUrl));

protected getAxiosConfig(baseURL: string): AxiosRequestConfig | undefined {
return { baseURL };
protected getAxiosConfig(baseURL: URI): AxiosRequestConfig | undefined {
return { baseURL: baseURL.toString() };
}
get(modeluri: string, format?: Format): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
get<M>(modeluri: string, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
get(modeluri: URI, format?: Format): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
get<M>(modeluri: URI, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
if (typeof formatOrGuard === 'function') {
const typeGuard = formatOrGuard;
return this.process(this.restClient.get(ModelServerPaths.MODEL_CRUD, { params: { modeluri, format } }), msg =>
MessageDataMapper.as(msg, typeGuard)
return this.process(
this.restClient.get(ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString(), format } }),
msg => MessageDataMapper.as(msg, typeGuard)
);
}
format = formatOrGuard ?? this.defaultFormat;
return this.process(this.restClient.get(ModelServerPaths.MODEL_CRUD, { params: { modeluri, format } }), MessageDataMapper.asObject);
return this.process(
this.restClient.get(ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString(), format } }),
MessageDataMapper.asObject
);
}

@@ -79,9 +84,9 @@

getModelUris(): Promise<string[]> {
return this.process(this.restClient.get(ModelServerPaths.MODEL_URIS), MessageDataMapper.asStringArray);
getModelUris(): Promise<URI[]> {
return this.process(this.restClient.get(ModelServerPaths.MODEL_URIS), MessageDataMapper.asURIArray);
}
getElementById(modeluri: string, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById<M>(modeluri: string, elementid: string, formatOrGuard?: FormatOrGuard<M>, format?: string): Promise<AnyObject | M> {
getElementById(modeluri: URI, elementid: string, format?: Format): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById<M>(modeluri: URI, elementid: string, formatOrGuard?: FormatOrGuard<M>, format?: string): Promise<AnyObject | M> {
format = format ?? this.defaultFormat;

@@ -91,4 +96,5 @@ if (formatOrGuard) {

const typeGuard = formatOrGuard;
return this.process(this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementid, format } }), msg =>
MessageDataMapper.as(msg, typeGuard)
return this.process(
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementid, format } }),
msg => MessageDataMapper.as(msg, typeGuard)
);

@@ -99,3 +105,3 @@ }

return this.process(
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementid, format } }),
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementid, format } }),
MessageDataMapper.asObject

@@ -105,5 +111,5 @@ );

getElementByName(modeluri: string, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName<M>(modeluri: string, elementname: string, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
getElementByName(modeluri: URI, elementname: string, format?: Format): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
getElementByName<M>(modeluri: URI, elementname: string, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
format = format ?? this.defaultFormat;

@@ -114,3 +120,3 @@ if (formatOrGuard) {

return this.process(
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementname, format } }),
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementname, format } }),
msg => MessageDataMapper.as(msg, typeGuard)

@@ -122,3 +128,3 @@ );

return this.process(
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri, elementname, format } }),
this.restClient.get(ModelServerPaths.MODEL_ELEMENT, { params: { modeluri: modeluri.toString(), elementname, format } }),
MessageDataMapper.asObject

@@ -128,5 +134,5 @@ );

create(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
create<M>(modeluri: string, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
create(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
create<M>(modeluri: URI, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>, format?: Format): Promise<AnyObject | M> {
format = format ?? this.defaultFormat;

@@ -137,3 +143,5 @@ if (formatOrGuard) {

return this.process(
this.restClient.post(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), { params: { modeluri, format } }),
this.restClient.post(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), {
params: { modeluri: modeluri.toString(), format }
}),
msg => MessageDataMapper.as(msg, typeGuard)

@@ -145,3 +153,5 @@ );

return this.process(
this.restClient.post(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), { params: { modeluri, format } }),
this.restClient.post(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), {
params: { modeluri: modeluri.toString(), format }
}),
MessageDataMapper.asObject

@@ -151,6 +161,6 @@ );

update(modeluri: string, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format?: Format): Promise<AnyObject>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>, format?: Format): Promise<M>;
update<M>(
modeluri: string,
modeluri: URI,
model: AnyObject | string,

@@ -165,3 +175,5 @@ formatOrGuard?: FormatOrGuard<M>,

return this.process(
this.restClient.put(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), { params: { modeluri, format } }),
this.restClient.put(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), {
params: { modeluri: modeluri.toString(), format }
}),
msg => MessageDataMapper.as(msg, typeGuard)

@@ -173,3 +185,5 @@ );

return this.process(
this.restClient.put(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), { params: { modeluri, format } }),
this.restClient.put(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(model), {
params: { modeluri: modeluri.toString(), format }
}),
MessageDataMapper.asObject

@@ -179,12 +193,21 @@ );

delete(modeluri: string): Promise<boolean> {
return this.process(this.restClient.delete(ModelServerPaths.MODEL_CRUD, { params: { modeluri } }), MessageDataMapper.isSuccess);
delete(modeluri: URI): Promise<boolean> {
return this.process(
this.restClient.delete(ModelServerPaths.MODEL_CRUD, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.isSuccess
);
}
close(modeluri: string): Promise<boolean> {
return this.process(this.restClient.post(ModelServerPaths.CLOSE, undefined, { params: { modeluri } }), MessageDataMapper.isSuccess);
close(modeluri: URI): Promise<boolean> {
return this.process(
this.restClient.post(ModelServerPaths.CLOSE, undefined, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.isSuccess
);
}
save(modeluri: string): Promise<boolean> {
return this.process(this.restClient.get(ModelServerPaths.SAVE, { params: { modeluri } }), MessageDataMapper.isSuccess);
save(modeluri: URI): Promise<boolean> {
return this.process(
this.restClient.get(ModelServerPaths.SAVE, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.isSuccess
);
}

@@ -196,4 +219,4 @@

validate(modeluri: string): Promise<Diagnostic> {
return this.process(this.restClient.get(ModelServerPaths.VALIDATION, { params: { modeluri } }), response =>
validate(modeluri: URI): Promise<Diagnostic> {
return this.process(this.restClient.get(ModelServerPaths.VALIDATION, { params: { modeluri: modeluri.toString() } }), response =>
MessageDataMapper.as(response, Diagnostic.is)

@@ -203,5 +226,5 @@ );

getValidationConstraints(modeluri: string): Promise<string> {
getValidationConstraints(modeluri: URI): Promise<string> {
return this.process(
this.restClient.get(ModelServerPaths.VALIDATION_CONSTRAINTS, { params: { modeluri } }),
this.restClient.get(ModelServerPaths.VALIDATION_CONSTRAINTS, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.asString

@@ -211,4 +234,7 @@ );

getTypeSchema(modeluri: string): Promise<string> {
return this.process(this.restClient.get(ModelServerPaths.TYPE_SCHEMA, { params: { modeluri } }), MessageDataMapper.asString);
getTypeSchema(modeluri: URI): Promise<string> {
return this.process(
this.restClient.get(ModelServerPaths.TYPE_SCHEMA, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.asString
);
}

@@ -221,7 +247,7 @@

configureServer(configuration: ServerConfiguration): Promise<boolean> {
let { workspaceRoot, uiSchemaFolder } = configuration;
workspaceRoot = workspaceRoot.replace('file://', '');
uiSchemaFolder = uiSchemaFolder?.replace('file://', '');
return this.process(
this.restClient.put(ModelServerPaths.SERVER_CONFIGURE, { workspaceRoot, uiSchemaFolder }),
this.restClient.put(ModelServerPaths.SERVER_CONFIGURE, {
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder?.toString()
}),
MessageDataMapper.isSuccess

@@ -235,6 +261,3 @@ );

edit(modeluri: string, patch: Operation): Promise<ModelUpdateResult>;
edit(modeluri: string, patch: Operation[]): Promise<ModelUpdateResult>;
edit(modeluri: string, command: ModelServerCommand): Promise<ModelUpdateResult>;
edit(modeluri: string, patchOrCommand: Operation | Operation[] | ModelServerCommand): Promise<ModelUpdateResult> {
edit(modeluri: URI, patchOrCommand: PatchOrCommand, format = this.defaultFormat): Promise<ModelUpdateResult> {
let patchMessage: any;

@@ -247,2 +270,3 @@ if (patchOrCommand instanceof ModelServerCommand) {

} 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];

@@ -253,6 +277,14 @@ patchMessage = {

};
if (fullPatch.length === 0) {
// No-op
return Promise.resolve({
success: true,
patchModel: (oldModel, copy, _modeluri) => (copy ? deepClone(oldModel) : oldModel),
patch: []
});
}
}
return this.process(
this.restClient.patch(ModelServerPaths.MODEL_CRUD, encodeRequestBody(this.defaultFormat)(patchMessage), {
params: { modeluri, format: this.defaultFormat }
this.restClient.patch(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(patchMessage), {
params: { modeluri: modeluri.toString(), format: format }
}),

@@ -263,23 +295,29 @@ MessageDataMapper.patchModel

undo(modeluri: string): Promise<ModelUpdateResult> {
return this.process(this.restClient.get(ModelServerPaths.UNDO, { params: { modeluri } }), MessageDataMapper.patchModel);
undo(modeluri: URI): Promise<ModelUpdateResult> {
return this.process(
this.restClient.get(ModelServerPaths.UNDO, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.patchModel
);
}
redo(modeluri: string): Promise<ModelUpdateResult> {
return this.process(this.restClient.get(ModelServerPaths.REDO, { params: { modeluri } }), MessageDataMapper.patchModel);
redo(modeluri: URI): Promise<ModelUpdateResult> {
return this.process(
this.restClient.get(ModelServerPaths.REDO, { params: { modeluri: modeluri.toString() } }),
MessageDataMapper.patchModel
);
}
send(modelUri: string, message: ModelServerMessage): void {
const openSocket = this.openSockets.get(modelUri);
send(modeluri: URI, message: ModelServerMessage): void {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.send(message);
openSocket.send(JSON.stringify(message));
}
}
subscribe(modeluri: string, listener: SubscriptionListener, options: SubscriptionOptions = {}): SubscriptionListener {
subscribe(modeluri: URI, listener: SubscriptionListener, options: SubscriptionOptions = {}): SubscriptionListener {
if (this.isSocketOpen(modeluri)) {
const errorMsg = `${modeluri} : Cannot open new socket, already subscribed!'`;
const errorMsg = `${modeluri.toString()} : Cannot open new socket, already subscribed!'`;
console.warn(errorMsg);
if (options.errorWhenUnsuccessful) {
throw new Error('errorMsg');
throw new Error(errorMsg);
}

@@ -292,32 +330,33 @@ }

unsubscribe(modeluri: string): void {
const openSocket = this.openSockets.get(modeluri);
unsubscribe(modeluri: URI): void {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.close();
this.openSockets.delete(modeluri);
this.openSockets.delete(modeluri.toString());
}
}
protected createSubscriptionPath(modeluri: string, options: SubscriptionOptions): string {
const queryParams = new URLSearchParams();
queryParams.append('modeluri', modeluri);
if (!options.format) {
options.format = this.defaultFormat;
}
Object.entries(options).forEach(entry => queryParams.append(entry[0], entry[1]));
queryParams.delete('errorWhenUnsuccessful');
return `${this._baseUrl}/${ModelServerPaths.SUBSCRIPTION}?${queryParams.toString()}`.replace(/^(http|https):\/\//i, 'ws://');
protected createSubscriptionPath(modeluri: URI, options: SubscriptionOptions): URI {
const { ...paramOptions } = options;
const subscriptionUri = this._baseUrl.clone();
subscriptionUri.protocol('ws');
subscriptionUri.segment(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;
}
protected doSubscribe(listener: SubscriptionListener, modelUri: string, path: string): void {
const socket = new WebSocket(path.trim());
socket.onopen = event => listener.onOpen?.(modelUri, event);
socket.onclose = event => listener.onClose?.(modelUri, event);
socket.onerror = event => listener.onError?.(modelUri, event);
socket.onmessage = event => listener.onMessage?.(modelUri, event);
this.openSockets.set(modelUri, socket);
protected doSubscribe(listener: SubscriptionListener, modeluri: URI, path: URI): void {
const socket = new WebSocket(path.toString() /* .trim() */);
socket.onopen = event => listener.onOpen?.(modeluri, event);
socket.onclose = event => listener.onClose?.(modeluri, event);
socket.onerror = event => listener.onError?.(modeluri, event);
socket.onmessage = event => listener.onMessage?.(modeluri, event);
this.openSockets.set(modeluri.toString(), socket);
}
protected isSocketOpen(modelUri: string): boolean {
return this.openSockets.get(modelUri) !== undefined;
protected isSocketOpen(modeluri: URI): boolean {
return this.openSockets.get(modeluri.toString()) !== undefined;
}

@@ -333,3 +372,3 @@

} catch (error) {
if (isAxiosError(error)) {
if (axios.isAxiosError(error)) {
const message = error.response?.data ? error.response.data : error.message;

@@ -344,6 +383,2 @@ throw new ModelServerError(message, error.code);

function isAxiosError(error: any): error is AxiosError {
return error !== undefined && error instanceof Error && 'isAxiosError' in error && error['isAxiosError'];
}
/**

@@ -356,9 +391,9 @@ * Helper type for method overloads where on parameter could either be

function mapModel<M>(model: Model, guard?: TypeGuard<M>, toString = false): Model<AnyObject | M | string> {
const { modelUri, content } = model;
const { modeluri, content } = model;
if (guard) {
return { modelUri, content: asType(content, guard) };
return { modeluri, content: asType(content, guard) };
} else if (toString) {
return { modelUri, content: asString(content) };
return { modeluri, content: asString(content) };
}
return { modelUri, content: asObject(content) };
return { modeluri, content: asObject(content) };
}

@@ -15,4 +15,4 @@ /********************************************************************************

import { spy } from 'sinon';
import URI from 'urijs';
import { SetCommand } from './model/command-model';
import { ModelServerClient } from './model-server-client';

@@ -22,6 +22,12 @@ import { ModelServerClientApiV1, ServerConfiguration } from './model-server-client-api-v1';

import { ModelServerPaths } from './model-server-paths';
import { SetCommand } from './model/command-model';
describe('tests for ModelServerClient', () => {
let client: ModelServerClient;
const baseUrl = `http://localhost:8081${ModelServerClientApiV1.API_ENDPOINT}`;
const baseUrl = new URI({
protocol: 'http',
hostname: 'localhost',
port: '8081',
path: ModelServerClientApiV1.API_ENDPOINT
});

@@ -40,4 +46,16 @@ beforeEach(() => {

const axios = client['restClient'];
expect(axios.defaults.baseURL).to.be.equal(baseUrl);
expect(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});
it('test createSubscriptionPath without trailing slash', () => {
client = new ModelServerClient();
client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath'](new URI('foo'), {});
expect(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo&format=json');
});
it('test createSubscriptionPath with trailing slash', () => {
client = new ModelServerClient();
client.initialize(new URI(`${baseUrl}/`));
const subscriptionPath = client['createSubscriptionPath'](new URI('foo'), {});
expect(subscriptionPath.toString()).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo&format=json');
});

@@ -53,3 +71,3 @@ describe('test requests', () => {

expect(request.config.params).to.include({ format: 'json' });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -68,3 +86,3 @@ request = moxios.requests.at(1);

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_URIS);

@@ -76,3 +94,3 @@ done();

it('getElementById', done => {
const modeluri = 'my/uri.model';
const modeluri = new URI('my/uri.model');
const elementid = 'myElement';

@@ -87,3 +105,3 @@

expect(request.config.params).to.include({ format: 'json', elementid, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_ELEMENT);

@@ -97,3 +115,3 @@ request = moxios.requests.at(1);

it('getElementByName', done => {
const modeluri = 'my/uri.model';
const modeluri = new URI('my/uri.model');
const elementname = 'myElement';

@@ -108,3 +126,3 @@

expect(request.config.params).to.include({ format: 'json', elementname, modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_ELEMENT);

@@ -118,3 +136,3 @@ request = moxios.requests.at(1);

it('delete', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
client.delete(modeluri);

@@ -125,3 +143,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -133,3 +151,3 @@ done();

it('close', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
client.close(modeluri);

@@ -140,3 +158,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.CLOSE);

@@ -148,3 +166,3 @@ done();

it('create', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -160,3 +178,3 @@ const data = JSON.stringify(model);

expect(request.config.params).to.include({ format: 'json', modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -170,3 +188,3 @@ request = moxios.requests.at(1);

it('update', done => {
const modeluri = 'delete/me/please';
const modeluri = new URI('delete/me/please');
const model = { name: 'myModel', id: 'myModelId' };

@@ -182,3 +200,3 @@ const data = JSON.stringify(model);

expect(request.config.params).to.include({ format: 'json', modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.MODEL_CRUD);

@@ -192,3 +210,3 @@ request = moxios.requests.at(1);

it('save', done => {
const modeluri = 'save/me/please';
const modeluri = new URI('save/me/please');
client.save(modeluri);

@@ -199,3 +217,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SAVE);

@@ -212,3 +230,3 @@ done();

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SAVE_ALL);

@@ -220,3 +238,3 @@ done();

it('validate', done => {
const modeluri = 'validate/me/please';
const modeluri = new URI('validate/me/please');
client.validate(modeluri);

@@ -227,3 +245,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.VALIDATION);

@@ -235,3 +253,3 @@ done();

it('getValidationConstraints', done => {
const modeluri = 'validate/me/please';
const modeluri = new URI('validate/me/please');
client.getValidationConstraints(modeluri);

@@ -242,3 +260,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.VALIDATION_CONSTRAINTS);

@@ -250,3 +268,3 @@ done();

it('getTypeSchema', done => {
const modeluri = 'my/model/uri';
const modeluri = new URI('my/model/uri');
client.getTypeSchema(modeluri);

@@ -257,3 +275,3 @@ moxios.wait(() => {

expect(request.config.params).to.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.TYPE_SCHEMA);

@@ -271,3 +289,3 @@ done();

expect(request.config.params).to.include({ schemaname });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.UI_SCHEMA);

@@ -280,4 +298,4 @@ done();

const configuration: ServerConfiguration = {
workspaceRoot: 'myRoot',
uiSchemaFolder: 'mySchemaFolder'
workspaceRoot: new URI('myRoot'),
uiSchemaFolder: new URI('mySchemaFolder')
};

@@ -288,5 +306,10 @@ client.configureServer(configuration);

expect(request.config.method).to.be.equal('put');
expect(request.config.data).to.equal(JSON.stringify(configuration));
expect(request.config.data).to.equal(
JSON.stringify({
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder!.toString()
})
);
expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SERVER_CONFIGURE);

@@ -303,3 +326,3 @@ done();

expect(request.config.params).to.be.undefined;
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.SERVER_PING);

@@ -311,3 +334,3 @@ done();

it('edit', done => {
const modeluri = 'edit/me/please';
const modeluri = new URI('edit/me/please');
const command = new SetCommand(

@@ -329,3 +352,3 @@ {

expect(request.config.params).to.include({ format: 'json', modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.EDIT);

@@ -337,3 +360,3 @@ done();

it('undo', done => {
const modeluri = 'undo/me/please';
const modeluri = new URI('undo/me/please');
client.undo(modeluri);

@@ -344,3 +367,3 @@ moxios.wait(() => {

expect(request.config.params).to.be.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.UNDO);

@@ -352,3 +375,3 @@ done();

it('redo', done => {
const modeluri = 'redo/me/please';
const modeluri = new URI('redo/me/please');
client.redo(modeluri);

@@ -359,3 +382,3 @@ moxios.wait(() => {

expect(request.config.params).to.be.include({ modeluri });
expect(request.config.baseURL).to.be.equal(baseUrl);
expect(request.config.baseURL).to.be.equal(baseUrl.toString());
expect(request.config.url).to.be.equal(ModelServerPaths.REDO);

@@ -368,3 +391,3 @@ done();

describe('test responses', () => {
it('ping ', done => {
it('ping', done => {
const expectedMsg: ModelServerMessage = {

@@ -389,3 +412,3 @@ data: '',

const model1: Model = {
modelUri: 'path/to/model1',
modeluri: 'file:/path/to/model1',
content: {

@@ -396,3 +419,3 @@ name: 'coffee'

const model2: Model = {
modelUri: 'path/to/model2',
modeluri: 'file:/path/to/model2',
content: {

@@ -404,4 +427,4 @@ name: 'coffee'

data: {
[model1.modelUri]: model1.content,
[model2.modelUri]: model2.content
[model1.modeluri]: model1.content,
[model2.modeluri]: model2.content
},

@@ -419,3 +442,4 @@ type: 'success'

const result = onFulfilled.getCall(0).args[0];
expect(result).to.deep.include.members([model2, model1]);
expect(result).to.be.an('array').of.length(2);
expect(result).to.deep.include.members([model1, model2]);
done();

@@ -422,0 +446,0 @@ });

/********************************************************************************
* Copyright (c) 2021-2022 STMicroelectronics and others.
* Copyright (c) 2021-2023 STMicroelectronics and others.
*

@@ -11,10 +11,11 @@ * This program and the accompanying materials are made available under the

*******************************************************************************/
import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import axios, { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';
import WebSocket from 'isomorphic-ws';
import URI from 'urijs';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { ModelServerClientApiV1, ModelServerError, ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
import { IdentityMapper, Mapper, MessageDataMapper, Model, ModelServerMessage } from './model-server-message';
import { ModelServerPaths } from './model-server-paths';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { SubscriptionListener } from './subscription-listener';

@@ -29,18 +30,18 @@ import { AnyObject, asObject, asString, asType, TypeGuard } from './utils/type-util';

protected openSockets: Map<string, WebSocket> = new Map();
protected _baseUrl: string;
protected _baseUrl: URI;
protected defaultFormat = 'json';
initialize(baseUrl: string): void | Promise<void> {
this._baseUrl = baseUrl;
initialize(baseUrl: URI): void | Promise<void> {
this._baseUrl = baseUrl.clone();
this.restClient = axios.create(this.getAxisConfig(baseUrl));
}
protected getAxisConfig(baseURL: string): AxiosRequestConfig | undefined {
return { baseURL };
protected getAxisConfig(baseURL: URI): AxiosRequestConfig | undefined {
return { baseURL: baseURL.toString() };
}
get(modeluri: string): Promise<AnyObject>;
get<M>(modeluri: string, typeGuard: TypeGuard<M>): Promise<M>;
get(modeluri: string, format: string): Promise<string>;
get<M>(modeluri: string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
get(modeluri: URI): Promise<AnyObject>;
get<M>(modeluri: URI, typeGuard: TypeGuard<M>): Promise<M>;
get(modeluri: URI, format: string): Promise<string>;
get<M>(modeluri: URI, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
const format = typeof formatOrGuard === 'string' ? formatOrGuard : this.defaultFormat;

@@ -72,10 +73,10 @@ const mapper = createMapper<M>(formatOrGuard);

getModelUris(): Promise<string[]> {
return this.process(this.restClient.get(ModelServerPaths.MODEL_URIS), MessageDataMapper.asStringArray);
getModelUris(): Promise<URI[]> {
return this.process(this.restClient.get(ModelServerPaths.MODEL_URIS), MessageDataMapper.asURIArray);
}
getElementById(modeluri: string, elementid: string): Promise<AnyObject>;
getElementById<M>(modeluri: string, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById(modeluri: string, elementid: string, format: string): Promise<string>;
getElementById<M>(modeluri: string, elementid: string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
getElementById(modeluri: URI, elementid: string): Promise<AnyObject>;
getElementById<M>(modeluri: URI, elementid: string, typeGuard: TypeGuard<M>): Promise<M>;
getElementById(modeluri: URI, elementid: string, format: string): Promise<string>;
getElementById<M>(modeluri: URI, elementid: string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
const format = typeof formatOrGuard === 'string' ? formatOrGuard : this.defaultFormat;

@@ -86,6 +87,6 @@ const mapper = createMapper<M>(formatOrGuard);

getElementByName(modeluri: string, elementname: string): Promise<AnyObject>;
getElementByName<M>(modeluri: string, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName(modeluri: string, elementname: string, format: string): Promise<string>;
getElementByName<M>(modeluri: string, elementname: string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
getElementByName(modeluri: URI, elementname: string): Promise<AnyObject>;
getElementByName<M>(modeluri: URI, elementname: string, typeGuard: TypeGuard<M>, format?: string): Promise<M>;
getElementByName(modeluri: URI, elementname: string, format: string): Promise<string>;
getElementByName<M>(modeluri: URI, elementname: string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
const format = typeof formatOrGuard === 'string' ? formatOrGuard : this.defaultFormat;

@@ -96,6 +97,6 @@ const mapper = createMapper<M>(formatOrGuard);

create(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: string, model: AnyObject | string, format: string): Promise<string>;
create<M>(modeluri: string, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
create<M>(modeluri: string, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
create(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
create(modeluri: URI, model: AnyObject | string, format: string): Promise<string>;
create<M>(modeluri: URI, model: AnyObject | string, typeGuard: TypeGuard<M>): Promise<M>;
create<M>(modeluri: URI, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
const format = typeof formatOrGuard === 'string' ? formatOrGuard : this.defaultFormat;

@@ -106,6 +107,6 @@ const mapper = createMapper<M>(formatOrGuard);

update(modeluri: string, model: AnyObject | string): Promise<AnyObject>;
update<M>(modeluri: string, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: string, model: AnyObject | string, format: string): Promise<AnyObject>;
update<M>(modeluri: string, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
update(modeluri: URI, model: AnyObject | string): Promise<AnyObject>;
update<M>(modeluri: URI, model: string | string, typeGuard: TypeGuard<M>): Promise<M>;
update(modeluri: URI, model: AnyObject | string, format: string): Promise<AnyObject>;
update<M>(modeluri: URI, model: AnyObject | string, formatOrGuard?: FormatOrGuard<M>): Promise<AnyObject | M | string> {
const format = typeof formatOrGuard === 'string' ? formatOrGuard : this.defaultFormat;

@@ -116,11 +117,11 @@ const mapper = createMapper<M>(formatOrGuard);

delete(modeluri: string): Promise<boolean> {
delete(modeluri: URI): Promise<boolean> {
return this.process(this.restClient.delete(ModelServerPaths.MODEL_CRUD, { params: { modeluri } }), MessageDataMapper.isSuccess);
}
close(modeluri: string): Promise<boolean> {
close(modeluri: URI): Promise<boolean> {
return this.process(this.restClient.post(ModelServerPaths.CLOSE, undefined, { params: { modeluri } }), MessageDataMapper.isSuccess);
}
save(modeluri: string): Promise<boolean> {
save(modeluri: URI): Promise<boolean> {
return this.process(this.restClient.get(ModelServerPaths.SAVE, { params: { modeluri } }), MessageDataMapper.isSuccess);

@@ -133,3 +134,3 @@ }

validate(modeluri: string): Promise<Diagnostic> {
validate(modeluri: URI): Promise<Diagnostic> {
return this.process(this.restClient.get(ModelServerPaths.VALIDATION, { params: { modeluri } }), response =>

@@ -140,3 +141,3 @@ MessageDataMapper.as(response, Diagnostic.is)

getValidationConstraints(modeluri: string): Promise<string> {
getValidationConstraints(modeluri: URI): Promise<string> {
return this.process(

@@ -148,3 +149,3 @@ this.restClient.get(ModelServerPaths.VALIDATION_CONSTRAINTS, { params: { modeluri } }),

getTypeSchema(modeluri: string): Promise<string> {
getTypeSchema(modeluri: URI): Promise<string> {
return this.process(this.restClient.get(ModelServerPaths.TYPE_SCHEMA, { params: { modeluri } }), MessageDataMapper.asString);

@@ -158,7 +159,7 @@ }

configureServer(configuration: ServerConfiguration): Promise<boolean> {
let { workspaceRoot, uiSchemaFolder } = configuration;
workspaceRoot = workspaceRoot.replace('file://', '');
uiSchemaFolder = uiSchemaFolder?.replace('file://', '');
return this.process(
this.restClient.put(ModelServerPaths.SERVER_CONFIGURE, { workspaceRoot, uiSchemaFolder }),
this.restClient.put(ModelServerPaths.SERVER_CONFIGURE, {
workspaceRoot: configuration.workspaceRoot.toString(),
uiSchemaFolder: configuration.uiSchemaFolder?.toString()
}),
MessageDataMapper.isSuccess

@@ -172,3 +173,3 @@ );

edit(modeluri: string, command: ModelServerCommand): Promise<boolean> {
edit(modeluri: URI, command: ModelServerCommand): Promise<boolean> {
return this.process(

@@ -180,12 +181,12 @@ this.restClient.patch(ModelServerPaths.EDIT, { data: command }, { params: { modeluri, format: this.defaultFormat } }),

undo(modeluri: string): Promise<string> {
undo(modeluri: URI): Promise<string> {
return this.process(this.restClient.get(ModelServerPaths.UNDO, { params: { modeluri } }), MessageDataMapper.asString);
}
redo(modeluri: string): Promise<string> {
redo(modeluri: URI): Promise<string> {
return this.process(this.restClient.get(ModelServerPaths.REDO, { params: { modeluri } }), MessageDataMapper.asString);
}
send(modelUri: string, message: ModelServerMessage): boolean {
const openSocket = this.openSockets.get(modelUri);
send(modeluri: URI, message: ModelServerMessage): boolean {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {

@@ -198,9 +199,9 @@ openSocket.send(JSON.stringify(message));

subscribe(modeluri: string, options: SubscriptionOptions = {}): void {
subscribe(modeluri: URI, options: SubscriptionOptions = {}): void {
if (!options.listener) {
const errorMsg = `${modeluri} : Cannot subscribe. No listener is present!'`;
const errorMsg = `${modeluri.toString()} : Cannot subscribe. No listener is present!'`;
throw new Error(errorMsg);
}
if (this.isSocketOpen(modeluri)) {
const errorMsg = `${modeluri} : Cannot open new socket, already subscribed!'`;
const errorMsg = `${modeluri.toString()} : Cannot open new socket, already subscribed!'`;
console.warn(errorMsg);

@@ -215,7 +216,7 @@ if (options.errorWhenUnsuccessful) {

unsubscribe(modeluri: string): boolean {
const openSocket = this.openSockets.get(modeluri);
unsubscribe(modeluri: URI): boolean {
const openSocket = this.openSockets.get(modeluri.toString());
if (openSocket) {
openSocket.close();
this.openSockets.delete(modeluri);
this.openSockets.delete(modeluri.toString());
return true;

@@ -226,30 +227,30 @@ }

protected createSubscriptionPath(modeluri: string, options: SubscriptionOptions): string {
protected createSubscriptionPath(modeluri: URI, options: SubscriptionOptions): URI {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { listener, ...paramOptions } = options;
const queryParams = new URLSearchParams();
queryParams.append('modeluri', modeluri);
if (!options.format) {
options.format = this.defaultFormat;
}
Object.entries(paramOptions).forEach(entry => queryParams.append(entry[0], entry[1]));
queryParams.delete('errorWhenUnsuccessful');
return `${this._baseUrl}${ModelServerPaths.SUBSCRIPTION}?${queryParams.toString()}`.replace(/^(http|https):\/\//i, 'ws://');
const subscriptionUri = this._baseUrl.clone();
subscriptionUri.protocol('ws');
subscriptionUri.segment(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;
}
protected doSubscribe(listener: SubscriptionListener, modelUri: string, path: string): void {
const socket = new WebSocket(path.trim());
socket.onopen = event => listener.onOpen(modelUri, event);
protected doSubscribe(listener: SubscriptionListener, modeluri: URI, path: URI): void {
const socket = new WebSocket(path.toString() /* .trim() */);
socket.onopen = event => listener.onOpen(modeluri, event);
socket.onclose = event => {
listener.onClose(modelUri, event);
this.openSockets.delete(modelUri);
listener.onClose(modeluri, event);
this.openSockets.delete(modeluri.toString());
};
socket.onerror = event => listener.onError(modelUri, event);
socket.onmessage = event => listener.onMessage(modelUri, event);
this.openSockets.set(modelUri, socket);
socket.onerror = event => listener.onError(modeluri, event);
socket.onmessage = event => listener.onMessage(modeluri, event);
this.openSockets.set(modeluri.toString(), socket);
}
protected isSocketOpen(modelUri: string): boolean {
return this.openSockets.get(modelUri) !== undefined;
protected isSocketOpen(modeluri: URI): boolean {
return this.openSockets.get(modeluri.toString()) !== undefined;
}

@@ -284,3 +285,3 @@

} catch (error) {
if (isAxiosError(error)) {
if (axios.isAxiosError(error)) {
const message = error.response?.data ? error.response.data : error.message;

@@ -295,6 +296,2 @@ throw new ModelServerError(message, error.code);

function isAxiosError(error: any): error is AxiosError {
return error !== undefined && error instanceof Error && 'isAxiosError' in error && error['isAxiosError'];
}
/**

@@ -323,9 +320,9 @@ * Helper type for method overloads where on parameter could either be

function mapModel<M>(model: Model, guard?: TypeGuard<M>, toString = false): Model<AnyObject | M | string> {
const { modelUri, content } = model;
const { modeluri, content } = model;
if (guard) {
return { modelUri, content: asType(content, guard) };
return { modeluri, content: asType(content, guard) };
} else if (toString) {
return { modelUri, content: asString(content) };
return { modeluri, content: asString(content) };
}
return { modelUri, content: asObject(content) };
return { modeluri, content: asObject(content) };
}

@@ -12,6 +12,7 @@ /********************************************************************************

import * as jsonpatch from 'fast-json-patch';
import { deepClone } from 'fast-json-patch';
import { deepClone, Operation } from 'fast-json-patch';
import URI from 'urijs';
import { ModelPatch, ModelUpdateResult } from './model-server-client-api-v2';
import { ModelServerElement } from './model/base-model';
import { ModelUpdateResult } from './model-server-client-api-v2';
import { Operations } from './utils/patch-utils';

@@ -83,3 +84,3 @@ import * as Type from './utils/type-util';

/** The uri of the model. */
modelUri: string;
modeluri: string;
/** The model content. */

@@ -96,4 +97,8 @@ content: C;

export function is(object: unknown): object is Model {
return Type.AnyObject.is(object) && Type.isString(object, 'modelUri') && Type.isObject(object, 'content');
return Type.AnyObject.is(object) && Type.isString(object, 'modeluri') && Type.isObject(object, 'content');
}
export function toString(model: Model): string {
return JSON.stringify(model, undefined, 2);
}
}

@@ -160,2 +165,12 @@

/**
* Maps the {@link ModelServerMessage.data} property of the given message to a URI[].
* @param message The message to map.
* @returns The `data` property as `URI[]`.
* @throws {@link Error} if the 'data' property is not an URI array.
*/
export function asURIArray(message: ModelServerMessage): URI[] {
return Type.asURIArray(message.data);
}
/**
* Maps the {@link ModelServerMessage.data} property of the given message to an {@link AnyObject}.

@@ -206,10 +221,15 @@ * @param message The message to map.

const patch = data ? data.patch : undefined;
if (patch && Operations.isPatch(patch)) {
const allPatches = data ? data.allPatches : undefined;
if (patch || allPatches) {
return {
success: isSuccess(message),
patch,
patchModel: (oldModel, copy) => {
patchModel: (oldModel, copy, modeluri) => {
const modelToPatch = copy ? deepClone(oldModel) : oldModel;
return jsonpatch.applyPatch(modelToPatch, patch).newDocument as ModelServerElement;
}
const patchToApply = modeluri ? getPatch(allPatches, modeluri) : Operations.isPatch(patch) ? patch : undefined;
return patchToApply
? (jsonpatch.applyPatch(modelToPatch, patchToApply).newDocument as ModelServerElement)
: modelToPatch;
},
allPatches
};

@@ -223,2 +243,6 @@ } else {

}
function getPatch(patches: ModelPatch[], modeluri: URI): Operation[] | undefined {
return patches.find(mp => mp.modelUri === modeluri.toString())?.patch;
}
}

@@ -12,2 +12,3 @@ /********************************************************************************

import { Operation } from 'fast-json-patch';
import * as URI from 'urijs';

@@ -18,3 +19,3 @@ import { MessageType, ModelServerObjectV2 } from '.';

import { ModelServerMessage } from './model-server-message';
import { AnyObject, isString } from './utils/type-util';
import { AnyObject, isObject, isString } from './utils/type-util';

@@ -26,3 +27,3 @@ /**

export interface ModelServerNotification {
modelUri: string;
modeluri: URI;
type: string;

@@ -33,3 +34,3 @@ }

export function is(object?: unknown): object is ModelServerNotification {
return AnyObject.is(object) && isString(object, 'modelUri') && isString(object, 'type');
return AnyObject.is(object) && isObject(object, 'modeluri') && isString(object, 'type');
}

@@ -36,0 +37,0 @@ }

@@ -136,3 +136,3 @@ /********************************************************************************

public feature: string,
changedValues: DataValueType[] | ModelServerReferenceDescription[]
changedValues: DataValueType[] | ModelServerReferenceDescription[] | ModelServerObject[]
) {

@@ -142,2 +142,4 @@ super(SetCommand.TYPE);

this.objectValues = changedValues;
} else if (isModelServerObjectArray(changedValues)) {
this.objectsToAdd = changedValues;
} else {

@@ -144,0 +146,0 @@ this.dataValues = changedValues;

@@ -13,6 +13,5 @@ /********************************************************************************

import WebSocket from 'isomorphic-ws';
import URI from 'urijs';
import { Operations } from '.';
import { CommandExecutionResult } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { MessageDataMapper, MessageType, ModelServerMessage } from './model-server-message';

@@ -30,2 +29,4 @@ import {

} from './model-server-notification';
import { CommandExecutionResult } from './model/command-model';
import { Diagnostic } from './model/diagnostic';

@@ -38,6 +39,6 @@ /**

export interface SubscriptionListener {
onOpen(modelUri: string, event: WebSocket.Event): void;
onClose(modelUri: string, event: WebSocket.CloseEvent): void;
onError(modelUri: string, event: WebSocket.ErrorEvent): void;
onMessage(modelUri: string, event: WebSocket.MessageEvent): void;
onOpen(modeluri: URI, event: WebSocket.Event): void;
onClose(modeluri: URI, event: WebSocket.CloseEvent): void;
onError(modeluri: URI, event: WebSocket.ErrorEvent): void;
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void;
}

@@ -113,15 +114,15 @@

onOpen(modelUri: string, _event: WebSocket.Event): void {
this.notificationListener.onOpen?.({ modelUri, type: MessageType.open });
onOpen(modeluri: URI, _event: WebSocket.Event): void {
this.notificationListener.onOpen?.({ modeluri, type: MessageType.open });
}
onClose(modelUri: string, event: WebSocket.CloseEvent): void {
this.notificationListener.onClose?.({ modelUri, code: event.code, reason: event.reason, type: MessageType.close });
onClose(modeluri: URI, event: WebSocket.CloseEvent): void {
this.notificationListener.onClose?.({ modeluri, code: event.code, reason: event.reason, type: MessageType.close });
}
onError(modelUri: string, event: WebSocket.ErrorEvent): void {
this.notificationListener.onError?.({ modelUri, error: event.error, type: MessageType.error });
onError(modeluri: URI, event: WebSocket.ErrorEvent): void {
this.notificationListener.onError?.({ modeluri, error: event.error, type: MessageType.error });
}
onMessage(modelUri: string, event: WebSocket.MessageEvent): void {
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void {
const message = JSON.parse(event.data.toString());

@@ -132,3 +133,3 @@ if (ModelServerMessage.is(message)) {

case MessageType.dirtyState: {
this.notificationListener.onDirtyStateChanged?.({ modelUri, isDirty: MessageDataMapper.asBoolean(message), type });
this.notificationListener.onDirtyStateChanged?.({ modeluri, isDirty: MessageDataMapper.asBoolean(message), type });
break;

@@ -138,7 +139,7 @@ }

case MessageType.success: {
this.notificationListener.onSuccess?.({ modelUri, type });
this.notificationListener.onSuccess?.({ modeluri, type });
break;
}
case MessageType.error: {
this.notificationListener.onError?.({ modelUri, error: MessageDataMapper.asString(message), type });
this.notificationListener.onError?.({ modeluri, error: MessageDataMapper.asString(message), type });
break;

@@ -148,3 +149,3 @@ }

this.notificationListener.onIncrementalUpdate?.({
modelUri,
modeluri,
result: MessageDataMapper.as(message, CommandExecutionResult.is),

@@ -156,11 +157,11 @@ type

case MessageType.fullUpdate: {
this.notificationListener.onFullUpdate?.({ modelUri, model: MessageDataMapper.asObject(message), type });
this.notificationListener.onFullUpdate?.({ modeluri, model: MessageDataMapper.asObject(message), type });
break;
}
case MessageType.validationResult: {
this.notificationListener.onValidation?.({ modelUri, diagnostic: MessageDataMapper.as(message, Diagnostic.is), type });
this.notificationListener.onValidation?.({ modeluri, diagnostic: MessageDataMapper.as(message, Diagnostic.is), type });
break;
}
default: {
this.notificationListener.onUnknown?.({ ...message, modelUri });
this.notificationListener.onUnknown?.({ ...message, modeluri });
}

@@ -184,3 +185,3 @@ }

onMessage(modelUri: string, event: WebSocket.MessageEvent): void {
onMessage(modeluri: URI, event: WebSocket.MessageEvent): void {
const message = JSON.parse(event.data.toString());

@@ -194,3 +195,3 @@ if (ModelServerMessage.is(message)) {

type: message.type,
modelUri,
modeluri,
patch,

@@ -205,3 +206,3 @@ patchModel: (model, copy) => {

default: {
super.onMessage(modelUri, event);
super.onMessage(modeluri, event);
}

@@ -208,0 +209,0 @@ }

@@ -22,5 +22,5 @@ /********************************************************************************

export function isModelServerReferenceDescriptionArray(
array: Array<DataValueType | ModelServerReferenceDescription>
array: Array<DataValueType | ModelServerReferenceDescription | ModelServerObject>
): array is ModelServerReferenceDescription[] {
return array.every(ModelServerReferenceDescription.is);
}

@@ -12,2 +12,3 @@ /********************************************************************************

import { AddOperation, Operation, RemoveOperation, ReplaceOperation } from 'fast-json-patch';
import URI from 'urijs';

@@ -45,3 +46,3 @@ import { ModelServerObjectV2, ModelServerReferenceDescriptionV2 } from '../model/base-model';

*/
export function replace<T>(modeluri: string, object: ModelServerObjectV2, feature: string, value: T): ReplaceOperation<T> {
export function replace<T>(modeluri: URI, object: ModelServerObjectV2, feature: string, value: T): ReplaceOperation<T> {
return {

@@ -64,3 +65,3 @@ op: REPLACE,

export function create(
modeluri: string,
modeluri: URI,
parent: ModelServerObjectV2,

@@ -90,3 +91,3 @@ feature: string,

export function add(
modeluri: string,
modeluri: URI,
parent: ModelServerObjectV2,

@@ -112,3 +113,3 @@ feature: string,

*/
export function deleteElement(modeluri: string, object: ModelServerObjectV2): RemoveOperation {
export function deleteElement(modeluri: URI, object: ModelServerObjectV2): RemoveOperation {
return {

@@ -127,3 +128,3 @@ op: REMOVE,

*/
export function removeValueAt(modeluri: string, object: ModelServerObjectV2, feature: string, index: number): RemoveOperation {
export function removeValueAt(modeluri: URI, object: ModelServerObjectV2, feature: string, index: number): RemoveOperation {
return {

@@ -142,3 +143,3 @@ op: REMOVE,

*/
export function removeValue(modeluri: string, object: ModelServerObjectV2, feature: string, value: AnyObject): RemoveOperation | undefined {
export function removeValue(modeluri: URI, object: ModelServerObjectV2, feature: string, value: AnyObject): RemoveOperation | undefined {
const index = findIndex(object, feature, value);

@@ -156,3 +157,3 @@ if (index >= 0) {

*/
export function removeObject(modeluri: string, objectToRemove: ModelServerObjectV2): RemoveOperation {
export function removeObject(modeluri: URI, objectToRemove: ModelServerObjectV2): RemoveOperation {
return {

@@ -174,5 +175,5 @@ op: REMOVE,

*/
function getObjectPath(modeluri: string, object: ModelServerObjectV2 | ModelServerReferenceDescriptionV2): string {
function getObjectPath(modeluri: URI, object: ModelServerObjectV2 | ModelServerReferenceDescriptionV2): string {
const id = ModelServerReferenceDescriptionV2.is(object) ? object.$ref : object.$id;
return `${modeluri}#${id}`;
return modeluri.clone().fragment(id).toString();
}

@@ -192,3 +193,3 @@

*/
function getPropertyPath(modeluri: string, object: ModelServerObjectV2, feature: string, index?: number): string {
function getPropertyPath(modeluri: URI, object: ModelServerObjectV2, feature: string, index?: number): string {
const indexSuffix = index === undefined ? '' : `/${index}`;

@@ -195,0 +196,0 @@ return `${getObjectPath(modeluri, object)}/${feature}${indexSuffix}`;

@@ -11,2 +11,5 @@ /********************************************************************************

*******************************************************************************/
import URI from 'urijs';
import { Format, FORMAT_JSON_V1, FORMAT_JSON_V2, FORMAT_XMI, JsonFormat } from '../model-server-client-api-v2';

@@ -100,2 +103,15 @@ import { Model } from '../model-server-message';

}
if (Model.is(object)) {
return Model.toString(object);
}
if (Array.isArray(object) && object.every(Model.is)) {
return object.map(e => Model.toString(e)).toString();
}
if (isURI(object)) {
return asURI(object).toString();
}
if (Array.isArray(object) && object.every(isURI)) {
const uriArray = object.map(e => asURI(e).toString());
return JSON.stringify(uriArray, undefined, 2);
}
return JSON.stringify(object, undefined, 2);

@@ -146,3 +162,3 @@ }

if (AnyObject.is(object)) {
return Object.entries(object).map(entry => ({ modelUri: entry[0], content: entry[1] }));
return Object.entries(object).map(entry => ({ modeluri: entry[0], content: entry[1] }));
}

@@ -153,2 +169,39 @@

/**
* Validates whether the given object is a (deferred) instance of an URI object.
* @param object The object that should be validated
* @returns `true` if the object is an instance of URI
*/
export function isURI(object: unknown): object is URI {
return AnyObject.is(object) && isObject(object, '_parts') && isBoolean(object, '_deferred_build') && isString(object, '_string');
}
/**
* Maps the given object to an `URI` object.
* @param obj The object to map
* @returns The object as `URI`
*/
export function asURI(obj: unknown): URI {
if (typeof obj === 'string') {
return new URI(obj);
}
// reconstruct if URI object was deferred
if (isURI(obj)) {
return new URI((obj as any)._parts);
}
throw new Error('Cannot map to URI. Given parameter is not an URI!');
}
/**
* Maps the given object to a `string` array.
* @param object The object to map
* @returns The object as `URI` array
* @throws {@link Error} if the given object is not an array
*/
export function asURIArray(object: unknown): URI[] {
if (Array.isArray(object)) {
return object.map(asURI);
}
throw new Error('Cannot map to URI[]. Given parameter is not an array!');
}
/** Protocol of a message encoder. */

@@ -155,0 +208,0 @@ export type Encoder<T = unknown> = (object: string | AnyObject) => T | string;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc