@js4cytoscape/ndex-client 0.5.0-alpha.9 → 0.6.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +248 -13
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.mts +1931 -0
- package/dist/index.d.ts +1931 -0
- package/dist/index.global.js +9 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +79 -21
- package/src/CyNDEx.js.bak +178 -0
- package/src/NDEx.js +66 -13
- package/src/NDEx.js.bak +1107 -0
- package/src/index.ts +207 -0
- package/src/models/CX2Network.ts +423 -0
- package/src/services/AdminService.ts +10 -0
- package/src/services/CyNDExService.ts +338 -0
- package/src/services/FilesService.ts +234 -0
- package/src/services/HTTPService.ts +445 -0
- package/src/services/NetworkServiceV2.ts +427 -0
- package/src/services/NetworkServiceV3.ts +287 -0
- package/src/services/UnifiedNetworkService.ts +653 -0
- package/src/services/UserService.ts +233 -0
- package/src/services/WorkspaceService.ts +159 -0
- package/src/types/cytoscape.ts +81 -0
- package/src/types/index.ts +515 -0
- package/dist/ndexClient.common.js +0 -1057
- package/dist/ndexClient.js +0 -538
- package/src/index.js +0 -2
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@js4cytoscape/ndex-client",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "NDEx client library",
|
|
3
|
+
"version": "0.6.0-alpha.1",
|
|
4
|
+
"description": "NDEx client library - Modern TypeScript implementation",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "git+https://github.com/cytoscape/js4cytoscape.git"
|
|
@@ -10,36 +10,94 @@
|
|
|
10
10
|
"url": "https://github.com/cytoscape/js4cytoscape/issues"
|
|
11
11
|
},
|
|
12
12
|
"homepage": "https://github.com/cytoscape/js4cytoscape",
|
|
13
|
-
"main": "./dist/
|
|
14
|
-
"module": "
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"module": "./dist/index.mjs",
|
|
15
|
+
"umd": "./dist/index.umd.js",
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./dist/index.d.ts",
|
|
20
|
+
"import": "./dist/index.mjs",
|
|
21
|
+
"require": "./dist/index.js"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
15
24
|
"files": [
|
|
16
25
|
"dist",
|
|
17
|
-
"src"
|
|
26
|
+
"src",
|
|
27
|
+
"README.md",
|
|
28
|
+
"LICENSE"
|
|
18
29
|
],
|
|
19
30
|
"scripts": {
|
|
20
|
-
"
|
|
21
|
-
"build": "
|
|
22
|
-
"build
|
|
23
|
-
"
|
|
31
|
+
"dev": "tsup --watch",
|
|
32
|
+
"build": "tsup",
|
|
33
|
+
"build:docs": "typedoc",
|
|
34
|
+
"docs:api": "npm run build:docs",
|
|
35
|
+
"docs:site": "cd docs-site && npm install && npm run build",
|
|
36
|
+
"docs:serve": "cd docs-site && npm run start",
|
|
37
|
+
"docs:build": "npm run docs:api && npm run docs:site",
|
|
38
|
+
"docs:clean": "rimraf docs docs-site/build docs-site/docs/api",
|
|
39
|
+
"test": "npm run test:unit",
|
|
40
|
+
"test:unit": "jest --config jest.unit.config.js",
|
|
41
|
+
"test:integration": "jest --config jest.integration.config.js",
|
|
42
|
+
"test:all": "npm run test:unit && npm run test:integration",
|
|
43
|
+
"test:watch": "npm run test:unit -- --watch",
|
|
44
|
+
"test:coverage": "npm run test:unit -- --coverage",
|
|
45
|
+
"test:ci": "npm run test:all -- --coverage",
|
|
46
|
+
"debug:integration": "node --inspect-brk ./node_modules/.bin/jest --config jest.integration.config.js --runInBand --no-cache",
|
|
47
|
+
"debug:unit": "node --inspect-brk ./node_modules/.bin/jest --config jest.unit.config.js --runInBand --no-cache",
|
|
48
|
+
"debug:client": "node --inspect-brk debug-response.js",
|
|
49
|
+
"lint": "eslint src __tests__ --ext .ts,.js --fix",
|
|
50
|
+
"format": "prettier --write \"src/**/*.{ts,js}\" \"__tests__/**/*.{ts,js}\"",
|
|
51
|
+
"type-check": "tsc --noEmit",
|
|
52
|
+
"clean": "rimraf dist coverage",
|
|
53
|
+
"prepare": "npm run build",
|
|
54
|
+
"changeset": "changeset",
|
|
55
|
+
"release": "changeset publish"
|
|
24
56
|
},
|
|
25
57
|
"author": "Jing Chen",
|
|
26
58
|
"license": "MIT",
|
|
27
59
|
"engines": {
|
|
28
|
-
"node": ">=
|
|
60
|
+
"node": ">=16.0.0"
|
|
29
61
|
},
|
|
62
|
+
"keywords": [
|
|
63
|
+
"ndex",
|
|
64
|
+
"network",
|
|
65
|
+
"cytoscape",
|
|
66
|
+
"bioinformatics",
|
|
67
|
+
"graph",
|
|
68
|
+
"cx2",
|
|
69
|
+
"typescript"
|
|
70
|
+
],
|
|
30
71
|
"dependencies": {
|
|
31
|
-
"axios": "^1.
|
|
72
|
+
"axios": "^1.11.0"
|
|
32
73
|
},
|
|
33
74
|
"devDependencies": {
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
|
|
43
|
-
|
|
75
|
+
"@changesets/cli": "^2.27.1",
|
|
76
|
+
"@types/jest": "^29.5.12",
|
|
77
|
+
"@types/node": "^20.11.25",
|
|
78
|
+
"@typescript-eslint/eslint-plugin": "^7.1.1",
|
|
79
|
+
"@typescript-eslint/parser": "^7.1.1",
|
|
80
|
+
"eslint": "^8.57.0",
|
|
81
|
+
"eslint-config-prettier": "^9.1.0",
|
|
82
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
83
|
+
"glob": "^7.2.0",
|
|
84
|
+
"jest": "^29.7.0",
|
|
85
|
+
"jest-environment-jsdom": "^29.7.0",
|
|
86
|
+
"nock": "^13.5.4",
|
|
87
|
+
"prettier": "^3.2.5",
|
|
88
|
+
"rimraf": "^5.0.5",
|
|
89
|
+
"ts-jest": "^29.1.2",
|
|
90
|
+
"tsup": "^8.0.2",
|
|
91
|
+
"typedoc": "^0.25.12",
|
|
92
|
+
"typedoc-plugin-markdown": "^3.17.1",
|
|
93
|
+
"typescript": "^5.4.2"
|
|
94
|
+
},
|
|
95
|
+
"peerDependencies": {
|
|
96
|
+
"cytoscape": "^3.0.0"
|
|
97
|
+
},
|
|
98
|
+
"peerDependenciesMeta": {
|
|
99
|
+
"cytoscape": {
|
|
100
|
+
"optional": true
|
|
101
|
+
}
|
|
44
102
|
}
|
|
45
103
|
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
const CY_REST_BASE_URL = 'http://127.0.0.1';
|
|
2
|
+
|
|
3
|
+
import { default as axios } from 'axios';
|
|
4
|
+
|
|
5
|
+
class CyNDEx {
|
|
6
|
+
|
|
7
|
+
constructor(port = 1234) {
|
|
8
|
+
this._port = port;
|
|
9
|
+
}
|
|
10
|
+
get port() { return this._port; }
|
|
11
|
+
|
|
12
|
+
static get cyRestBaseURL() {
|
|
13
|
+
return CY_REST_BASE_URL;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
setNDExServer(ndexServer) {
|
|
17
|
+
if (ndexServer !== undefined && ndexServer != null && ndexServer !== '') {
|
|
18
|
+
this._ndexServer = ndexServer;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
getNDExServer() {
|
|
23
|
+
return this._ndexServer ? this._ndexServer : 'https://www.ndexbio.org';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setGoogleAuth(googleAuthObj) {
|
|
27
|
+
if (googleAuthObj !== undefined) {
|
|
28
|
+
this._googleAuth = googleAuthObj;
|
|
29
|
+
this._authType = 'g'; // valid values are 'g','b' or undefined
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
setAuthToken(authToken) {
|
|
34
|
+
if (authToken !== undefined ) {
|
|
35
|
+
this._authToken = authToken;
|
|
36
|
+
this._authType = 'g'; // valid values are 'g','b' or undefined
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
setBasicAuth(username, password) {
|
|
41
|
+
if (username !== undefined && username != null && username !== '') {
|
|
42
|
+
this._username = username;
|
|
43
|
+
this._password = password;
|
|
44
|
+
this._authType = 'b';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
cyRestURL() {
|
|
49
|
+
return CY_REST_BASE_URL + ':' + this._port;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_getIdToken() {
|
|
53
|
+
return this._authToken ? this._authToken : this._googleAuth.getAuthInstance().currentUser.get().getAuthResponse().id_token;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
_getAuthorizationFields() {
|
|
57
|
+
switch (this._authType) {
|
|
58
|
+
case 'b' : return {
|
|
59
|
+
username : this._username,
|
|
60
|
+
password : this._password
|
|
61
|
+
};
|
|
62
|
+
case 'g' : return {
|
|
63
|
+
idToken : this._getIdToken()
|
|
64
|
+
};
|
|
65
|
+
default : return {};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
_httpGet(url) {
|
|
70
|
+
|
|
71
|
+
const baseURL = this.cyRestURL();
|
|
72
|
+
|
|
73
|
+
return new Promise(function (resolve, reject) {
|
|
74
|
+
axios({
|
|
75
|
+
method: 'get',
|
|
76
|
+
url: url,
|
|
77
|
+
baseURL: baseURL
|
|
78
|
+
}).then((response) => {
|
|
79
|
+
if (response.status === 200) {
|
|
80
|
+
return resolve(response.data);
|
|
81
|
+
}
|
|
82
|
+
return reject(response);
|
|
83
|
+
},
|
|
84
|
+
(response) => { return reject(response); }
|
|
85
|
+
);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
_httpPut(url, parameters, data) {
|
|
90
|
+
return this._http('put', url, parameters, data);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
_httpPost(url, parameters, data) {
|
|
94
|
+
return this._http('post', url, parameters, data);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_http(method, url, parameters, data) {
|
|
98
|
+
|
|
99
|
+
const baseURL = this.cyRestURL();
|
|
100
|
+
|
|
101
|
+
let config = {
|
|
102
|
+
method: method,
|
|
103
|
+
url: url,
|
|
104
|
+
baseURL: baseURL
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
if (parameters !== undefined) {
|
|
108
|
+
config['params'] = parameters;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
config.data = data;
|
|
112
|
+
return new Promise(function (resolve, reject) {
|
|
113
|
+
axios(config).then((response) => {
|
|
114
|
+
if (response.status >= 200 && response.status <= 299) {
|
|
115
|
+
return resolve(response.data);
|
|
116
|
+
}
|
|
117
|
+
return reject(response);
|
|
118
|
+
},
|
|
119
|
+
(response) => {
|
|
120
|
+
return reject(response);
|
|
121
|
+
}
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getCyNDExStatus() {
|
|
128
|
+
return this._httpGet('/cyndex2/v1');
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
getCytoscapeNetworkSummary(suid = 'current') {
|
|
132
|
+
return this._httpGet('/cyndex2/v1/networks/' + suid);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
postNDExNetworkToCytoscape(uuid, accessKey, createView = undefined) {
|
|
136
|
+
const importParams = {
|
|
137
|
+
serverUrl: this.getNDExServer() + '/v2',
|
|
138
|
+
uuid: uuid,
|
|
139
|
+
accessKey: accessKey,
|
|
140
|
+
createView: createView
|
|
141
|
+
};
|
|
142
|
+
|
|
143
|
+
const authorizationFields = this._getAuthorizationFields();
|
|
144
|
+
|
|
145
|
+
return this._httpPost('/cyndex2/v1/networks', undefined, Object.assign(importParams, authorizationFields));
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
postCXNetworkToCytoscape(cx) {
|
|
149
|
+
return this._httpPost('/cyndex2/v1/networks/cx', undefined, cx);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
postCX2NetworkToCytoscape(cx2_string, title, collection_name) {
|
|
153
|
+
return this._httpPost('/v1/networks',{ 'format': 'cx2', 'collection': collection_name, 'title':title}, cx2_string);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
postCytoscapeNetworkToNDEx(suid = 'current') {
|
|
157
|
+
const saveParams = {
|
|
158
|
+
serverUrl: this.getNDExServer() + '/v2',
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const authorizationFields = this._getAuthorizationFields();
|
|
162
|
+
|
|
163
|
+
return this._httpPost('/cyndex2/v1/networks/' + suid, undefined, Object.assign(saveParams, authorizationFields));
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
putCytoscapeNetworkInNDEx(suid = 'current', uuid) {
|
|
167
|
+
const saveParams = {
|
|
168
|
+
serverUrl: this.getNDExServer() + '/v2',
|
|
169
|
+
uuid: uuid
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
const authorizationFields = this._getAuthorizationFields();
|
|
173
|
+
|
|
174
|
+
return this._httpPut('/cyndex2/v1/networks/' + suid, undefined, Object.assign(saveParams, authorizationFields));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export default CyNDEx ;
|
package/src/NDEx.js
CHANGED
|
@@ -593,11 +593,19 @@ class NDEx {
|
|
|
593
593
|
}
|
|
594
594
|
|
|
595
595
|
moveNetworks(networkIds, folderId){
|
|
596
|
-
|
|
596
|
+
if(Object.isArray(networkIds)){
|
|
597
|
+
return this._httpPostV3ProtectedObj('batch/networks/move', undefined, {targetFolder:folderId, networks: networkIds});
|
|
598
|
+
}else{
|
|
599
|
+
throw new Error('Invalid networkIds');
|
|
600
|
+
}
|
|
597
601
|
}
|
|
598
602
|
|
|
599
603
|
setNetworksVisibility(files, visibility){
|
|
600
|
-
|
|
604
|
+
if(this._validateShareData(files)){
|
|
605
|
+
return this._httpPostV3ProtectedObj('batch/networks/visibility', undefined, {items: files, visibility: visibility});
|
|
606
|
+
}else{
|
|
607
|
+
throw new Error('Invalid share data');
|
|
608
|
+
}
|
|
601
609
|
}
|
|
602
610
|
|
|
603
611
|
/* network set functions */
|
|
@@ -877,6 +885,18 @@ class NDEx {
|
|
|
877
885
|
return this._httpPostV3ProtectedObj('users/signin', undefined, {idToken: idToken});
|
|
878
886
|
}
|
|
879
887
|
|
|
888
|
+
// Permission and AccessKey APIs
|
|
889
|
+
|
|
890
|
+
//Todo:permission APIs
|
|
891
|
+
|
|
892
|
+
getAccessKey(uuid){
|
|
893
|
+
return this._httpGetProtectedObj('network/'+uuid+'/accesskey', {});
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
updateAccessKey(uuid, action){
|
|
897
|
+
return this._httpPutObj('network/'+uuid+'/accesskey', {action: action});
|
|
898
|
+
}
|
|
899
|
+
|
|
880
900
|
// V3-Files APIs
|
|
881
901
|
copyFile(fromUuid, toPath, type, accessKey) {
|
|
882
902
|
let parameters = {};
|
|
@@ -908,14 +928,6 @@ class NDEx {
|
|
|
908
928
|
}
|
|
909
929
|
// Sharing
|
|
910
930
|
//add, remove, update member
|
|
911
|
-
updateMember(files, members){
|
|
912
|
-
return this._httpPostV3ProtectedObj('files/sharing/members', undefined, {files: files, members: members});
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
listMembers(files){
|
|
916
|
-
return this._httpGetV3ProtectedObj('files/sharing/members/list', files);
|
|
917
|
-
}
|
|
918
|
-
|
|
919
931
|
_validateShareData(data) {
|
|
920
932
|
// Check if data is an object and has files property
|
|
921
933
|
if (typeof data !== 'object' || data === null || data.files === undefined) {
|
|
@@ -942,9 +954,42 @@ class NDEx {
|
|
|
942
954
|
}
|
|
943
955
|
}
|
|
944
956
|
}
|
|
957
|
+
_validateMemberData(data){
|
|
958
|
+
if(typeof data !== 'object' || data === null || data.members === undefined){
|
|
959
|
+
throw new Error('Data must be an object with a "members" property');
|
|
960
|
+
}
|
|
961
|
+
const validValues = ['READ', 'WRITE'];
|
|
962
|
+
for (const [uuid, permission] of Object.entries(data.members)) {
|
|
963
|
+
if (!validValues.includes(permission)) {
|
|
964
|
+
throw new Error(`Invalid permission for ${uuid}: ${permission}. Must be one of: ${validValues.join(', ')}`);
|
|
965
|
+
}
|
|
966
|
+
if(typeof uuid !== 'string' || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(uuid)){
|
|
967
|
+
throw new Error(`Invalid UUID format: ${uuid}`);
|
|
968
|
+
}
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
updateMember(files, members){
|
|
974
|
+
if(this._validateShareData(files) && this._validateMemberData(members)){
|
|
975
|
+
return this._httpPostV3ProtectedObj('files/sharing/members', undefined, {files: files, members: members});
|
|
976
|
+
}else{
|
|
977
|
+
throw new Error('Invalid share data');
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
listMembers(files){
|
|
982
|
+
return this._httpGetV3ProtectedObj('files/sharing/members/list', files);
|
|
983
|
+
}
|
|
984
|
+
|
|
985
|
+
|
|
945
986
|
|
|
946
987
|
transferOwnership(files, newOwner){
|
|
947
|
-
|
|
988
|
+
if(this._validateShareData(files)){
|
|
989
|
+
return this._httpPostV3ProtectedObj('files/sharing/transfer_ownership', undefined, {files: files, new_owner: newOwner});
|
|
990
|
+
} else {
|
|
991
|
+
throw new Error('Invalid share data');
|
|
992
|
+
}
|
|
948
993
|
}
|
|
949
994
|
|
|
950
995
|
listShares(limit){
|
|
@@ -956,11 +1001,19 @@ class NDEx {
|
|
|
956
1001
|
}
|
|
957
1002
|
|
|
958
1003
|
share(files){
|
|
959
|
-
|
|
1004
|
+
if(this._validateShareData(files)){
|
|
1005
|
+
return this._httpPostV3ProtectedObj('files/sharing/share', undefined, {files: files});
|
|
1006
|
+
}else{
|
|
1007
|
+
throw new Error('Invalid share data');
|
|
1008
|
+
}
|
|
960
1009
|
}
|
|
961
1010
|
|
|
962
1011
|
unshare(files){
|
|
963
|
-
|
|
1012
|
+
if(this._validateShareData(files)){
|
|
1013
|
+
return this._httpPostV3ProtectedObj('files/sharing/unshare', undefined, {files: files});
|
|
1014
|
+
}else{
|
|
1015
|
+
throw new Error('Invalid share data');
|
|
1016
|
+
}
|
|
964
1017
|
}
|
|
965
1018
|
|
|
966
1019
|
// Folder
|