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-theia-cr01 to 0.8.0-theia-cr02

lib/utils/index.d.ts

69

lib/model-server-client-api-v1.d.ts

@@ -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;
/**

@@ -58,3 +59,3 @@ * Additional subscription options supported by API v2 model subscriptions.

*/
export declare type PatchOrCommand = Operation | Operation[] | ModelPatch | ModelPatch[] | ModelServerCommand;
export type PatchOrCommand = Operation | Operation[] | ModelPatch | ModelPatch[] | ModelServerCommand;
/**

@@ -67,3 +68,3 @@ * Basic client API to interact with a model server that conforms to the Modelserver API Version 2.

* 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.

@@ -75,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>;
/**

@@ -83,32 +84,32 @@ * 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, patchOrCommand: PatchOrCommand, 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";
}

@@ -145,8 +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.
* @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, modelUri?: string): ModelServerElement;
patchModel?(oldModel: ModelServerElement, copy?: boolean, modeluri?: URI): ModelServerElement;
/**

@@ -153,0 +154,0 @@ * The Json Patch describing the changes that were applied to the model. Only present if

@@ -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

@@ -25,2 +25,5 @@ "use strict";

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });

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

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

@@ -44,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) => {

@@ -68,3 +77,3 @@ // Expected: originalModel === undoModel === patchedUndoModel

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

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

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

@@ -96,3 +105,3 @@ const newWorkflowName = 'New Test Workflow';

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

@@ -116,3 +125,3 @@ // Add a second workflow to the model; we'll use it to move a Task from a workflow to the other

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

@@ -129,3 +138,3 @@ const parentWorkflow = originalModel.workflows[0];

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

@@ -143,3 +152,3 @@ const parentWorkflow = originalModel.workflows[0];

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

@@ -149,3 +158,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 })
};

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

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

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

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

@@ -184,3 +193,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 })
};

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

const patch = notification.patch;
(0, chai_1.expect)(notification.modelUri).to.be.equal(modeluri);
(0, chai_1.expect)(notification.modeluri.toString()).to.be.equal(modeluri.toString());
(0, chai_1.expect)(patch.length).to.be.equal(1);

@@ -215,3 +224,3 @@ const operation = patch[0];

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

@@ -221,3 +230,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 })
};

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

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

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

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

@@ -284,3 +293,3 @@ const initialWorkflowsSize = machine.workflows.length;

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

@@ -302,3 +311,3 @@ const initialValue = machine.children[1].processor.thermalDesignPower;

it('check all patch replies', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

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

// Patch the first resource
const updatedMachineFirstPatch = result.patchModel(machine, true, result.allPatches[0].modelUri);
const updatedMachineFirstPatch = result.patchModel(machine, true, new urijs_1.default(result.allPatches[0].modelUri));
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineFirstPatch);

@@ -327,3 +336,3 @@ await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);

it('test model patches', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new urijs_1.default('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -335,9 +344,5 @@ const machine = await client.get(modeluri, _1.ModelServerObjectV2.is);

patchedMachine.children[1].processor.clockSpeed = 6;
// Generate patch by diffing the original model and the patched one
// Generate patches by diffing the original model and the patched one
const patch = fast_json_patch_1.default.compare(machine, patchedMachine);
const modelPatch = {
modelUri: modeluri,
patch
};
const result = await client.edit(modeluri, modelPatch);
const result = await client.edit(modeluri, patch);
(0, chai_1.expect)(result.success).to.be.true;

@@ -351,3 +356,3 @@ (0, chai_1.expect)(result.patch).to.not.be.undefined;

// Patch the first resource
const updatedMachineFirstPatch = result.patchModel(machine, true, result.allPatches[0].modelUri);
const updatedMachineFirstPatch = result.patchModel(machine, true, new urijs_1.default(result.allPatches[0].modelUri));
(0, chai_1.expect)(patchedMachine).to.deep.equal(updatedMachineFirstPatch);

@@ -354,0 +359,0 @@ await testUndoRedo(modeluri, machine, updatedMachineFirstPatch);

/********************************************************************************
* Copyright (c) 2022 STMicroelectronics and others.
* Copyright (c) 2022-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 { Diagnostic } from './model/diagnostic';
import URI from 'urijs';
import { ServerConfiguration, SubscriptionOptions } from './model-server-client-api-v1';
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';

@@ -26,41 +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, patchOrCommand: PatchOrCommand, format?: string): 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.
*

@@ -21,4 +32,2 @@ * This program and the accompanying materials are made available under the

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

@@ -28,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");

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

initialize(baseUrl, defaultFormat = model_server_client_api_v2_1.FORMAT_JSON_V2) {
this._baseUrl = baseUrl.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl;
this._baseUrl = baseUrl.clone();
this.defaultFormat = defaultFormat;

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

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

@@ -51,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);
}

@@ -74,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);
}

@@ -82,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);
}

@@ -94,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);
}

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

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

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

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

@@ -138,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);
}

@@ -151,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);
}

@@ -179,3 +199,3 @@ ping() {

success: true,
patchModel: (oldModel, copy, _modelUri) => (copy ? (0, fast_json_patch_1.deepClone)(oldModel) : oldModel),
patchModel: (oldModel, copy, _modeluri) => (copy ? (0, fast_json_patch_1.deepClone)(oldModel) : oldModel),
patch: []

@@ -186,15 +206,15 @@ });

return this.process(this.restClient.patch(model_server_paths_1.ModelServerPaths.MODEL_CRUD, (0, type_util_1.encodeRequestBody)(format)(patchMessage), {
params: { modeluri, format: format }
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));
}

@@ -204,3 +224,3 @@ }

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

@@ -216,28 +236,29 @@ 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());
}
}
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;
}

@@ -254,3 +275,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;

@@ -266,15 +287,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: (0, type_util_1.asType)(content, guard) };
return { modeluri, content: (0, type_util_1.asType)(content, guard) };
}
else if (toString) {
return { modelUri, content: (0, type_util_1.asString)(content) };
return { modeluri, content: (0, type_util_1.asString)(content) };
}
return { modelUri, content: (0, 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,3 +44,3 @@ client = new model_server_client_v2_1.ModelServerClientV2();

const axios = client['restClient'];
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl);
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});

@@ -44,10 +50,10 @@ it('test createSubscriptionPath without trailing slash', () => {

client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
(0, chai_1.expect)(subscriptionPath).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
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(`${baseUrl}/`);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
(0, chai_1.expect)(subscriptionPath).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
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');
});

@@ -63,3 +69,3 @@ describe('test requests', () => {

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

@@ -77,3 +83,3 @@ request = moxios_1.default.requests.at(1);

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -84,3 +90,3 @@ done();

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

@@ -92,7 +98,7 @@ client.getElementById(modeluri, elementid);

(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 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);
(0, 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();

@@ -102,3 +108,3 @@ });

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

@@ -110,7 +116,7 @@ client.getElementByName(modeluri, elementname);

(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 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);
(0, 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();

@@ -120,3 +126,3 @@ });

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

@@ -126,4 +132,4 @@ moxios_1.default.wait(() => {

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

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

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

@@ -140,4 +146,4 @@ moxios_1.default.wait(() => {

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

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

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

@@ -158,7 +164,7 @@ const data = JSON.stringify(model);

(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 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);
(0, 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();

@@ -168,3 +174,3 @@ });

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

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

(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 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);
(0, 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();

@@ -188,3 +194,3 @@ });

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

@@ -194,4 +200,4 @@ moxios_1.default.wait(() => {

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

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

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

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

@@ -220,4 +226,4 @@ moxios_1.default.wait(() => {

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

@@ -228,3 +234,3 @@ done();

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

@@ -234,4 +240,4 @@ moxios_1.default.wait(() => {

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

@@ -242,3 +248,3 @@ done();

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

@@ -248,4 +254,4 @@ moxios_1.default.wait(() => {

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

@@ -262,3 +268,3 @@ done();

(0, chai_1.expect)(request.config.params).to.include({ schemaname });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -270,4 +276,4 @@ done();

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

@@ -278,5 +284,8 @@ client.configureServer(configuration);

(0, chai_1.expect)(request.config.method).to.be.equal('put');
(0, chai_1.expect)(request.config.data).to.equal(JSON.stringify(configuration));
(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);
(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);

@@ -292,3 +301,3 @@ done();

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -299,3 +308,3 @@ done();

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

@@ -317,4 +326,4 @@ {

(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 });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -325,3 +334,3 @@ done();

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

@@ -331,4 +340,4 @@ moxios_1.default.wait(() => {

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

@@ -339,3 +348,3 @@ done();

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

@@ -345,4 +354,4 @@ moxios_1.default.wait(() => {

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

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

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

@@ -372,5 +381,5 @@ data: '',

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

@@ -381,3 +390,3 @@ name: 'coffee'

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

@@ -389,4 +398,4 @@ name: 'coffee'

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

@@ -404,3 +413,4 @@ type: 'success'

const result = onFulfilled.getCall(0).args[0];
(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();

@@ -407,0 +417,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.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : 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].toString()));
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: (0, type_util_1.asType)(content, guard) };
return { modeluri, content: (0, type_util_1.asType)(content, guard) };
}
else if (toString) {
return { modelUri, content: (0, type_util_1.asString)(content) };
return { modeluri, content: (0, type_util_1.asString)(content) };
}
return { modelUri, content: (0, 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,3 +44,3 @@ client = new model_server_client_1.ModelServerClient();

const axios = client['restClient'];
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl);
(0, chai_1.expect)(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});

@@ -44,10 +50,10 @@ it('test createSubscriptionPath without trailing slash', () => {

client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
(0, chai_1.expect)(subscriptionPath).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo');
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(`${baseUrl}/`);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
(0, chai_1.expect)(subscriptionPath).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo');
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');
});

@@ -63,3 +69,3 @@ describe('test requests', () => {

(0, chai_1.expect)(request.config.params).to.include({ format: 'json' });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -77,3 +83,3 @@ request = moxios_1.default.requests.at(1);

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -84,3 +90,3 @@ done();

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

@@ -93,3 +99,3 @@ client.getElementById(modeluri, elementid);

(0, chai_1.expect)(request.config.params).to.include({ format: 'json', elementid, modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -102,3 +108,3 @@ request = moxios_1.default.requests.at(1);

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

@@ -111,3 +117,3 @@ client.getElementByName(modeluri, elementname);

(0, chai_1.expect)(request.config.params).to.include({ format: 'json', elementname, modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -120,3 +126,3 @@ request = moxios_1.default.requests.at(1);

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

@@ -127,3 +133,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

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

@@ -141,3 +147,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

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

@@ -159,3 +165,3 @@ const data = JSON.stringify(model);

(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -168,3 +174,3 @@ request = moxios_1.default.requests.at(1);

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

@@ -179,3 +185,3 @@ const data = JSON.stringify(model);

(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -188,3 +194,3 @@ request = moxios_1.default.requests.at(1);

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

@@ -195,3 +201,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

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

@@ -221,3 +227,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -228,3 +234,3 @@ done();

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

@@ -235,3 +241,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -242,3 +248,3 @@ done();

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

@@ -249,3 +255,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -262,3 +268,3 @@ done();

(0, chai_1.expect)(request.config.params).to.include({ schemaname });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -270,4 +276,4 @@ done();

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

@@ -278,5 +284,8 @@ client.configureServer(configuration);

(0, chai_1.expect)(request.config.method).to.be.equal('put');
(0, chai_1.expect)(request.config.data).to.equal(JSON.stringify(configuration));
(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);
(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);

@@ -292,3 +301,3 @@ done();

(0, chai_1.expect)(request.config.params).to.be.undefined;
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -299,3 +308,3 @@ done();

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

@@ -311,3 +320,3 @@ eClass: 'http://www.eclipsesource.com/modelserver/example/coffeemodel#//Workflow',

(0, chai_1.expect)(request.config.params).to.include({ format: 'json', modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

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

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

@@ -325,3 +334,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.be.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -332,3 +341,3 @@ done();

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

@@ -339,3 +348,3 @@ moxios_1.default.wait(() => {

(0, chai_1.expect)(request.config.params).to.be.include({ modeluri });
(0, chai_1.expect)(request.config.baseURL).to.be.equal(baseUrl);
(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);

@@ -347,3 +356,3 @@ done();

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

@@ -367,3 +376,3 @@ data: '',

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

@@ -374,3 +383,3 @@ name: 'coffee'

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

@@ -382,4 +391,4 @@ name: 'coffee'

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

@@ -397,3 +406,4 @@ type: 'success'

const result = onFulfilled.getCall(0).args[0];
(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();

@@ -400,0 +410,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.

@@ -94,5 +94,9 @@ "use strict";

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 = {}));

@@ -149,2 +153,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.
*/
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}.

@@ -200,5 +214,5 @@ * @param message The message to map.

patch,
patchModel: (oldModel, copy, modelUri) => {
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;
const patchToApply = modeluri ? getPatch(allPatches, modeluri) : patch_utils_1.Operations.isPatch(patch) ? patch : undefined;
return patchToApply

@@ -220,7 +234,7 @@ ? jsonpatch.applyPatch(modelToPatch, patchToApply).newDocument

MessageDataMapper.patchModel = patchModel;
function getPatch(patches, modelUri) {
function getPatch(patches, modeluri) {
var _a;
return (_a = patches.find(mp => mp.modelUri === modelUri)) === null || _a === void 0 ? void 0 : _a.patch;
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) && (0, type_util_1.isString)(object, 'modelUri') && (0, 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;

@@ -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 @@ }

@@ -113,2 +113,5 @@ "use strict";

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

@@ -115,0 +118,0 @@ this.dataValues = changedValues;

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,3 +112,3 @@ const message = JSON.parse(event.data.toString());

type: message.type,
modelUri,
modeluri,
patch,

@@ -123,3 +123,3 @@ patchModel: (model, copy) => {

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 @@ *

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

"bugs": "https://github.com/eclipse-emfcloud/emfcloud-modelserver-theia/issues",
"version": "0.8.0-theia-cr01",
"version": "0.8.0-theia-cr02",
"files": [

@@ -48,6 +48,8 @@ "lib",

"isomorphic-ws": "^4.0.1",
"ws": "^7.4.6"
"urijs": "^1.19.11",
"ws": "^7.1.2"
},
"devDependencies": {
"@types/moxios": "0.4.14",
"@types/urijs": "^1.19.19",
"@types/ws": "8.2.2",

@@ -68,3 +70,3 @@ "ignore-styles": "^5.0.1",

},
"gitHead": "c64d6b75e0cf501c0032e2ca714b56418743bf17"
"gitHead": "df49caac32ac1a9e29584e36efdd00ad0bbf332d"
}

@@ -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';

@@ -74,3 +75,3 @@ import { ModelServerElement } from './model/base-model';

* 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.

@@ -82,3 +83,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>;

@@ -92,32 +93,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>;

@@ -130,17 +131,17 @@ getUiSchema(schemaname: string): Promise<string>;

edit(modeluri: string, patchOrCommand: PatchOrCommand, 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';
}

@@ -181,8 +182,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.
* @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, modelUri?: string): ModelServerElement;
patchModel?(oldModel: ModelServerElement, copy?: boolean, modeluri?: URI): ModelServerElement;

@@ -189,0 +190,0 @@ /**

@@ -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) => Promise<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);

@@ -378,3 +384,3 @@

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

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

// Patch the first resource
const updatedMachineFirstPatch = result.patchModel!(machine, true, result.allPatches![0].modelUri);
const updatedMachineFirstPatch = result.patchModel!(machine, true, new URI(result.allPatches![0].modelUri));
expect(patchedMachine).to.deep.equal(updatedMachineFirstPatch);

@@ -412,3 +418,3 @@

it('test model patches', async () => {
const modeluri = 'SuperBrewer3000.coffee';
const modeluri = new URI('SuperBrewer3000.coffee');
const newName = 'Super Brewer 6000';

@@ -423,10 +429,6 @@ const machine = await client.get(modeluri, ModelServerObjectV2.is);

// Generate patch by diffing the original model and the patched one
// Generate patches by diffing the original model and the patched one
const patch = jsonpatch.compare(machine, patchedMachine);
const modelPatch = {
modelUri: modeluri,
patch
};
const result = await client.edit(modeluri, modelPatch);
const result = await client.edit(modeluri, patch);
expect(result.success).to.be.true;

@@ -443,3 +445,3 @@

// Patch the first resource
const updatedMachineFirstPatch = result.patchModel!(machine, true, result.allPatches![0].modelUri);
const updatedMachineFirstPatch = result.patchModel!(machine, true, new URI(result.allPatches![0].modelUri));
expect(patchedMachine).to.deep.equal(updatedMachineFirstPatch);

@@ -446,0 +448,0 @@

@@ -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,3 +47,3 @@ beforeEach(() => {

const axios = client['restClient'];
expect(axios.defaults.baseURL).to.be.equal(baseUrl);
expect(axios.defaults.baseURL).to.be.equal(baseUrl.toString());
});

@@ -47,10 +53,10 @@ it('test createSubscriptionPath without trailing slash', () => {

client.initialize(baseUrl);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
expect(subscriptionPath).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
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(`${baseUrl}/`);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
expect(subscriptionPath).to.be.equal('ws://localhost:8081/api/v2/subscribe?modeluri=foo&format=json-v2');
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');
});

@@ -67,3 +73,3 @@

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

@@ -82,3 +88,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);

@@ -90,3 +96,3 @@ done();

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

@@ -100,7 +106,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();

@@ -111,3 +117,3 @@ });

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

@@ -121,7 +127,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();

@@ -132,3 +138,3 @@ });

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

@@ -138,4 +144,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);

@@ -147,3 +153,3 @@ done();

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

@@ -153,4 +159,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);

@@ -162,3 +168,3 @@ done();

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

@@ -173,7 +179,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();

@@ -184,3 +190,3 @@ });

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

@@ -195,7 +201,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();

@@ -206,3 +212,3 @@ });

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

@@ -212,4 +218,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);

@@ -226,3 +232,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);

@@ -234,3 +240,3 @@ done();

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

@@ -240,4 +246,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);

@@ -249,3 +255,3 @@ done();

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

@@ -255,4 +261,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);

@@ -264,3 +270,3 @@ done();

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

@@ -270,4 +276,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);

@@ -285,3 +291,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);

@@ -294,4 +300,4 @@ done();

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

@@ -302,5 +308,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);

@@ -317,3 +328,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);

@@ -325,3 +336,3 @@ done();

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

@@ -344,4 +355,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);

@@ -353,3 +364,3 @@ done();

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

@@ -359,4 +370,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);

@@ -368,3 +379,3 @@ done();

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

@@ -374,4 +385,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);

@@ -384,3 +395,3 @@ done();

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

@@ -403,5 +414,5 @@ data: '',

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

@@ -412,3 +423,3 @@ name: 'coffee'

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

@@ -420,4 +431,4 @@ name: 'coffee'

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

@@ -435,3 +446,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();

@@ -438,0 +450,0 @@ });

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

@@ -11,8 +11,7 @@ * 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 { 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';

@@ -22,2 +21,4 @@ import { Format, FORMAT_JSON_V2, ModelServerClientApiV2, ModelUpdateResult, PatchOrCommand } from './model-server-client-api-v2';

import { ModelServerPaths } from './model-server-paths';
import { ModelServerCommand } from './model/command-model';
import { Diagnostic } from './model/diagnostic';
import { SubscriptionListener } from './subscription-listener';

@@ -32,7 +33,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.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : baseUrl;
initialize(baseUrl: URI, defaultFormat: Format = FORMAT_JSON_V2): void | Promise<void> {
this._baseUrl = baseUrl.clone();
this.defaultFormat = defaultFormat;

@@ -42,17 +43,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
);
}

@@ -80,9 +85,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;

@@ -92,4 +97,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)
);

@@ -100,3 +106,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

@@ -106,5 +112,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;

@@ -115,3 +121,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)

@@ -123,3 +129,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

@@ -129,5 +135,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;

@@ -138,3 +144,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)

@@ -146,3 +154,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

@@ -152,6 +162,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,

@@ -166,3 +176,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)

@@ -174,3 +186,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

@@ -180,12 +194,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
);
}

@@ -197,4 +220,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)

@@ -204,5 +227,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

@@ -212,4 +235,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
);
}

@@ -222,7 +248,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

@@ -236,3 +262,3 @@ );

edit(modeluri: string, patchOrCommand: PatchOrCommand, format = this.defaultFormat): Promise<ModelUpdateResult> {
edit(modeluri: URI, patchOrCommand: PatchOrCommand, format = this.defaultFormat): Promise<ModelUpdateResult> {
let patchMessage: any;

@@ -255,3 +281,3 @@ if (patchOrCommand instanceof ModelServerCommand) {

success: true,
patchModel: (oldModel, copy, _modelUri) => (copy ? deepClone(oldModel) : oldModel),
patchModel: (oldModel, copy, _modeluri) => (copy ? deepClone(oldModel) : oldModel),
patch: []

@@ -263,3 +289,3 @@ });

this.restClient.patch(ModelServerPaths.MODEL_CRUD, encodeRequestBody(format)(patchMessage), {
params: { modeluri, format: format }
params: { modeluri: modeluri.toString(), format: format }
}),

@@ -270,20 +296,26 @@ 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);

@@ -299,32 +331,33 @@ if (options.errorWhenUnsuccessful) {

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

@@ -340,3 +373,3 @@

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

@@ -351,6 +384,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'];
}
/**

@@ -363,9 +392,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,16 +46,15 @@ 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']('foo', {});
expect(subscriptionPath).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo');
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(`${baseUrl}/`);
const subscriptionPath = client['createSubscriptionPath']('foo', {});
expect(subscriptionPath).to.be.equal('ws://localhost:8081/api/v1/subscribe?modeluri=foo');
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');
});

@@ -66,3 +71,3 @@

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

@@ -81,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);

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

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

@@ -100,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);

@@ -110,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';

@@ -121,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);

@@ -131,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);

@@ -138,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);

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

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

@@ -153,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);

@@ -161,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' };

@@ -173,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);

@@ -183,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' };

@@ -195,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);

@@ -205,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);

@@ -212,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);

@@ -225,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);

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

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

@@ -240,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);

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

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

@@ -255,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);

@@ -263,3 +268,3 @@ done();

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

@@ -270,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);

@@ -284,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);

@@ -293,4 +298,4 @@ done();

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

@@ -301,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);

@@ -316,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);

@@ -324,3 +334,3 @@ done();

it('edit', done => {
const modeluri = 'edit/me/please';
const modeluri = new URI('edit/me/please');
const command = new SetCommand(

@@ -342,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);

@@ -350,3 +360,3 @@ done();

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

@@ -357,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);

@@ -365,3 +375,3 @@ done();

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

@@ -372,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);

@@ -381,3 +391,3 @@ done();

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

@@ -402,3 +412,3 @@ data: '',

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

@@ -409,3 +419,3 @@ name: 'coffee'

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

@@ -417,4 +427,4 @@ name: 'coffee'

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

@@ -432,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();

@@ -435,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.endsWith('/') ? baseUrl.substring(0, baseUrl.length - 1) : 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].toString()));
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) };
}

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

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 { ModelPatch, 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}.

@@ -211,5 +226,5 @@ * @param message The message to map.

patch,
patchModel: (oldModel, copy, modelUri) => {
patchModel: (oldModel, copy, modeluri) => {
const modelToPatch = copy ? deepClone(oldModel) : oldModel;
const patchToApply = modelUri ? getPatch(allPatches, modelUri) : Operations.isPatch(patch) ? patch : undefined;
const patchToApply = modeluri ? getPatch(allPatches, modeluri) : Operations.isPatch(patch) ? patch : undefined;
return patchToApply

@@ -229,5 +244,5 @@ ? (jsonpatch.applyPatch(modelToPatch, patchToApply).newDocument as ModelServerElement)

function getPatch(patches: ModelPatch[], modelUri: string): Operation[] | undefined {
return patches.find(mp => mp.modelUri === modelUri)?.patch;
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

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