From 05cacd6a31fa0052a10267e4e44b9a662b1d5aac Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Mon, 11 Apr 2016 14:34:05 +0900
Subject: [PATCH 01/15] [FEATURE] support electron
- added some work-around code to use same dojo profile with browser,
renaming CJS require/module to nrequire, nmodule
- fixed site-config.json for conn server url typo
---
apps/ide/src/dojoConfig.js | 24 +++++++++++++++++++++++-
site-config.json | 8 ++++----
2 files changed, 27 insertions(+), 5 deletions(-)
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index 3a5b0de2..2d2b535c 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -16,6 +16,19 @@
(function (global) {
'use strict';
+
+ // in electron, we should remove global.require & global.module
+ // to make dojo & other amd module work
+ // how can we detect that we're working in electron?
+ if (typeof(global.process) === 'object' &&
+ typeof(global.require) === 'function' &&
+ typeof(global.module) === 'object') {
+ global.nrequire = global.require;
+ global.nmodule = global.module;
+ delete global.require;
+ delete global.module;
+ }
+
var webidaLocale = decodeURIComponent(
document.cookie.replace(/(?:(?:^|.*;\s*)webida\.locale\s*\=\s*([^;]*).*$)|^.*$/, '$1')
);
@@ -52,6 +65,15 @@
['msg', 'webida-lib/msg.js'],
// diff_match_patch is used in codemirror
['diff_match_patch', '//cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js']
- ]
+ ],
};
+
+ // dojo may understand cjs require() by building option
+ // but some bower modules works under amd system only
+ // we don't allow to mix amd/cjs modules with same require function
+ if (global.nrequire) {
+ global.dojoConfig.has = {
+ 'host-node': false // Prevent dojo from being fooled by Electron
+ }
+ }
})(window);
diff --git a/site-config.json b/site-config.json
index 0f970329..6c33654c 100644
--- a/site-config.json
+++ b/site-config.json
@@ -14,7 +14,7 @@
"buildTime": "1970 01 01 00 00 00",
"commitId": ""
},
- "googleAnalytics" : "UA-68503782-1"
+ "googleAnalyics" : false
},
"server": {
"appServer": "https://app.webida.org",
@@ -22,13 +22,13 @@
"fsServer": "https://fs.webida.org",
"buildServer": "https://build.webida.org",
"ntfServer": "https://ntf.webida.org",
- "connServer": "https://build.webida.org",
+ "connServer": "https://conn.webida.org",
"corsServer": "https://cors.webida.org",
"deploy": {
- "type": "domain",
+ "type": "path",
"pathPrefix": "-"
},
"signUpEnable": false,
- "guestMode": true
+ "guestMode": false
}
}
From fcbd16412b3dea250d5f1634d50058d1c2de7720 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 20 May 2016 17:49:14 +0900
Subject: [PATCH 02/15] added site-config-desktop.json
- fixed old site-config*.json files to have right 'build' property
---
site-config-desktop.json | 23 +++++++++++++++++++++++
site-config-example.json | 14 +++++++-------
site-config.json | 12 ++++++------
3 files changed, 36 insertions(+), 13 deletions(-)
create mode 100644 site-config-desktop.json
diff --git a/site-config-desktop.json b/site-config-desktop.json
new file mode 100644
index 00000000..ed325796
--- /dev/null
+++ b/site-config-desktop.json
@@ -0,0 +1,23 @@
+{
+ "app": {
+ "appId" : "webida-ide-desktop",
+ "baseUrl": false,
+ "dashboardBaseUrl" : "unused",
+ "apidocBaseUrl" : "will be generated automatically",
+ "oauth": {
+ "clientId": "webida-ide-desktop",
+ "redirectUrl": false
+ }
+ },
+
+ "// server" : " data will be filled from local storage, (webida-destktop-config item)",
+ "server": { },
+
+ "// build" : "will be re-written while packaging webida desktop with electron-packager",
+ "build" : {
+ "version" : "0.0.0",
+ "buildNumber": 0,
+ "buildTime": "1970-01-01 00:00:00",
+ "commitId": "unknown"
+ }
+}
\ No newline at end of file
diff --git a/site-config-example.json b/site-config-example.json
index bc58cfef..75522651 100644
--- a/site-config-example.json
+++ b/site-config-example.json
@@ -8,12 +8,6 @@
"clientId": "webida-ide-local-5000",
"redirectUrl": "http://localhost:5000/webida-client/auth.html"
},
- "build" : {
- "version" : "0.0.0",
- "buildNumber": 0,
- "buildTime": "1970-01-01 00:00:00",
- "commitId": "unknown"
- },
"googleAnalytics" : false
},
"server": {
@@ -22,7 +16,7 @@
"fsServer": "http://fs.webida.net",
"buildServer": "http://build.webida.net",
"ntfServer": "http://ntf.webida.net",
- "connServer": "http://build.webida.net",
+ "connServer": "http://conn.webida.net",
"corsServer": "http://cors.webida.net",
"deploy": {
"type": "domain",
@@ -30,5 +24,11 @@
},
"signUpEnable": false,
"guestMode": true
+ },
+ "build" : {
+ "version" : "0.0.0",
+ "buildNumber": 0,
+ "buildTime": "1970-01-01 00:00:00",
+ "commitId": "unknown"
}
}
\ No newline at end of file
diff --git a/site-config.json b/site-config.json
index 6c33654c..b3aab279 100644
--- a/site-config.json
+++ b/site-config.json
@@ -8,12 +8,6 @@
"clientId": "webida-ide-local-5000",
"redirectUrl": "http://localhost:5000/webida-client/auth.html"
},
- "build" : {
- "version" : "1.7.0",
- "buildNumber": 127,
- "buildTime": "1970 01 01 00 00 00",
- "commitId": ""
- },
"googleAnalyics" : false
},
"server": {
@@ -28,6 +22,12 @@
"type": "path",
"pathPrefix": "-"
},
+ "build" : {
+ "version" : "1.7.0",
+ "buildNumber": 127,
+ "buildTime": "1970 01 01 00 00 00",
+ "commitId": ""
+ },
"signUpEnable": false,
"guestMode": false
}
From c0e8b516ddcfea9c56aac4fdd2d17bdc2fdd0586 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Mon, 23 May 2016 19:54:48 +0900
Subject: [PATCH 03/15] change require for webida-*.js and added new server-api
skeletons
- fixed a small bug in webida-0.3.js, mountByFSID(), to use proper fs server url
- fixed FS Cache to use mountByFSID, not mount()
- many plugins & common modules now requires webida-server-api
aliased to webida-0.3 by default.
- added support to save browser window postiion & size when closing window
in desktop version
- forced to use plugin-settings-desktop.json instead of plugin-settings.json
in desktop version
- added some skeleton codes in server-api-0.1
(now server-api are modulized in server-api-*-lib/)
---
apps/ide/src/dojoConfig.js | 56 ++++++++----
apps/ide/src/index.html | 44 +++++++++-
.../src/plugins/project-wizard/build/build.js | 2 +-
.../project-wizard/build/signing-new.js | 2 +-
.../project-wizard/build/signing-select.js | 2 +-
.../src/plugins/project-wizard/commands.js | 2 +-
.../src/plugins/project-wizard/constants.js | 2 +-
.../project-wizard/device/device-select.js | 2 +-
.../src/plugins/project-wizard/launcher.js | 2 +-
apps/ide/src/plugins/project-wizard/main.js | 2 +-
apps/ide/src/plugins/project-wizard/plugin.js | 2 +-
.../plugins/project-wizard/run-commands.js | 2 +-
.../plugins/project-wizard/test-commands.js | 2 +-
apps/ide/src/plugins/uid-menu-items/plugin.js | 2 +-
.../webida.ide.project.deploy/commands.js | 2 +-
.../content-view-controller.js | 2 +-
.../webida.terminal.restrict/plugin.js | 2 +-
.../ide/src/plugins/webida.terminal/plugin.js | 2 +-
common/src/webida/FSCache-0.1.js | 5 +-
common/src/webida/app.js | 4 +-
common/src/webida/msg.js | 2 +-
common/src/webida/plugin-manager-0.1.js | 2 +-
common/src/webida/plugins/git/git-commands.js | 2 +-
.../webida/plugins/resources/legacy-event.js | 2 +-
.../plugins/resources/resource-event.js | 2 +-
.../plugins/workbench/views-controller.js | 2 +-
common/src/webida/plugins/workspace/plugin.js | 2 +-
common/src/webida/serer-api-0.1-lib/auth.js | 33 +++++++
common/src/webida/serer-api-0.1-lib/common.js | 49 +++++++++++
common/src/webida/serer-api-0.1-lib/fs.js | 30 +++++++
common/src/webida/server-api-0.1.js | 87 +++++++++++++++++++
common/src/webida/server-pubsub-0.1.js | 82 +++++++++++++++++
common/src/webida/webida-0.3.js | 13 ++-
33 files changed, 399 insertions(+), 50 deletions(-)
create mode 100644 common/src/webida/serer-api-0.1-lib/auth.js
create mode 100644 common/src/webida/serer-api-0.1-lib/common.js
create mode 100644 common/src/webida/serer-api-0.1-lib/fs.js
create mode 100644 common/src/webida/server-api-0.1.js
create mode 100644 common/src/webida/server-pubsub-0.1.js
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index 2d2b535c..3e022e1d 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -14,25 +14,25 @@
* limitations under the License.
*/
-(function (global) {
+(function (globalObject) {
'use strict';
// in electron, we should remove global.require & global.module
// to make dojo & other amd module work
// how can we detect that we're working in electron?
- if (typeof(global.process) === 'object' &&
- typeof(global.require) === 'function' &&
- typeof(global.module) === 'object') {
- global.nrequire = global.require;
- global.nmodule = global.module;
- delete global.require;
- delete global.module;
+ if (typeof(globalObject.process) === 'object' &&
+ typeof(globalObject.require) === 'function' &&
+ typeof(globalObject.module) === 'object') {
+ globalObject.nrequire = globalObject.require;
+ globalObject.nmodule = globalObject.module;
+ delete globalObject.require;
+ delete globalObject.module;
}
var webidaLocale = decodeURIComponent(
document.cookie.replace(/(?:(?:^|.*;\s*)webida\.locale\s*\=\s*([^;]*).*$)|^.*$/, '$1')
);
- global.dojoConfig = {
+ globalObject.dojoConfig = {
async: true,
baseUrl: '../../../bower_components',
parseOnLoad: false,
@@ -59,21 +59,41 @@
['text', 'dojo/text'],
['popup-dialog', 'webida-lib/widgets/dialogs/popup-dialog/PopupDialog'],
// TODO should use these below aliases for versioned resources
- ['webida', 'webida-lib/webida-0.3'],
['FSCache', 'webida-lib/FSCache-0.1'],
['plugin-manager', 'webida-lib/plugin-manager-0.1'],
- ['msg', 'webida-lib/msg.js'],
// diff_match_patch is used in codemirror
- ['diff_match_patch', '//cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js']
- ],
+ ['diff_match_patch', '//cdnjs.cloudflare.com/ajax/libs/diff_match_patch/20121119/diff_match_patch.js'],
+
+ // following server api will be removed when window.nrequire is true
+ // so, put these always at the end of aliases array
+ ['webida-lib/server-api', 'webida-lib/webida-0.3'],
+ ['webida-lib/server-pubsub', 'webida-lib/msg']
+ ]
};
- // dojo may understand cjs require() by building option
- // but some bower modules works under amd system only
- // we don't allow to mix amd/cjs modules with same require function
- if (global.nrequire) {
- global.dojoConfig.has = {
+ // default.html (new index.html for new server) should set
+ // session storage variable 'webida-workspace-type'
+ // to 'legacy' for 1.x clients who uses webida-0.4 API as default
+ if (globalObject.nrequire) {
+
+ // dojo may understand cjs require() by building option
+ // but some bower modules works under amd system only
+ // we don't allow to mix amd/cjs modules with same require function
+ globalObject.dojoConfig.has = {
'host-node': false // Prevent dojo from being fooled by Electron
+ };
+ // twick requirejs alias to use new server-api
+ // when using legacy server
+
+ if (window.location.href.indexOf('legacy=') < 0 ) {
+ globalObject.dojoConfig.aliases.pop();
+ globalObject.dojoConfig.aliases.pop();
+ globalObject.dojoConfig.aliases.push(['webida-lib/server-api' , 'webida-lib/server-api-0.1']);
+ globalObject.dojoConfig.aliases.push(['webida-lib/server-pubsub' , 'webida-lib/server-pubsub-0.1']);
+ globalObject.dojoConfig.aliases.push(['top/site-config.json' , 'top/site-config-desktop.json']);
+ console.log('under electrion re-wrote some requirejs aliases');
}
+ globalObject.__ELECTRON_BROWSER__ = true;
+ console.log("ready for electron");
}
})(window);
diff --git a/apps/ide/src/index.html b/apps/ide/src/index.html
index fc03ee26..4c647793 100644
--- a/apps/ide/src/index.html
+++ b/apps/ide/src/index.html
@@ -19,12 +19,14 @@
'webida-lib/app',
'webida-lib/app-config',
'webida-lib/theme',
- 'webida-lib/util/load-polyfills'
+ 'webida-lib/util/load-polyfills',
+ 'external/URIjs/src/URI'
], function (
ide,
config,
theme,
- loader
+ loader,
+ URI
) {
'use strict';
theme.loadTheme();
@@ -37,6 +39,44 @@
ga('create',config.googleAnalytics, 'auto');
ga('send', 'pageview');
}
+
+ // dojoConfig.js has handled some tricks for window.nrequire and set __ELECTRON_BROWSER__ already
+ // so, within electron, there's always a window.nrequire for node.js
+ if (window.__ELECTRON_BROWSER__) {
+ var uri = new URI(window.location.href);
+ var bootArgs = uri.query(true);
+ var desktopConfig = window.localStorage.getItem('webida-desktop-config');
+ if (desktopConfig) {
+ console.log('loaded desktop config ' + desktopConfig);
+ desktopConfig = JSON.parse(desktopConfig);
+ }
+ var browserWindowStatusStorageKey = 'webida-desktop-window-status-' + bootArgs.workspace;
+ var browserWindowStatus = window.localStorage.getItem(browserWindowStatusStorageKey);
+ var browserWindowStatus = browserWindowStatus ? JSON.parse(browserWindowStatus)
+ : desktopConfig.ideWindowDefaults;
+ var browserWindow = window.nrequire('electron').remote.getCurrentWindow();
+ if(browserWindowStatus.x) {
+ browserWindow.setBounds(browserWindowStatus);
+ } else {
+ browserWindow.setSize(browserWindowStatus.width, browserWindowStatus.height);
+ }
+ if (browserWindowStatus.maximized) {
+ browserWindow.maximze();
+ }
+ if (bootArgs.legacy) {
+ window.legacySiteServerConfig = desktopConfig.legacySiteConfigs[bootArgs.legacy];
+ if (!window.legacySiteServerConfig) {
+ alert('cannot read site configuration for legacy remote server');
+ }
+ }
+ browserWindow.on('close', function(event) {
+ var newStatus = browserWindow.getBounds();
+ newStatus.maximized = browserWindow.isMaximized();
+ newStatus = JSON.stringify(newStatus);
+ console.log("saving browser window status for closing " + newStatus);
+ window.localStorage.setItem(browserWindowStatusStorageKey, newStatus);
+ });
+ }
});
diff --git a/apps/ide/src/plugins/project-wizard/build/build.js b/apps/ide/src/plugins/project-wizard/build/build.js
index 564af90d..f9e9fb9e 100644
--- a/apps/ide/src/plugins/project-wizard/build/build.js
+++ b/apps/ide/src/plugins/project-wizard/build/build.js
@@ -29,7 +29,7 @@ define([
'webida-lib/app',
'webida-lib/util/logger/logger-client',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'./buildProfile',
'../constants',
diff --git a/apps/ide/src/plugins/project-wizard/build/signing-new.js b/apps/ide/src/plugins/project-wizard/build/signing-new.js
index 6ae3ec6b..af6abe1c 100644
--- a/apps/ide/src/plugins/project-wizard/build/signing-new.js
+++ b/apps/ide/src/plugins/project-wizard/build/signing-new.js
@@ -27,7 +27,7 @@ define([
'dijit/registry',
'dojo/Deferred',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'text!plugins/project-wizard/layer/export-signing-new.html',
'./buildProfile',
diff --git a/apps/ide/src/plugins/project-wizard/build/signing-select.js b/apps/ide/src/plugins/project-wizard/build/signing-select.js
index 6a01ebc7..77bea43c 100644
--- a/apps/ide/src/plugins/project-wizard/build/signing-select.js
+++ b/apps/ide/src/plugins/project-wizard/build/signing-select.js
@@ -28,7 +28,7 @@ define([
'dojo',
'dojo/Deferred',
'dojo/store/Memory',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'text!plugins/project-wizard/layer/export-signing-select.html',
'./buildProfile',
diff --git a/apps/ide/src/plugins/project-wizard/commands.js b/apps/ide/src/plugins/project-wizard/commands.js
index 892d7753..4dcf67dc 100644
--- a/apps/ide/src/plugins/project-wizard/commands.js
+++ b/apps/ide/src/plugins/project-wizard/commands.js
@@ -28,7 +28,7 @@ define([
'dojo/topic',
'lib/test/bootstrap/bootstrap.custom',
'webida-lib/app',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/util/locale',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'text!./layer/pw-layout.html',
diff --git a/apps/ide/src/plugins/project-wizard/constants.js b/apps/ide/src/plugins/project-wizard/constants.js
index bfbba420..2f61d56d 100644
--- a/apps/ide/src/plugins/project-wizard/constants.js
+++ b/apps/ide/src/plugins/project-wizard/constants.js
@@ -19,7 +19,7 @@
* @author kh5325.kim@samsung.com
*/
define([
- 'webida-lib/webida-0.3'
+ 'webida-lib/server-api'
], function (
webida
) {
diff --git a/apps/ide/src/plugins/project-wizard/device/device-select.js b/apps/ide/src/plugins/project-wizard/device/device-select.js
index 5c2443b2..71e5667c 100644
--- a/apps/ide/src/plugins/project-wizard/device/device-select.js
+++ b/apps/ide/src/plugins/project-wizard/device/device-select.js
@@ -29,7 +29,7 @@ define([
'dojo/store/Memory',
'dojox/grid/EnhancedGrid',
'dojox/grid/enhanced/plugins/IndirectSelection',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'text!plugins/project-wizard/layer/device-select.html',
'./gcm'
diff --git a/apps/ide/src/plugins/project-wizard/launcher.js b/apps/ide/src/plugins/project-wizard/launcher.js
index 1927d3a4..8d7b5969 100644
--- a/apps/ide/src/plugins/project-wizard/launcher.js
+++ b/apps/ide/src/plugins/project-wizard/launcher.js
@@ -23,7 +23,7 @@
define([
'webida-lib/util/logger/logger-client',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'./constants',
'./lib/util'
], function (
diff --git a/apps/ide/src/plugins/project-wizard/main.js b/apps/ide/src/plugins/project-wizard/main.js
index ea10ffbd..2b75f11c 100644
--- a/apps/ide/src/plugins/project-wizard/main.js
+++ b/apps/ide/src/plugins/project-wizard/main.js
@@ -36,7 +36,7 @@ define([
'dojo/topic',
'lib/image-slide/sly.wrapper',
'showdown',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/app',
'webida-lib/util/logger/logger-client',
'webida-lib/util/notify',
diff --git a/apps/ide/src/plugins/project-wizard/plugin.js b/apps/ide/src/plugins/project-wizard/plugin.js
index 37264305..5a3f0bae 100644
--- a/apps/ide/src/plugins/project-wizard/plugin.js
+++ b/apps/ide/src/plugins/project-wizard/plugin.js
@@ -25,7 +25,7 @@ define([
'webida-lib/plugins/workbench/plugin',
'webida-lib/plugins/workspace/plugin',
'webida-lib/util/locale',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'./lib/util'
], function (
i18n,
diff --git a/apps/ide/src/plugins/project-wizard/run-commands.js b/apps/ide/src/plugins/project-wizard/run-commands.js
index d3bb2f5a..cf667d37 100644
--- a/apps/ide/src/plugins/project-wizard/run-commands.js
+++ b/apps/ide/src/plugins/project-wizard/run-commands.js
@@ -30,7 +30,7 @@ define([
'dojox/grid/EnhancedGrid',
'dojox/grid/enhanced/plugins/IndirectSelection',
'webida-lib/app',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/util/path',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'webida-lib/plugins/workspace/plugin',
diff --git a/apps/ide/src/plugins/project-wizard/test-commands.js b/apps/ide/src/plugins/project-wizard/test-commands.js
index 0a3f6d65..9c779d8b 100644
--- a/apps/ide/src/plugins/project-wizard/test-commands.js
+++ b/apps/ide/src/plugins/project-wizard/test-commands.js
@@ -29,7 +29,7 @@ define([
'webida-lib/util/logger/logger-client',
'webida-lib/util/path',
'webida-lib/plugins/workspace/plugin',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/views/view',
'webida-lib/widgets/views/viewmanager',
'text!./layer/test-layout.html',
diff --git a/apps/ide/src/plugins/uid-menu-items/plugin.js b/apps/ide/src/plugins/uid-menu-items/plugin.js
index cb6702c8..049886ba 100644
--- a/apps/ide/src/plugins/uid-menu-items/plugin.js
+++ b/apps/ide/src/plugins/uid-menu-items/plugin.js
@@ -23,7 +23,7 @@ define([
'dojo/i18n!./nls/resource',
'webida-lib/app-config',
'webida-lib/util/notify',
- 'webida-lib/webida-0.3'
+ 'webida-lib/server-api'
], function (
i18n,
appConfig,
diff --git a/apps/ide/src/plugins/webida.ide.project.deploy/commands.js b/apps/ide/src/plugins/webida.ide.project.deploy/commands.js
index 1024cc9f..d159d783 100644
--- a/apps/ide/src/plugins/webida.ide.project.deploy/commands.js
+++ b/apps/ide/src/plugins/webida.ide.project.deploy/commands.js
@@ -31,7 +31,7 @@ define([
'webida-lib/util/logger/logger-client',
'webida-lib/util/notify',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'./content-view-controller',
'./workspace-view-controller',
'text!./layout/deploy-layout.html',
diff --git a/apps/ide/src/plugins/webida.ide.project.deploy/content-view-controller.js b/apps/ide/src/plugins/webida.ide.project.deploy/content-view-controller.js
index 5f6be221..6958527a 100644
--- a/apps/ide/src/plugins/webida.ide.project.deploy/content-view-controller.js
+++ b/apps/ide/src/plugins/webida.ide.project.deploy/content-view-controller.js
@@ -39,7 +39,7 @@ define([
'webida-lib/util/locale',
'webida-lib/util/logger/logger-client',
'webida-lib/util/notify',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/file-selection/FileSelDlg3States', // FileDialog
'text!./layout/app-information.html'
], function (
diff --git a/apps/ide/src/plugins/webida.terminal.restrict/plugin.js b/apps/ide/src/plugins/webida.terminal.restrict/plugin.js
index bccb8b7a..2d2ae24a 100644
--- a/apps/ide/src/plugins/webida.terminal.restrict/plugin.js
+++ b/apps/ide/src/plugins/webida.terminal.restrict/plugin.js
@@ -33,7 +33,7 @@ define([
'dojo/i18n!./nls/resource',
'webida-lib/app', // ide
'webida-lib/util/locale',
- 'webida-lib/webida-0.3', // webida
+ 'webida-lib/server-api', // webida
'webida-lib/widgets/views/view', // View
'dojo/text!./layout/terminal.html'
], function (
diff --git a/apps/ide/src/plugins/webida.terminal/plugin.js b/apps/ide/src/plugins/webida.terminal/plugin.js
index 5262ed82..59d4ca25 100644
--- a/apps/ide/src/plugins/webida.terminal/plugin.js
+++ b/apps/ide/src/plugins/webida.terminal/plugin.js
@@ -41,7 +41,7 @@ define([
'webida-lib/plugins/workbench/plugin', // workbench
'webida-lib/util/locale',
'webida-lib/util/logger/logger-client', // Logger
- 'webida-lib/webida-0.3', // webida
+ 'webida-lib/server-api', // webida
'webida-lib/widgets/views/view', // View
'dojo/text!./layout/terminal.html', // terminalHtml
'xstyle/css!./style/terminal.css'
diff --git a/common/src/webida/FSCache-0.1.js b/common/src/webida/FSCache-0.1.js
index b416b217..a59be24a 100644
--- a/common/src/webida/FSCache-0.1.js
+++ b/common/src/webida/FSCache-0.1.js
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-define(['webida-lib/webida-0.3',
+define(['webida-lib/server-api',
'webida-lib/util/arrays/SortedArray',
'webida-lib/util/path',
'external/lodash/lodash.min',
@@ -96,7 +96,8 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
fsURLParsed = parseWFSURL(fsURL);
dirsToCache = dirsToCacheArg;
publishing = false;
- mount = webida.fs.mount(fsURL);
+ mount = webida.fs.mountByFSID(fsURLParsed.fsid);
+
root = new Directory(null, ''); // no parent, empty name
root.getByAbsPath = function (absPath) {
//console.log('hina temp: absPath = ' + absPath);
diff --git a/common/src/webida/app.js b/common/src/webida/app.js
index 7b93ffa6..e989c3dc 100644
--- a/common/src/webida/app.js
+++ b/common/src/webida/app.js
@@ -21,13 +21,13 @@ define([
'dojo/topic',
'webida-lib/app-config',
'webida-lib/FSCache-0.1',
- 'webida-lib/msg',
+ 'webida-lib/server-pubsub',
'webida-lib/plugin-manager-0.1',
'webida-lib/util/browserInfo',
'webida-lib/util/loading-screen',
'webida-lib/util/logger/logger-client',
'webida-lib/util/notify',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/popup-dialog/PopupDialog',
'dojo/domReady!'
], function (
diff --git a/common/src/webida/msg.js b/common/src/webida/msg.js
index df1d821d..78b3f089 100644
--- a/common/src/webida/msg.js
+++ b/common/src/webida/msg.js
@@ -33,7 +33,7 @@
* @module msg
*/
define([
- './webida-0.3',
+ 'webida-lib/server-api',
'external/socket.io-client/socket.io',
'webida-lib/util/logger/logger-client'
], function (
diff --git a/common/src/webida/plugin-manager-0.1.js b/common/src/webida/plugin-manager-0.1.js
index 61e5872b..01f3fe1a 100644
--- a/common/src/webida/plugin-manager-0.1.js
+++ b/common/src/webida/plugin-manager-0.1.js
@@ -23,7 +23,7 @@
*
*/
-define(['webida-lib/webida-0.3',
+define(['webida-lib/server-api',
'external/lodash/lodash.min',
'external/URIjs/src/URI',
'dojo/promise/all',
diff --git a/common/src/webida/plugins/git/git-commands.js b/common/src/webida/plugins/git/git-commands.js
index cdb71eed..9d6038ad 100644
--- a/common/src/webida/plugins/git/git-commands.js
+++ b/common/src/webida/plugins/git/git-commands.js
@@ -57,7 +57,7 @@ define([
'webida-lib/util/arrays/BubblingArray',
'webida-lib/util/notify',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'./git-core',
'./git-icon',
diff --git a/common/src/webida/plugins/resources/legacy-event.js b/common/src/webida/plugins/resources/legacy-event.js
index 16490284..d29c3f7c 100644
--- a/common/src/webida/plugins/resources/legacy-event.js
+++ b/common/src/webida/plugins/resources/legacy-event.js
@@ -29,7 +29,7 @@ define([
'dojo/topic',
'external/URIjs/src/URI',
'webida-lib/util/logger/logger-client',
- 'webida-lib/webida-0.3'
+ 'webida-lib/server-api'
], function (
topic,
URI,
diff --git a/common/src/webida/plugins/resources/resource-event.js b/common/src/webida/plugins/resources/resource-event.js
index 64ca2c8e..62b018fa 100644
--- a/common/src/webida/plugins/resources/resource-event.js
+++ b/common/src/webida/plugins/resources/resource-event.js
@@ -25,7 +25,7 @@
define([
'dojo/topic',
'webida-lib/util/logger/logger-client',
- 'webida-lib/webida-0.3'
+ 'webida-lib/server-api'
], function (
topic,
Logger,
diff --git a/common/src/webida/plugins/workbench/views-controller.js b/common/src/webida/plugins/workbench/views-controller.js
index 764d5e24..45619d6b 100644
--- a/common/src/webida/plugins/workbench/views-controller.js
+++ b/common/src/webida/plugins/workbench/views-controller.js
@@ -29,7 +29,7 @@ define([
'require',
'webida-lib/plugin-manager-0.1',
'dojox/layout/ToggleSplitter', // ToggleSplitter
- 'webida-lib/webida-0.3', // webida
+ 'webida-lib/server-api', // webida
'webida-lib/app', // app
'webida-lib/widgets/views/viewmanager', // vm
'webida-lib/widgets/views/viewFocusController', // ViewFocusController
diff --git a/common/src/webida/plugins/workspace/plugin.js b/common/src/webida/plugins/workspace/plugin.js
index 797b4dab..7c207229 100644
--- a/common/src/webida/plugins/workspace/plugin.js
+++ b/common/src/webida/plugins/workspace/plugin.js
@@ -30,7 +30,7 @@ define([
//'webida-lib/plugins/workbench/preference-system/store', // TODO: issue #12055
'plugins/webida.preference/preference-service-factory',
'webida-lib/plugins/workbench/plugin',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'dijit',
'dijit/registry',
'dijit/Tree',
diff --git a/common/src/webida/serer-api-0.1-lib/auth.js b/common/src/webida/serer-api-0.1-lib/auth.js
new file mode 100644
index 00000000..f3a7b36e
--- /dev/null
+++ b/common/src/webida/serer-api-0.1-lib/auth.js
@@ -0,0 +1,33 @@
+/**
+ * Created by lunaris on 2016-05-23.
+ */
+
+define([
+ './common'
+], function (
+ common
+) {
+ "use strict";
+ var publics = {};
+ var privates = {
+ bootArgs : common.bootArgs
+ };
+
+ function initAuth() {
+
+ }
+
+ function getToken() {
+
+ }
+
+ function getMyInfo() {
+
+ }
+
+ return {
+ initAuth : initAuth,
+ getToken : getToken,
+ getMyInfo : getMyInfo
+ };
+});
\ No newline at end of file
diff --git a/common/src/webida/serer-api-0.1-lib/common.js b/common/src/webida/serer-api-0.1-lib/common.js
new file mode 100644
index 00000000..39e65916
--- /dev/null
+++ b/common/src/webida/serer-api-0.1-lib/common.js
@@ -0,0 +1,49 @@
+
+define([
+ 'external/URIjs/src/URI'
+], function (
+ URI
+) {
+ "use strict";
+ var publics = {
+ bootArgs : null
+ };
+ var privates = {
+ swaggerClient : null
+ };
+
+ // for embedded server
+ // - main process will set some 'boot token', randomly chosen when webida desktop starts
+ // - embedded server understands boot token and convert it to actual jwt for any webida client
+ // - auth.initAuth() will send boot token to server if set
+ // (in next version, initAuth will be removed & auth.login() will handle it directly)
+
+ // module-wide variables
+ function getSwaggerClientAsync() {
+ return new Promise( function(resolve, reject) {
+ if (privates.swaggerClient) {
+ resolve(swaggerCleint);
+ } else {
+ reject( new Error('get Swagger client is not impelmented yet') );
+ }
+ });
+ }
+
+ function initialize() {
+ // for embedded server
+ // - main process will set some 'boot token', randomly chosen when webida desktop starts
+ // - embedded server understands boot token and convert it to actual jwt for any webida client
+ // - auth.initAuth() will send boot token to server if set
+ // (in next version, initAuth will be removed & auth.login() will handle it directly)
+ var locationUri = new URI (window.location.href);
+ publics.bootArgs = locationUri.query;
+ }
+
+ /* module script */
+ initialize();
+ return {
+ bootArgs : publics.bootArgs,
+ getSwaggerClientAsync : getSwaggerClientAsync
+ };
+
+});
diff --git a/common/src/webida/serer-api-0.1-lib/fs.js b/common/src/webida/serer-api-0.1-lib/fs.js
new file mode 100644
index 00000000..50899886
--- /dev/null
+++ b/common/src/webida/serer-api-0.1-lib/fs.js
@@ -0,0 +1,30 @@
+/**
+ * Created by lunaris on 2016-05-23.
+ */
+
+define([
+ './common',
+ './FileSystem'
+], function (
+ common,
+ FileSystem
+) {
+ "use strict";
+ var publics = {
+
+ };
+ var privates = {
+ mounts : {}
+ };
+
+
+
+ function mountByFSID() {
+
+ }
+
+ return {
+ mountByFSID : mountFileSystemById,
+ FileSystem : FileSystem
+ };
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
new file mode 100644
index 00000000..862be39c
--- /dev/null
+++ b/common/src/webida/server-api-0.1.js
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+/**
+* @fileOverview Webida Server API binding library for Webida 1.x client
+*
+* This module should not be used in Webida 2.x
+* This module implements some sub-set of webida-0.3.js
+* @module server-api
+* @version 0.1
+*/
+
+define([
+ './server-api-0.1-lib/common',
+ './server-api-0.1-lib/auth',
+ './server-api-0.1-lib/fs'
+], function (
+ URI,
+ common,
+ auth,
+ fs
+) {
+ 'use strict';
+
+
+ // do we need some values from local storage, especially workspace-specific ones?
+
+ // auth & fs uses swagger client
+ // common will create the swagger client object in initialize() function
+ // other modueles (auth, fs) will get the client from commmon module
+
+ common.initSwaggerClient();
+
+ var mod = {
+ auth : auth,
+ fs : fs,
+
+ // for compatibility with plugisn who are dependent to webida-0.3.js conf object
+ conf : {
+ fsServer : bootArgs.server,
+ connServer: bootArgs.server,
+ fsApiBaseUrl: fsServer + '/api/fs',
+ },
+
+ // for compatibility with current plugin manager
+ // - should be removed in next version
+ // - PM should should decide which plugin catalog to load by itself
+ // via window.__ELECTRON_BROWSER__ variable
+ // - PM should not load .user_info/plugin-settings.json file directly while initializing
+ // and may use local storage instead of using server api
+ getPluginSettingsPath : function(callback) {
+ // for desktop mode, check legacy or not
+ if (window.__ELECTRON_BROWSER__) {
+ if(bootArgs.legacy) {
+ return 'plugins/plugin-settings-desktop.json'
+ } else {
+ return 'plugins/plugin-setting.json'
+ }
+ } else {
+ // keep same behavior to webida 0.3
+ mod.auth.getMyInfo(function (err, myInfo) {
+ if (err) {
+ callback(defaultPath);
+ } else {
+ callback(myInfo.isGuest ? 'plugins/plugin-settings-guest.json' : defaultPath);
+ }
+ });
+ }
+ }
+ };
+
+ return mod;
+});
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-0.1.js
new file mode 100644
index 00000000..c4ba223a
--- /dev/null
+++ b/common/src/webida/server-pubsub-0.1.js
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @module server-pubsub
+ * @fileoverview messaging pub/sub library for webida 1.x client
+ *
+ * Ths module provides some sub-set of msgs.js
+ * @version: 0.1
+ */
+
+
+
+/**
+* messaging api for Javascript module.
+*
+* This module provides JavaScript API's for message service.
+* It depends on socket.io in external/socket.io-client/
+* @module msg
+*/
+define([
+ './server-api-0.1',
+ 'external/socket.io-client/socket.io',
+ 'webida-lib/util/logger/logger-client'
+], function (
+ serverApi,
+ sio,
+ Logger
+) {
+ 'use strict';
+
+ var logger = new Logger();
+ // logger.setConfig('level', Logger.LEVELS.log); // for development mode only
+ //logger.off();
+
+ var User = function (nick, email, uid, token) {
+ this.nick = nick;
+ this.email = email;
+ this.uid = uid;
+ this.token = token;
+ };
+
+ var systemNotificationCallback;
+
+ var init = function (uid, token, host, callbackFunctions, cb) {
+ var user = new User('nick', 'email', uid, token);
+ // dummy stuffs
+ systemNotificationCallback = callbackFunctions.topicsysnotify_callback;
+ window.setTimeout( function() {
+ cb(user);
+ }, 0);
+ };
+
+ var sub2 = function (user, topics, cb) {
+ // dummy stuffs
+ var subscriptionResult = {
+ 'topics': topics
+ };
+ window.setTimeout( function() {
+ cb(subscriptionResult);
+ }, 0);
+ };
+
+ return {
+ init: init,
+ sub2: sub2
+ };
+
+});
diff --git a/common/src/webida/webida-0.3.js b/common/src/webida/webida-0.3.js
index 73f73291..b84cab4e 100644
--- a/common/src/webida/webida-0.3.js
+++ b/common/src/webida/webida-0.3.js
@@ -29,8 +29,9 @@
/* global io: true */
define([
+ 'external/URIjs/src/URI',
'text!top/site-config.json'
-], function (siteConfigText) {
+], function (URI, siteConfigText) {
'use strict';
var XHR = XMLHttpRequest || require('xmlhttprequest').XMLHttpRequest;
@@ -2298,7 +2299,13 @@ define([
* @memberOf module:webida.FSService
*/
mod.FSService.prototype.mountByFSID = function (fsid) {
- return new mod.FSService.FileSystem('wfs://webida/' + fsid);
+ var fsServerUri = new URI(mod.conf.fsServer);
+ var newWfsUri = fsServerUri
+ .protocol('wfs')
+ .path('/' + fsid)
+ .search('')
+ .toString();
+ return new mod.FSService.FileSystem(newWfsUri);
};
/**
@@ -4237,7 +4244,7 @@ define([
token.issueTime = Date.now();
token.data = href.substring(startIndex, endIndex);
mod.tokenGenerator.validateToken = function (/*token*/) { return true; };
- console.log(token.data, token.issueTime);
+ console.log("webida.js set personal token " + token.data, + " at " + token.issueTime);
}
}
From 9d1df776a69731e2879921055a8b33be0666133c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Thu, 16 Jun 2016 23:43:44 +0900
Subject: [PATCH 04/15] implemented webida-service-api
- now basic auth/fs service works. can read/write files via generated swagger client
with a little bit of patch
- removed some obsolute bower components not used in webida client anymore
- added .bowerrc to resolve repositories with https, not ssh
- reordring & some fixing in dojoConfig.js
---
.bowerrc | 3 +
apps/ide/src/dojoConfig.js | 13 +-
.../src/plugins/plugin-settings-desktop.json | 43 +
bower.json | 43 +-
common/src/webida/serer-api-0.1-lib/auth.js | 33 -
common/src/webida/serer-api-0.1-lib/common.js | 49 -
common/src/webida/serer-api-0.1-lib/fs.js | 30 -
common/src/webida/server-api-0.1-lib/Stats.js | 30 +
.../src/webida/server-api-0.1-lib/WfsEntry.js | 84 +
.../src/webida/server-api-0.1-lib/WfsMount.js | 248 +++
common/src/webida/server-api-0.1-lib/auth.js | 83 +
.../src/webida/server-api-0.1-lib/common.js | 97 +
common/src/webida/server-api-0.1-lib/fs.js | 39 +
.../webida-service-api-0.1/.jshintignore | 1 +
.../.swagger-codegen-ignore | 23 +
.../webida-service-api-0.1/LICENSE | 201 +++
.../webida-service-api-0.1/README.md | 142 ++
.../docs/AccessToken.md | 9 +
.../webida-service-api-0.1/docs/AuthApi.md | 216 +++
.../webida-service-api-0.1/docs/DefaultApi.md | 77 +
.../webida-service-api-0.1/docs/DirEntry.md | 10 +
.../docs/ExecAsyncResponse.md | 10 +
.../docs/ExecRequest.md | 12 +
.../docs/ExecResponse.md | 10 +
.../docs/LoginRequest.md | 10 +
.../docs/LoginResponse.md | 11 +
.../docs/MasterToken.md | 8 +
.../webida-service-api-0.1/docs/Match.md | 9 +
.../webida-service-api-0.1/docs/OpsApi.md | 74 +
.../webida-service-api-0.1/docs/RestError.md | 9 +
.../webida-service-api-0.1/docs/RestOK.md | 8 +
.../webida-service-api-0.1/docs/Session.md | 29 +
.../webida-service-api-0.1/docs/SessionApi.md | 171 ++
.../webida-service-api-0.1/docs/Stats.md | 37 +
.../webida-service-api-0.1/docs/Token.md | 23 +
.../webida-service-api-0.1/docs/User.md | 10 +
.../webida-service-api-0.1/docs/WfsApi.md | 570 ++++++
.../webida-service-api-0.1/docs/Workspace.md | 12 +
.../docs/WorkspaceApi.md | 403 +++++
.../webida-service-api-0.1/git_push.sh | 52 +
.../webida-service-api-0.1/package.json | 18 +
.../webida-service-api-0.1/src/ApiClient.js | 501 ++++++
.../webida-service-api-0.1/src/api/AuthApi.js | 210 +++
.../src/api/DefaultApi.js | 109 ++
.../webida-service-api-0.1/src/api/OpsApi.js | 102 ++
.../src/api/SessionApi.js | 169 ++
.../webida-service-api-0.1/src/api/WfsApi.js | 574 ++++++
.../src/api/WorkspaceApi.js | 372 ++++
.../webida-service-api-0.1/src/index.js | 162 ++
.../src/model/AccessToken.js | 85 +
.../src/model/DirEntry.js | 87 +
.../src/model/ExecAsyncResponse.js | 90 +
.../src/model/ExecRequest.js | 106 ++
.../src/model/ExecResponse.js | 90 +
.../src/model/LoginRequest.js | 86 +
.../src/model/LoginResponse.js | 96 +
.../src/model/MasterToken.js | 75 +
.../webida-service-api-0.1/src/model/Match.js | 78 +
.../src/model/RestError.js | 77 +
.../src/model/RestOK.js | 67 +
.../src/model/Session.js | 169 ++
.../webida-service-api-0.1/src/model/Stats.js | 163 ++
.../webida-service-api-0.1/src/model/Token.js | 109 ++
.../webida-service-api-0.1/src/model/User.js | 85 +
.../src/model/Workspace.js | 110 ++
.../webida-service-api-0.1/src/superagent.js | 1569 +++++++++++++++++
.../webida/server-api-0.1-lib/wfs-utils.js | 89 +
common/src/webida/server-api-0.1.js | 47 +-
common/src/webida/server-pubsub-0.1.js | 2 +
69 files changed, 8271 insertions(+), 168 deletions(-)
create mode 100644 .bowerrc
create mode 100644 apps/ide/src/plugins/plugin-settings-desktop.json
delete mode 100644 common/src/webida/serer-api-0.1-lib/auth.js
delete mode 100644 common/src/webida/serer-api-0.1-lib/common.js
delete mode 100644 common/src/webida/serer-api-0.1-lib/fs.js
create mode 100644 common/src/webida/server-api-0.1-lib/Stats.js
create mode 100644 common/src/webida/server-api-0.1-lib/WfsEntry.js
create mode 100644 common/src/webida/server-api-0.1-lib/WfsMount.js
create mode 100644 common/src/webida/server-api-0.1-lib/auth.js
create mode 100644 common/src/webida/server-api-0.1-lib/common.js
create mode 100644 common/src/webida/server-api-0.1-lib/fs.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
create mode 100644 common/src/webida/server-api-0.1-lib/wfs-utils.js
diff --git a/.bowerrc b/.bowerrc
new file mode 100644
index 00000000..eebc6dfc
--- /dev/null
+++ b/.bowerrc
@@ -0,0 +1,3 @@
+{
+ "shorthand-resolver": "https://github.com/{{owner}}/{{package}}.git"
+}
\ No newline at end of file
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index 3e022e1d..2fbc9f31 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -37,13 +37,16 @@
baseUrl: '../../../bower_components',
parseOnLoad: false,
packages: [
- {name: 'xstyle', location: './xstyle'},
- {name: 'put-selector', location: './put-selector'},
+ {name: 'dijit', location: './dijit'},
+ {name: 'dojo', location: './dojo'},
+ {name: 'dojox', location: './dojox'},
{name: 'jquery', location: './jquery/dist', main: 'jquery.min'},
+ {name: 'put-selector', location: './put-selector'},
{name: 'showdown', location: './showdown/dist', main: 'showdown.min'},
- {name: 'dojo', location: './dojo'},
- {name: 'dijit', location: './dijit'},
- {name: 'dojox', location: './dojox'}
+ {name: 'superagent', location: './superagent/lib', main: 'client'},
+
+ {name: 'URIjs', location:'./URIjs/src', main:'URI'},
+ {name: 'xstyle', location: './xstyle'}
],
locale: ((webidaLocale === 'default') || (webidaLocale === '')) ?
(location.search.match(/locale=([\w\-]+)/) ? RegExp.$1 : 'en-us') : webidaLocale,
diff --git a/apps/ide/src/plugins/plugin-settings-desktop.json b/apps/ide/src/plugins/plugin-settings-desktop.json
new file mode 100644
index 00000000..e6208684
--- /dev/null
+++ b/apps/ide/src/plugins/plugin-settings-desktop.json
@@ -0,0 +1,43 @@
+{
+ "plugins" : [
+ "plugins/webida.editor.text-editor",
+ "plugins/webida.editor.code-editor",
+ "plugins/webida.editor.code-editor.ca.css.lint",
+ "plugins/webida.editor.code-editor.ca.html.lint",
+ "plugins/webida.editor.code-editor.ca.js.lint",
+ "plugins/webida.editor.code-editor.ca.json.lint",
+ "plugins/webida.editor.code-editor.content-assist.beautify",
+ "plugins/webida.editor.code-editor.content-assist.comments",
+ "plugins/webida.editor.code-editor.content-assist.css.css-smart",
+ "plugins/webida.editor.code-editor.content-assist.css.default",
+ "plugins/webida.editor.code-editor.content-assist.html.htmlsmart",
+ "plugins/webida.editor.code-editor.content-assist.html.html-link",
+ "plugins/webida.editor.code-editor.content-assist.html.default",
+ "plugins/webida.editor.code-editor.content-assist.tern",
+ "plugins/webida.editor.example.simple-editor",
+ "plugins/webida.viewer.image-viewer",
+ "plugins/help",
+ "plugins/webida.preference",
+ "plugins/project-configurator",
+ "plugins/webida.ide.project-management.run",
+ "plugins/webida.ide.project-management.run.java",
+ "plugins/webida.ide.search-result",
+ "plugins/webida.locale",
+ "plugins/uid-menu-items",
+ "plugins/webida.ide.notification.view",
+ "plugins/webida.ide.notification.toast",
+ "plugins/webida.plugin-setting",
+ "webida-lib/plugins/editors",
+ "webida-lib/plugins/fs-commands",
+ "webida-lib/plugins/git",
+ "webida-lib/plugins/output",
+ "webida-lib/plugins/preview",
+ "webida-lib/plugins/workspace",
+ "webida-lib/plugins/workbench",
+ "webida-lib/plugins/resources"
+ ],
+ "start-plugins" : [
+ "webida-lib/plugins/workbench",
+ "plugins/webida.ide.notification.toast"
+ ]
+}
diff --git a/bower.json b/bower.json
index 300a3b75..ec803c7f 100644
--- a/bower.json
+++ b/bower.json
@@ -6,35 +6,34 @@
"bower_components"
],
"dependencies": {
+ "async": "~1.3.0",
+ "bootstrap-tooltip-popover": "twbs/bootstrap#ebc69356637143c938c07904d10928c11e742196",
+ "calcium": "webida/calcium#415ebc22cc6a09457bb9e7445f149061787920fe",
"codemirror": "webida/codemirror#b1738f33d1920d7d3e3423dc96c1878097d01d24",
"dgrid": "0.3.11",
- "put-selector": "~0.3.6",
- "xstyle": "~0.3.1",
- "async": "~1.3.0",
+ "dijit": "dojo/dijit#~1.10.4",
+ "dojo": "dojo/dojo#~1.10.4",
+ "dojox": "dojo/dojox#~1.10.4",
+ "eventEmitter": "~4.2.11",
+ "es6-shim": "~0.33.9",
+ "jquery": "~2.1.4",
+ "jquery-cookie" : "carhartl/jquery-cookie#faa09dc38bd3c791212e8fca67ee661af55fa530",
"js-beautify": "~1.5.10",
"lodash": "~3.10.0",
"moment": "~2.10.3",
- "URIjs": "~1.15.2",
- "requirejs": "~2.1.18",
+ "put-selector": "~0.3.6",
"qunit": "~1.18.0",
- "qunit-composite": "git://github.com/JamesMGreene/qunit-composite#~1.1.0",
- "toastr": "~2.1.1",
+ "qunit-composite": "JamesMGreene/qunit-composite#~1.1.0",
+ "requirejs": "~2.1.18",
"showdown": "~1.1.0",
- "socket.io-client": "git://github.com/automattic/socket.io-client#~1.3.5",
- "eventEmitter": "~4.2.11",
- "bootstrap-treeview": "~1.2.0",
- "calcium": "git://github.com/webida/calcium#415ebc22cc6a09457bb9e7445f149061787920fe",
- "tern": "git://github.com/webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
"smalot-bootstrap-datetimepicker": "~2.3.4",
- "es6-shim": "~0.33.9",
- "term.js": "git://github.com/chjj/term.js.git#~v0.0.7",
- "dojo": "dojo/dojo#~1.10.4",
- "dijit": "dojo/dijit#~1.10.4",
- "dojox": "dojo/dojox#~1.10.4",
- "util": "dojo/util#~1.10.4",
- "jquery": "~2.1.4",
- "ladda": "git://github.com/hakimel/Ladda#ec575edabd0602ed303978148df7d5e731014010",
- "bootstrap-tooltip-popover": "git://github.com/twbs/bootstrap#ebc69356637143c938c07904d10928c11e742196",
- "jquery-cookie" : "git://github.com/carhartl/jquery-cookie#faa09dc38bd3c791212e8fca67ee661af55fa530"
+ "socket.io-client": "socket.io-client#~1.4.5",
+ "superagent" : "~2.0.0",
+ "ladda": "hakimel/Ladda#ec575edabd0602ed303978148df7d5e731014010",
+ "term.js": "chjj/term.js#~v0.0.7",
+ "tern": "webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
+ "toastr": "~2.1.1",
+ "URIjs": "~1.15.2",
+ "xstyle": "~0.3.1"
}
}
diff --git a/common/src/webida/serer-api-0.1-lib/auth.js b/common/src/webida/serer-api-0.1-lib/auth.js
deleted file mode 100644
index f3a7b36e..00000000
--- a/common/src/webida/serer-api-0.1-lib/auth.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * Created by lunaris on 2016-05-23.
- */
-
-define([
- './common'
-], function (
- common
-) {
- "use strict";
- var publics = {};
- var privates = {
- bootArgs : common.bootArgs
- };
-
- function initAuth() {
-
- }
-
- function getToken() {
-
- }
-
- function getMyInfo() {
-
- }
-
- return {
- initAuth : initAuth,
- getToken : getToken,
- getMyInfo : getMyInfo
- };
-});
\ No newline at end of file
diff --git a/common/src/webida/serer-api-0.1-lib/common.js b/common/src/webida/serer-api-0.1-lib/common.js
deleted file mode 100644
index 39e65916..00000000
--- a/common/src/webida/serer-api-0.1-lib/common.js
+++ /dev/null
@@ -1,49 +0,0 @@
-
-define([
- 'external/URIjs/src/URI'
-], function (
- URI
-) {
- "use strict";
- var publics = {
- bootArgs : null
- };
- var privates = {
- swaggerClient : null
- };
-
- // for embedded server
- // - main process will set some 'boot token', randomly chosen when webida desktop starts
- // - embedded server understands boot token and convert it to actual jwt for any webida client
- // - auth.initAuth() will send boot token to server if set
- // (in next version, initAuth will be removed & auth.login() will handle it directly)
-
- // module-wide variables
- function getSwaggerClientAsync() {
- return new Promise( function(resolve, reject) {
- if (privates.swaggerClient) {
- resolve(swaggerCleint);
- } else {
- reject( new Error('get Swagger client is not impelmented yet') );
- }
- });
- }
-
- function initialize() {
- // for embedded server
- // - main process will set some 'boot token', randomly chosen when webida desktop starts
- // - embedded server understands boot token and convert it to actual jwt for any webida client
- // - auth.initAuth() will send boot token to server if set
- // (in next version, initAuth will be removed & auth.login() will handle it directly)
- var locationUri = new URI (window.location.href);
- publics.bootArgs = locationUri.query;
- }
-
- /* module script */
- initialize();
- return {
- bootArgs : publics.bootArgs,
- getSwaggerClientAsync : getSwaggerClientAsync
- };
-
-});
diff --git a/common/src/webida/serer-api-0.1-lib/fs.js b/common/src/webida/serer-api-0.1-lib/fs.js
deleted file mode 100644
index 50899886..00000000
--- a/common/src/webida/serer-api-0.1-lib/fs.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * Created by lunaris on 2016-05-23.
- */
-
-define([
- './common',
- './FileSystem'
-], function (
- common,
- FileSystem
-) {
- "use strict";
- var publics = {
-
- };
- var privates = {
- mounts : {}
- };
-
-
-
- function mountByFSID() {
-
- }
-
- return {
- mountByFSID : mountFileSystemById,
- FileSystem : FileSystem
- };
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/Stats.js b/common/src/webida/server-api-0.1-lib/Stats.js
new file mode 100644
index 00000000..653287fd
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/Stats.js
@@ -0,0 +1,30 @@
+"use strict"
+
+define([ ], function() {
+
+ function Stats (serverStats, path, name) {
+ this.path = path;
+ this.name = name || this.path.split('/').pop();
+
+ // all other properties are inherited from server stats object
+ this.size = serverStats.size;
+ this.mtime = serverStats.mtime;
+ this.birthtime = serverStats.birthtime;
+ this.mode = serverStats.mode;
+ this.nlink = serverStats.nlink;
+ this.type = serverStats.type;
+
+ };
+
+ Stats.prorotype = {
+ get isFile() { return (this.type !== 'DIRECTORY'); },
+ get isDirectory() { return (this.type === 'DIRECTORY'); },
+ get isBlockDevice() { return (this.type === 'BLOCK_DEVICE'); },
+ get isCharacterDevice() { return (this.type === 'CHARACTER_DEVICE'); },
+ get isSymbolicLink() { return (this.type === 'LINK'); },
+ get isFIFO() { return (this.type === 'FIFO'); },
+ get isSocket() { return (this.type === 'SOCKET'); }
+ };
+
+ return Stats;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/WfsEntry.js b/common/src/webida/server-api-0.1-lib/WfsEntry.js
new file mode 100644
index 00000000..cb760be9
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/WfsEntry.js
@@ -0,0 +1,84 @@
+"use strict"
+
+define([
+], function(
+) {
+
+ function WfsEntry (stats, name, parent) {
+
+ // currently hidden stats property that controls everthing
+ Object.defineProperty(this, 'stats', {
+ value: stats,
+ writable:true,
+ enumerable : false,
+ configurable : false
+ });
+
+ this.children = [];
+
+ this.name = name;
+
+ this._basepath = null; // will be filled later
+
+ // when building tree with entries
+ // parent property will be set later and initially undefined
+ // root entry should have 'null' (not empty) parent
+ this.parent = parent || null;
+ }
+
+ WfsEntry.prototype = {
+ // not implemented yet
+ refreshStats : function() {
+ throw new Error('do not use this abstract method');
+ },
+
+ isRoot : function isRoot() { return !this.parent; },
+
+ // for compatiblity with webida 1.x client
+ // (will be replaced to function as node.js does, later )
+ get path() {
+ if (this.parent) {
+ return this.parent.path + '/' + this.name;
+ } else {
+ var basePath = this.basePath || '/';
+ return basePath + this.name;
+ }
+ },
+
+ get basepath() {
+ if (this._basepath) {
+ return this._basepath;
+ } else {
+ return this.parent ? this.parent.basepath() : null;
+ }
+
+ },
+
+ set basepath(value) {
+ this._basepath = value;
+ },
+
+ get isFile() { return !this.isDirectory; },
+
+ get isDirectory() { return (this.stats.type === 'DIRECTORY'); },
+
+ hasChildren : function hasChildren() {
+ return this.children; // remember again, [] is falsy
+ }
+ };
+
+ WfsEntry.fromJson = function fromJson(obj, parent) {
+ var entry = new WfsEntry(obj.stats, obj.name, parent);
+ entry.children = obj.children.map( function (child) {
+ var childEntry = WfsEntry.fromJson(child, entry);
+ return childEntry;
+ });
+ return entry;
+ };
+
+ // later, we should extend this class to WfsFile & WfsDirectory
+ // we also need WfsTree to handle WfsEntry trees and subtree
+ //
+ return WfsEntry;
+});
+
diff --git a/common/src/webida/server-api-0.1-lib/WfsMount.js b/common/src/webida/server-api-0.1-lib/WfsMount.js
new file mode 100644
index 00000000..078cc450
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/WfsMount.js
@@ -0,0 +1,248 @@
+"use strict"
+
+
+define([
+ './common',
+ './WfsEntry',
+ './wfs-utils'
+], function (
+ common,
+ WfsEntry,
+ wfsUtils
+) {
+
+ //
+ // provides subset of legacy FileSystem object
+ // some methods are not supported, completely
+ // we should create better interface in next api 0.2 with cleaner spec and Promise
+ //
+ var logger = common.logger;
+ var wfsApi = new common.api.WfsApi();
+
+ function abstractify(name) {
+ return function abstractMethod() {
+ var methodName = name || 'method'
+ throw new Error(methodName + ' is abstract');
+ }
+ }
+
+ function WfsMount(fsid) {
+ this.wfsId = fsid;
+ }
+
+ WfsMount.prototype = {
+ _fromLegacyPath: function _fromLegacyPath(legacyPath, allowUrl) {
+ return wfsUtils.fromLegacyPath(legacyPath, allowUrl ? this.wfsId : undefined);
+ },
+
+ // result handler is (result, xhr) => desired (processed) result
+ // usually, some json object will be transformed into a class instance
+
+ _createApiCallback(apiName, resultHandler, callback) {
+ function echo(x) {
+ return x;
+ }
+ function invokeCallback(callback, err, result) {
+ try {
+ callback(err, result);
+ } catch(e) {
+ logger.debug('app layer callback for ' + apiName + '() had error', e);
+ }
+ }
+ return function (err, result, response) {
+ if (err) {
+ logger.debug('wfsapi.' + apiName + '() error', err);
+ callback(err);
+ } else {
+ // if no handler is given, we use incoming result, unmodified
+ resultHandler = resultHandler || echo;
+ // some error handler will takes somewhat long gime
+ // we should accept promise as result of the handler
+ Promise.resolve( resultHandler(result, response.xhr) )
+ .then( function(finalResult) {
+ // if callback throws some unexpected error,
+ // following catch function will catch it and some bad logs will be left.
+ invokeCallback(callback, null, finalResult);
+ })
+ .catch( function (err) {
+ logger.debug('result handler for ' + apiName + '() had error', err);
+ invokeCallback(callback, err);
+ });
+ }
+ };
+ },
+
+ _callSimpleApi : function (apiName, path /*, .... , result handler, callback */ ) {
+ var callable = wfsApi[apiName];
+ var wfsPath = this._fromLegacyPath(path);
+ var args = [ this.wfsId, wfsPath ];
+ for (let i = 2; i < arguments.length; i++) {
+ args.push(arguments[i]);
+ }
+ var callback = args.pop();
+ var resultHandler = args.pop();
+ var apiCallback = this._createApiCallback(apiName, resultHandler, callback);
+ args.push(apiCallback);
+
+ logger.log('call WfsApi.' + apiName + '()' , args);
+ return callable.apply(wfsApi, args);
+ },
+
+ createDirectory: function wfsCreateDir(path, recursive, callback) {
+ this._callSimpleApi('createDir', path, {ensure : recursive}, null, callback);
+ },
+
+ exists: function wfsExists(path, callback) {
+ this._callSimpleApi('stat', path, {ignoreError: true},
+ function(result) {
+ return (result.type !== 'DUMMY');
+ },
+ callback
+ );
+ },
+
+ // legacy stat is renamed to mstat
+ // TODO : change operation id of stats to stat, in swagger spec
+ stat: function wfsStat(path, callback) {
+ this._callSimpleApi('stat', path, { /* no option */ },
+ function (result) {
+ return new Stats(result);
+ },
+ callback
+ );
+ },
+
+
+ // prefer dirTree
+ list : function wfsList(path, recursive, callback) {
+ if (!callback) {
+ callback = recursive;
+ recursive = false;
+ }
+ this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
+ callback(err, tree.children);
+ });
+ },
+
+ dirTree: function wfsDirTree(path, maxDepth, callback) {
+ var self = this;
+
+ // TODO: 'full recursive' seems to be dangerous
+ // server might suffer from stack overflow or starvation with disk i/o
+ // so, server may response with incomplete tree
+ // 1) add a 'response header' for incomplete message
+ // 2) add timeout parameter in spec
+ // 3) in server, find a way to limit concurrency
+
+ this._callSimpleApi('dirTree', path, maxDepth,
+ function (result) {
+ // re-constructing a very large tree in a single tick looks dangerous
+ // we need a fromServerResultAsync, which checks height of tree and take some
+ // reasonable delays while converting response DirEntry object to WfsEntry
+ // or, introduce som 'builder' class to handle large tree
+ return WfsEntry.fromJson(result);
+ },
+ callback
+ );
+ },
+
+
+ remove : function wfsRemove(path, recursive, callback ) {
+ this._callSimpleApi('remove', path, {recursive : recursive}, null, callback);
+ } ,
+
+ readFile : function wfsReadFile(path, responseType, callback) {
+
+ // TODO : we need 'as' parameter replacing response type in next client release
+ // as : enum of ['text', 'blob', 'json']
+
+ responseType = responseType || 'text';
+ if (!callback) {
+ callback = responseType;
+ responseType = 'text';
+ }
+
+ this._callSimpleApi('readFile', path,
+ function (noUseResult, xhr) {
+ if (responseType === '' || responseType === 'text') {
+ return xhr.responseText;
+ } else {
+ return xhr.response;
+ }
+ },
+ callback
+ );
+ },
+
+ writeFile : function wfsWriteFile(path, data, ensure, callback) {
+ if (!callback) {
+ callback = ensure;
+ ensure = true; // in next relase, default value for ensure will be changed to false
+ }
+ var dataType = typeof(data);
+
+ // TODO : support plain object serialization, using AsyncApi class from swagger
+ switch( dataType ) {
+ case 'string':
+ data = new Blob([data], {type:'text/plain'});
+ break;
+ case 'object':
+ if (!(data instanceof Blob)) {
+ throw new Error('invalid data - should be string or Blob');
+ }
+ break;
+ default:
+ throw new Error('invalid data type - should be string or Blob');
+ }
+
+ this._callSimpleApi('writeFile', path, data, { ensure: true }, null, callback);
+ },
+
+ // deprecated. use stat, instead
+ isDirectory: function wfsIsDirectory(path, callback) {
+ this._callSimpleApi('stat', path, {/* no option */},
+ function (result) {
+ return result.type === 'DIRECTORY';
+ },
+ callback
+ );
+ },
+
+ // deprecated. use stat, instead
+ isFile: function wfsIsFile(path, callback) {
+ this._callSimpleApi('stat', path, {/* no option */},
+ function (result) {
+ return result.type !== 'DIRECTORY';
+ },
+ callback
+ );
+ },
+
+ // deprecated. use dirTree or never call this method
+ isEmpty: function wfsIsEmpty(path, callback) {
+ this._callSimpleApi('listDir', path, {recursive: true},
+ function (result) {
+ return result.children && result.children.length > 0;
+ },
+ callback
+ );
+ },
+
+
+ // deprecated. use 'remove'
+ 'delete' : function wfsDelete(path, recursive, callback ) {
+ return this.remove(path, recursive, callback);
+ } ,
+
+ // not implemented yet
+ copy: abstractify('copy'),
+ move : abstractify('move'),
+ exec : abstractify('exec'),
+ searchFiles: abstractify('searchFiles'),
+ replaceFiles: abstractify('replaceFiles'),
+ addAlias : abstractify('addAlias'),
+ mstat : abstractify('mstat') // we should GET :wfsid/op/mstats, not :wfsid/any/:wfsPath
+ };
+
+ return WfsMount;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
new file mode 100644
index 00000000..2c36c8f1
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/auth.js
@@ -0,0 +1,83 @@
+/**
+ * Created by lunaris on 2016-05-23.
+ */
+
+define([
+ './common'
+], function (
+ common
+) {
+ "use strict";
+ var logger = common.logger;
+ var AuthApi = common.api.AuthApi;
+ var authApi = new AuthApi();
+
+ // initAuth is called by app.js at first, before loading any other plugins
+ // it's good place to initialize swagger client
+ function initAuth(clientId, redirectUrl, tokenGenerator, callback) {
+ var masterToken = common.bootArgs.masterToken;
+
+ if (!masterToken) {
+ throw new Error('in-app login is not implemented yet');
+ // TODO : respect webida-0.3.js TokenGenerator class
+ }
+
+ console.log("webida auth service api", authApi);
+ var loginRequest = common.api.LoginRequest.constructFromObject({
+ loginId: 'bogus',
+ loginPassword: 'bogus',
+ masterToken: masterToken
+ });
+
+ authApi.login(loginRequest, function (error, data, response) {
+ if (!error) {
+ logger.debug('login response', data, response);
+ common.setLoginResponse(data);
+ // Oddly, there's no error-fist-callback for initAuth
+ callback(data.sessionId);
+ } else {
+ logger.error('initAuth failed', error);
+ callback(error)
+ }
+ });
+ }
+
+ function getMyInfo(callback) {
+
+ authApi.getInfo(function (error, data, response) {
+ if (!error) {
+ logger.debug('info response', data, response);
+ // TODO : add common.userInfo and check it before sending request
+ // don't forget to invoke callback with setTimeout(0)
+ callback(null, data);
+ } else {
+ logger.debug('getMyInfo failed', error);
+ callback(error)
+ }
+ });
+ }
+
+ return {
+ initAuth : initAuth,
+ getMyInfo : getMyInfo,
+
+ // for compatiblity
+ getTokenObj : function getTokenObject() {
+ let token = common.loginResponse.accessToken;
+ if (token) {
+ return {
+ issueTime : common.loginResponse.decodedAccessToken.issuedAt,
+ data : common.loginResponse.accessToken
+ }
+ }
+ },
+
+ getToken : function getToken() {
+ return common.loginResponse.accessToken;
+ },
+
+ getSessionID : function getSessionID() {
+ return common.loginResponse.decodedAccessToken.sessionId;
+ }
+ };
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/common.js b/common/src/webida/server-api-0.1-lib/common.js
new file mode 100644
index 00000000..0584166b
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/common.js
@@ -0,0 +1,97 @@
+"use strict";
+
+define([
+ 'URIjs',
+ 'webida-lib/util/logger/logger-client',
+ './webida-service-api-0.1/src/index'
+], function (
+ URI,
+ Logger,
+ WebidaServiceApi
+) {
+ "use strict";
+
+ var logger = new Logger();
+ if (!logger.debug) {
+ logger.debug = logger.log;
+ }
+
+ var privates = {
+ bootArgs : null,
+ isDebugging : false,
+
+ // comes from boot args. need public accessor
+ serverUri : null,
+ serverUrl : null,
+
+ // comes from login response, need public accessor for each properties
+ loginResponse : {},
+
+ };
+
+ var publics = {
+ // accessors to privates. getters only, no setters
+
+ get logger() { return logger; },
+ get bootArgs() { return privates.bootArgs; },
+ get loginResponse() { return privates.loginResponse },
+
+ // TODO - break login response object into tokens
+ setLoginResponse : function setLoginResponse(loginResponse) {
+ if (!loginResponse) {
+ logger.error('should not set empty login response');
+ throw new Error('empty login response');
+ }
+ privates.loginResponse = loginResponse; // believe swagger client
+ Object.freeze(privates.loginResponse);
+ },
+
+ get api() {
+ return WebidaServiceApi;
+ }
+ };
+
+ function initialize() {
+ // for embedded server
+ // - main process will set some 'boot token', randomly chosen when webida desktop starts
+ // - embedded server understands boot token and convert it to actual jwt for any webida client
+ // - auth.initAuth() will send boot token to server if set
+ // (in next version, initAuth will be removed & auth.login() will handle it directly)
+ var locationUri = new URI(window.location.href);
+ var bootArgs = locationUri.query(true);
+
+ privates.bootArgs = bootArgs;
+ Object.freeze(privates.bootArgs);
+
+ privates.serverUri = new URI(bootArgs.serverUrl).normalize().resource('').path('');
+ privates.serverUrl = privates.serverUri.toString().slice(0, -1);
+
+ logger.log("webida service url base is " + privates.serverUrl);
+ // by default, generated js client uses 'http://localhost/api' as base url
+ // we should replace
+
+ var defaultClient = WebidaServiceApi.ApiClient.instance;
+ defaultClient.basePath = privates.serverUrl + '/api';
+ var webidaSimpleAuth = defaultClient.authentications['webida-simple-auth'];
+ Object.defineProperty(webidaSimpleAuth, 'apiKey', {
+ enumerable: true,
+ get : function getSimpleAuthApiKey() {
+ if (privates.loginResponse.accessToken) {
+ return privates.loginResponse.accessToken;
+ } else {
+ logger.debug('sending api request without access token', obj);
+ return 'not-a-token';
+ }
+ }
+ });
+
+ console.log("defaultClient", defaultClient);
+
+ }
+
+ /* module script */
+
+ initialize();
+ return publics;
+
+});
diff --git a/common/src/webida/server-api-0.1-lib/fs.js b/common/src/webida/server-api-0.1-lib/fs.js
new file mode 100644
index 00000000..c381663b
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/fs.js
@@ -0,0 +1,39 @@
+'use strict';
+
+define([
+ './common',
+ './WfsMount'
+], function (
+ common,
+ WfsMount
+) {
+
+ var privates = {
+ mounts : {}
+ };
+
+ // To support multiple file systems in single workspace
+ // 1) we need a way to set access token for each file system mounted
+ // 2) server should provide a way to get an access token for each file system
+ // But, don't make things too hard.
+ // "1 ws == 1 fs" policy looks stupid but simple and clean for IDE application
+
+ // In the view point of resource abstraction
+ // every workspace items in workspace plugin may have some URI
+ // and this API supports only wfs:// URI
+ // If some application wants to implement its own workspace persistence,
+ // then the application can decide to implement multiple data source provider or not.
+ // IDE currently does not need more than 1 FS.
+
+ function mountByFSID(fsid) {
+ if (!privates.mounts[fsid]) {
+ privates.mounts[fsid] = new WfsMount(fsid);
+ }
+ return privates.mounts[fsid];
+ }
+
+ return {
+ mountByFSID : mountByFSID
+ };
+
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
new file mode 100644
index 00000000..23cbdf1a
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
@@ -0,0 +1 @@
+generated via swagger-codegen. no need to check style
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
new file mode 100644
index 00000000..19d33771
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
@@ -0,0 +1,23 @@
+# Swagger Codegen Ignore
+# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
+
+# Use this file to prevent files from being overwritten by the generator.
+# The patterns follow closely to .gitignore or .dockerignore.
+
+# As an example, the C# client generator defines ApiClient.cs.
+# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
+#ApiClient.cs
+
+# You can match any string of characters against a directory, file or extension with a single asterisk (*):
+#foo/*/qux
+# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
+
+# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
+#foo/**/qux
+# Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
+
+# You can also negate patterns with an exclamation (!).
+# For example, you can ignore all files in a docs folder with the file extension .md:
+#docs/*.md
+# Then explicitly reverse the ignore rule for a single file:
+#!docs/README.md
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
new file mode 100644
index 00000000..8dada3ed
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
new file mode 100644
index 00000000..60e6c69d
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
@@ -0,0 +1,142 @@
+# webida-service-api
+
+WebidaServiceApi - JavaScript client for webida-service-api
+Webida Service API specfication
+This SDK is automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:
+
+- API version: 0.1
+- Package version: 0.1
+- Build date: 2016-06-16T12:58:21.441Z
+- Build package: class io.swagger.codegen.languages.JavascriptClientCodegen
+
+## Installation
+
+### For [Node.js](https://nodejs.org/)
+
+#### npm
+
+To publish the library as a [npm](https://www.npmjs.com/),
+please follow the procedure in ["Publishing npm packages"](https://docs.npmjs.com/getting-started/publishing-npm-packages).
+
+Then install it via:
+
+```shell
+npm install webida-service-api --save
+```
+
+#### git
+#
+If the library is hosted at a git repository, e.g.
+https://github.com/YOUR_USERNAME/webida-service-api
+then install it via:
+
+```shell
+ npm install YOUR_USERNAME/webida-service-api --save
+```
+
+### For browser
+
+The library also works in the browser environment via npm and [browserify](http://browserify.org/). After following
+the above steps with Node.js and installing browserify with `npm install -g browserify`,
+perform the following (assuming *main.js* is your entry file):
+
+```shell
+browserify main.js > bundle.js
+```
+
+Then include *bundle.js* in the HTML pages.
+
+## Getting Started
+
+Please follow the [installation](#installation) instruction and execute the following JS code:
+
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = "YOUR API KEY"
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix['Authorization'] = "Token"
+
+var api = new WebidaServiceApi.AuthApi()
+
+var opts = {
+ 'tokenText': "tokenText_example" // {String} token text to decode. if not given, access token in request will be used
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+api.decodeToken(opts, callback);
+
+```
+
+## Documentation for API Endpoints
+
+All URIs are relative to *https://localhost/api*
+
+Class | Method | HTTP request | Description
+------------ | ------------- | ------------- | -------------
+*WebidaServiceApi.AuthApi* | [**decodeToken**](docs/AuthApi.md#decodeToken) | **GET** /auth/token |
+*WebidaServiceApi.AuthApi* | [**getInfo**](docs/AuthApi.md#getInfo) | **GET** /auth/info |
+*WebidaServiceApi.AuthApi* | [**issueToken**](docs/AuthApi.md#issueToken) | **POST** /auth/token |
+*WebidaServiceApi.AuthApi* | [**login**](docs/AuthApi.md#login) | **POST** /auth/login |
+*WebidaServiceApi.DefaultApi* | [**replace**](docs/DefaultApi.md#replace) | **POST** /wfs/{wfsId}/ops/replace |
+*WebidaServiceApi.OpsApi* | [**search**](docs/OpsApi.md#search) | **GET** /wfs/{wfsId}/ops/search/{wfsPath} |
+*WebidaServiceApi.SessionApi* | [**deleteSession**](docs/SessionApi.md#deleteSession) | **DELETE** /sessions/{sessionId} |
+*WebidaServiceApi.SessionApi* | [**getSession**](docs/SessionApi.md#getSession) | **GET** /sessions/{sessionId} |
+*WebidaServiceApi.SessionApi* | [**getSessions**](docs/SessionApi.md#getSessions) | **GET** /sessions |
+*WebidaServiceApi.WfsApi* | [**copy**](docs/WfsApi.md#copy) | **PUT** /wfs/{wfsId}/any/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**createDir**](docs/WfsApi.md#createDir) | **PUT** /wfs/{wfsId}/dir/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**dirTree**](docs/WfsApi.md#dirTree) | **GET** /wfs/{wfsId}/dir/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**move**](docs/WfsApi.md#move) | **POST** /wfs/{wfsId}/dir/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**readFile**](docs/WfsApi.md#readFile) | **GET** /wfs/{wfsId}/file/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**remove**](docs/WfsApi.md#remove) | **DELETE** /wfs/{wfsId}/any/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**rename**](docs/WfsApi.md#rename) | **POST** /wfs/{wfsId}/file/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**stat**](docs/WfsApi.md#stat) | **GET** /wfs/{wfsId}/any/{wfsPath} |
+*WebidaServiceApi.WfsApi* | [**writeFile**](docs/WfsApi.md#writeFile) | **PUT** /wfs/{wfsId}/file/{wfsPath} |
+*WebidaServiceApi.WorkspaceApi* | [**cancel**](docs/WorkspaceApi.md#cancel) | **DELETE** /workspaces/{workspaceId}/exec |
+*WebidaServiceApi.WorkspaceApi* | [**createWorkspace**](docs/WorkspaceApi.md#createWorkspace) | **POST** /workspaces |
+*WebidaServiceApi.WorkspaceApi* | [**exec**](docs/WorkspaceApi.md#exec) | **POST** /workspaces/{workspaceId}/exec |
+*WebidaServiceApi.WorkspaceApi* | [**getAllWorkspaces**](docs/WorkspaceApi.md#getAllWorkspaces) | **GET** /workspaces |
+*WebidaServiceApi.WorkspaceApi* | [**getWorkspace**](docs/WorkspaceApi.md#getWorkspace) | **GET** /workspaces/{workspaceId} |
+*WebidaServiceApi.WorkspaceApi* | [**removeWorkspace**](docs/WorkspaceApi.md#removeWorkspace) | **DELETE** /workspaces/{workspaceId} |
+*WebidaServiceApi.WorkspaceApi* | [**updateWorkspace**](docs/WorkspaceApi.md#updateWorkspace) | **PUT** /workspaces/{workspaceId} |
+
+
+## Documentation for Models
+
+ - [WebidaServiceApi.AccessToken](docs/AccessToken.md)
+ - [WebidaServiceApi.DirEntry](docs/DirEntry.md)
+ - [WebidaServiceApi.ExecAsyncResponse](docs/ExecAsyncResponse.md)
+ - [WebidaServiceApi.ExecRequest](docs/ExecRequest.md)
+ - [WebidaServiceApi.ExecResponse](docs/ExecResponse.md)
+ - [WebidaServiceApi.LoginRequest](docs/LoginRequest.md)
+ - [WebidaServiceApi.LoginResponse](docs/LoginResponse.md)
+ - [WebidaServiceApi.MasterToken](docs/MasterToken.md)
+ - [WebidaServiceApi.Match](docs/Match.md)
+ - [WebidaServiceApi.RestError](docs/RestError.md)
+ - [WebidaServiceApi.RestOK](docs/RestOK.md)
+ - [WebidaServiceApi.Session](docs/Session.md)
+ - [WebidaServiceApi.Stats](docs/Stats.md)
+ - [WebidaServiceApi.Token](docs/Token.md)
+ - [WebidaServiceApi.User](docs/User.md)
+ - [WebidaServiceApi.Workspace](docs/Workspace.md)
+
+
+## Documentation for Authorization
+
+
+### webida-simple-auth
+
+- **Type**: API key
+- **API key parameter name**: Authorization
+- **Location**: HTTP header
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
new file mode 100644
index 00000000..ca366d8d
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
@@ -0,0 +1,9 @@
+# WebidaServiceApi.AccessToken
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**sessionId** | **String** | An access token should not be shared between ide sessions, for each sessions requires distinct websocket connection, identified with session id. To change session id, call login again. Any Websocket connection will be rejected if requested upgrade does not contains proper access token data |
+**workspaceId** | **String** | the workspaceId inherited from master token | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
new file mode 100644
index 00000000..5afec9da
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
@@ -0,0 +1,216 @@
+# WebidaServiceApi.AuthApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**decodeToken**](AuthApi.md#decodeToken) | **GET** /auth/token |
+[**getInfo**](AuthApi.md#getInfo) | **GET** /auth/info |
+[**issueToken**](AuthApi.md#issueToken) | **POST** /auth/token |
+[**login**](AuthApi.md#login) | **POST** /auth/login |
+
+
+
+# **decodeToken**
+> Token decodeToken(opts)
+
+
+
+decode token to get data.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.AuthApi();
+
+var opts = {
+ 'tokenText': "tokenText_example" // String | token text to decode. if not given, access token in request will be used
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.decodeToken(opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **tokenText** | **String**| token text to decode. if not given, access token in request will be used | [optional]
+
+### Return type
+
+[**Token**](Token.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **getInfo**
+> User getInfo()
+
+
+
+Gets user information of that can be identified with current access token. Implementations should provide a more restful api based on domain data model. Don't override this operation for multi-user system.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.AuthApi();
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.getInfo(callback);
+```
+
+### Parameters
+This endpoint does not need any parameter.
+
+### Return type
+
+[**User**](User.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **issueToken**
+> Token issueToken(tokenType, opts)
+
+
+
+Creates new token - Any restrictions are inherited Clients cannot create new access token from exiting one via this operation. Call login with master token. When user logs in without master token, login api response alwyas contains master token
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.AuthApi();
+
+var tokenType = "tokenType_example"; // String | 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt.
+
+var opts = {
+ 'workspaceId': "workspaceId_example" // String | mandatory to issue a 'MASTER' type token, restricted to some workspace
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.issueToken(tokenType, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **tokenType** | **String**| 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt. |
+ **workspaceId** | **String**| mandatory to issue a 'MASTER' type token, restricted to some workspace | [optional]
+
+### Return type
+
+[**Token**](Token.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **login**
+> LoginResponse login(body)
+
+
+
+Basic authentication to support webida-simple-auth security scheme defined in this spec. Service / Product implementations who need better security, should override this operation or add their own login api and security definitions. see webida devloper guide to read details about webida-simpe-auth security sceheme.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+
+var apiInstance = new WebidaServiceApi.AuthApi();
+
+var body = new WebidaServiceApi.LoginRequest(); // LoginRequest |
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.login(body, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **body** | [**LoginRequest**](LoginRequest.md)| |
+
+### Return type
+
+[**LoginResponse**](LoginResponse.md)
+
+### Authorization
+
+No authorization required
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
new file mode 100644
index 00000000..024997e4
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
@@ -0,0 +1,77 @@
+# WebidaServiceApi.DefaultApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**replace**](DefaultApi.md#replace) | **POST** /wfs/{wfsId}/ops/replace |
+
+
+
+# **replace**
+> RestOK replace(wfsId, wfsPathList, patternreplaceTo, opts)
+
+
+
+replace file contents with regex matching
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.DefaultApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPathList = ["wfsPathList_example"]; // [String] | array of wfsPath, with heading / (collection format may be changed by implementation)
+
+var pattern = "pattern_example"; // String | regex pattern to match
+
+var replaceTo = "replaceTo_example"; // String | string to replace with
+
+var opts = {
+ 'ignoreCase': false, // Boolean | regex matching option to ignore case
+ 'wholeWord': false // Boolean | regex matching option to match whole word
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.replace(wfsId, wfsPathList, patternreplaceTo, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPathList** | [**[String]**](String.md)| array of wfsPath, with heading / (collection format may be changed by implementation) |
+ **pattern** | **String**| regex pattern to match |
+ **replaceTo** | **String**| string to replace with |
+ **ignoreCase** | **Boolean**| regex matching option to ignore case | [optional] [default to false]
+ **wholeWord** | **Boolean**| regex matching option to match whole word | [optional] [default to false]
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
new file mode 100644
index 00000000..1ab01913
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.DirEntry
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**name** | **String** | |
+**stats** | [**Stats**](Stats.md) | |
+**children** | [**[DirEntry]**](DirEntry.md) | |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
new file mode 100644
index 00000000..ab2b7dd1
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.ExecAsyncResponse
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**exitCode** | **Integer** | exit code of child process. for async operation, it's always 0 |
+**stdout** | **String** | standard out of child process |
+**stderr** | **String** | standard error of child process |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
new file mode 100644
index 00000000..2910e650
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
@@ -0,0 +1,12 @@
+# WebidaServiceApi.ExecRequest
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**command** | **String** | name or path of executable file to run. should not contain any arguments. |
+**args** | **[String]** | the command line arguments for the command. if 'shell' property is true, this args will be joined with ' ' and appended to command string | [optional]
+**cwd** | **String** | Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept shell-variable form like $HOME, %USERPROFILE% | [optional]
+**input** | **String** | The value which will be passed as stdin to the spawned process. If abscent, server will not write to input anything | [optional]
+**maxBuffer** | **String** | largest amount of data (in bytes) allowed on stdout or stderr. if exceeded child process is killed by server. if async is true, this arguments will be ignored by spawn() | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
new file mode 100644
index 00000000..6672f2f7
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.ExecResponse
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**exitCode** | **Integer** | exit code of child process. for async operation, it's always 0 |
+**stdout** | **String** | standard out of child process |
+**stderr** | **String** | standard error of child process |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
new file mode 100644
index 00000000..6e49b269
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.LoginRequest
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**loginId** | **String** | |
+**loginPassword** | **String** | |
+**masterToken** | **String** | If master token is set and valid, login Id / Password will be ignored but still required. Put some bogus values to pass argument validation. Bogus master token in request will not make server issue a new master token. | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
new file mode 100644
index 00000000..e9807e87
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
@@ -0,0 +1,11 @@
+# WebidaServiceApi.LoginResponse
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**accessToken** | **String** | actual token text which should be included in header or cookie |
+**decodedAccessToken** | [**AccessToken**](AccessToken.md) | |
+**masterToken** | **String** | unrestricted master token when user has logged in with valid credential | [optional]
+**decodedMasterToken** | [**MasterToken**](MasterToken.md) | | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
new file mode 100644
index 00000000..7e669b21
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
@@ -0,0 +1,8 @@
+# WebidaServiceApi.MasterToken
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**workspaceId** | **String** | Some MASTER tokens has some 'restricted' access rights, bound to specific workspace, with as issueToken() operation specifies. Any access tokens created from a restricted master token inherits same restriction. If this value is falsy, token has no restriction and can be used to access all apis. If truthy, some api calls that touches internal access registry or session registry will have met 403 error. Some filesystem apis will be rejected, too. | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
new file mode 100644
index 00000000..6207cd26
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
@@ -0,0 +1,9 @@
+# WebidaServiceApi.Match
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**line** | **Integer** | |
+**text** | **String** | |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
new file mode 100644
index 00000000..37142e90
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
@@ -0,0 +1,74 @@
+# WebidaServiceApi.OpsApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**search**](OpsApi.md#search) | **GET** /wfs/{wfsId}/ops/search/{wfsPath} |
+
+
+
+# **search**
+> {'String': Match} search(wfsId, wfsPath, pattern, opts)
+
+
+
+search files in some path, with given pattern
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.OpsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var pattern = "pattern_example"; // String | regex pattern to match
+
+var opts = {
+ 'ignoreCase': false, // Boolean | regex matching option to ignore case
+ 'wholeWord': false // Boolean | regex matching option to match whole word
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.search(wfsId, wfsPath, pattern, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **pattern** | **String**| regex pattern to match |
+ **ignoreCase** | **Boolean**| regex matching option to ignore case | [optional] [default to false]
+ **wholeWord** | **Boolean**| regex matching option to match whole word | [optional] [default to false]
+
+### Return type
+
+[**{'String': Match}**](Match.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
new file mode 100644
index 00000000..5c9bc12d
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
@@ -0,0 +1,9 @@
+# WebidaServiceApi.RestError
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**code** | **String** | | [optional]
+**message** | **String** | |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
new file mode 100644
index 00000000..19679959
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
@@ -0,0 +1,8 @@
+# WebidaServiceApi.RestOK
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**message** | **String** | | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
new file mode 100644
index 00000000..0bc3568c
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
@@ -0,0 +1,29 @@
+# WebidaServiceApi.Session
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **String** | the id of a session. usually same to socket id |
+**name** | **String** | human readable name, usually derived from workspace name. |
+**state** | **String** | state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout. |
+**workspaceId** | **String** | the id of workspace that this sessions is working on. |
+**clientAddress** | **String** | absolute path of this workspace in server |
+**connectedAt** | **Date** | the time when socket connection is established |
+**disconnectedAt** | **Date** | the time when socket is closed. |
+**willCloseAt** | **Date** | when state becomes CLOSING, actual closing time will be updated by server. | [optional]
+**willLoseAt** | **Date** | when state becomes LOSING, server will not wait for reconnection after this time. | [optional]
+
+
+
+## Enum: StateEnum
+
+
+* `NORMAL` (value: `"NORMAL"`)
+
+* `LOSING` (value: `"LOSING"`)
+
+* `CLOSING` (value: `"CLOSING"`)
+
+
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
new file mode 100644
index 00000000..cf45d357
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
@@ -0,0 +1,171 @@
+# WebidaServiceApi.SessionApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**deleteSession**](SessionApi.md#deleteSession) | **DELETE** /sessions/{sessionId} |
+[**getSession**](SessionApi.md#getSession) | **GET** /sessions/{sessionId} |
+[**getSessions**](SessionApi.md#getSessions) | **GET** /sessions |
+
+
+
+# **deleteSession**
+> [Session] deleteSession(sessionId)
+
+
+
+close session with timeout
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.SessionApi();
+
+var sessionId = "sessionId_example"; // String | webida session id (usually different from socket id from sock.io)
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.deleteSession(sessionId, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **sessionId** | **String**| webida session id (usually different from socket id from sock.io) |
+
+### Return type
+
+[**[Session]**](Session.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **getSession**
+> [Session] getSession(sessionId)
+
+
+
+get a session object by id
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.SessionApi();
+
+var sessionId = "sessionId_example"; // String | webida session id (usually different from socket id from sock.io)
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.getSession(sessionId, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **sessionId** | **String**| webida session id (usually different from socket id from sock.io) |
+
+### Return type
+
+[**[Session]**](Session.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **getSessions**
+> [Session] getSessions(opts)
+
+
+
+get all / some webida sessions established to server
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.SessionApi();
+
+var opts = {
+ 'workspaceId': "workspaceId_example" // String | only include sessions working on some given workspace
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.getSessions(opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| only include sessions working on some given workspace | [optional]
+
+### Return type
+
+[**[Session]**](Session.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
new file mode 100644
index 00000000..c00ce85f
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
@@ -0,0 +1,37 @@
+# WebidaServiceApi.Stats
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**type** | **String** | |
+**birthtime** | **Date** | | [optional]
+**mtime** | **Date** | | [optional]
+**mode** | **String** | | [optional]
+**size** | **Integer** | | [optional]
+**nlink** | **Integer** | | [optional]
+**error** | [**RestError**](RestError.md) | | [optional]
+
+
+
+## Enum: TypeEnum
+
+
+* `DUMMY` (value: `"DUMMY"`)
+
+* `FILE` (value: `"FILE"`)
+
+* `DIRECTORY` (value: `"DIRECTORY"`)
+
+* `BLOCK_DEVICE` (value: `"BLOCK_DEVICE"`)
+
+* `CHARACTER_DEVICE` (value: `"CHARACTER_DEVICE"`)
+
+* `LINK` (value: `"LINK"`)
+
+* `FIFO` (value: `"FIFO"`)
+
+* `SOCKET` (value: `"SOCKET"`)
+
+
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
new file mode 100644
index 00000000..fae05360
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
@@ -0,0 +1,23 @@
+# WebidaServiceApi.Token
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**tokenType** | **String** | MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a 'side-way' to create an 'unrestricted' master token before starting IDE instances. So, every ide client has a master token. If client want to access remote workspace directly, it should call login api with given master token which is generated from the remote login credential when adding remote workspace in main ui. Switching from a remote workspace to local one requires a local master token. It's not desirable to mix local and remote tokens in a single client instance in the view point of security. So, it's recommended to save local master token in session storage. |
+**expiresAt** | **Date** | |
+**issuedAt** | **Date** | |
+
+
+
+## Enum: TokenTypeEnum
+
+
+* `MASTER` (value: `"MASTER"`)
+
+* `ACCESS` (value: `"ACCESS"`)
+
+* `ADMIN` (value: `"ADMIN"`)
+
+
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
new file mode 100644
index 00000000..32ae9e64
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.User
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **String** | unique id per user (email is also unique) | [optional]
+**email** | **String** | | [optional]
+**name** | **String** | | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
new file mode 100644
index 00000000..e948fecf
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
@@ -0,0 +1,570 @@
+# WebidaServiceApi.WfsApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**copy**](WfsApi.md#copy) | **PUT** /wfs/{wfsId}/any/{wfsPath} |
+[**createDir**](WfsApi.md#createDir) | **PUT** /wfs/{wfsId}/dir/{wfsPath} |
+[**dirTree**](WfsApi.md#dirTree) | **GET** /wfs/{wfsId}/dir/{wfsPath} |
+[**move**](WfsApi.md#move) | **POST** /wfs/{wfsId}/dir/{wfsPath} |
+[**readFile**](WfsApi.md#readFile) | **GET** /wfs/{wfsId}/file/{wfsPath} |
+[**remove**](WfsApi.md#remove) | **DELETE** /wfs/{wfsId}/any/{wfsPath} |
+[**rename**](WfsApi.md#rename) | **POST** /wfs/{wfsId}/file/{wfsPath} |
+[**stat**](WfsApi.md#stat) | **GET** /wfs/{wfsId}/any/{wfsPath} |
+[**writeFile**](WfsApi.md#writeFile) | **PUT** /wfs/{wfsId}/file/{wfsPath} |
+
+
+
+# **copy**
+> RestOK copy(wfsId, wfsPath, srcPath, opts)
+
+
+
+Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error Copying from sockets, fifo, .. and any other type of file system object is not supported.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
+
+var opts = {
+ 'removeExisting': false // Boolean | remove any existing file/dir before writing.
+ 'followSymbolicLinks': false, // Boolean | dereference symlinks or not
+ 'noPreserveTimestamps': false, // Boolean | to change default behavior, keep mtime/atime of source files in destination
+ 'filterPattern': "filterPattern_example" // String | execute copy if source matches to this regex pattern.
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.copy(wfsId, wfsPath, srcPath, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **srcPath** | **String**| source data path of some operations, with have heading / |
+ **removeExisting** | **Boolean**| remove any existing file/dir before writing. | [optional] [default to false]
+ **followSymbolicLinks** | **Boolean**| dereference symlinks or not | [optional] [default to false]
+ **noPreserveTimestamps** | **Boolean**| to change default behavior, keep mtime/atime of source files in destination | [optional] [default to false]
+ **filterPattern** | **String**| execute copy if source matches to this regex pattern. | [optional]
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **createDir**
+> RestOK createDir(wfsId, wfsPath, , opts)
+
+
+
+create a directory at the path. will return error when wfsPath exists and not empty
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var opts = {
+ 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.createDir(wfsId, wfsPath, , opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **dirTree**
+> DirEntry dirTree(wfsId, wfsPath, maxDepth)
+
+
+
+returns a directory tree of given path, for listing dir and managing file system
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var maxDepth = 56; // Integer | Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list.
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.dirTree(wfsId, wfsPath, maxDepth, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **maxDepth** | **Integer**| Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list. |
+
+### Return type
+
+[**DirEntry**](DirEntry.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **move**
+> RestOK move(wfsId, wfsPath, srcPath, opts)
+
+
+
+move file or directory to given path. works like mv command
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
+
+var opts = {
+ 'removeExisting': false // Boolean | remove any existing file/dir before writing.
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.move(wfsId, wfsPath, srcPath, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **srcPath** | **String**| source data path of some operations, with have heading / |
+ **removeExisting** | **Boolean**| remove any existing file/dir before writing. | [optional] [default to false]
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **readFile**
+> File readFile(wfsId, wfsPath, )
+
+
+
+read file data on path
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.readFile(wfsId, wfsPath, , callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+
+### Return type
+
+**File**
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **remove**
+> RestOK remove(wfsId, wfsPath, , opts)
+
+
+
+delete file or directory
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var opts = {
+ 'recursive': false // Boolean | flag to set copy with
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.remove(wfsId, wfsPath, , opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **recursive** | **Boolean**| flag to set copy with | [optional] [default to false]
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **rename**
+> File rename(wfsId, wfsPath, srcPath, opts)
+
+
+
+Rename a file or directory to. This api does not remove an existing one.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
+
+var opts = {
+ 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.rename(wfsId, wfsPath, srcPath, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **srcPath** | **String**| source data path of some operations, with have heading / |
+ **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
+
+### Return type
+
+**File**
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **stat**
+> Stats stat(wfsId, wfsPath, , opts)
+
+
+
+get stats of given path. (stat returns 'stats' object in node and POSIX)
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var opts = {
+ 'ignoreError': false // Boolean | flag to ignore stat errors to check existence only
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.stat(wfsId, wfsPath, , opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **ignoreError** | **Boolean**| flag to ignore stat errors to check existence only | [optional] [default to false]
+
+### Return type
+
+[**Stats**](Stats.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **writeFile**
+> File writeFile(wfsId, wfsPath, data, opts)
+
+
+
+create / update file with body data
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WfsApi();
+
+var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
+
+var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
+
+var data = "/path/to/file.txt"; // File | file contents to write.
+
+var opts = {
+ 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.writeFile(wfsId, wfsPath, data, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **wfsId** | **String**| webida file system id (same to workspace id) to access. |
+ **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
+ **data** | **File**| file contents to write. |
+ **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
+
+### Return type
+
+**File**
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: multipart/form-data
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
new file mode 100644
index 00000000..517324a2
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
@@ -0,0 +1,12 @@
+# WebidaServiceApi.Workspace
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**id** | **String** | the id of a workspace. usually same to file system id |
+**name** | **String** | display text of this workspace. should not conflit to other workspaces |
+**workspacePath** | **String** | absolute path of this workspace in server |
+**createdAt** | **Date** | the time when this workspace is created (registered from local file system) |
+**accessedAt** | **Date** | the time when the last session on this workspace was made |
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
new file mode 100644
index 00000000..6af8fe67
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
@@ -0,0 +1,403 @@
+# WebidaServiceApi.WorkspaceApi
+
+All URIs are relative to *https://localhost/api*
+
+Method | HTTP request | Description
+------------- | ------------- | -------------
+[**cancel**](WorkspaceApi.md#cancel) | **DELETE** /workspaces/{workspaceId}/exec |
+[**createWorkspace**](WorkspaceApi.md#createWorkspace) | **POST** /workspaces |
+[**exec**](WorkspaceApi.md#exec) | **POST** /workspaces/{workspaceId}/exec |
+[**getAllWorkspaces**](WorkspaceApi.md#getAllWorkspaces) | **GET** /workspaces |
+[**getWorkspace**](WorkspaceApi.md#getWorkspace) | **GET** /workspaces/{workspaceId} |
+[**removeWorkspace**](WorkspaceApi.md#removeWorkspace) | **DELETE** /workspaces/{workspaceId} |
+[**updateWorkspace**](WorkspaceApi.md#updateWorkspace) | **PUT** /workspaces/{workspaceId} |
+
+
+
+# **cancel**
+> RestOK cancel(workspaceId, execId)
+
+
+
+cancels a async execution
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
+
+var execId = "execId_example"; // String | the execId property in ExecResponse
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.cancel(workspaceId, execId, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
+ **execId** | **String**| the execId property in ExecResponse |
+
+### Return type
+
+[**RestOK**](RestOK.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **createWorkspace**
+> Workspace createWorkspace(workspacePath)
+
+
+
+create a new workspace at given path
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspacePath = "workspacePath_example"; // String | a real path of the system or relative path to workspace cellar
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.createWorkspace(workspacePath, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspacePath** | **String**| a real path of the system or relative path to workspace cellar |
+
+### Return type
+
+[**Workspace**](Workspace.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **exec**
+> ExecResponse exec(workspaceId, body, opts)
+
+
+
+execute a shell command
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
+
+var body = new WebidaServiceApi.ExecRequest(); // ExecRequest |
+
+var opts = {
+ 'async': false, // Boolean | Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel.
+ 'execId': "execId_example" // String | mandatory for async execution. the result stream will be identified with this id
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.exec(workspaceId, body, opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
+ **body** | [**ExecRequest**](ExecRequest.md)| |
+ **async** | **Boolean**| Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel. | [optional] [default to false]
+ **execId** | **String**| mandatory for async execution. the result stream will be identified with this id | [optional]
+
+### Return type
+
+[**ExecResponse**](ExecResponse.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **getAllWorkspaces**
+> [Workspace] getAllWorkspaces(opts)
+
+
+
+get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var opts = {
+ 'disposable': false // Boolean | include disposable workspaces in response
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.getAllWorkspaces(opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **disposable** | **Boolean**| include disposable workspaces in response | [optional] [default to false]
+
+### Return type
+
+[**[Workspace]**](Workspace.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **getWorkspace**
+> Workspace getWorkspace(workspaceId, )
+
+
+
+get all workspaces registerd (non-disposable) in the server
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.getWorkspace(workspaceId, , callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
+
+### Return type
+
+[**Workspace**](Workspace.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **removeWorkspace**
+> Workspace removeWorkspace(workspaceId, , opts)
+
+
+
+remove a workspace. all sessions on this workspace will be closed.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
+
+var opts = {
+ 'wait': 0 // Integer | Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely.
+};
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.removeWorkspace(workspaceId, , opts, callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
+ **wait** | **Integer**| Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely. | [optional] [default to 0]
+
+### Return type
+
+[**Workspace**](Workspace.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
+
+# **updateWorkspace**
+> Workspace updateWorkspace(workspaceId, )
+
+
+
+update workspace information. some properties will not be updated by this api.
+
+### Example
+```javascript
+var WebidaServiceApi = require('webida-service-api');
+var defaultClient = WebidaServiceApi.ApiClient.default;
+
+// Configure API key authorization: webida-simple-auth
+var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
+webida-simple-auth.apiKey = 'YOUR API KEY';
+// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
+//webida-simple-auth.apiKeyPrefix = 'Token';
+
+var apiInstance = new WebidaServiceApi.WorkspaceApi();
+
+var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
+
+
+var callback = function(error, data, response) {
+ if (error) {
+ console.error(error);
+ } else {
+ console.log('API called successfully. Returned data: ' + data);
+ }
+};
+apiInstance.updateWorkspace(workspaceId, , callback);
+```
+
+### Parameters
+
+Name | Type | Description | Notes
+------------- | ------------- | ------------- | -------------
+ **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
+
+### Return type
+
+[**Workspace**](Workspace.md)
+
+### Authorization
+
+[webida-simple-auth](../README.md#webida-simple-auth)
+
+### HTTP request headers
+
+ - **Content-Type**: application/json
+ - **Accept**: application/json, application/octet-stream
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
new file mode 100644
index 00000000..0f1f2144
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
@@ -0,0 +1,52 @@
+#!/bin/sh
+# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
+#
+# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
+
+git_user_id=$1
+git_repo_id=$2
+release_note=$3
+
+if [ "$git_user_id" = "" ]; then
+ git_user_id=""
+ echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
+fi
+
+if [ "$git_repo_id" = "" ]; then
+ git_repo_id=""
+ echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
+fi
+
+if [ "$release_note" = "" ]; then
+ release_note=""
+ echo "[INFO] No command line input provided. Set \$release_note to $release_note"
+fi
+
+# Initialize the local directory as a Git repository
+git init
+
+# Adds the files in the local repository and stages them for commit.
+git add .
+
+# Commits the tracked changes and prepares them to be pushed to a remote repository.
+git commit -m "$release_note"
+
+# Sets the new remote
+git_remote=`git remote`
+if [ "$git_remote" = "" ]; then # git remote not defined
+
+ if [ "$GIT_TOKEN" = "" ]; then
+ echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the Git credential in your environment."
+ git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
+ else
+ git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
+ fi
+
+fi
+
+git pull origin master
+
+# Pushes (Forces) the changes in the local repository up to the remote repository
+echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
+git push origin master 2>&1 | grep -v 'To https'
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
new file mode 100644
index 00000000..a130ea7b
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
@@ -0,0 +1,18 @@
+{
+ "name": "webida-service-api",
+ "version": "0.1",
+ "description": "Webida Service API specfication",
+ "license": "Apache-2.0",
+ "main": "src/index.js",
+ "scripts": {
+ "test": "./node_modules/mocha/bin/mocha --recursive"
+ },
+ "dependencies": {
+ "superagent": "1.7.1"
+ },
+ "devDependencies": {
+ "mocha": "~2.3.4",
+ "sinon": "1.17.3",
+ "expect.js": "~0.3.1"
+ }
+}
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
new file mode 100644
index 00000000..72c58d15
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
@@ -0,0 +1,501 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['./superagent'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('superagent'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.ApiClient = factory(root.superagent);
+ }
+}(this, function(superagent) {
+ 'use strict';
+
+ /**
+ * @module ApiClient
+ * @version 0.1
+ */
+
+ /**
+ * Manages low level client-server communications, parameter marshalling, etc. There should not be any need for an
+ * application to use this class directly - the *Api and model classes provide the public API for the service. The
+ * contents of this file should be regarded as internal but are documented for completeness.
+ * @alias module:ApiClient
+ * @class
+ */
+ var exports = function() {
+ /**
+ * The base URL against which to resolve every API call's (relative) path.
+ * @type {String}
+ * @default https://localhost/api
+ */
+ this.basePath = 'https://localhost/api'.replace(/\/+$/, '');
+
+ /**
+ * The authentication methods to be included for all API calls.
+ * @type {Array.}
+ */
+ this.authentications = {
+ 'webida-simple-auth': {type: 'apiKey', 'in': 'header', name: 'Authorization'}
+ };
+ /**
+ * The default HTTP headers to be included for all API calls.
+ * @type {Array.}
+ * @default {}
+ */
+ this.defaultHeaders = {};
+
+ /**
+ * The default HTTP timeout for all API calls.
+ * @type {Number}
+ * @default 60000
+ */
+ this.timeout = 60000;
+ };
+
+ /**
+ * Returns a string representation for an actual parameter.
+ * @param param The actual parameter.
+ * @returns {String} The string representation of param.
+ */
+ exports.prototype.paramToString = function(param) {
+ if (param == undefined || param == null) {
+ return '';
+ }
+ if (param instanceof Date) {
+ return param.toJSON();
+ }
+ return param.toString();
+ };
+
+ /**
+ * Builds full URL by appending the given path to the base URL and replacing path parameter place-holders with parameter values.
+ * NOTE: query parameters are not handled here.
+ * @param {String} path The path to append to the base URL.
+ * @param {Object} pathParams The parameter values to append.
+ * @returns {String} The encoded path with parameter values substituted.
+ */
+ exports.prototype.buildUrl = function(path, pathParams) {
+ if (!path.match(/^\//)) {
+ path = '/' + path;
+ }
+ var url = this.basePath + path;
+ var _this = this;
+ url = url.replace(/\{([\w-]+)\}/g, function(fullMatch, key) {
+ var value;
+ if (pathParams.hasOwnProperty(key)) {
+ value = _this.paramToString(pathParams[key]);
+ } else {
+ value = fullMatch;
+ }
+ return encodeURIComponent(value);
+ });
+ return url;
+ };
+
+ /**
+ * Checks whether the given content type represents JSON.
+ * JSON content type examples:
+ *
+ * - application/json
+ * - application/json; charset=UTF8
+ * - APPLICATION/JSON
+ *
+ * @param {String} contentType The MIME content type to check.
+ * @returns {Boolean} true if contentType represents JSON, otherwise false.
+ */
+ exports.prototype.isJsonMime = function(contentType) {
+ return Boolean(contentType != null && contentType.match(/^application\/json(;.*)?$/i));
+ };
+
+ /**
+ * Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first.
+ * @param {Array.} contentTypes
+ * @returns {String} The chosen content type, preferring JSON.
+ */
+ exports.prototype.jsonPreferredMime = function(contentTypes) {
+ for (var i = 0; i < contentTypes.length; i++) {
+ if (this.isJsonMime(contentTypes[i])) {
+ return contentTypes[i];
+ }
+ }
+ return contentTypes[0];
+ };
+
+ /**
+ * Checks whether the given parameter value represents file-like content.
+ * @param param The parameter to check.
+ * @returns {Boolean} true if param represents a file.
+ */
+ exports.prototype.isFileParam = function(param) {
+ // fs.ReadStream in Node.js (but not in runtime like browserify)
+ if (typeof window === 'undefined' &&
+ typeof require === 'function' &&
+ require('fs') &&
+ param instanceof require('fs').ReadStream) {
+ return true;
+ }
+ // Buffer in Node.js
+ if (typeof Buffer === 'function' && param instanceof Buffer) {
+ return true;
+ }
+ // Blob in browser
+ if (typeof Blob === 'function' && param instanceof Blob) {
+ return true;
+ }
+ // File in browser (it seems File object is also instance of Blob, but keep this for safe)
+ if (typeof File === 'function' && param instanceof File) {
+ return true;
+ }
+ return false;
+ };
+
+ /**
+ * Normalizes parameter values:
+ *
+ * - remove nils
+ * - keep files and arrays
+ * - format to string with `paramToString` for other cases
+ *
+ * @param {Object.} params The parameters as object properties.
+ * @returns {Object.} normalized parameters.
+ */
+ exports.prototype.normalizeParams = function(params) {
+ var newParams = {};
+ for (var key in params) {
+ if (params.hasOwnProperty(key) && params[key] != undefined && params[key] != null) {
+ var value = params[key];
+ if (this.isFileParam(value) || Array.isArray(value)) {
+ newParams[key] = value;
+ } else {
+ newParams[key] = this.paramToString(value);
+ }
+ }
+ }
+ return newParams;
+ };
+
+ /**
+ * Enumeration of collection format separator strategies.
+ * @enum {String}
+ * @readonly
+ */
+ exports.CollectionFormatEnum = {
+ /**
+ * Comma-separated values. Value: csv
+ * @const
+ */
+ CSV: ',',
+ /**
+ * Space-separated values. Value: ssv
+ * @const
+ */
+ SSV: ' ',
+ /**
+ * Tab-separated values. Value: tsv
+ * @const
+ */
+ TSV: '\t',
+ /**
+ * Pipe(|)-separated values. Value: pipes
+ * @const
+ */
+ PIPES: '|',
+ /**
+ * Native array. Value: multi
+ * @const
+ */
+ MULTI: 'multi'
+ };
+
+ /**
+ * Builds a string representation of an array-type actual parameter, according to the given collection format.
+ * @param {Array} param An array parameter.
+ * @param {module:ApiClient.CollectionFormatEnum} collectionFormat The array element separator strategy.
+ * @returns {String|Array} A string representation of the supplied collection, using the specified delimiter. Returns
+ * param as is if collectionFormat is multi.
+ */
+ exports.prototype.buildCollectionParam = function buildCollectionParam(param, collectionFormat) {
+ if (param == null) {
+ return null;
+ }
+ switch (collectionFormat) {
+ case 'csv':
+ return param.map(this.paramToString).join(',');
+ case 'ssv':
+ return param.map(this.paramToString).join(' ');
+ case 'tsv':
+ return param.map(this.paramToString).join('\t');
+ case 'pipes':
+ return param.map(this.paramToString).join('|');
+ case 'multi':
+ // return the array directly as SuperAgent will handle it as expected
+ return param.map(this.paramToString);
+ default:
+ throw new Error('Unknown collection format: ' + collectionFormat);
+ }
+ };
+
+ /**
+ * Applies authentication headers to the request.
+ * @param {Object} request The request object created by a superagent() call.
+ * @param {Array.} authNames An array of authentication method names.
+ */
+ exports.prototype.applyAuthToRequest = function(request, authNames) {
+ var _this = this;
+ authNames.forEach(function(authName) {
+ var auth = _this.authentications[authName];
+ switch (auth.type) {
+ case 'basic':
+ if (auth.username || auth.password) {
+ request.auth(auth.username || '', auth.password || '');
+ }
+ break;
+ case 'apiKey':
+ if (auth.apiKey) {
+ var data = {};
+ if (auth.apiKeyPrefix) {
+ data[auth.name] = auth.apiKeyPrefix + ' ' + auth.apiKey;
+ } else {
+ data[auth.name] = auth.apiKey;
+ }
+ if (auth['in'] === 'header') {
+ request.set(data);
+ } else {
+ request.query(data);
+ }
+ }
+ break;
+ case 'oauth2':
+ if (auth.accessToken) {
+ request.set({'Authorization': 'Bearer ' + auth.accessToken});
+ }
+ break;
+ default:
+ throw new Error('Unknown authentication type: ' + auth.type);
+ }
+ });
+ };
+
+ /**
+ * Deserializes an HTTP response body into a value of the specified type.
+ * @param {Object} response A SuperAgent response object.
+ * @param {(String|Array.|Object.|Function)} returnType The type to return. Pass a string for simple types
+ * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
+ * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
+ * all properties on data will be converted to this type.
+ * @returns A value of the specified type.
+ */
+ exports.prototype.deserialize = function deserialize(response, returnType) {
+ if (response == null || returnType == null) {
+ return null;
+ }
+ // Rely on SuperAgent for parsing response body.
+ // See http://visionmedia.github.io/superagent/#parsing-response-bodies
+ var data = response.body;
+ if (data == null) {
+ // SuperAgent does not always produce a body; use the unparsed response as a fallback
+ data = response.text;
+ }
+ return exports.convertToType(data, returnType);
+ };
+
+ /**
+ * Callback function to receive the result of the operation.
+ * @callback module:ApiClient~callApiCallback
+ * @param {String} error Error message, if any.
+ * @param data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Invokes the REST service using the supplied settings and parameters.
+ * @param {String} path The base URL to invoke.
+ * @param {String} httpMethod The HTTP method to use.
+ * @param {Object.} pathParams A map of path parameters and their values.
+ * @param {Object.} queryParams A map of query parameters and their values.
+ * @param {Object.} headerParams A map of header parameters and their values.
+ * @param {Object.} formParams A map of form parameters and their values.
+ * @param {Object} bodyParam The value to pass as the request body.
+ * @param {Array.} authNames An array of authentication type names.
+ * @param {Array.} contentTypes An array of request MIME types.
+ * @param {Array.} accepts An array of acceptable response MIME types.
+ * @param {(String|Array|ObjectFunction)} returnType The required type to return; can be a string for simple types or the
+ * constructor for a complex type.
+ * @param {module:ApiClient~callApiCallback} callback The callback function.
+ * @returns {Object} The SuperAgent request object.
+ */
+ exports.prototype.callApi = function callApi(path, httpMethod, pathParams,
+ queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
+ returnType, callback) {
+
+ var _this = this;
+ var url = this.buildUrl(path, pathParams);
+ var request = superagent(httpMethod, url);
+
+ // apply authentications
+ this.applyAuthToRequest(request, authNames);
+
+ // set query parameters
+ request.query(this.normalizeParams(queryParams));
+
+ // set header parameters
+ request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
+
+ // set request timeout
+ request.timeout(this.timeout);
+
+ // FIX 3 - should not set 'multipart/form-data' header too early
+ // for superagent will not add 'boundary' string for the header automatically
+ // let the agent handle multipart/form-data
+ var contentType = this.jsonPreferredMime(contentTypes);
+ if (contentType !== 'multipart/form-data') {
+ if (contentType) {
+ request.type(contentType);
+ } else if (!request.header['Content-Type']) {
+ request.type('application/json');
+ }
+ }
+
+ if (contentType === 'application/x-www-form-urlencoded') {
+ request.send(this.normalizeParams(formParams));
+ } else if (contentType == 'multipart/form-data') {
+ var _formParams = this.normalizeParams(formParams);
+ for (var key in _formParams) {
+ if (_formParams.hasOwnProperty(key)) {
+ if (this.isFileParam(_formParams[key])) {
+ // file field
+ request.attach(key, _formParams[key]);
+ } else {
+ request.field(key, _formParams[key]);
+ }
+ }
+ }
+ } else if (bodyParam) {
+ request.send(bodyParam);
+ }
+
+ var accept = this.jsonPreferredMime(accepts);
+ if (accept) {
+ request.accept(accept);
+ }
+
+
+ request.end(function(error, response) {
+ if (callback) {
+ var data = null;
+ if (!error) {
+ data = _this.deserialize(response, returnType);
+ }
+ callback(error, data, response);
+ }
+ });
+
+ return request;
+ };
+
+ /**
+ * Parses an ISO-8601 string representation of a date value.
+ * @param {String} str The date value as a string.
+ * @returns {Date} The parsed date object.
+ */
+ exports.parseDate = function(str) {
+ return new Date(str.replace(/T/i, ' '));
+ };
+
+ /**
+ * Converts a value to the specified type.
+ * @param {(String|Object)} data The data to convert, as a string or object.
+ * @param {(String|Array.|Object.|Function)} type The type to return. Pass a string for simple types
+ * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
+ * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
+ * all properties on data will be converted to this type.
+ * @returns An instance of the specified type.
+ */
+ exports.convertToType = function(data, type) {
+ switch (type) {
+ case 'Boolean':
+ return Boolean(data);
+ case 'Integer':
+ return parseInt(data, 10);
+ case 'Number':
+ return parseFloat(data);
+ case 'String':
+ return String(data);
+ case 'Date':
+ return this.parseDate(String(data));
+ default:
+ // FIXED 1 - when type is File, do not convert
+ if (type === Object || type === File ) {
+ // generic object, return directly
+ return data;
+ } else if (typeof type === 'function') {
+ // for model type like: User
+ // FIXED 2 - consruct only when it's available
+ if (typeof type.constructFromObject !== 'function')
+ return data;
+ else
+ return type.constructFromObject(data);
+ } else if (Array.isArray(type)) {
+ // for array type like: ['String']
+ var itemType = type[0];
+ return data.map(function(item) {
+ return exports.convertToType(item, itemType);
+ });
+ } else if (typeof type === 'object') {
+ // for plain object type like: {'String': 'Integer'}
+ var keyType, valueType;
+ for (var k in type) {
+ if (type.hasOwnProperty(k)) {
+ keyType = k;
+ valueType = type[k];
+ break;
+ }
+ }
+ var result = {};
+ for (var k in data) {
+ if (data.hasOwnProperty(k)) {
+ var key = exports.convertToType(k, keyType);
+ var value = exports.convertToType(data[k], valueType);
+ result[key] = value;
+ }
+ }
+ return result;
+ } else {
+ // for unknown type, return the data directly
+ return data;
+ }
+ }
+ };
+
+ /**
+ * Constructs a new map or array model from REST data.
+ * @param data {Object|Array} The REST data.
+ * @param obj {Object|Array} The target object or array.
+ */
+ exports.constructFromObject = function(data, obj, itemType) {
+ if (Array.isArray(data)) {
+ for (var i = 0; i < data.length; i++) {
+ if (data.hasOwnProperty(i))
+ obj[i] = exports.convertToType(data[i], itemType);
+ }
+ } else {
+ for (var k in data) {
+ if (data.hasOwnProperty(k))
+ result[k] = exports.convertToType(data[k], itemType);
+ }
+ }
+ };
+
+ /**
+ * The default API client implementation.
+ * @type {module:ApiClient}
+ */
+ exports.instance = new exports();
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
new file mode 100644
index 00000000..c786c63a
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
@@ -0,0 +1,210 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestError', '../model/Token', '../model/User', '../model/LoginResponse', '../model/LoginRequest'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Token'), require('../model/User'), require('../model/LoginResponse'), require('../model/LoginRequest'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.AuthApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Token, root.WebidaServiceApi.User, root.WebidaServiceApi.LoginResponse, root.WebidaServiceApi.LoginRequest);
+ }
+}(this, function(ApiClient, RestError, Token, User, LoginResponse, LoginRequest) {
+ 'use strict';
+
+ /**
+ * Auth service.
+ * @module api/AuthApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new AuthApi.
+ * @alias module:api/AuthApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the decodeToken operation.
+ * @callback module:api/AuthApi~decodeTokenCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Token} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * decode token to get data.
+ * @param {Object} opts Optional parameters
+ * @param {String} opts.tokenText token text to decode. if not given, access token in request will be used
+ * @param {module:api/AuthApi~decodeTokenCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Token}
+ */
+ this.decodeToken = function(opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ 'tokenText': opts['tokenText']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Token;
+
+ return this.apiClient.callApi(
+ '/auth/token', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the getInfo operation.
+ * @callback module:api/AuthApi~getInfoCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/User} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Gets user information of that can be identified with current access token. Implementations should provide a more restful api based on domain data model. Don't override this operation for multi-user system.
+ * @param {module:api/AuthApi~getInfoCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/User}
+ */
+ this.getInfo = function(callback) {
+ var postBody = null;
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = User;
+
+ return this.apiClient.callApi(
+ '/auth/info', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the issueToken operation.
+ * @callback module:api/AuthApi~issueTokenCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Token} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Creates new token - Any restrictions are inherited Clients cannot create new access token from exiting one via this operation. Call login with master token. When user logs in without master token, login api response alwyas contains master token
+ * @param {module:model/String} tokenType 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt.
+ * @param {Object} opts Optional parameters
+ * @param {String} opts.workspaceId mandatory to issue a 'MASTER' type token, restricted to some workspace
+ * @param {module:api/AuthApi~issueTokenCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Token}
+ */
+ this.issueToken = function(tokenType, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'tokenType' is set
+ if (tokenType == undefined || tokenType == null) {
+ throw "Missing the required parameter 'tokenType' when calling issueToken";
+ }
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ 'tokenType': tokenType,
+ 'workspaceId': opts['workspaceId']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Token;
+
+ return this.apiClient.callApi(
+ '/auth/token', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the login operation.
+ * @callback module:api/AuthApi~loginCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/LoginResponse} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Basic authentication to support webida-simple-auth security scheme defined in this spec. Service / Product implementations who need better security, should override this operation or add their own login api and security definitions. see webida devloper guide to read details about webida-simpe-auth security sceheme.
+ * @param {module:model/LoginRequest} body
+ * @param {module:api/AuthApi~loginCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/LoginResponse}
+ */
+ this.login = function(body, callback) {
+ var postBody = body;
+
+ // verify the required parameter 'body' is set
+ if (body == undefined || body == null) {
+ throw "Missing the required parameter 'body' when calling login";
+ }
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = [];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = LoginResponse;
+
+ return this.apiClient.callApi(
+ '/auth/login', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
new file mode 100644
index 00000000..5fe4f7b6
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
@@ -0,0 +1,109 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestOK', '../model/RestError'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.DefaultApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError);
+ }
+}(this, function(ApiClient, RestOK, RestError) {
+ 'use strict';
+
+ /**
+ * Default service.
+ * @module api/DefaultApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new DefaultApi.
+ * @alias module:api/DefaultApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the replace operation.
+ * @callback module:api/DefaultApi~replaceCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * replace file contents with regex matching
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {Array.} wfsPathList array of wfsPath, with heading / (collection format may be changed by implementation)
+ * @param {String} pattern regex pattern to match
+ * @param {String} replaceTo string to replace with
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ignoreCase regex matching option to ignore case (default to false)
+ * @param {Boolean} opts.wholeWord regex matching option to match whole word (default to false)
+ * @param {module:api/DefaultApi~replaceCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.replace = function(wfsId, wfsPathList, pattern, replaceTo, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling replace";
+ }
+
+ // verify the required parameter 'wfsPathList' is set
+ if (wfsPathList == undefined || wfsPathList == null) {
+ throw "Missing the required parameter 'wfsPathList' when calling replace";
+ }
+
+ // verify the required parameter 'pattern' is set
+ if (pattern == undefined || pattern == null) {
+ throw "Missing the required parameter 'pattern' when calling replace";
+ }
+
+ // verify the required parameter 'replaceTo' is set
+ if (replaceTo == undefined || replaceTo == null) {
+ throw "Missing the required parameter 'replaceTo' when calling replace";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId
+ };
+ var queryParams = {
+ 'wfsPathList': this.apiClient.buildCollectionParam(wfsPathList, 'multi'),
+ 'pattern': pattern,
+ 'replaceTo': replaceTo,
+ 'ignoreCase': opts['ignoreCase'],
+ 'wholeWord': opts['wholeWord']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/ops/replace', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
new file mode 100644
index 00000000..4534edba
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
@@ -0,0 +1,102 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestError', '../model/Match'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Match'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.OpsApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Match);
+ }
+}(this, function(ApiClient, RestError, Match) {
+ 'use strict';
+
+ /**
+ * Ops service.
+ * @module api/OpsApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new OpsApi.
+ * @alias module:api/OpsApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the search operation.
+ * @callback module:api/OpsApi~searchCallback
+ * @param {String} error Error message, if any.
+ * @param {Object.} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * search files in some path, with given pattern
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {String} pattern regex pattern to match
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ignoreCase regex matching option to ignore case (default to false)
+ * @param {Boolean} opts.wholeWord regex matching option to match whole word (default to false)
+ * @param {module:api/OpsApi~searchCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {Object.}
+ */
+ this.search = function(wfsId, wfsPath, pattern, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling search";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling search";
+ }
+
+ // verify the required parameter 'pattern' is set
+ if (pattern == undefined || pattern == null) {
+ throw "Missing the required parameter 'pattern' when calling search";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'pattern': pattern,
+ 'ignoreCase': opts['ignoreCase'],
+ 'wholeWord': opts['wholeWord']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = {'String': Match};
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/ops/search/{wfsPath}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
new file mode 100644
index 00000000..198676b8
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
@@ -0,0 +1,169 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestError', '../model/Session'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Session'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.SessionApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Session);
+ }
+}(this, function(ApiClient, RestError, Session) {
+ 'use strict';
+
+ /**
+ * Session service.
+ * @module api/SessionApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new SessionApi.
+ * @alias module:api/SessionApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the deleteSession operation.
+ * @callback module:api/SessionApi~deleteSessionCallback
+ * @param {String} error Error message, if any.
+ * @param {Array.} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * close session with timeout
+ * @param {String} sessionId webida session id (usually different from socket id from sock.io)
+ * @param {module:api/SessionApi~deleteSessionCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {Array.}
+ */
+ this.deleteSession = function(sessionId, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'sessionId' is set
+ if (sessionId == undefined || sessionId == null) {
+ throw "Missing the required parameter 'sessionId' when calling deleteSession";
+ }
+
+
+ var pathParams = {
+ 'sessionId': sessionId
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = [Session];
+
+ return this.apiClient.callApi(
+ '/sessions/{sessionId}', 'DELETE',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the getSession operation.
+ * @callback module:api/SessionApi~getSessionCallback
+ * @param {String} error Error message, if any.
+ * @param {Array.} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * get a session object by id
+ * @param {String} sessionId webida session id (usually different from socket id from sock.io)
+ * @param {module:api/SessionApi~getSessionCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {Array.}
+ */
+ this.getSession = function(sessionId, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'sessionId' is set
+ if (sessionId == undefined || sessionId == null) {
+ throw "Missing the required parameter 'sessionId' when calling getSession";
+ }
+
+
+ var pathParams = {
+ 'sessionId': sessionId
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = [Session];
+
+ return this.apiClient.callApi(
+ '/sessions/{sessionId}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the getSessions operation.
+ * @callback module:api/SessionApi~getSessionsCallback
+ * @param {String} error Error message, if any.
+ * @param {Array.} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * get all / some webida sessions established to server
+ * @param {Object} opts Optional parameters
+ * @param {String} opts.workspaceId only include sessions working on some given workspace
+ * @param {module:api/SessionApi~getSessionsCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {Array.}
+ */
+ this.getSessions = function(opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ 'workspaceId': opts['workspaceId']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = [Session];
+
+ return this.apiClient.callApi(
+ '/sessions', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
new file mode 100644
index 00000000..3bbf3c4d
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
@@ -0,0 +1,574 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/DirEntry', '../model/Stats'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/DirEntry'), require('../model/Stats'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.WfsApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.DirEntry, root.WebidaServiceApi.Stats);
+ }
+}(this, function(ApiClient, RestOK, RestError, DirEntry, Stats) {
+ 'use strict';
+
+ /**
+ * Wfs service.
+ * @module api/WfsApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new WfsApi.
+ * @alias module:api/WfsApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the copy operation.
+ * @callback module:api/WfsApi~copyCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error Copying from sockets, fifo, .. and any other type of file system object is not supported.
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {String} srcPath source data path of some operations, with have heading /
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.removeExisting remove any existing file/dir before writing. (default to false)
+ * @param {Boolean} opts.followSymbolicLinks dereference symlinks or not (default to false)
+ * @param {Boolean} opts.noPreserveTimestamps to change default behavior, keep mtime/atime of source files in destination (default to false)
+ * @param {String} opts.filterPattern execute copy if source matches to this regex pattern.
+ * @param {module:api/WfsApi~copyCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.copy = function(wfsId, wfsPath, srcPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling copy";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling copy";
+ }
+
+ // verify the required parameter 'srcPath' is set
+ if (srcPath == undefined || srcPath == null) {
+ throw "Missing the required parameter 'srcPath' when calling copy";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'srcPath': srcPath,
+ 'removeExisting': opts['removeExisting'],
+ 'followSymbolicLinks': opts['followSymbolicLinks'],
+ 'noPreserveTimestamps': opts['noPreserveTimestamps'],
+ 'filterPattern': opts['filterPattern']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/any/{wfsPath}', 'PUT',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the createDir operation.
+ * @callback module:api/WfsApi~createDirCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * create a directory at the path. will return error when wfsPath exists and not empty
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
+ * @param {module:api/WfsApi~createDirCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.createDir = function(wfsId, wfsPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling createDir";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling createDir";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'ensure': opts['ensure']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/dir/{wfsPath}', 'PUT',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the dirTree operation.
+ * @callback module:api/WfsApi~dirTreeCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/DirEntry} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * returns a directory tree of given path, for listing dir and managing file system
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {Integer} maxDepth Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list.
+ * @param {module:api/WfsApi~dirTreeCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/DirEntry}
+ */
+ this.dirTree = function(wfsId, wfsPath, maxDepth, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling dirTree";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling dirTree";
+ }
+
+ // verify the required parameter 'maxDepth' is set
+ if (maxDepth == undefined || maxDepth == null) {
+ throw "Missing the required parameter 'maxDepth' when calling dirTree";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'maxDepth': maxDepth
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = DirEntry;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/dir/{wfsPath}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the move operation.
+ * @callback module:api/WfsApi~moveCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * move file or directory to given path. works like mv command
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {String} srcPath source data path of some operations, with have heading /
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.removeExisting remove any existing file/dir before writing. (default to false)
+ * @param {module:api/WfsApi~moveCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.move = function(wfsId, wfsPath, srcPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling move";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling move";
+ }
+
+ // verify the required parameter 'srcPath' is set
+ if (srcPath == undefined || srcPath == null) {
+ throw "Missing the required parameter 'srcPath' when calling move";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'srcPath': srcPath,
+ 'removeExisting': opts['removeExisting']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/dir/{wfsPath}', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the readFile operation.
+ * @callback module:api/WfsApi~readFileCallback
+ * @param {String} error Error message, if any.
+ * @param {File} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * read file data on path
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {module:api/WfsApi~readFileCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {File}
+ */
+ this.readFile = function(wfsId, wfsPath, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling readFile";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling readFile";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = File;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/file/{wfsPath}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the remove operation.
+ * @callback module:api/WfsApi~removeCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * delete file or directory
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.recursive flag to set copy with (default to false)
+ * @param {module:api/WfsApi~removeCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.remove = function(wfsId, wfsPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling remove";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling remove";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'recursive': opts['recursive']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/any/{wfsPath}', 'DELETE',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the rename operation.
+ * @callback module:api/WfsApi~renameCallback
+ * @param {String} error Error message, if any.
+ * @param {File} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * Rename a file or directory to. This api does not remove an existing one.
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {String} srcPath source data path of some operations, with have heading /
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
+ * @param {module:api/WfsApi~renameCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {File}
+ */
+ this.rename = function(wfsId, wfsPath, srcPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling rename";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling rename";
+ }
+
+ // verify the required parameter 'srcPath' is set
+ if (srcPath == undefined || srcPath == null) {
+ throw "Missing the required parameter 'srcPath' when calling rename";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'srcPath': srcPath,
+ 'ensure': opts['ensure']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = File;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/file/{wfsPath}', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the stat operation.
+ * @callback module:api/WfsApi~statCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Stats} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * get stats of given path. (stat returns 'stats' object in node and POSIX)
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ignoreError flag to ignore stat errors to check existence only (default to false)
+ * @param {module:api/WfsApi~statCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Stats}
+ */
+ this.stat = function(wfsId, wfsPath, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling stat";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling stat";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'ignoreError': opts['ignoreError']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Stats;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/any/{wfsPath}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the writeFile operation.
+ * @callback module:api/WfsApi~writeFileCallback
+ * @param {String} error Error message, if any.
+ * @param {File} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * create / update file with body data
+ * @param {String} wfsId webida file system id (same to workspace id) to access.
+ * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
+ * @param {File} data file contents to write.
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
+ * @param {module:api/WfsApi~writeFileCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {File}
+ */
+ this.writeFile = function(wfsId, wfsPath, data, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'wfsId' is set
+ if (wfsId == undefined || wfsId == null) {
+ throw "Missing the required parameter 'wfsId' when calling writeFile";
+ }
+
+ // verify the required parameter 'wfsPath' is set
+ if (wfsPath == undefined || wfsPath == null) {
+ throw "Missing the required parameter 'wfsPath' when calling writeFile";
+ }
+
+ // verify the required parameter 'data' is set
+ if (data == undefined || data == null) {
+ throw "Missing the required parameter 'data' when calling writeFile";
+ }
+
+
+ var pathParams = {
+ 'wfsId': wfsId,
+ 'wfsPath': wfsPath
+ };
+ var queryParams = {
+ 'ensure': opts['ensure']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ 'data': data
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['multipart/form-data'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = File;
+
+ return this.apiClient.callApi(
+ '/wfs/{wfsId}/file/{wfsPath}', 'PUT',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
new file mode 100644
index 00000000..a9d6351d
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
@@ -0,0 +1,372 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Workspace', '../model/ExecRequest', '../model/ExecResponse', '../model/ExecAsyncResponse'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Workspace'), require('../model/ExecRequest'), require('../model/ExecResponse'), require('../model/ExecAsyncResponse'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.WorkspaceApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Workspace, root.WebidaServiceApi.ExecRequest, root.WebidaServiceApi.ExecResponse, root.WebidaServiceApi.ExecAsyncResponse);
+ }
+}(this, function(ApiClient, RestOK, RestError, Workspace, ExecRequest, ExecResponse, ExecAsyncResponse) {
+ 'use strict';
+
+ /**
+ * Workspace service.
+ * @module api/WorkspaceApi
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new WorkspaceApi.
+ * @alias module:api/WorkspaceApi
+ * @class
+ * @param {module:ApiClient} apiClient Optional API client implementation to use,
+ * default to {@link module:ApiClient#instance} if unspecified.
+ */
+ var exports = function(apiClient) {
+ this.apiClient = apiClient || ApiClient.instance;
+
+
+ /**
+ * Callback function to receive the result of the cancel operation.
+ * @callback module:api/WorkspaceApi~cancelCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/RestOK} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * cancels a async execution
+ * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
+ * @param {String} execId the execId property in ExecResponse
+ * @param {module:api/WorkspaceApi~cancelCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/RestOK}
+ */
+ this.cancel = function(workspaceId, execId, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'workspaceId' is set
+ if (workspaceId == undefined || workspaceId == null) {
+ throw "Missing the required parameter 'workspaceId' when calling cancel";
+ }
+
+ // verify the required parameter 'execId' is set
+ if (execId == undefined || execId == null) {
+ throw "Missing the required parameter 'execId' when calling cancel";
+ }
+
+
+ var pathParams = {
+ 'workspaceId': workspaceId
+ };
+ var queryParams = {
+ 'execId': execId
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = RestOK;
+
+ return this.apiClient.callApi(
+ '/workspaces/{workspaceId}/exec', 'DELETE',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the createWorkspace operation.
+ * @callback module:api/WorkspaceApi~createWorkspaceCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Workspace} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * create a new workspace at given path
+ * @param {String} workspacePath a real path of the system or relative path to workspace cellar
+ * @param {module:api/WorkspaceApi~createWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Workspace}
+ */
+ this.createWorkspace = function(workspacePath, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'workspacePath' is set
+ if (workspacePath == undefined || workspacePath == null) {
+ throw "Missing the required parameter 'workspacePath' when calling createWorkspace";
+ }
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ 'workspacePath': workspacePath
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Workspace;
+
+ return this.apiClient.callApi(
+ '/workspaces', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the exec operation.
+ * @callback module:api/WorkspaceApi~execCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/ExecResponse} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * execute a shell command
+ * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
+ * @param {module:model/ExecRequest} body
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.async Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel. (default to false)
+ * @param {String} opts.execId mandatory for async execution. the result stream will be identified with this id
+ * @param {module:api/WorkspaceApi~execCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/ExecResponse}
+ */
+ this.exec = function(workspaceId, body, opts, callback) {
+ opts = opts || {};
+ var postBody = body;
+
+ // verify the required parameter 'workspaceId' is set
+ if (workspaceId == undefined || workspaceId == null) {
+ throw "Missing the required parameter 'workspaceId' when calling exec";
+ }
+
+ // verify the required parameter 'body' is set
+ if (body == undefined || body == null) {
+ throw "Missing the required parameter 'body' when calling exec";
+ }
+
+
+ var pathParams = {
+ 'workspaceId': workspaceId
+ };
+ var queryParams = {
+ 'async': opts['async'],
+ 'execId': opts['execId']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = ExecResponse;
+
+ return this.apiClient.callApi(
+ '/workspaces/{workspaceId}/exec', 'POST',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the getAllWorkspaces operation.
+ * @callback module:api/WorkspaceApi~getAllWorkspacesCallback
+ * @param {String} error Error message, if any.
+ * @param {Array.} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
+ * @param {Object} opts Optional parameters
+ * @param {Boolean} opts.disposable include disposable workspaces in response (default to false)
+ * @param {module:api/WorkspaceApi~getAllWorkspacesCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {Array.}
+ */
+ this.getAllWorkspaces = function(opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+
+ var pathParams = {
+ };
+ var queryParams = {
+ 'disposable': opts['disposable']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = [Workspace];
+
+ return this.apiClient.callApi(
+ '/workspaces', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the getWorkspace operation.
+ * @callback module:api/WorkspaceApi~getWorkspaceCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Workspace} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * get all workspaces registerd (non-disposable) in the server
+ * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
+ * @param {module:api/WorkspaceApi~getWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Workspace}
+ */
+ this.getWorkspace = function(workspaceId, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'workspaceId' is set
+ if (workspaceId == undefined || workspaceId == null) {
+ throw "Missing the required parameter 'workspaceId' when calling getWorkspace";
+ }
+
+
+ var pathParams = {
+ 'workspaceId': workspaceId
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Workspace;
+
+ return this.apiClient.callApi(
+ '/workspaces/{workspaceId}', 'GET',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the removeWorkspace operation.
+ * @callback module:api/WorkspaceApi~removeWorkspaceCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Workspace} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * remove a workspace. all sessions on this workspace will be closed.
+ * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
+ * @param {Object} opts Optional parameters
+ * @param {Integer} opts.wait Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely. (default to 0)
+ * @param {module:api/WorkspaceApi~removeWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Workspace}
+ */
+ this.removeWorkspace = function(workspaceId, opts, callback) {
+ opts = opts || {};
+ var postBody = null;
+
+ // verify the required parameter 'workspaceId' is set
+ if (workspaceId == undefined || workspaceId == null) {
+ throw "Missing the required parameter 'workspaceId' when calling removeWorkspace";
+ }
+
+
+ var pathParams = {
+ 'workspaceId': workspaceId
+ };
+ var queryParams = {
+ 'wait': opts['wait']
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Workspace;
+
+ return this.apiClient.callApi(
+ '/workspaces/{workspaceId}', 'DELETE',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+
+ /**
+ * Callback function to receive the result of the updateWorkspace operation.
+ * @callback module:api/WorkspaceApi~updateWorkspaceCallback
+ * @param {String} error Error message, if any.
+ * @param {module:model/Workspace} data The data returned by the service call.
+ * @param {String} response The complete HTTP response.
+ */
+
+ /**
+ * update workspace information. some properties will not be updated by this api.
+ * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
+ * @param {module:api/WorkspaceApi~updateWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
+ * data is of type: {module:model/Workspace}
+ */
+ this.updateWorkspace = function(workspaceId, callback) {
+ var postBody = null;
+
+ // verify the required parameter 'workspaceId' is set
+ if (workspaceId == undefined || workspaceId == null) {
+ throw "Missing the required parameter 'workspaceId' when calling updateWorkspace";
+ }
+
+
+ var pathParams = {
+ 'workspaceId': workspaceId
+ };
+ var queryParams = {
+ };
+ var headerParams = {
+ };
+ var formParams = {
+ };
+
+ var authNames = ['webida-simple-auth'];
+ var contentTypes = ['application/json'];
+ var accepts = ['application/json', 'application/octet-stream'];
+ var returnType = Workspace;
+
+ return this.apiClient.callApi(
+ '/workspaces/{workspaceId}', 'PUT',
+ pathParams, queryParams, headerParams, formParams, postBody,
+ authNames, contentTypes, accepts, returnType, callback
+ );
+ }
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
new file mode 100644
index 00000000..4920edff
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
@@ -0,0 +1,162 @@
+(function(factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['./ApiClient', './model/AccessToken', './model/DirEntry', './model/ExecAsyncResponse', './model/ExecRequest', './model/ExecResponse', './model/LoginRequest', './model/LoginResponse', './model/MasterToken', './model/Match', './model/RestError', './model/RestOK', './model/Session', './model/Stats', './model/Token', './model/User', './model/Workspace', './api/AuthApi', './api/DefaultApi', './api/OpsApi', './api/SessionApi', './api/WfsApi', './api/WorkspaceApi'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('./ApiClient'), require('./model/AccessToken'), require('./model/DirEntry'), require('./model/ExecAsyncResponse'), require('./model/ExecRequest'), require('./model/ExecResponse'), require('./model/LoginRequest'), require('./model/LoginResponse'), require('./model/MasterToken'), require('./model/Match'), require('./model/RestError'), require('./model/RestOK'), require('./model/Session'), require('./model/Stats'), require('./model/Token'), require('./model/User'), require('./model/Workspace'), require('./api/AuthApi'), require('./api/DefaultApi'), require('./api/OpsApi'), require('./api/SessionApi'), require('./api/WfsApi'), require('./api/WorkspaceApi'));
+ }
+}(function(ApiClient, AccessToken, DirEntry, ExecAsyncResponse, ExecRequest, ExecResponse, LoginRequest, LoginResponse, MasterToken, Match, RestError, RestOK, Session, Stats, Token, User, Workspace, AuthApi, DefaultApi, OpsApi, SessionApi, WfsApi, WorkspaceApi) {
+ 'use strict';
+
+ /**
+ * Webida Service API specfication.
+ * The index module provides access to constructors for all the classes which comprise the public API.
+ *
+ * An AMD (recommended!) or CommonJS application will generally do something equivalent to the following:
+ *
+ * var WebidaServiceApi = require('index'); // See note below*.
+ * var xxxSvc = new WebidaServiceApi.XxxApi(); // Allocate the API class we're going to use.
+ * var yyyModel = new WebidaServiceApi.Yyy(); // Construct a model instance.
+ * yyyModel.someProperty = 'someValue';
+ * ...
+ * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
+ * ...
+ *
+ * *NOTE: For a top-level AMD script, use require(['index'], function(){...})
+ * and put the application logic within the callback function.
+ *
+ *
+ * A non-AMD browser application (discouraged) might do something like this:
+ *
+ * var xxxSvc = new WebidaServiceApi.XxxApi(); // Allocate the API class we're going to use.
+ * var yyy = new WebidaServiceApi.Yyy(); // Construct a model instance.
+ * yyyModel.someProperty = 'someValue';
+ * ...
+ * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
+ * ...
+ *
+ *
+ * @module index
+ * @version 0.1
+ */
+ var exports = {
+ /**
+ * The ApiClient constructor.
+ * @property {module:ApiClient}
+ */
+ ApiClient: ApiClient,
+ /**
+ * The AccessToken model constructor.
+ * @property {module:model/AccessToken}
+ */
+ AccessToken: AccessToken,
+ /**
+ * The DirEntry model constructor.
+ * @property {module:model/DirEntry}
+ */
+ DirEntry: DirEntry,
+ /**
+ * The ExecAsyncResponse model constructor.
+ * @property {module:model/ExecAsyncResponse}
+ */
+ ExecAsyncResponse: ExecAsyncResponse,
+ /**
+ * The ExecRequest model constructor.
+ * @property {module:model/ExecRequest}
+ */
+ ExecRequest: ExecRequest,
+ /**
+ * The ExecResponse model constructor.
+ * @property {module:model/ExecResponse}
+ */
+ ExecResponse: ExecResponse,
+ /**
+ * The LoginRequest model constructor.
+ * @property {module:model/LoginRequest}
+ */
+ LoginRequest: LoginRequest,
+ /**
+ * The LoginResponse model constructor.
+ * @property {module:model/LoginResponse}
+ */
+ LoginResponse: LoginResponse,
+ /**
+ * The MasterToken model constructor.
+ * @property {module:model/MasterToken}
+ */
+ MasterToken: MasterToken,
+ /**
+ * The Match model constructor.
+ * @property {module:model/Match}
+ */
+ Match: Match,
+ /**
+ * The RestError model constructor.
+ * @property {module:model/RestError}
+ */
+ RestError: RestError,
+ /**
+ * The RestOK model constructor.
+ * @property {module:model/RestOK}
+ */
+ RestOK: RestOK,
+ /**
+ * The Session model constructor.
+ * @property {module:model/Session}
+ */
+ Session: Session,
+ /**
+ * The Stats model constructor.
+ * @property {module:model/Stats}
+ */
+ Stats: Stats,
+ /**
+ * The Token model constructor.
+ * @property {module:model/Token}
+ */
+ Token: Token,
+ /**
+ * The User model constructor.
+ * @property {module:model/User}
+ */
+ User: User,
+ /**
+ * The Workspace model constructor.
+ * @property {module:model/Workspace}
+ */
+ Workspace: Workspace,
+ /**
+ * The AuthApi service constructor.
+ * @property {module:api/AuthApi}
+ */
+ AuthApi: AuthApi,
+ /**
+ * The DefaultApi service constructor.
+ * @property {module:api/DefaultApi}
+ */
+ DefaultApi: DefaultApi,
+ /**
+ * The OpsApi service constructor.
+ * @property {module:api/OpsApi}
+ */
+ OpsApi: OpsApi,
+ /**
+ * The SessionApi service constructor.
+ * @property {module:api/SessionApi}
+ */
+ SessionApi: SessionApi,
+ /**
+ * The WfsApi service constructor.
+ * @property {module:api/WfsApi}
+ */
+ WfsApi: WfsApi,
+ /**
+ * The WorkspaceApi service constructor.
+ * @property {module:api/WorkspaceApi}
+ */
+ WorkspaceApi: WorkspaceApi
+ };
+
+ return exports;
+}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
new file mode 100644
index 00000000..3c92b878
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
@@ -0,0 +1,85 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/Token'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('./Token'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.AccessToken = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.Token);
+ }
+}(this, function(ApiClient, Token) {
+ 'use strict';
+
+
+
+
+ /**
+ * The AccessToken model module.
+ * @module model/AccessToken
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new AccessToken.
+ * @alias module:model/AccessToken
+ * @class
+ * @extends module:model/Token
+ * @param tokenType
+ * @param expiresAt
+ * @param issuedAt
+ * @param sessionId
+ */
+ var exports = function(tokenType, expiresAt, issuedAt, sessionId) {
+ var _this = this;
+ Token.call(_this, tokenType, expiresAt, issuedAt);
+ _this['sessionId'] = sessionId;
+
+ };
+
+ /**
+ * Constructs a AccessToken from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/AccessToken} obj Optional instance to populate.
+ * @return {module:model/AccessToken} The populated AccessToken instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+ Token.constructFromObject(data, obj);
+ if (data.hasOwnProperty('sessionId')) {
+ obj['sessionId'] = ApiClient.convertToType(data['sessionId'], 'String');
+ }
+ if (data.hasOwnProperty('workspaceId')) {
+ obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ exports.prototype = Object.create(Token.prototype);
+ exports.prototype.constructor = exports;
+
+ /**
+ * An access token should not be shared between ide sessions, for each sessions requires distinct websocket connection, identified with session id. To change session id, call login again. Any Websocket connection will be rejected if requested upgrade does not contains proper access token data
+ * @member {String} sessionId
+ */
+ exports.prototype['sessionId'] = undefined;
+ /**
+ * the workspaceId inherited from master token
+ * @member {String} workspaceId
+ */
+ exports.prototype['workspaceId'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
new file mode 100644
index 00000000..a2c1b0be
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
@@ -0,0 +1,87 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/DirEntry', '../model/Stats'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('./DirEntry'), require('./Stats'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.DirEntry = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.DirEntry, root.WebidaServiceApi.Stats);
+ }
+}(this, function(ApiClient, DirEntry, Stats) {
+ 'use strict';
+
+
+
+
+ /**
+ * The DirEntry model module.
+ * @module model/DirEntry
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new DirEntry.
+ * a directory entry (file or directory) with children that represents a (sub) tree
+ * @alias module:model/DirEntry
+ * @class
+ * @param name
+ * @param stats
+ * @param children
+ */
+ var exports = function(name, stats, children) {
+ var _this = this;
+
+ _this['name'] = name;
+ _this['stats'] = stats;
+ _this['children'] = children;
+ };
+
+ /**
+ * Constructs a DirEntry from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/DirEntry} obj Optional instance to populate.
+ * @return {module:model/DirEntry} The populated DirEntry instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('name')) {
+ obj['name'] = ApiClient.convertToType(data['name'], 'String');
+ }
+ if (data.hasOwnProperty('stats')) {
+ obj['stats'] = Stats.constructFromObject(data['stats']);
+ }
+ if (data.hasOwnProperty('children')) {
+ obj['children'] = ApiClient.convertToType(data['children'], [DirEntry]);
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {String} name
+ */
+ exports.prototype['name'] = undefined;
+ /**
+ * @member {module:model/Stats} stats
+ */
+ exports.prototype['stats'] = undefined;
+ /**
+ * @member {Array.} children
+ */
+ exports.prototype['children'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
new file mode 100644
index 00000000..4a812e1f
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
@@ -0,0 +1,90 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.ExecAsyncResponse = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The ExecAsyncResponse model module.
+ * @module model/ExecAsyncResponse
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new ExecAsyncResponse.
+ * execution response with output and exit code
+ * @alias module:model/ExecAsyncResponse
+ * @class
+ * @param exitCode
+ * @param stdout
+ * @param stderr
+ */
+ var exports = function(exitCode, stdout, stderr) {
+ var _this = this;
+
+ _this['exitCode'] = exitCode;
+ _this['stdout'] = stdout;
+ _this['stderr'] = stderr;
+ };
+
+ /**
+ * Constructs a ExecAsyncResponse from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/ExecAsyncResponse} obj Optional instance to populate.
+ * @return {module:model/ExecAsyncResponse} The populated ExecAsyncResponse instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('exitCode')) {
+ obj['exitCode'] = ApiClient.convertToType(data['exitCode'], 'Integer');
+ }
+ if (data.hasOwnProperty('stdout')) {
+ obj['stdout'] = ApiClient.convertToType(data['stdout'], 'String');
+ }
+ if (data.hasOwnProperty('stderr')) {
+ obj['stderr'] = ApiClient.convertToType(data['stderr'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * exit code of child process. for async operation, it's always 0
+ * @member {Integer} exitCode
+ */
+ exports.prototype['exitCode'] = undefined;
+ /**
+ * standard out of child process
+ * @member {String} stdout
+ */
+ exports.prototype['stdout'] = undefined;
+ /**
+ * standard error of child process
+ * @member {String} stderr
+ */
+ exports.prototype['stderr'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
new file mode 100644
index 00000000..559074ba
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
@@ -0,0 +1,106 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.ExecRequest = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The ExecRequest model module.
+ * @module model/ExecRequest
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new ExecRequest.
+ * execution request, simlilar to node.js child_proc.exec / spawn see node.js documentation for details of each properties. some properties are not configurable for portability - encoding : fixed to utf-8 - shell : fixed to system default. Using shell env variables in command is not recommended. - killSignal : fixed to default (SIGTERM) - uid, gid : will not be set - stdio : does not support 'ignore' and 'inherit'. all streams are handled by server.
+ * @alias module:model/ExecRequest
+ * @class
+ * @param command
+ */
+ var exports = function(command) {
+ var _this = this;
+
+ _this['command'] = command;
+
+
+
+
+ };
+
+ /**
+ * Constructs a ExecRequest from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/ExecRequest} obj Optional instance to populate.
+ * @return {module:model/ExecRequest} The populated ExecRequest instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('command')) {
+ obj['command'] = ApiClient.convertToType(data['command'], 'String');
+ }
+ if (data.hasOwnProperty('args')) {
+ obj['args'] = ApiClient.convertToType(data['args'], ['String']);
+ }
+ if (data.hasOwnProperty('cwd')) {
+ obj['cwd'] = ApiClient.convertToType(data['cwd'], 'String');
+ }
+ if (data.hasOwnProperty('input')) {
+ obj['input'] = ApiClient.convertToType(data['input'], 'String');
+ }
+ if (data.hasOwnProperty('maxBuffer')) {
+ obj['maxBuffer'] = ApiClient.convertToType(data['maxBuffer'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * name or path of executable file to run. should not contain any arguments.
+ * @member {String} command
+ */
+ exports.prototype['command'] = undefined;
+ /**
+ * the command line arguments for the command. if 'shell' property is true, this args will be joined with ' ' and appended to command string
+ * @member {Array.} args
+ */
+ exports.prototype['args'] = undefined;
+ /**
+ * Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept shell-variable form like $HOME, %USERPROFILE%
+ * @member {String} cwd
+ */
+ exports.prototype['cwd'] = undefined;
+ /**
+ * The value which will be passed as stdin to the spawned process. If abscent, server will not write to input anything
+ * @member {String} input
+ */
+ exports.prototype['input'] = undefined;
+ /**
+ * largest amount of data (in bytes) allowed on stdout or stderr. if exceeded child process is killed by server. if async is true, this arguments will be ignored by spawn()
+ * @member {String} maxBuffer
+ */
+ exports.prototype['maxBuffer'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
new file mode 100644
index 00000000..135877f3
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
@@ -0,0 +1,90 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.ExecResponse = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The ExecResponse model module.
+ * @module model/ExecResponse
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new ExecResponse.
+ * execution response with output and exit code
+ * @alias module:model/ExecResponse
+ * @class
+ * @param exitCode
+ * @param stdout
+ * @param stderr
+ */
+ var exports = function(exitCode, stdout, stderr) {
+ var _this = this;
+
+ _this['exitCode'] = exitCode;
+ _this['stdout'] = stdout;
+ _this['stderr'] = stderr;
+ };
+
+ /**
+ * Constructs a ExecResponse from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/ExecResponse} obj Optional instance to populate.
+ * @return {module:model/ExecResponse} The populated ExecResponse instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('exitCode')) {
+ obj['exitCode'] = ApiClient.convertToType(data['exitCode'], 'Integer');
+ }
+ if (data.hasOwnProperty('stdout')) {
+ obj['stdout'] = ApiClient.convertToType(data['stdout'], 'String');
+ }
+ if (data.hasOwnProperty('stderr')) {
+ obj['stderr'] = ApiClient.convertToType(data['stderr'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * exit code of child process. for async operation, it's always 0
+ * @member {Integer} exitCode
+ */
+ exports.prototype['exitCode'] = undefined;
+ /**
+ * standard out of child process
+ * @member {String} stdout
+ */
+ exports.prototype['stdout'] = undefined;
+ /**
+ * standard error of child process
+ * @member {String} stderr
+ */
+ exports.prototype['stderr'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js
new file mode 100644
index 00000000..335231b1
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js
@@ -0,0 +1,86 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.LoginRequest = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The LoginRequest model module.
+ * @module model/LoginRequest
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new LoginRequest.
+ * @alias module:model/LoginRequest
+ * @class
+ * @param loginId
+ * @param loginPassword
+ */
+ var exports = function(loginId, loginPassword) {
+ var _this = this;
+
+ _this['loginId'] = loginId;
+ _this['loginPassword'] = loginPassword;
+
+ };
+
+ /**
+ * Constructs a LoginRequest from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/LoginRequest} obj Optional instance to populate.
+ * @return {module:model/LoginRequest} The populated LoginRequest instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('loginId')) {
+ obj['loginId'] = ApiClient.convertToType(data['loginId'], 'String');
+ }
+ if (data.hasOwnProperty('loginPassword')) {
+ obj['loginPassword'] = ApiClient.convertToType(data['loginPassword'], 'String');
+ }
+ if (data.hasOwnProperty('masterToken')) {
+ obj['masterToken'] = ApiClient.convertToType(data['masterToken'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {String} loginId
+ */
+ exports.prototype['loginId'] = undefined;
+ /**
+ * @member {String} loginPassword
+ */
+ exports.prototype['loginPassword'] = undefined;
+ /**
+ * If master token is set and valid, login Id / Password will be ignored but still required. Put some bogus values to pass argument validation. Bogus master token in request will not make server issue a new master token.
+ * @member {String} masterToken
+ */
+ exports.prototype['masterToken'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
new file mode 100644
index 00000000..156f3800
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
@@ -0,0 +1,96 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/AccessToken', '../model/MasterToken'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('./AccessToken'), require('./MasterToken'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.LoginResponse = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.AccessToken, root.WebidaServiceApi.MasterToken);
+ }
+}(this, function(ApiClient, AccessToken, MasterToken) {
+ 'use strict';
+
+
+
+
+ /**
+ * The LoginResponse model module.
+ * @module model/LoginResponse
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new LoginResponse.
+ * login response for clients to use in service access. use 'decode' api to see detail
+ * @alias module:model/LoginResponse
+ * @class
+ * @param accessToken
+ * @param decodedAccessToken
+ */
+ var exports = function(accessToken, decodedAccessToken) {
+ var _this = this;
+
+ _this['accessToken'] = accessToken;
+ _this['decodedAccessToken'] = decodedAccessToken;
+
+
+ };
+
+ /**
+ * Constructs a LoginResponse from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/LoginResponse} obj Optional instance to populate.
+ * @return {module:model/LoginResponse} The populated LoginResponse instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('accessToken')) {
+ obj['accessToken'] = ApiClient.convertToType(data['accessToken'], 'String');
+ }
+ if (data.hasOwnProperty('decodedAccessToken')) {
+ obj['decodedAccessToken'] = AccessToken.constructFromObject(data['decodedAccessToken']);
+ }
+ if (data.hasOwnProperty('masterToken')) {
+ obj['masterToken'] = ApiClient.convertToType(data['masterToken'], 'String');
+ }
+ if (data.hasOwnProperty('decodedMasterToken')) {
+ obj['decodedMasterToken'] = MasterToken.constructFromObject(data['decodedMasterToken']);
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * actual token text which should be included in header or cookie
+ * @member {String} accessToken
+ */
+ exports.prototype['accessToken'] = undefined;
+ /**
+ * @member {module:model/AccessToken} decodedAccessToken
+ */
+ exports.prototype['decodedAccessToken'] = undefined;
+ /**
+ * unrestricted master token when user has logged in with valid credential
+ * @member {String} masterToken
+ */
+ exports.prototype['masterToken'] = undefined;
+ /**
+ * @member {module:model/MasterToken} decodedMasterToken
+ */
+ exports.prototype['decodedMasterToken'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
new file mode 100644
index 00000000..c177646c
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
@@ -0,0 +1,75 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/Token'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('./Token'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.MasterToken = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.Token);
+ }
+}(this, function(ApiClient, Token) {
+ 'use strict';
+
+
+
+
+ /**
+ * The MasterToken model module.
+ * @module model/MasterToken
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new MasterToken.
+ * @alias module:model/MasterToken
+ * @class
+ * @extends module:model/Token
+ * @param tokenType
+ * @param expiresAt
+ * @param issuedAt
+ */
+ var exports = function(tokenType, expiresAt, issuedAt) {
+ var _this = this;
+ Token.call(_this, tokenType, expiresAt, issuedAt);
+
+ };
+
+ /**
+ * Constructs a MasterToken from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/MasterToken} obj Optional instance to populate.
+ * @return {module:model/MasterToken} The populated MasterToken instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+ Token.constructFromObject(data, obj);
+ if (data.hasOwnProperty('workspaceId')) {
+ obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ exports.prototype = Object.create(Token.prototype);
+ exports.prototype.constructor = exports;
+
+ /**
+ * Some MASTER tokens has some 'restricted' access rights, bound to specific workspace, with as issueToken() operation specifies. Any access tokens created from a restricted master token inherits same restriction. If this value is falsy, token has no restriction and can be used to access all apis. If truthy, some api calls that touches internal access registry or session registry will have met 403 error. Some filesystem apis will be rejected, too.
+ * @member {String} workspaceId
+ */
+ exports.prototype['workspaceId'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
new file mode 100644
index 00000000..a499d4fd
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
@@ -0,0 +1,78 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.Match = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The Match model module.
+ * @module model/Match
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new Match.
+ * search result for a file
+ * @alias module:model/Match
+ * @class
+ * @param line
+ * @param text
+ */
+ var exports = function(line, text) {
+ var _this = this;
+
+ _this['line'] = line;
+ _this['text'] = text;
+ };
+
+ /**
+ * Constructs a Match from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/Match} obj Optional instance to populate.
+ * @return {module:model/Match} The populated Match instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('line')) {
+ obj['line'] = ApiClient.convertToType(data['line'], 'Integer');
+ }
+ if (data.hasOwnProperty('text')) {
+ obj['text'] = ApiClient.convertToType(data['text'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {Integer} line
+ */
+ exports.prototype['line'] = undefined;
+ /**
+ * @member {String} text
+ */
+ exports.prototype['text'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
new file mode 100644
index 00000000..30169a70
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
@@ -0,0 +1,77 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.RestError = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The RestError model module.
+ * @module model/RestError
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new RestError.
+ * Contains status text, not status code.
+ * @alias module:model/RestError
+ * @class
+ * @param message
+ */
+ var exports = function(message) {
+ var _this = this;
+
+
+ _this['message'] = message;
+ };
+
+ /**
+ * Constructs a RestError from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/RestError} obj Optional instance to populate.
+ * @return {module:model/RestError} The populated RestError instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('code')) {
+ obj['code'] = ApiClient.convertToType(data['code'], 'String');
+ }
+ if (data.hasOwnProperty('message')) {
+ obj['message'] = ApiClient.convertToType(data['message'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {String} code
+ */
+ exports.prototype['code'] = undefined;
+ /**
+ * @member {String} message
+ */
+ exports.prototype['message'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
new file mode 100644
index 00000000..4826532e
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
@@ -0,0 +1,67 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.RestOK = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The RestOK model module.
+ * @module model/RestOK
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new RestOK.
+ * @alias module:model/RestOK
+ * @class
+ */
+ var exports = function() {
+ var _this = this;
+
+
+ };
+
+ /**
+ * Constructs a RestOK from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/RestOK} obj Optional instance to populate.
+ * @return {module:model/RestOK} The populated RestOK instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('message')) {
+ obj['message'] = ApiClient.convertToType(data['message'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {String} message
+ */
+ exports.prototype['message'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
new file mode 100644
index 00000000..65606f30
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
@@ -0,0 +1,169 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.Session = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The Session model module.
+ * @module model/Session
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new Session.
+ * an application session per ide instance. bound to access token
+ * @alias module:model/Session
+ * @class
+ * @param id
+ * @param name
+ * @param state
+ * @param workspaceId
+ * @param clientAddress
+ * @param connectedAt
+ * @param disconnectedAt
+ */
+ var exports = function(id, name, state, workspaceId, clientAddress, connectedAt, disconnectedAt) {
+ var _this = this;
+
+ _this['id'] = id;
+ _this['name'] = name;
+ _this['state'] = state;
+ _this['workspaceId'] = workspaceId;
+ _this['clientAddress'] = clientAddress;
+ _this['connectedAt'] = connectedAt;
+ _this['disconnectedAt'] = disconnectedAt;
+
+
+ };
+
+ /**
+ * Constructs a Session from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/Session} obj Optional instance to populate.
+ * @return {module:model/Session} The populated Session instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('id')) {
+ obj['id'] = ApiClient.convertToType(data['id'], 'String');
+ }
+ if (data.hasOwnProperty('name')) {
+ obj['name'] = ApiClient.convertToType(data['name'], 'String');
+ }
+ if (data.hasOwnProperty('state')) {
+ obj['state'] = ApiClient.convertToType(data['state'], 'String');
+ }
+ if (data.hasOwnProperty('workspaceId')) {
+ obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
+ }
+ if (data.hasOwnProperty('clientAddress')) {
+ obj['clientAddress'] = ApiClient.convertToType(data['clientAddress'], 'String');
+ }
+ if (data.hasOwnProperty('connectedAt')) {
+ obj['connectedAt'] = ApiClient.convertToType(data['connectedAt'], 'Date');
+ }
+ if (data.hasOwnProperty('disconnectedAt')) {
+ obj['disconnectedAt'] = ApiClient.convertToType(data['disconnectedAt'], 'Date');
+ }
+ if (data.hasOwnProperty('willCloseAt')) {
+ obj['willCloseAt'] = ApiClient.convertToType(data['willCloseAt'], 'Date');
+ }
+ if (data.hasOwnProperty('willLoseAt')) {
+ obj['willLoseAt'] = ApiClient.convertToType(data['willLoseAt'], 'Date');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * the id of a session. usually same to socket id
+ * @member {String} id
+ */
+ exports.prototype['id'] = undefined;
+ /**
+ * human readable name, usually derived from workspace name.
+ * @member {String} name
+ */
+ exports.prototype['name'] = undefined;
+ /**
+ * state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout.
+ * @member {module:model/Session.StateEnum} state
+ */
+ exports.prototype['state'] = undefined;
+ /**
+ * the id of workspace that this sessions is working on.
+ * @member {String} workspaceId
+ */
+ exports.prototype['workspaceId'] = undefined;
+ /**
+ * absolute path of this workspace in server
+ * @member {String} clientAddress
+ */
+ exports.prototype['clientAddress'] = undefined;
+ /**
+ * the time when socket connection is established
+ * @member {Date} connectedAt
+ */
+ exports.prototype['connectedAt'] = undefined;
+ /**
+ * the time when socket is closed.
+ * @member {Date} disconnectedAt
+ */
+ exports.prototype['disconnectedAt'] = undefined;
+ /**
+ * when state becomes CLOSING, actual closing time will be updated by server.
+ * @member {Date} willCloseAt
+ */
+ exports.prototype['willCloseAt'] = undefined;
+ /**
+ * when state becomes LOSING, server will not wait for reconnection after this time.
+ * @member {Date} willLoseAt
+ */
+ exports.prototype['willLoseAt'] = undefined;
+
+
+ /**
+ * Allowed values for the state property.
+ * @enum {String}
+ * @readonly
+ */
+ exports.StateEnum = {
+ /**
+ * value: "NORMAL"
+ * @const
+ */
+ "NORMAL": "NORMAL",
+ /**
+ * value: "LOSING"
+ * @const
+ */
+ "LOSING": "LOSING",
+ /**
+ * value: "CLOSING"
+ * @const
+ */
+ "CLOSING": "CLOSING" };
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
new file mode 100644
index 00000000..342c631e
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
@@ -0,0 +1,163 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient', '../model/RestError'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'), require('./RestError'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.Stats = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError);
+ }
+}(this, function(ApiClient, RestError) {
+ 'use strict';
+
+
+
+
+ /**
+ * The Stats model module.
+ * @module model/Stats
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new Stats.
+ * simplified/augmented fs.Stats class - see node.js doc for all properties
+ * @alias module:model/Stats
+ * @class
+ * @param type
+ */
+ var exports = function(type) {
+ var _this = this;
+
+ _this['type'] = type;
+
+
+
+
+
+
+ };
+
+ /**
+ * Constructs a Stats from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/Stats} obj Optional instance to populate.
+ * @return {module:model/Stats} The populated Stats instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('type')) {
+ obj['type'] = ApiClient.convertToType(data['type'], 'String');
+ }
+ if (data.hasOwnProperty('birthtime')) {
+ obj['birthtime'] = ApiClient.convertToType(data['birthtime'], 'Date');
+ }
+ if (data.hasOwnProperty('mtime')) {
+ obj['mtime'] = ApiClient.convertToType(data['mtime'], 'Date');
+ }
+ if (data.hasOwnProperty('mode')) {
+ obj['mode'] = ApiClient.convertToType(data['mode'], 'String');
+ }
+ if (data.hasOwnProperty('size')) {
+ obj['size'] = ApiClient.convertToType(data['size'], 'Integer');
+ }
+ if (data.hasOwnProperty('nlink')) {
+ obj['nlink'] = ApiClient.convertToType(data['nlink'], 'Integer');
+ }
+ if (data.hasOwnProperty('error')) {
+ obj['error'] = RestError.constructFromObject(data['error']);
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * @member {module:model/Stats.TypeEnum} type
+ */
+ exports.prototype['type'] = undefined;
+ /**
+ * @member {Date} birthtime
+ */
+ exports.prototype['birthtime'] = undefined;
+ /**
+ * @member {Date} mtime
+ */
+ exports.prototype['mtime'] = undefined;
+ /**
+ * @member {String} mode
+ */
+ exports.prototype['mode'] = undefined;
+ /**
+ * @member {Integer} size
+ */
+ exports.prototype['size'] = undefined;
+ /**
+ * @member {Integer} nlink
+ */
+ exports.prototype['nlink'] = undefined;
+ /**
+ * @member {module:model/RestError} error
+ */
+ exports.prototype['error'] = undefined;
+
+
+ /**
+ * Allowed values for the type property.
+ * @enum {String}
+ * @readonly
+ */
+ exports.TypeEnum = {
+ /**
+ * value: "DUMMY"
+ * @const
+ */
+ "DUMMY": "DUMMY",
+ /**
+ * value: "FILE"
+ * @const
+ */
+ "FILE": "FILE",
+ /**
+ * value: "DIRECTORY"
+ * @const
+ */
+ "DIRECTORY": "DIRECTORY",
+ /**
+ * value: "BLOCK_DEVICE"
+ * @const
+ */
+ "BLOCK_DEVICE": "BLOCK_DEVICE",
+ /**
+ * value: "CHARACTER_DEVICE"
+ * @const
+ */
+ "CHARACTER_DEVICE": "CHARACTER_DEVICE",
+ /**
+ * value: "LINK"
+ * @const
+ */
+ "LINK": "LINK",
+ /**
+ * value: "FIFO"
+ * @const
+ */
+ "FIFO": "FIFO",
+ /**
+ * value: "SOCKET"
+ * @const
+ */
+ "SOCKET": "SOCKET" };
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
new file mode 100644
index 00000000..ee58d9dc
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
@@ -0,0 +1,109 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.Token = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The Token model module.
+ * @module model/Token
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new Token.
+ * Decoded token's data accessible to client apps
+ * @alias module:model/Token
+ * @class
+ * @param tokenType
+ * @param expiresAt
+ * @param issuedAt
+ */
+ var exports = function(tokenType, expiresAt, issuedAt) {
+ var _this = this;
+
+ _this['tokenType'] = tokenType;
+ _this['expiresAt'] = expiresAt;
+ _this['issuedAt'] = issuedAt;
+ };
+
+ /**
+ * Constructs a Token from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/Token} obj Optional instance to populate.
+ * @return {module:model/Token} The populated Token instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('tokenType')) {
+ obj['tokenType'] = ApiClient.convertToType(data['tokenType'], 'String');
+ }
+ if (data.hasOwnProperty('expiresAt')) {
+ obj['expiresAt'] = ApiClient.convertToType(data['expiresAt'], 'Date');
+ }
+ if (data.hasOwnProperty('issuedAt')) {
+ obj['issuedAt'] = ApiClient.convertToType(data['issuedAt'], 'Date');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a 'side-way' to create an 'unrestricted' master token before starting IDE instances. So, every ide client has a master token. If client want to access remote workspace directly, it should call login api with given master token which is generated from the remote login credential when adding remote workspace in main ui. Switching from a remote workspace to local one requires a local master token. It's not desirable to mix local and remote tokens in a single client instance in the view point of security. So, it's recommended to save local master token in session storage.
+ * @member {module:model/Token.TokenTypeEnum} tokenType
+ */
+ exports.prototype['tokenType'] = undefined;
+ /**
+ * @member {Date} expiresAt
+ */
+ exports.prototype['expiresAt'] = undefined;
+ /**
+ * @member {Date} issuedAt
+ */
+ exports.prototype['issuedAt'] = undefined;
+
+
+ /**
+ * Allowed values for the tokenType property.
+ * @enum {String}
+ * @readonly
+ */
+ exports.TokenTypeEnum = {
+ /**
+ * value: "MASTER"
+ * @const
+ */
+ "MASTER": "MASTER",
+ /**
+ * value: "ACCESS"
+ * @const
+ */
+ "ACCESS": "ACCESS",
+ /**
+ * value: "ADMIN"
+ * @const
+ */
+ "ADMIN": "ADMIN" };
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
new file mode 100644
index 00000000..43b2b5e6
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
@@ -0,0 +1,85 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.User = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The User model module.
+ * @module model/User
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new User.
+ * Any services/products should define some admin apis to manage users in the system and expose what should be exposed to client app. So, no properties are mandatory. Current properties are defined for compatiblity with legacy clients. Access token data can be decoded with another operations.
+ * @alias module:model/User
+ * @class
+ */
+ var exports = function() {
+ var _this = this;
+
+
+
+
+ };
+
+ /**
+ * Constructs a User from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/User} obj Optional instance to populate.
+ * @return {module:model/User} The populated User instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('id')) {
+ obj['id'] = ApiClient.convertToType(data['id'], 'String');
+ }
+ if (data.hasOwnProperty('email')) {
+ obj['email'] = ApiClient.convertToType(data['email'], 'String');
+ }
+ if (data.hasOwnProperty('name')) {
+ obj['name'] = ApiClient.convertToType(data['name'], 'String');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * unique id per user (email is also unique)
+ * @member {String} id
+ */
+ exports.prototype['id'] = undefined;
+ /**
+ * @member {String} email
+ */
+ exports.prototype['email'] = undefined;
+ /**
+ * @member {String} name
+ */
+ exports.prototype['name'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
new file mode 100644
index 00000000..2ff81145
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
@@ -0,0 +1,110 @@
+(function(root, factory) {
+ if (typeof define === 'function' && define.amd) {
+ // AMD. Register as an anonymous module.
+ define(['../ApiClient'], factory);
+ } else if (typeof module === 'object' && module.exports) {
+ // CommonJS-like environments that support module.exports, like Node.
+ module.exports = factory(require('../ApiClient'));
+ } else {
+ // Browser globals (root is window)
+ if (!root.WebidaServiceApi) {
+ root.WebidaServiceApi = {};
+ }
+ root.WebidaServiceApi.Workspace = factory(root.WebidaServiceApi.ApiClient);
+ }
+}(this, function(ApiClient) {
+ 'use strict';
+
+
+
+
+ /**
+ * The Workspace model module.
+ * @module model/Workspace
+ * @version 0.1
+ */
+
+ /**
+ * Constructs a new Workspace.
+ * Users' workspace in server
+ * @alias module:model/Workspace
+ * @class
+ * @param id
+ * @param name
+ * @param workspacePath
+ * @param createdAt
+ * @param accessedAt
+ */
+ var exports = function(id, name, workspacePath, createdAt, accessedAt) {
+ var _this = this;
+
+ _this['id'] = id;
+ _this['name'] = name;
+ _this['workspacePath'] = workspacePath;
+ _this['createdAt'] = createdAt;
+ _this['accessedAt'] = accessedAt;
+ };
+
+ /**
+ * Constructs a Workspace from a plain JavaScript object, optionally creating a new instance.
+ * Copies all relevant properties from data to obj if supplied or a new instance if not.
+ * @param {Object} data The plain JavaScript object bearing properties of interest.
+ * @param {module:model/Workspace} obj Optional instance to populate.
+ * @return {module:model/Workspace} The populated Workspace instance.
+ */
+ exports.constructFromObject = function(data, obj) {
+ if (data) {
+ obj = obj || new exports();
+
+ if (data.hasOwnProperty('id')) {
+ obj['id'] = ApiClient.convertToType(data['id'], 'String');
+ }
+ if (data.hasOwnProperty('name')) {
+ obj['name'] = ApiClient.convertToType(data['name'], 'String');
+ }
+ if (data.hasOwnProperty('workspacePath')) {
+ obj['workspacePath'] = ApiClient.convertToType(data['workspacePath'], 'String');
+ }
+ if (data.hasOwnProperty('createdAt')) {
+ obj['createdAt'] = ApiClient.convertToType(data['createdAt'], 'Date');
+ }
+ if (data.hasOwnProperty('accessedAt')) {
+ obj['accessedAt'] = ApiClient.convertToType(data['accessedAt'], 'Date');
+ }
+ }
+ return obj;
+ }
+
+ /**
+ * the id of a workspace. usually same to file system id
+ * @member {String} id
+ */
+ exports.prototype['id'] = undefined;
+ /**
+ * display text of this workspace. should not conflit to other workspaces
+ * @member {String} name
+ */
+ exports.prototype['name'] = undefined;
+ /**
+ * absolute path of this workspace in server
+ * @member {String} workspacePath
+ */
+ exports.prototype['workspacePath'] = undefined;
+ /**
+ * the time when this workspace is created (registered from local file system)
+ * @member {Date} createdAt
+ */
+ exports.prototype['createdAt'] = undefined;
+ /**
+ * the time when the last session on this workspace was made
+ * @member {Date} accessedAt
+ */
+ exports.prototype['accessedAt'] = undefined;
+
+
+
+
+ return exports;
+}));
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
new file mode 100644
index 00000000..8a81c1cd
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
@@ -0,0 +1,1569 @@
+(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.superagent = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 200 && res.status < 300) {
+ return self.callback(err, res);
+ }
+
+ var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
+ new_err.original = err;
+ new_err.response = res;
+ new_err.status = res.status;
+
+ self.callback(new_err, res);
+ } catch(e) {
+ self.callback(e); // #985 touching res may cause INVALID_STATE_ERR on old Android
+ }
+ });
+}
+
+/**
+ * Mixin `Emitter` and `requestBase`.
+ */
+
+Emitter(Request.prototype);
+for (var key in requestBase) {
+ Request.prototype[key] = requestBase[key];
+}
+
+/**
+ * Set Content-Type to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.xml = 'application/xml';
+ *
+ * request.post('/')
+ * .type('xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * request.post('/')
+ * .type('application/xml')
+ * .send(xmlstring)
+ * .end(callback);
+ *
+ * @param {String} type
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.type = function(type){
+ this.set('Content-Type', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set responseType to `val`. Presently valid responseTypes are 'blob' and
+ * 'arraybuffer'.
+ *
+ * Examples:
+ *
+ * req.get('/')
+ * .responseType('blob')
+ * .end(callback);
+ *
+ * @param {String} val
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.responseType = function(val){
+ this._responseType = val;
+ return this;
+};
+
+/**
+ * Set Accept to `type`, mapping values from `request.types`.
+ *
+ * Examples:
+ *
+ * superagent.types.json = 'application/json';
+ *
+ * request.get('/agent')
+ * .accept('json')
+ * .end(callback);
+ *
+ * request.get('/agent')
+ * .accept('application/json')
+ * .end(callback);
+ *
+ * @param {String} accept
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.accept = function(type){
+ this.set('Accept', request.types[type] || type);
+ return this;
+};
+
+/**
+ * Set Authorization field value with `user` and `pass`.
+ *
+ * @param {String} user
+ * @param {String} pass
+ * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.auth = function(user, pass, options){
+ if (!options) {
+ options = {
+ type: 'basic'
+ }
+ }
+
+ switch (options.type) {
+ case 'basic':
+ var str = btoa(user + ':' + pass);
+ this.set('Authorization', 'Basic ' + str);
+ break;
+
+ case 'auto':
+ this.username = user;
+ this.password = pass;
+ break;
+ }
+ return this;
+};
+
+/**
+* Add query-string `val`.
+*
+* Examples:
+*
+* request.get('/shoes')
+* .query('size=10')
+* .query({ color: 'blue' })
+*
+* @param {Object|String} val
+* @return {Request} for chaining
+* @api public
+*/
+
+Request.prototype.query = function(val){
+ if ('string' != typeof val) val = serialize(val);
+ if (val) this._query.push(val);
+ return this;
+};
+
+/**
+ * Queue the given `file` as an attachment to the specified `field`,
+ * with optional `filename`.
+ *
+ * ``` js
+ * request.post('/upload')
+ * .attach('content', new Blob(['hey!'], { type: "text/html"}))
+ * .end(callback);
+ * ```
+ *
+ * @param {String} field
+ * @param {Blob|File} file
+ * @param {String} filename
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.attach = function(field, file, filename){
+ this._getFormData().append(field, file, filename || file.name);
+ return this;
+};
+
+Request.prototype._getFormData = function(){
+ if (!this._formData) {
+ this._formData = new root.FormData();
+ }
+ return this._formData;
+};
+
+/**
+ * Invoke the callback with `err` and `res`
+ * and handle arity check.
+ *
+ * @param {Error} err
+ * @param {Response} res
+ * @api private
+ */
+
+Request.prototype.callback = function(err, res){
+ var fn = this._callback;
+ this.clearTimeout();
+ fn(err, res);
+};
+
+/**
+ * Invoke callback with x-domain error.
+ *
+ * @api private
+ */
+
+Request.prototype.crossDomainError = function(){
+ var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
+ err.crossDomain = true;
+
+ err.status = this.status;
+ err.method = this.method;
+ err.url = this.url;
+
+ this.callback(err);
+};
+
+/**
+ * Invoke callback with timeout error.
+ *
+ * @api private
+ */
+
+Request.prototype._timeoutError = function(){
+ var timeout = this._timeout;
+ var err = new Error('timeout of ' + timeout + 'ms exceeded');
+ err.timeout = timeout;
+ this.callback(err);
+};
+
+/**
+ * Compose querystring to append to req.url
+ *
+ * @api private
+ */
+
+Request.prototype._appendQueryString = function(){
+ var query = this._query.join('&');
+ if (query) {
+ this.url += ~this.url.indexOf('?')
+ ? '&' + query
+ : '?' + query;
+ }
+};
+
+/**
+ * Initiate request, invoking callback `fn(res)`
+ * with an instanceof `Response`.
+ *
+ * @param {Function} fn
+ * @return {Request} for chaining
+ * @api public
+ */
+
+Request.prototype.end = function(fn){
+ var self = this;
+ var xhr = this.xhr = request.getXHR();
+ var timeout = this._timeout;
+ var data = this._formData || this._data;
+
+ // store callback
+ this._callback = fn || noop;
+
+ // state change
+ xhr.onreadystatechange = function(){
+ if (4 != xhr.readyState) return;
+
+ // In IE9, reads to any property (e.g. status) off of an aborted XHR will
+ // result in the error "Could not complete the operation due to error c00c023f"
+ var status;
+ try { status = xhr.status } catch(e) { status = 0; }
+
+ if (0 == status) {
+ if (self.timedout) return self._timeoutError();
+ if (self._aborted) return;
+ return self.crossDomainError();
+ }
+ self.emit('end');
+ };
+
+ // progress
+ var handleProgress = function(e){
+ if (e.total > 0) {
+ e.percent = e.loaded / e.total * 100;
+ }
+ e.direction = 'download';
+ self.emit('progress', e);
+ };
+ if (this.hasListeners('progress')) {
+ xhr.onprogress = handleProgress;
+ }
+ try {
+ if (xhr.upload && this.hasListeners('progress')) {
+ xhr.upload.onprogress = handleProgress;
+ }
+ } catch(e) {
+ // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
+ // Reported here:
+ // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
+ }
+
+ // timeout
+ if (timeout && !this._timer) {
+ this._timer = setTimeout(function(){
+ self.timedout = true;
+ self.abort();
+ }, timeout);
+ }
+
+ // querystring
+ this._appendQueryString();
+
+ // initiate request
+ if (this.username && this.password) {
+ xhr.open(this.method, this.url, true, this.username, this.password);
+ } else {
+ xhr.open(this.method, this.url, true);
+ }
+
+ // CORS
+ if (this._withCredentials) xhr.withCredentials = true;
+
+ // body
+ if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
+ // serialize stuff
+ var contentType = this._header['content-type'];
+ var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
+ if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
+ if (serialize) data = serialize(data);
+ }
+
+ // set header fields
+ for (var field in this.header) {
+ if (null == this.header[field]) continue;
+ xhr.setRequestHeader(field, this.header[field]);
+ }
+
+ if (this._responseType) {
+ xhr.responseType = this._responseType;
+ }
+
+ // send stuff
+ this.emit('request', this);
+
+ // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
+ // We need null here if data is undefined
+ xhr.send(typeof data !== 'undefined' ? data : null);
+ return this;
+};
+
+
+/**
+ * Expose `Request`.
+ */
+
+request.Request = Request;
+
+/**
+ * GET `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.get = function(url, data, fn){
+ var req = request('GET', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.query(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * HEAD `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.head = function(url, data, fn){
+ var req = request('HEAD', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * OPTIONS query to `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.options = function(url, data, fn){
+ var req = request('OPTIONS', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * DELETE `url` with optional callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+function del(url, fn){
+ var req = request('DELETE', url);
+ if (fn) req.end(fn);
+ return req;
+};
+
+request['del'] = del;
+request['delete'] = del;
+
+/**
+ * PATCH `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.patch = function(url, data, fn){
+ var req = request('PATCH', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * POST `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed} data
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.post = function(url, data, fn){
+ var req = request('POST', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+/**
+ * PUT `url` with optional `data` and callback `fn(res)`.
+ *
+ * @param {String} url
+ * @param {Mixed|Function} data or fn
+ * @param {Function} fn
+ * @return {Request}
+ * @api public
+ */
+
+request.put = function(url, data, fn){
+ var req = request('PUT', url);
+ if ('function' == typeof data) fn = data, data = null;
+ if (data) req.send(data);
+ if (fn) req.end(fn);
+ return req;
+};
+
+},{"./is-object":1,"./request":3,"./request-base":2,"emitter":4,"reduce":5}]},{},[6])(6)
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs-utils.js b/common/src/webida/server-api-0.1-lib/wfs-utils.js
new file mode 100644
index 00000000..0b391ea5
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs-utils.js
@@ -0,0 +1,89 @@
+"use strict";
+
+define([
+ 'URIjs'
+], function (
+ URI
+) {
+
+ var internals = {
+ createWfsUrl : function createWfsUrl(parsed) {
+ var tmpUri = new URI('').protocol('wfs').path(parsed.wfsId + '/' + parsed.wfsPath);
+ return tmpUri.toString();
+ },
+
+ parseLegacyUrl : function parseLegacyUrl(legacyUrl) {
+ var uri = new URI(legacyUrl);
+ var srcPathSegments = uri.normalize().path(true).split('/').slice(1); // drops heading '/' in path
+
+ var wfsId = srcPathSegments[0];
+ if (!wfsId) {
+ throw new Error('no fsid part in wfs url' + legacyUrl);
+ }
+
+ var wfsPath = srcPathSegments.slice(1).join('/');
+ if (!wfsPath || wfsPath === '/') {
+ throw new Error('no path part in wfs url ' + legacyUrl);
+ }
+
+ // we can drop host of uri, for ide does not access to 'outside' of workspace
+ return {
+ wfsId: wfsId,
+ wfsPath: wfsPath // wfsPath should not have heading '/'
+ };
+ }
+ };
+
+ function fromLegacyPath(legacyPath, wfsId) {
+ if (typeof(legacyPath) !== 'string' || legacyPath.constructor.name !== 'String' || !legacyPath) {
+ throw new Error('wfs url must a truthy string');
+ }
+ let ret = '';
+ if (legacyPath.indexOf('wfs://') !== 0 ) {
+ // looks very heavy but normalizing path is not a simple job. believe me.
+ var tmpUri = new URI('file:///' + legacyPath);
+ ret = tmpUri.normalize().path(true).slice(1); // should start with /, always
+ } else {
+ var parsed = internals.parseLegacyUrl(legacyPath);
+ if (parsed.wfsId !== wfsId) {
+ ret = internals.createWfsUrl(parsed);
+ } else {
+ ret = parsed.wfsPath;
+ }
+ }
+ if (ret.length > 0 && ret[length-1] === '/') {
+ ret = ret.slice(0,-1);
+ }
+ return ret;
+ }
+
+ function devideArrayWithFilter (array, propertyNameToFilter) {
+ var ret = {
+ truthy:[],
+ falsy:[]
+ };
+
+ array.forEach( function (item) {
+ var property;
+ if (!propertyNameToFilter) {
+ property = item;
+ } else {
+ property = item ? item[propertyNameToFilter] : undefined;
+ }
+ if (property) {
+ ret.truthy.push(item);
+ } else {
+ if (item) {
+ ret.falsy.push(item);
+ }
+ }
+ });
+
+ return ret;
+ }
+
+ return {
+ fromLegacyPath : fromLegacyPath,
+ devideArrayWithFilter : devideArrayWithFilter
+ };
+});
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
index 862be39c..0f240752 100644
--- a/common/src/webida/server-api-0.1.js
+++ b/common/src/webida/server-api-0.1.js
@@ -29,31 +29,22 @@ define([
'./server-api-0.1-lib/auth',
'./server-api-0.1-lib/fs'
], function (
- URI,
common,
- auth,
+ auth,
fs
) {
'use strict';
-
- // do we need some values from local storage, especially workspace-specific ones?
-
- // auth & fs uses swagger client
- // common will create the swagger client object in initialize() function
- // other modueles (auth, fs) will get the client from commmon module
-
- common.initSwaggerClient();
-
+ var serverUrl = common.bootArgs.serverUrl;
var mod = {
auth : auth,
fs : fs,
// for compatibility with plugisn who are dependent to webida-0.3.js conf object
conf : {
- fsServer : bootArgs.server,
- connServer: bootArgs.server,
- fsApiBaseUrl: fsServer + '/api/fs',
+ fsServer : serverUrl,
+ connServer: serverUrl,
+ fsApiBaseUrl: serverUrl + '/vfs'
},
// for compatibility with current plugin manager
@@ -63,25 +54,23 @@ define([
// - PM should not load .user_info/plugin-settings.json file directly while initializing
// and may use local storage instead of using server api
getPluginSettingsPath : function(callback) {
- // for desktop mode, check legacy or not
- if (window.__ELECTRON_BROWSER__) {
- if(bootArgs.legacy) {
- return 'plugins/plugin-settings-desktop.json'
- } else {
- return 'plugins/plugin-setting.json'
- }
+ // plugin-settings-desktop.json : to connect embedded server from desktop (0.1)
+ // : to connect server from desktop (0.2)
+ // plugin-settings.json : to connect legacy server from desktop/browser (0.1)
+ // : to connect server from browser (0.2)
+
+ // this is version 0.1. (simple but enough, for we don't access legacy server as guest)
+ if(common.bootArgs.legacy) {
+ return callback('plugins/plugin-setting.json')
} else {
- // keep same behavior to webida 0.3
- mod.auth.getMyInfo(function (err, myInfo) {
- if (err) {
- callback(defaultPath);
- } else {
- callback(myInfo.isGuest ? 'plugins/plugin-settings-guest.json' : defaultPath);
- }
- });
+ return callback('plugins/plugin-settings-desktop.json')
}
}
};
+
+ // for debugging purpose only in debugger js console
+ window.__webida = mod;
+ mod.common = common;
return mod;
});
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-0.1.js
index c4ba223a..00a5a27b 100644
--- a/common/src/webida/server-pubsub-0.1.js
+++ b/common/src/webida/server-pubsub-0.1.js
@@ -57,6 +57,8 @@ define([
var init = function (uid, token, host, callbackFunctions, cb) {
var user = new User('nick', 'email', uid, token);
+ logger('pubsub init - new user', user);
+
// dummy stuffs
systemNotificationCallback = callbackFunctions.topicsysnotify_callback;
window.setTimeout( function() {
From b4ed400657c98c025600fc58547b520296bb4eb5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 17 Jun 2016 14:43:39 +0900
Subject: [PATCH 05/15] fix jshit errors & misc
- fixed jshitrc to respect function hoisting
- fixed some errors from doublequote
- removed some logs in server-api
- fixed pubsub init error
---
.jshintrc | 2 +-
apps/ide/src/dojoConfig.js | 4 ++--
apps/ide/src/index.html | 2 +-
apps/ide/src/plugins/plugin-settings-desktop.json | 2 ++
common/src/webida/app.js | 12 ++++++++++++
common/src/webida/server-api-0.1-lib/auth.js | 2 --
common/src/webida/server-pubsub-0.1.js | 3 +--
7 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/.jshintrc b/.jshintrc
index d3637e3f..d5e54aeb 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -28,7 +28,7 @@
"eqeqeq": true,
"forin": true,
"immed": true,
- "latedef": true,
+ "latedef": "nofunc",
"newcap": true,
"noarg": true,
"noempty": true,
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index 2fbc9f31..2146901f 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -27,6 +27,7 @@
globalObject.nmodule = globalObject.module;
delete globalObject.require;
delete globalObject.module;
+ globalObject.__ELECTRON_BROWSER__ = true;
}
var webidaLocale = decodeURIComponent(
@@ -96,7 +97,6 @@
globalObject.dojoConfig.aliases.push(['top/site-config.json' , 'top/site-config-desktop.json']);
console.log('under electrion re-wrote some requirejs aliases');
}
- globalObject.__ELECTRON_BROWSER__ = true;
- console.log("ready for electron");
+ console.log('dojoConfig is now ready for electron');
}
})(window);
diff --git a/apps/ide/src/index.html b/apps/ide/src/index.html
index 4c647793..ea863726 100644
--- a/apps/ide/src/index.html
+++ b/apps/ide/src/index.html
@@ -73,7 +73,7 @@
var newStatus = browserWindow.getBounds();
newStatus.maximized = browserWindow.isMaximized();
newStatus = JSON.stringify(newStatus);
- console.log("saving browser window status for closing " + newStatus);
+ console.log('saving browser window status for closing ' + newStatus);
window.localStorage.setItem(browserWindowStatusStorageKey, newStatus);
});
}
diff --git a/apps/ide/src/plugins/plugin-settings-desktop.json b/apps/ide/src/plugins/plugin-settings-desktop.json
index e6208684..4e87a1b5 100644
--- a/apps/ide/src/plugins/plugin-settings-desktop.json
+++ b/apps/ide/src/plugins/plugin-settings-desktop.json
@@ -27,6 +27,7 @@
"plugins/webida.ide.notification.view",
"plugins/webida.ide.notification.toast",
"plugins/webida.plugin-setting",
+ "webida-lib/plugins/command-system",
"webida-lib/plugins/editors",
"webida-lib/plugins/fs-commands",
"webida-lib/plugins/git",
@@ -37,6 +38,7 @@
"webida-lib/plugins/resources"
],
"start-plugins" : [
+ "webida-lib/plugins/command-system",
"webida-lib/plugins/workbench",
"plugins/webida.ide.notification.toast"
]
diff --git a/common/src/webida/app.js b/common/src/webida/app.js
index e989c3dc..44ccbde8 100644
--- a/common/src/webida/app.js
+++ b/common/src/webida/app.js
@@ -363,6 +363,7 @@ define([
}
function connectToConnServer() {
+
webida.auth.getMyInfo(function (e, data) {
if (e) {
logger.error('getMyInfo error: ' + e);
@@ -374,6 +375,17 @@ define([
logger.log('connected to conn server');
// sys.fs.change notification subscribe
+
+ // note from webida-desktop
+ // new server-api-*.js has no acl service and does not require
+ // explicit subscription for default server events fs.change
+ // And, since
+
+ if (typeof webida.acl !== 'object') {
+ logger.log('no need to subscribe and topic relay with new api ');
+ return;
+ }
+
webida.acl.getAuthorizedRsc('fs:readFile', function (err, topics) {
if (err) {
logger.error('getAuthorizedRsc: ', err);
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
index 2c36c8f1..c44ff02f 100644
--- a/common/src/webida/server-api-0.1-lib/auth.js
+++ b/common/src/webida/server-api-0.1-lib/auth.js
@@ -31,7 +31,6 @@ define([
authApi.login(loginRequest, function (error, data, response) {
if (!error) {
- logger.debug('login response', data, response);
common.setLoginResponse(data);
// Oddly, there's no error-fist-callback for initAuth
callback(data.sessionId);
@@ -46,7 +45,6 @@ define([
authApi.getInfo(function (error, data, response) {
if (!error) {
- logger.debug('info response', data, response);
// TODO : add common.userInfo and check it before sending request
// don't forget to invoke callback with setTimeout(0)
callback(null, data);
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-0.1.js
index 00a5a27b..9eb87214 100644
--- a/common/src/webida/server-pubsub-0.1.js
+++ b/common/src/webida/server-pubsub-0.1.js
@@ -52,12 +52,11 @@ define([
this.uid = uid;
this.token = token;
};
-
var systemNotificationCallback;
var init = function (uid, token, host, callbackFunctions, cb) {
var user = new User('nick', 'email', uid, token);
- logger('pubsub init - new user', user);
+ logger.log('pubsub init - new user', user);
// dummy stuffs
systemNotificationCallback = callbackFunctions.topicsysnotify_callback;
From 0f9ba6ab2185db93f0132cdc39910da39119c3b8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 17 Jun 2016 15:24:11 +0900
Subject: [PATCH 06/15] fix more jshint errors
- reordered some variable positions
---
.../project-wizard/build/signing-new.js | 76 +-
apps/ide/src/plugins/project-wizard/main.js | 25 +-
.../plugins/project-wizard/test-commands.js | 15 +-
common/src/webida/FSCache-0.1.js | 1126 +++++++++--------
common/src/webida/msg.js | 39 +-
.../plugins/workbench/views-controller.js | 77 +-
6 files changed, 683 insertions(+), 675 deletions(-)
diff --git a/apps/ide/src/plugins/project-wizard/build/signing-new.js b/apps/ide/src/plugins/project-wizard/build/signing-new.js
index af6abe1c..0077142f 100644
--- a/apps/ide/src/plugins/project-wizard/build/signing-new.js
+++ b/apps/ide/src/plugins/project-wizard/build/signing-new.js
@@ -1,12 +1,12 @@
/*
* Copyright (c) 2012-2015 S-Core Co., Ltd.
- *
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -93,6 +93,42 @@ define([
var self = this;
var data = null;
+ var dlg = new ButtonedDialog({
+ buttons: [
+ { id: 'signingCreate',
+ caption: 'OK',
+ methodOnClick: 'checkAndCreate'
+ },
+ { id: 'signingCancel',
+ caption: 'Cancel',
+ methodOnClick: 'hide'
+ }
+ ],
+ methodOnEnter: 'checkAndCreate',
+ title: Messages.GEN_SIGNED_WIZARD_NEW_KEY_STORE,
+ refocus: false,
+
+ onHide: function () {
+ dlg.destroyRecursive();
+ return deferred.resolve(data);
+ },
+
+ onLoad: function () {
+ },
+
+ checkAndCreate: function () {
+ _super.setMessage('');
+ var newName = reg.byId('alias').get('value');
+ try {
+ if (self.validate()) {
+ doCreation(newName);
+ }
+ } catch (err) {
+ _super.setError(err);
+ }
+ }
+ });
+
function doCreation(newName) {
var alias = newName;
var keyPassword = reg.byId('keyPassword').get('value');
@@ -126,41 +162,7 @@ define([
}
var deferred = new Deferred();
- var dlg = new ButtonedDialog({
- buttons: [
- { id: 'signingCreate',
- caption: 'OK',
- methodOnClick: 'checkAndCreate'
- },
- { id: 'signingCancel',
- caption: 'Cancel',
- methodOnClick: 'hide'
- }
- ],
- methodOnEnter: 'checkAndCreate',
- title: Messages.GEN_SIGNED_WIZARD_NEW_KEY_STORE,
- refocus: false,
-
- onHide: function () {
- dlg.destroyRecursive();
- return deferred.resolve(data);
- },
-
- onLoad: function () {
- },
- checkAndCreate: function () {
- _super.setMessage('');
- var newName = reg.byId('alias').get('value');
- try {
- if (self.validate()) {
- doCreation(newName);
- }
- } catch (err) {
- _super.setError(err);
- }
- }
- });
_super.setId(dlg.id);
dlg.set('doLayout', false);
dlg.setContentArea(tplLayout);
diff --git a/apps/ide/src/plugins/project-wizard/main.js b/apps/ide/src/plugins/project-wizard/main.js
index 2b75f11c..e5dd4c69 100644
--- a/apps/ide/src/plugins/project-wizard/main.js
+++ b/apps/ide/src/plugins/project-wizard/main.js
@@ -72,7 +72,7 @@ define([
var logger = new Logger();
logger.off();
-
+
var PW_MSG = {
ERROR : 'Error',
FAIL : 'Fail',
@@ -643,6 +643,18 @@ define([
}
function onCreateProject(event, prjName, selectedTemplate, options) {
+
+ var item = selectedTemplate ? selectedTemplate : getSelectedTemplate();
+ logger.log('onCreateProject', options);
+ var projectName = prjName;
+ var destSelect = targetPath;
+
+ var srcFSPath = '/' + (item && item.template && item.template.path ? item.template.path : '');
+ var srcFSPrjPath = srcFSPath + '/project';
+ //logger.log('destFSPath', destSelect, projectName);
+ var destFSPath = Util.concatWFSPath([destSelect, projectName]);
+ var destFSCopyPath = Util.concatWFSPath(['wfs://', destFS, destSelect, projectName]);
+
function createProject() {
function createDefaultProjectConf() {
var name = projectName ? projectName : item.name;
@@ -791,17 +803,6 @@ define([
});
}
- var item = selectedTemplate ? selectedTemplate : getSelectedTemplate();
- logger.log('onCreateProject', options);
- var projectName = prjName;
- var destSelect = targetPath;
-
- var srcFSPath = '/' + (item && item.template && item.template.path ? item.template.path : '');
- var srcFSPrjPath = srcFSPath + '/project';
- //logger.log('destFSPath', destSelect, projectName);
- var destFSPath = Util.concatWFSPath([destSelect, projectName]);
- var destFSCopyPath = Util.concatWFSPath(['wfs://', destFS, destSelect, projectName]);
-
if (!isValidInfo()) {
return;
} else {
diff --git a/apps/ide/src/plugins/project-wizard/test-commands.js b/apps/ide/src/plugins/project-wizard/test-commands.js
index 9c779d8b..b43ca074 100644
--- a/apps/ide/src/plugins/project-wizard/test-commands.js
+++ b/apps/ide/src/plugins/project-wizard/test-commands.js
@@ -69,7 +69,6 @@ define([
var FRAMES = JSON.parse(frames).frames;
function TestViewCommand() {
- _self = this;
this.$resolutions = null;
this.url = null;
}
@@ -78,7 +77,6 @@ define([
var _super = TestViewCommand.prototype = new ViewCommand(VIEW_ID);
// correct the constructor pointer because it points to ViewCommand
TestViewCommand.prototype.constructor = TestViewCommand;
- var _self = null;
TestViewCommand.prototype.doTest = function () {
var curDir = wv.getSelectedPath();
@@ -90,23 +88,24 @@ define([
}; // doTest
TestViewCommand.prototype.onViewAppended = function () {
+ var self = this;
_super.initView(tplToolbar, function (selectedProjectPath) {
- if (_self.getProjectPath() === selectedProjectPath) {
+ if (self.getProjectPath() === selectedProjectPath) {
return;
}
- _self.refreshView();
+ self.refreshView();
// FIXME use directly `reg.byId('testTab').selectChild()` method
Util.selectTab('testTab', 'testPreview');
});
- _self.$resolutions = $('#testResolutions');
- _self.$resolutions.multiselect({
+ self.$resolutions = $('#testResolutions');
+ self.$resolutions.multiselect({
includeSelectAllOption: false,
enableCaseInsensitiveFiltering: false
});
- _self.init(); // Event listeners should be attached once
- _self.refreshView();
+ self.init(); // Event listeners should be attached once
+ self.refreshView();
_super.getView().select();
};
diff --git a/common/src/webida/FSCache-0.1.js b/common/src/webida/FSCache-0.1.js
index a59be24a..9d3767e8 100644
--- a/common/src/webida/FSCache-0.1.js
+++ b/common/src/webida/FSCache-0.1.js
@@ -56,6 +56,8 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
// class FSCacheInner
//*******************************
+ var fsCache;
+
//--------------------------
// private fields of FSCacheInner
//--------------------------
@@ -1263,588 +1265,255 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
});
- //---------------------------
- //---------------------------
- // private methods of FSCacheInner
- //---------------------------
- //---------------------------
+ //*******************************
+ // inner class of FSCacheInner: FSNode
+ //*******************************
- //---------------------------
- // utility functions
- //---------------------------
+ var FSNode = declare(null, {
- function parseWFSURL(fsURL) {
- var uri = new URI(fsURL);
- var ret = {
- fsServer: uri.host(),
- fsid: uri.segment(0)
- };
- uri.segment(0, ''); // drop the fsid
- ret.path = uri.path(true);
+ constructor : function (parent, name) {
+ this.parent = parent; // null iff this is the root node
+ this.name = name;
+ this.metadata = {};
+ this.metadataInvalidated = {};
+ },
- return ret;
- }
- function subscribeToNotificationsOnFS(fsCache) {
- function isIgnoredNotification(data, checkedURLs) {
- // ignore changed caused by myself
- var mySessionID = webida.auth.getSessionID();
- if (!data.sid) {
- console.error('The session id of a notification is unknown');
- return true;
- }
+ setMetadata: function (key, value, caseStr) {
+ var origValue = this.metadata[key];
+ this.metadata[key] = value;
+ this.metadataInvalidated[key] = false;
- if (mySessionID === data.sid) {
- console.log('notification ignored: changes by the current app');
- return true;
+ var path = this.getPath();
+ switch (caseStr) {
+ case 'fetched':
+ onMetadataFetched(path, key);
+ break;
+ case 'written':
+ onMetadataSet(path, key, value !== origValue);
+ break;
+ case 'refreshed':
+ onMetadataRefreshed(path, key);
+ break;
+ default:
+ console.assert(false, 'Unreachable');
}
+ },
- if (checkedURLs.every(function (url) { return !withinCache(data[url]); })) {
- console.log('notification ignored: changes outside cache');
- return true;
- }
+ refreshMetadata: function (key) {
+ var self = this;
+ Object.keys(this.metadata).forEach(function (k) {
+ if (key === undefined || key === k) {
+ var origVal = self.metadata[k];
+ var path = self.getPath();
+ mount.getMeta(path, k, function (err, newVal) {
+ if (err) {
+ console.error('Cannot get metadata ' + k + ' of ' + path +
+ ' from server: ' + err);
+ } else {
+ if (origVal !== newVal) {
+ this.setMetadata(k, newVal, 'refreshed');
+ }
+ }
+ });
+ }
+ });
+ },
- return false;
- }
+ getParentPath : function () {
+ return this.parent ? this.parent.getPath() : EMPTY_PATH;
+ },
- topic.subscribe('sys.fs.file.written', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
+ getPath : function () {
+ if (!this._path) {
+ // memoize
+ this._path = this.computePath();
}
+ return this._path;
+ },
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- // file created
- if (existing === null) {
- root.putByAbsPath(urlParsed.path, 'file-written');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.written] for "' +
- urlParsed.path + '" (as a file creation)');
- topic.publish('#REQUEST.log', '');
- }
- } else if (existing.getType() === TYPE_FILE) {
- // file written
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.written] for "' +
- urlParsed.path + '" (as a file cache invalidation)');
- topic.publish('#REQUEST.log', '');
- } else {
- console.error('sys.fs.file.written arrived for a non-file "' +
- urlParsed.path + '"');
- }
+ computePath : function () {
+ return this.getParentPath() + this.name;
+ },
- });
- topic.subscribe('sys.fs.file.deleted', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
+ getType : function () {
+ return TYPE_UNKNOWN;
+ },
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.file.deleted arrived for an absent file "' +
- urlParsed.path + '"');
+ detach : function (movedTo) {
+ if (this.parent) {
+ var detached = this.parent.removeSubnode(this.name, movedTo);
+ if (this !== detached) {
+ throw new Error('Detached node is wrong.');
}
- } else if (existing.getType() === TYPE_FILE) {
- existing.detach();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.deleted] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
} else {
- console.error('sys.fs.file.deleted arrived for a non-file "' +
- urlParsed.path + '"');
+ throw new Error('Cannot detach the root node');
}
+ },
- });
- topic.subscribe('sys.fs.dir.created', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
+ satisfyingCond : function (cond) {
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- root.putByAbsPath(pathUtil.attachSlash(urlParsed.path), 'dir-created');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.dir.created] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
+ if (cond.types) {
+ if (cond.types.indexOf(this.getType()) < 0) {
+ return false;
}
- } else if (existing.getType() === TYPE_DIRECTORY) {
- console.error('sys.fs.dir.created arrived for an existing directory "' +
- urlParsed.path + '"');
- } else {
- console.error('sys.fs.dir.created arrived for a non-directory "' +
- urlParsed.path + '"');
- }
- });
- topic.subscribe('sys.fs.dir.deleted', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
}
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.dir.deleted arrived for an absent directory "' +
- urlParsed.path + '"');
- }
- } else if (existing.getType() === TYPE_DIRECTORY) {
- existing.detach();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.dir.deleted] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- } else {
- console.error('sys.fs.dir.deleted arrived for a non-directory "' +
- urlParsed.path + '"');
+ return true;
+ },
+
+ collectNodes : function (arr, cond) {
+ if (this.satisfyingCond(cond)) {
+ arr.push(this);
}
- });
- topic.subscribe('sys.fs.node.intractableChanges', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
+ },
+
+ getListInfo : function () {
+ return {
+ name : this.name,
+ isDirectory : this instanceof Directory,
+ isFile : this instanceof File
+ };
+ },
+
+ show : function (level) { // for debugging
+ var arr = [];
+ for (var i = 0; i < level; i++) {
+ arr.push('| ');
}
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.dir.intractableChanges arrived for an absent directory "' +
- urlParsed.path + '"');
- }
- } else if (existing.getType() === TYPE_DIRECTORY) {
- fsCache.refresh(urlParsed.path, { level: -1 }, function () {
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.intractableChanges] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
+ arr.push(this.name);
+ console.log(arr.join(''));
+ },
- onNodeChanges(urlParsed.path);
+ invalidateFileContents: function () {
+ console.error('assertion fail: unreachable');
+ },
+
+ invalidateMetadata: function (key) {
+ var keys = Object.keys(this.metadataInvalidated);
+ var path = this.getPath();
+ if (key === undefined) {
+ keys.forEach(function (k) {
+ if (this.metadata[k] !== undefined &&
+ !this.metadataInvalidated[k]) {
+ this.metadataInvalidated[k] = true;
+ onMetadataInvalidated(path, k);
+ }
});
+ } else if (keys.indexOf(key) >= 0) {
+ if (this.metadata[key] !== undefined &&
+ !this.metadataInvalidated[key]) {
+ this.metadataInvalidated[key] = true;
+ onMetadataInvalidated(path, key);
+ }
} else {
- console.error('sys.fs.dir.intractable-changes arrived for a non-directory "' +
- urlParsed.path + '"');
+ throw new Error('Metadata ' + key + ' is not set for "' +
+ this.getPath() + '"');
}
+ }
- });
- topic.subscribe('sys.fs.node.moved', function (data) {
- if (isIgnoredNotification(data, ['srcURL', 'dstURL'])) {
- return;
- }
+ });
- var dstURLParsed;
- if (withinCache(data.dstURL)) {
- dstURLParsed = parseWFSURL(data.dstURL);
- mount.isDirectory(dstURLParsed.path, function (err, isDir) {
- if (err) {
- console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
- '" of a notification sys.fs.node.moved is a directory or not: ' + err);
- console.log('The notification is ignored.');
- } else {
- var existing = root.getByAbsPath(dstURLParsed.path);
- if (existing) {
- if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
- if (isDir) {
- console.error('sys.fs.node.moved arraived for an existing "' +
- dstURLParsed.path + '" as its destination');
- } else {
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] ' +
- 'for its overwritten target file "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- } else {
- console.error('The type of the destination of a notification sys.fs.node.moved ' +
- 'does not match that of the corresponding node in the fs-cache for "' +
- dstURLParsed.path + '"');
- }
- } else {
- if (existing === null) {
- root.putByAbsPath((isDir ?
- pathUtil.attachSlash :
- pathUtil.detachSlash)(dstURLParsed.path),
- 'moved');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] for its target "' +
- dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- }
- }
- });
- }
+ //*******************************
+ // inner class of FSCacheInner: File
+ //*******************************
- if (withinCache(data.srcURL)) {
- var srcURLParsed = parseWFSURL(data.srcURL);
- var existing = root.getByAbsPath(srcURLParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.node.moved arrived for an absent "' +
- srcURLParsed.path + '" as its source');
- }
- } else {
- existing.detach(withinCache(data.dstURL) ? dstURLParsed.path : undefined);
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] for its source "' +
- srcURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- }
+ var File = declare(FSNode, {
+ constructor : function (/*parent, name*/) {
+ this.contentInvalidated = false;
+ },
- // TODO: need to publish fs.cache.node.moved?
- // But the topic does not support the case when the source is out of the current file system.
- });
- topic.subscribe('sys.fs.node.copied', function (data) {
- if (isIgnoredNotification(data, ['dstURL'])) {
- return;
+ invalidateFileContents: function () {
+ if (this.content !== undefined && !this.contentInvalidated) {
+ this.contentInvalidated = true;
+ onFileInvalidated(this.getPath());
}
+ },
- var existing;
- var dstURLParsed = parseWFSURL(data.dstURL);
- if (withinCache(dstURLParsed.path)) {
- mount.isDirectory(dstURLParsed.path, function (err, isDir) {
+ refreshFileContents : function () {
+
+ // NOTE: refreshing contents is possible for invalidated contents too
+
+ var origContent = this.content;
+ if (origContent !== undefined) {
+ var path = this.getPath();
+ var self = this;
+ mount.readFile(path, function (err, newContent) {
if (err) {
- console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
- '" of a notification sys.fs.node.copied is a directory or not: ' + err);
- console.log('The notification is ignored.');
+ console.log('Cannot get content of ' + path +
+ ' from server. cannot refresh the file content (' +
+ err + ')');
} else {
- existing = root.getByAbsPath(dstURLParsed.path);
- if (existing) {
- if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
- if (isDir) {
- fsCache.refresh(dstURLParsed.path, { level: -1 });
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its merged target directory "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- } else {
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its overwritten target file "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- } else {
- console.error('The type of the destination of a notification sys.fs.node.copied ' +
- 'does not match that of the corresponding node in the fs-cache for "' +
- dstURLParsed.path + '"');
- }
- } else {
- if (existing === null) {
- root.putByAbsPath((isDir ?
- pathUtil.attachSlash :
- pathUtil.detachSlash)(dstURLParsed.path),
- 'copied');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its target "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
+ if (origContent !== newContent) {
+ self.setContent(newContent, 'refreshed');
}
}
});
}
+ },
- // TODO: need to publish fs.cache.node.copied?
- // But the topic does not support the case when the source is out of the current file system.
- });
- }
+ setContent : function (content, caseStr) {
+ var origContent = this.content;
+ this.content = content;
+ this.contentInvalidated = false;
- function withinCache(path) {
- if (path.indexOf('wfs://') === 0) {
- // path is given in Webida File System URL
- var pathParsed = parseWFSURL(path);
- if (fsURLParsed.fsServer !== pathParsed.fsServer ||
- fsURLParsed.fsid !== pathParsed.fsid) {
- return false;
+ var path = this.getPath();
+ switch (caseStr) {
+ case 'fetched':
+ onFileFetched(path);
+ break;
+ case 'written':
+ onFileWritten(path, content === undefined || content !== origContent);
+ break;
+ case 'refreshed':
+ onFileRefreshed(path);
+ break;
+ default:
+ console.assert(false, 'Unreachable');
}
- path = pathParsed.path;
- }
- return dirsToCache.some(function (cached) { return path.indexOf(cached) === 0; });
- }
- function getName(obj) { return obj.name; }
- function isDir(stat) { return stat.isDirectory; }
- function isFile(stat) { return stat.isFile; }
- function checkTargetPath(path, exists, allowsDirPath) {
- if (!isValidAbsPath(path)) {
- return 'The path "' + path + '" is not a valid absolute path';
- }
+ },
- var node = root.getByAbsPath(path);
- if (typeof exists === 'boolean') {
- if ((exists && node === null) || (!exists && node)) {
- return 'The path "' + path + '" must be ' + (exists ? 'present' : 'absent');
- }
- }
+ getType : function () {
+ return TYPE_FILE;
+ },
- if (!allowsDirPath && pathUtil.isDirPath(path)) {
- return 'The path "' + path + '" ends with a slash, which is disallowed';
+ getSummary : function () {
+ return this.name;
}
-
- return node;
- }
-
- //---------------------------
- //---------------------------
- // end of private methods of FSCacheInner
- //---------------------------
- //---------------------------
+ });
//*******************************
- // inner class of FSCacheInner: FSNode
+ // inner class of FSCacheInner: Directory
//*******************************
- var FSNode = declare(null, {
-
- constructor : function (parent, name) {
- this.parent = parent; // null iff this is the root node
- this.name = name;
- this.metadata = {};
- this.metadataInvalidated = {};
- },
-
- setMetadata: function (key, value, caseStr) {
- var origValue = this.metadata[key];
- this.metadata[key] = value;
- this.metadataInvalidated[key] = false;
-
- var path = this.getPath();
- switch (caseStr) {
- case 'fetched':
- onMetadataFetched(path, key);
- break;
- case 'written':
- onMetadataSet(path, key, value !== origValue);
- break;
- case 'refreshed':
- onMetadataRefreshed(path, key);
- break;
- default:
- console.assert(false, 'Unreachable');
- }
+ var Directory = declare(FSNode, {
+ constructor : function (/*parent, name*/) {
+ this.dirs = new SortedArray('name');
+ this.files = new SortedArray('name');
},
- refreshMetadata: function (key) {
- var self = this;
- Object.keys(this.metadata).forEach(function (k) {
- if (key === undefined || key === k) {
- var origVal = self.metadata[k];
- var path = self.getPath();
- mount.getMeta(path, k, function (err, newVal) {
- if (err) {
- console.error('Cannot get metadata ' + k + ' of ' + path +
- ' from server: ' + err);
- } else {
- if (origVal !== newVal) {
- this.setMetadata(k, newVal, 'refreshed');
- }
- }
- });
- }
+ invalidateFileContents: function () {
+ this.dirs.forEach(function (dir) {
+ dir.invalidateFileContents();
+ });
+ this.files.forEach(function (file) {
+ file.invalidateFileContents();
});
},
- getParentPath : function () {
- return this.parent ? this.parent.getPath() : EMPTY_PATH;
+ invalidateMetadata: function (key) {
+ FSNode.prototype.invalidateMetadata.call(this, key);
+ this.dirs.forEach(function (dir) {
+ dir.invalidateMetadata(key);
+ });
+ this.files.forEach(function (file) {
+ file.invalidateMetadata(key);
+ });
},
- getPath : function () {
- if (!this._path) {
- // memoize
- this._path = this.computePath();
- }
- return this._path;
- },
-
- computePath : function () {
- return this.getParentPath() + this.name;
- },
-
- getType : function () {
- return TYPE_UNKNOWN;
- },
-
- detach : function (movedTo) {
- if (this.parent) {
- var detached = this.parent.removeSubnode(this.name, movedTo);
- if (this !== detached) {
- throw new Error('Detached node is wrong.');
- }
- } else {
- throw new Error('Cannot detach the root node');
- }
- },
-
- satisfyingCond : function (cond) {
-
- if (cond.types) {
- if (cond.types.indexOf(this.getType()) < 0) {
- return false;
- }
- }
-
- return true;
- },
-
- collectNodes : function (arr, cond) {
- if (this.satisfyingCond(cond)) {
- arr.push(this);
- }
- },
-
- getListInfo : function () {
- return {
- name : this.name,
- isDirectory : this instanceof Directory,
- isFile : this instanceof File
- };
- },
-
- show : function (level) { // for debugging
- var arr = [];
- for (var i = 0; i < level; i++) {
- arr.push('| ');
- }
-
- arr.push(this.name);
- console.log(arr.join(''));
- },
-
- invalidateFileContents: function () {
- console.error('assertion fail: unreachable');
- },
-
- invalidateMetadata: function (key) {
- var keys = Object.keys(this.metadataInvalidated);
- var path = this.getPath();
- if (key === undefined) {
- keys.forEach(function (k) {
- if (this.metadata[k] !== undefined &&
- !this.metadataInvalidated[k]) {
- this.metadataInvalidated[k] = true;
- onMetadataInvalidated(path, k);
- }
- });
- } else if (keys.indexOf(key) >= 0) {
- if (this.metadata[key] !== undefined &&
- !this.metadataInvalidated[key]) {
- this.metadataInvalidated[key] = true;
- onMetadataInvalidated(path, key);
- }
- } else {
- throw new Error('Metadata ' + key + ' is not set for "' +
- this.getPath() + '"');
- }
- }
-
- });
-
- //*******************************
- // inner class of FSCacheInner: File
- //*******************************
-
- var File = declare(FSNode, {
- constructor : function (/*parent, name*/) {
- this.contentInvalidated = false;
- },
-
- invalidateFileContents: function () {
- if (this.content !== undefined && !this.contentInvalidated) {
- this.contentInvalidated = true;
- onFileInvalidated(this.getPath());
- }
- },
-
- refreshFileContents : function () {
-
- // NOTE: refreshing contents is possible for invalidated contents too
-
- var origContent = this.content;
- if (origContent !== undefined) {
- var path = this.getPath();
- var self = this;
- mount.readFile(path, function (err, newContent) {
- if (err) {
- console.log('Cannot get content of ' + path +
- ' from server. cannot refresh the file content (' +
- err + ')');
- } else {
- if (origContent !== newContent) {
- self.setContent(newContent, 'refreshed');
- }
- }
- });
- }
- },
-
- setContent : function (content, caseStr) {
- var origContent = this.content;
- this.content = content;
- this.contentInvalidated = false;
-
- var path = this.getPath();
- switch (caseStr) {
- case 'fetched':
- onFileFetched(path);
- break;
- case 'written':
- onFileWritten(path, content === undefined || content !== origContent);
- break;
- case 'refreshed':
- onFileRefreshed(path);
- break;
- default:
- console.assert(false, 'Unreachable');
- }
- },
-
- getType : function () {
- return TYPE_FILE;
- },
-
- getSummary : function () {
- return this.name;
- }
- });
-
- //*******************************
- // inner class of FSCacheInner: Directory
- //*******************************
-
- var Directory = declare(FSNode, {
- constructor : function (/*parent, name*/) {
- this.dirs = new SortedArray('name');
- this.files = new SortedArray('name');
- },
-
- invalidateFileContents: function () {
- this.dirs.forEach(function (dir) {
- dir.invalidateFileContents();
- });
- this.files.forEach(function (file) {
- file.invalidateFileContents();
- });
- },
-
- invalidateMetadata: function (key) {
- FSNode.prototype.invalidateMetadata.call(this, key);
- this.dirs.forEach(function (dir) {
- dir.invalidateMetadata(key);
- });
- this.files.forEach(function (file) {
- file.invalidateMetadata(key);
- });
- },
-
- refreshFileContents : function (level) {
- if (typeof level !== 'number') { // TODO: remove this check when stabilized
- throw new Error('assertion fail: unrechable');
+ refreshFileContents : function (level) {
+ if (typeof level !== 'number') { // TODO: remove this check when stabilized
+ throw new Error('assertion fail: unrechable');
}
if (level) {
@@ -1879,7 +1548,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
putByRelPath : function (relPath, caseStr) {
console.assert(relPath,
- 'Directory.putByRelPath() was called with a falsy argument');
+ 'Directory.putByRelPath() was called with a falsy argument');
var i = relPath.indexOf('/');
if (i < 0) {
@@ -1921,9 +1590,9 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
} else {
if (subnode) {
console.warn('A subnode with the same name "' + name +
- '" but with different type was detected while putting a ' +
- (isDir ? 'directory' : 'file') + ' to "' +
- this.getPath() + '"');
+ '" but with different type was detected while putting a ' +
+ (isDir ? 'directory' : 'file') + ' to "' +
+ this.getPath() + '"');
return null;
} else {
var added = this.addSubnode(name, isDir, caseStr);
@@ -1935,9 +1604,9 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
addSubnode : function (name, isDir, caseStr) {
if (this.getSubnode(name)) { // TODO: remove this check if code is stabilized
console.error('Unreachable: Cannot overwrite existing subnode ' + name +
- ' of ' + this.getPath() + ' by addSubnode()');
+ ' of ' + this.getPath() + ' by addSubnode()');
throw new Error('Unreachable: Cannot overwrite existing subnode ' + name +
- ' of ' + this.getPath() + ' by addSubnode()');
+ ' of ' + this.getPath() + ' by addSubnode()');
} else {
var C = isDir ? Directory : File;
var subnode = new C(this, name);
@@ -1949,23 +1618,23 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
var maybeCreated;
switch (caseStr) {
- case 'cache-root':
- case 'inferred':
- case 'fetched':
- case 'restored':
- maybeCreated = false;
- break;
- case 'copied':
- case 'moved':
- case 'dir-created':
- case 'zip-created':
- case 'zip-extracted':
- case 'file-written':
- case 'refreshed':
- maybeCreated = true;
- break;
- default:
- console.assert(false, 'Unreachable');
+ case 'cache-root':
+ case 'inferred':
+ case 'fetched':
+ case 'restored':
+ maybeCreated = false;
+ break;
+ case 'copied':
+ case 'moved':
+ case 'dir-created':
+ case 'zip-created':
+ case 'zip-extracted':
+ case 'file-written':
+ case 'refreshed':
+ maybeCreated = true;
+ break;
+ default:
+ console.assert(false, 'Unreachable');
}
onNodeAdded(this.getPath(), name, subnode.getType(), maybeCreated, caseStr === 'moved');
@@ -1977,16 +1646,16 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
getByRelPath: function (relPath) {
//console.log('hina temp: relPath = ' + relPath);
console.assert(relPath,
- 'Directory.getByRelPath() was called ' +
- 'with falsy argument');
+ 'Directory.getByRelPath() was called ' +
+ 'with falsy argument');
var i = relPath.indexOf('/');
if (i < 0) {
return this.getSubnode(relPath);
} else {
console.assert(i > 0,
- 'Directory.getByRelPath() was called ' +
- 'with an absolute path: ' + relPath);
+ 'Directory.getByRelPath() was called ' +
+ 'with an absolute path: ' + relPath);
var nextPath;
var subnodeName = relPath.substring(0, i);
var subnode = this.getSubnode(subnodeName);
@@ -2083,7 +1752,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
if (err) {
console.warn('Error: FileSystem.list failed while refreshing "' +
- dirPath + '" (' + err + ')');
+ dirPath + '" (' + err + ')');
doWhenAllDone();
} else {
var newDirs = stats.filter(isDir);
@@ -2142,9 +1811,9 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
return arr;
} else {
console.error('Unreachable: list should not be called on ' +
- 'a node which has never fetched subnodes: ' + this.getPath());
+ 'a node which has never fetched subnodes: ' + this.getPath());
throw new Error('Unreachable: list should not be called on ' +
- 'a node which has never fetched subnodes: ' + this.getPath());
+ 'a node which has never fetched subnodes: ' + this.getPath());
}
},
@@ -2172,13 +1841,13 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
this.dirs.forEach(function (dir) {
var val = dir.getSummary();
console.assert(typeof val === 'object',
- 'Summary of a subdir must be an object');
+ 'Summary of a subdir must be an object');
subSummaries.push(val);
});
this.files.forEach(function (file) {
var val = file.getSummary();
console.assert(typeof val === 'string',
- 'Summary of a file must be a string');
+ 'Summary of a file must be a string');
subSummaries.push(val);
});
} else {
@@ -2196,7 +1865,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
restoreFromSummary : function (subSummaries) {
if (subSummaries) {
console.assert(subSummaries instanceof Array,
- 'SubSummaries must be an array');
+ 'SubSummaries must be an array');
var self = this;
subSummaries.forEach(function (summary) {
@@ -2208,7 +1877,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
self.addSubnode(summary, false, 'restored');
} else {
console.assert(false,
- 'Summary must be an object or string');
+ 'Summary must be an object or string');
}
});
this.fetchedSubnodes = true;
@@ -2216,6 +1885,341 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
});
+ //---------------------------
+ //---------------------------
+ // private methods of FSCacheInner
+ //---------------------------
+ //---------------------------
+
+ //---------------------------
+ // utility functions
+ //---------------------------
+
+ function parseWFSURL(fsURL) {
+ var uri = new URI(fsURL);
+ var ret = {
+ fsServer: uri.host(),
+ fsid: uri.segment(0)
+ };
+ uri.segment(0, ''); // drop the fsid
+ ret.path = uri.path(true);
+
+ return ret;
+ }
+ function subscribeToNotificationsOnFS(fsCache) {
+ function isIgnoredNotification(data, checkedURLs) {
+ // ignore changed caused by myself
+ var mySessionID = webida.auth.getSessionID();
+ if (!data.sid) {
+ console.error('The session id of a notification is unknown');
+ return true;
+ }
+
+ if (mySessionID === data.sid) {
+ console.log('notification ignored: changes by the current app');
+ return true;
+ }
+
+ if (checkedURLs.every(function (url) { return !withinCache(data[url]); })) {
+ console.log('notification ignored: changes outside cache');
+ return true;
+ }
+
+ return false;
+ }
+
+ topic.subscribe('sys.fs.file.written', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ // file created
+ if (existing === null) {
+ root.putByAbsPath(urlParsed.path, 'file-written');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.written] for "' +
+ urlParsed.path + '" (as a file creation)');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else if (existing.getType() === TYPE_FILE) {
+ // file written
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.written] for "' +
+ urlParsed.path + '" (as a file cache invalidation)');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.file.written arrived for a non-file "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.file.deleted', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.file.deleted arrived for an absent file "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_FILE) {
+ existing.detach();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.deleted] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.file.deleted arrived for a non-file "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.dir.created', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ root.putByAbsPath(pathUtil.attachSlash(urlParsed.path), 'dir-created');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.dir.created] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ console.error('sys.fs.dir.created arrived for an existing directory "' +
+ urlParsed.path + '"');
+ } else {
+ console.error('sys.fs.dir.created arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+ });
+ topic.subscribe('sys.fs.dir.deleted', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.dir.deleted arrived for an absent directory "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ existing.detach();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.dir.deleted] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.dir.deleted arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+ });
+ topic.subscribe('sys.fs.node.intractableChanges', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.dir.intractableChanges arrived for an absent directory "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ fsCache.refresh(urlParsed.path, { level: -1 }, function () {
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.intractableChanges] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+
+ onNodeChanges(urlParsed.path);
+ });
+ } else {
+ console.error('sys.fs.dir.intractable-changes arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.node.moved', function (data) {
+ if (isIgnoredNotification(data, ['srcURL', 'dstURL'])) {
+ return;
+ }
+
+ var dstURLParsed;
+ if (withinCache(data.dstURL)) {
+ dstURLParsed = parseWFSURL(data.dstURL);
+ mount.isDirectory(dstURLParsed.path, function (err, isDir) {
+ if (err) {
+ console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
+ '" of a notification sys.fs.node.moved is a directory or not: ' + err);
+ console.log('The notification is ignored.');
+ } else {
+ var existing = root.getByAbsPath(dstURLParsed.path);
+ if (existing) {
+ if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
+ if (isDir) {
+ console.error('sys.fs.node.moved arraived for an existing "' +
+ dstURLParsed.path + '" as its destination');
+ } else {
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] ' +
+ 'for its overwritten target file "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else {
+ console.error('The type of the destination of a notification sys.fs.node.moved ' +
+ 'does not match that of the corresponding node in the fs-cache for "' +
+ dstURLParsed.path + '"');
+ }
+ } else {
+ if (existing === null) {
+ root.putByAbsPath((isDir ?
+ pathUtil.attachSlash :
+ pathUtil.detachSlash)(dstURLParsed.path),
+ 'moved');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] for its target "' +
+ dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+ }
+ });
+ }
+
+ if (withinCache(data.srcURL)) {
+ var srcURLParsed = parseWFSURL(data.srcURL);
+ var existing = root.getByAbsPath(srcURLParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.node.moved arrived for an absent "' +
+ srcURLParsed.path + '" as its source');
+ }
+ } else {
+ existing.detach(withinCache(data.dstURL) ? dstURLParsed.path : undefined);
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] for its source "' +
+ srcURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+
+ // TODO: need to publish fs.cache.node.moved?
+ // But the topic does not support the case when the source is out of the current file system.
+ });
+ topic.subscribe('sys.fs.node.copied', function (data) {
+ if (isIgnoredNotification(data, ['dstURL'])) {
+ return;
+ }
+
+ var existing;
+ var dstURLParsed = parseWFSURL(data.dstURL);
+ if (withinCache(dstURLParsed.path)) {
+ mount.isDirectory(dstURLParsed.path, function (err, isDir) {
+ if (err) {
+ console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
+ '" of a notification sys.fs.node.copied is a directory or not: ' + err);
+ console.log('The notification is ignored.');
+ } else {
+ existing = root.getByAbsPath(dstURLParsed.path);
+ if (existing) {
+ if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
+ if (isDir) {
+ fsCache.refresh(dstURLParsed.path, { level: -1 });
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its merged target directory "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its overwritten target file "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else {
+ console.error('The type of the destination of a notification sys.fs.node.copied ' +
+ 'does not match that of the corresponding node in the fs-cache for "' +
+ dstURLParsed.path + '"');
+ }
+ } else {
+ if (existing === null) {
+ root.putByAbsPath((isDir ?
+ pathUtil.attachSlash :
+ pathUtil.detachSlash)(dstURLParsed.path),
+ 'copied');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its target "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+ }
+ });
+ }
+
+ // TODO: need to publish fs.cache.node.copied?
+ // But the topic does not support the case when the source is out of the current file system.
+ });
+ }
+
+ function withinCache(path) {
+ if (path.indexOf('wfs://') === 0) {
+ // path is given in Webida File System URL
+ var pathParsed = parseWFSURL(path);
+ if (fsURLParsed.fsServer !== pathParsed.fsServer ||
+ fsURLParsed.fsid !== pathParsed.fsid) {
+ return false;
+ }
+ path = pathParsed.path;
+ }
+ return dirsToCache.some(function (cached) { return path.indexOf(cached) === 0; });
+ }
+ function getName(obj) { return obj.name; }
+ function isDir(stat) { return stat.isDirectory; }
+ function isFile(stat) { return stat.isFile; }
+ function checkTargetPath(path, exists, allowsDirPath) {
+ if (!isValidAbsPath(path)) {
+ return 'The path "' + path + '" is not a valid absolute path';
+ }
+
+ var node = root.getByAbsPath(path);
+ if (typeof exists === 'boolean') {
+ if ((exists && node === null) || (!exists && node)) {
+ return 'The path "' + path + '" must be ' + (exists ? 'present' : 'absent');
+ }
+ }
+
+ if (!allowsDirPath && pathUtil.isDirPath(path)) {
+ return 'The path "' + path + '" ends with a slash, which is disallowed';
+ }
+
+ return node;
+ }
+
+ //---------------------------
+ //---------------------------
+ // end of private methods of FSCacheInner
+ //---------------------------
+ //---------------------------
+
+
+
//---------------------------
// event handlers
//---------------------------
@@ -2287,7 +2291,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
// finally, the object
- var fsCache = new FSCacheInner();
+ fsCache = new FSCacheInner();
return fsCache; // NOTE: 'this' is ignored for the constructor FSCache.
}
diff --git a/common/src/webida/msg.js b/common/src/webida/msg.js
index 78b3f089..56f2dbf3 100644
--- a/common/src/webida/msg.js
+++ b/common/src/webida/msg.js
@@ -139,6 +139,26 @@ define([
}
};
+ var connMap = new HashMap();
+
+ var TaskMgr = function () {
+ var taskMap = new HashMap();
+ this.pushTask = function (cb) {
+ var taskid = guid();
+ taskMap.put(taskid, cb);
+ return taskid;
+ };
+
+ this.popTask = function (id, err, msg) {
+ var func = taskMap.get(id);
+ if (func) {
+ func(err, msg);
+ }
+ taskMap.remove(id);
+ };
+ };
+
+ var taskMgr = new TaskMgr();
/**
* In order to receive messages, you need to define callback functons as follow
@@ -246,25 +266,6 @@ define([
})();
- var TaskMgr = function () {
- var taskMap = new HashMap();
- this.pushTask = function (cb) {
- var taskid = guid();
- taskMap.put(taskid, cb);
- return taskid;
- };
-
- this.popTask = function (id, err, msg) {
- var func = taskMap.get(id);
- if (func) {
- func(err, msg);
- }
- taskMap.remove(id);
- };
- };
-
- var taskMgr = new TaskMgr();
- var connMap = new HashMap();
/**
diff --git a/common/src/webida/plugins/workbench/views-controller.js b/common/src/webida/plugins/workbench/views-controller.js
index 45619d6b..2b3cc8fb 100644
--- a/common/src/webida/plugins/workbench/views-controller.js
+++ b/common/src/webida/plugins/workbench/views-controller.js
@@ -57,15 +57,9 @@ define([
) {
'use strict';
- topic.subscribe('view/unregistered', function (event) {
- viewsController.focusController.unregisterView(event.view);
- });
- topic.subscribe('view/maximize', function (event) {
- viewsController.toggleFullScreen(event.location);
- });
-
var GROUPNAME = 'COMMON-VIEW';
var statusbarText;
+
var viewsController = {
_leftSplitViewContainer : null,
_rightSplitViewContainer : null,
@@ -562,7 +556,7 @@ define([
aspect.before(leftSplitter, '_startDrag', function () {
topic.publish('layout/pane/resized');
- });
+ });
aspect.before(rightSplitter, '_handleOnChange', function () {
topic.publish('layout/pane/resized');
@@ -570,7 +564,7 @@ define([
aspect.before(rightSplitter, '_startDrag', function () {
topic.publish('layout/pane/resized');
- });
+ });
aspect.before(bottomSplitter, '_handleOnChange', function () {
topic.publish('layout/pane/resized');
@@ -578,7 +572,7 @@ define([
aspect.before(bottomSplitter, '_startDrag', function () {
topic.publish('layout/pane/resized');
- });
+ });
var vcList;
@@ -670,32 +664,32 @@ define([
});
}
});
-
- (function () {
- var menu = new DropDownMenu({ style: 'display: none;' });
+
+ (function () {
+ var menu = new DropDownMenu({ style: 'display: none;' });
var exts = pm.getExtensions('webida.common.workbench:perspective') || [];
var button;
var defaultPerspectiveName = 'Default';
var perspectiveNamePrefix = 'Perspective: ';
- var initialPerspectiveButtonLabel = perspectiveNamePrefix + defaultPerspectiveName;
-
+ var initialPerspectiveButtonLabel = perspectiveNamePrefix + defaultPerspectiveName;
+
function getPerspectiveNameById(perspectiveId) {
var name = defaultPerspectiveName;
if (perspectiveId) {
- exts.forEach(function (ext) {
+ exts.forEach(function (ext) {
if (ext.id === perspectiveId) {
name = ext.name;
}
- });
- }
- return name;
+ });
+ }
+ return name;
}
if (exts.length > 0) {
menu.addChild(new MenuItem({
label: defaultPerspectiveName,
onClick: function () {
- button.set('label', initialPerspectiveButtonLabel);
+ button.set('label', initialPerspectiveButtonLabel);
_self.currentPerspectiveID = null;
}
}));
@@ -722,7 +716,7 @@ define([
dom.byId('dropDownPerspectiveinfo').appendChild(button.domNode);
}
})();
- },
+ },
getActivatedPanel : function () {
var _self = this;
@@ -1073,15 +1067,15 @@ define([
if (panel) {
_self.expandPanel(location);
switch (location) {
- case 'bottom' :
- _self.lastPanelState.height = domStyle.get(panel.domNode, 'height');
- domStyle.set(panel.domNode, 'height', '100%');
- break;
- case 'left' :
- case 'right' :
- _self.lastPanelState.width = domStyle.get(panel.domNode, 'width');
- domStyle.set(panel.domNode, 'width', '100%');
- break;
+ case 'bottom' :
+ _self.lastPanelState.height = domStyle.get(panel.domNode, 'height');
+ domStyle.set(panel.domNode, 'height', '100%');
+ break;
+ case 'left' :
+ case 'right' :
+ _self.lastPanelState.width = domStyle.get(panel.domNode, 'width');
+ domStyle.set(panel.domNode, 'width', '100%');
+ break;
}
}
},
@@ -1091,13 +1085,13 @@ define([
var panel = _self._getPanel(location);
if (panel) {
switch (location) {
- case 'bottom' :
- domStyle.set(panel.domNode, 'height', _self.lastPanelState.height + 'px');
- break;
- case 'left' :
- case 'right' :
- domStyle.set(panel.domNode, 'width', _self.lastPanelState.width + 'px');
- break;
+ case 'bottom' :
+ domStyle.set(panel.domNode, 'height', _self.lastPanelState.height + 'px');
+ break;
+ case 'left' :
+ case 'right' :
+ domStyle.set(panel.domNode, 'width', _self.lastPanelState.width + 'px');
+ break;
}
}
},
@@ -1284,7 +1278,14 @@ define([
});
}
- };
+ }; // end of viewsController
+
+ topic.subscribe('view/unregistered', function (event) {
+ viewsController.focusController.unregisterView(event.view);
+ });
+ topic.subscribe('view/maximize', function (event) {
+ viewsController.toggleFullScreen(event.location);
+ });
return viewsController;
});
From 11031fe847618b23efaf2d7b42782890cd5f704d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 17 Jun 2016 15:46:46 +0900
Subject: [PATCH 07/15] yet another jshint fix
- aligned .jshintrc file with code convention checking script in jenkins server
- more fixes
---
.jshintrc | 2 +-
.../project-wizard/build/signing-new.js | 3 +-
common/src/webida/FSCache-0.1.js | 336 ++++++++++++++++++
common/src/webida/msg.js | 9 +-
4 files changed, 341 insertions(+), 9 deletions(-)
diff --git a/.jshintrc b/.jshintrc
index d5e54aeb..38b67a06 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -34,7 +34,7 @@
"noempty": true,
"nonew": true,
"plusplus": false,
- "undef": true,
+ "undef": "nofunc",
"unused": true,
"strict": true,
"trailing": false,
diff --git a/apps/ide/src/plugins/project-wizard/build/signing-new.js b/apps/ide/src/plugins/project-wizard/build/signing-new.js
index 0077142f..e1449686 100644
--- a/apps/ide/src/plugins/project-wizard/build/signing-new.js
+++ b/apps/ide/src/plugins/project-wizard/build/signing-new.js
@@ -92,6 +92,7 @@ define([
NewSigning.prototype.openDialog = function () {
var self = this;
var data = null;
+ var deferred = new Deferred();
var dlg = new ButtonedDialog({
buttons: [
@@ -161,8 +162,6 @@ define([
});
}
- var deferred = new Deferred();
-
_super.setId(dlg.id);
dlg.set('doLayout', false);
dlg.setContentArea(tplLayout);
diff --git a/common/src/webida/FSCache-0.1.js b/common/src/webida/FSCache-0.1.js
index 9d3767e8..d2202c78 100644
--- a/common/src/webida/FSCache-0.1.js
+++ b/common/src/webida/FSCache-0.1.js
@@ -1264,6 +1264,7 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
}
});
+ var fsCache;
//*******************************
// inner class of FSCacheInner: FSNode
@@ -1885,6 +1886,341 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
});
+
+ //---------------------------
+ //---------------------------
+ // private methods of FSCacheInner
+ //---------------------------
+ //---------------------------
+
+ //---------------------------
+ // utility functions
+ //---------------------------
+
+ function parseWFSURL(fsURL) {
+ var uri = new URI(fsURL);
+ var ret = {
+ fsServer: uri.host(),
+ fsid: uri.segment(0)
+ };
+ uri.segment(0, ''); // drop the fsid
+ ret.path = uri.path(true);
+
+ return ret;
+ }
+ function subscribeToNotificationsOnFS(fsCache) {
+ function isIgnoredNotification(data, checkedURLs) {
+ // ignore changed caused by myself
+ var mySessionID = webida.auth.getSessionID();
+ if (!data.sid) {
+ console.error('The session id of a notification is unknown');
+ return true;
+ }
+
+ if (mySessionID === data.sid) {
+ console.log('notification ignored: changes by the current app');
+ return true;
+ }
+
+ if (checkedURLs.every(function (url) { return !withinCache(data[url]); })) {
+ console.log('notification ignored: changes outside cache');
+ return true;
+ }
+
+ return false;
+ }
+
+ topic.subscribe('sys.fs.file.written', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ // file created
+ if (existing === null) {
+ root.putByAbsPath(urlParsed.path, 'file-written');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.written] for "' +
+ urlParsed.path + '" (as a file creation)');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else if (existing.getType() === TYPE_FILE) {
+ // file written
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.written] for "' +
+ urlParsed.path + '" (as a file cache invalidation)');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.file.written arrived for a non-file "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.file.deleted', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.file.deleted arrived for an absent file "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_FILE) {
+ existing.detach();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.file.deleted] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.file.deleted arrived for a non-file "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.dir.created', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ root.putByAbsPath(pathUtil.attachSlash(urlParsed.path), 'dir-created');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.dir.created] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ console.error('sys.fs.dir.created arrived for an existing directory "' +
+ urlParsed.path + '"');
+ } else {
+ console.error('sys.fs.dir.created arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+ });
+ topic.subscribe('sys.fs.dir.deleted', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.dir.deleted arrived for an absent directory "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ existing.detach();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.dir.deleted] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ console.error('sys.fs.dir.deleted arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+ });
+ topic.subscribe('sys.fs.node.intractableChanges', function (data) {
+ if (isIgnoredNotification(data, ['url'])) {
+ return;
+ }
+
+ var urlParsed = parseWFSURL(data.url);
+ var existing = root.getByAbsPath(urlParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.dir.intractableChanges arrived for an absent directory "' +
+ urlParsed.path + '"');
+ }
+ } else if (existing.getType() === TYPE_DIRECTORY) {
+ fsCache.refresh(urlParsed.path, { level: -1 }, function () {
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.intractableChanges] for "' +
+ urlParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+
+ onNodeChanges(urlParsed.path);
+ });
+ } else {
+ console.error('sys.fs.dir.intractable-changes arrived for a non-directory "' +
+ urlParsed.path + '"');
+ }
+
+ });
+ topic.subscribe('sys.fs.node.moved', function (data) {
+ if (isIgnoredNotification(data, ['srcURL', 'dstURL'])) {
+ return;
+ }
+
+ var dstURLParsed;
+ if (withinCache(data.dstURL)) {
+ dstURLParsed = parseWFSURL(data.dstURL);
+ mount.isDirectory(dstURLParsed.path, function (err, isDir) {
+ if (err) {
+ console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
+ '" of a notification sys.fs.node.moved is a directory or not: ' + err);
+ console.log('The notification is ignored.');
+ } else {
+ var existing = root.getByAbsPath(dstURLParsed.path);
+ if (existing) {
+ if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
+ if (isDir) {
+ console.error('sys.fs.node.moved arraived for an existing "' +
+ dstURLParsed.path + '" as its destination');
+ } else {
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] ' +
+ 'for its overwritten target file "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else {
+ console.error('The type of the destination of a notification sys.fs.node.moved ' +
+ 'does not match that of the corresponding node in the fs-cache for "' +
+ dstURLParsed.path + '"');
+ }
+ } else {
+ if (existing === null) {
+ root.putByAbsPath((isDir ?
+ pathUtil.attachSlash :
+ pathUtil.detachSlash)(dstURLParsed.path),
+ 'moved');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] for its target "' +
+ dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+ }
+ });
+ }
+
+ if (withinCache(data.srcURL)) {
+ var srcURLParsed = parseWFSURL(data.srcURL);
+ var existing = root.getByAbsPath(srcURLParsed.path);
+ if (!existing) {
+ if (existing === null) {
+ console.error('sys.fs.node.moved arrived for an absent "' +
+ srcURLParsed.path + '" as its source');
+ }
+ } else {
+ existing.detach(withinCache(data.dstURL) ? dstURLParsed.path : undefined);
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.moved] for its source "' +
+ srcURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+
+ // TODO: need to publish fs.cache.node.moved?
+ // But the topic does not support the case when the source is out of the current file system.
+ });
+ topic.subscribe('sys.fs.node.copied', function (data) {
+ if (isIgnoredNotification(data, ['dstURL'])) {
+ return;
+ }
+
+ var existing;
+ var dstURLParsed = parseWFSURL(data.dstURL);
+ if (withinCache(dstURLParsed.path)) {
+ mount.isDirectory(dstURLParsed.path, function (err, isDir) {
+ if (err) {
+ console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
+ '" of a notification sys.fs.node.copied is a directory or not: ' + err);
+ console.log('The notification is ignored.');
+ } else {
+ existing = root.getByAbsPath(dstURLParsed.path);
+ if (existing) {
+ if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
+ if (isDir) {
+ fsCache.refresh(dstURLParsed.path, { level: -1 });
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its merged target directory "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ } else {
+ existing.invalidateFileContents();
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its overwritten target file "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ } else {
+ console.error('The type of the destination of a notification sys.fs.node.copied ' +
+ 'does not match that of the corresponding node in the fs-cache for "' +
+ dstURLParsed.path + '"');
+ }
+ } else {
+ if (existing === null) {
+ root.putByAbsPath((isDir ?
+ pathUtil.attachSlash :
+ pathUtil.detachSlash)(dstURLParsed.path),
+ 'copied');
+ topic.publish('#REQUEST.log',
+ 'Handled a notification [sys.fs.node.copied] ' +
+ 'for its target "' + dstURLParsed.path + '"');
+ topic.publish('#REQUEST.log', '');
+ }
+ }
+ }
+ });
+ }
+
+ // TODO: need to publish fs.cache.node.copied?
+ // But the topic does not support the case when the source is out of the current file system.
+ });
+ }
+
+ function withinCache(path) {
+ if (path.indexOf('wfs://') === 0) {
+ // path is given in Webida File System URL
+ var pathParsed = parseWFSURL(path);
+ if (fsURLParsed.fsServer !== pathParsed.fsServer ||
+ fsURLParsed.fsid !== pathParsed.fsid) {
+ return false;
+ }
+ path = pathParsed.path;
+ }
+ return dirsToCache.some(function (cached) { return path.indexOf(cached) === 0; });
+ }
+ function getName(obj) { return obj.name; }
+ function isDir(stat) { return stat.isDirectory; }
+ function isFile(stat) { return stat.isFile; }
+ function checkTargetPath(path, exists, allowsDirPath) {
+ if (!isValidAbsPath(path)) {
+ return 'The path "' + path + '" is not a valid absolute path';
+ }
+
+ var node = root.getByAbsPath(path);
+ if (typeof exists === 'boolean') {
+ if ((exists && node === null) || (!exists && node)) {
+ return 'The path "' + path + '" must be ' + (exists ? 'present' : 'absent');
+ }
+ }
+
+ if (!allowsDirPath && pathUtil.isDirPath(path)) {
+ return 'The path "' + path + '" ends with a slash, which is disallowed';
+ }
+
+ return node;
+ }
+
+ //---------------------------
+ //---------------------------
+ // end of private methods of FSCacheInner
+ //---------------------------
+ //---------------------------
+
+
//---------------------------
//---------------------------
// private methods of FSCacheInner
diff --git a/common/src/webida/msg.js b/common/src/webida/msg.js
index 56f2dbf3..58cc281c 100644
--- a/common/src/webida/msg.js
+++ b/common/src/webida/msg.js
@@ -253,18 +253,15 @@ define([
];
/* jshint camelcase: true */
- var guid = (function () {
+ function guid () {
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}
- return function () {
- return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
+ return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
s4() + '-' + s4() + s4() + s4();
- };
- })();
-
+ }
From f7268c79fed5b9ad6aae9acb08c891b63b76042e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 17 Jun 2016 16:06:42 +0900
Subject: [PATCH 08/15] removed duplicated functions in FSCache
- fixed invalid undef value in .jshintrc, too.
---
.jshintrc | 2 +-
common/src/webida/FSCache-0.1.js | 3114 +++++++++++++-----------------
2 files changed, 1391 insertions(+), 1725 deletions(-)
diff --git a/.jshintrc b/.jshintrc
index 38b67a06..d5e54aeb 100644
--- a/.jshintrc
+++ b/.jshintrc
@@ -34,7 +34,7 @@
"noempty": true,
"nonew": true,
"plusplus": false,
- "undef": "nofunc",
+ "undef": true,
"unused": true,
"strict": true,
"trailing": false,
diff --git a/common/src/webida/FSCache-0.1.js b/common/src/webida/FSCache-0.1.js
index d2202c78..ea802561 100644
--- a/common/src/webida/FSCache-0.1.js
+++ b/common/src/webida/FSCache-0.1.js
@@ -68,2159 +68,1825 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
var mount;
var root;
- var FSCacheInner = declare(null, {
- constructor : function () {
- // dirsToCaches_ must be an array of valid absolute paths
- if (!dirsToCacheArg.every(function (dir) {
- return isValidAbsPath(dir) && pathUtil.isDirPath(dir);
- })) {
+ //*******************************
+ // inner class of FSCacheInner: FSNode
+ //*******************************
- throw new Error('The second argument must be an ' +
- 'array of absolute directory paths');
- }
+ var FSNode = declare(null, {
- // they must represent disjoin set of directories.
- var len = dirsToCacheArg.length;
- for (var i = 0; i < len - 1; i++) {
- var di = dirsToCacheArg[i];
- for (var j = i + 1; j < len; j++) {
- if (di.indexOf(dirsToCacheArg[j]) === 0) {
- throw new Error('Directories to cache are not disjoint');
- }
- }
- }
+ constructor : function (parent, name) {
+ this.parent = parent; // null iff this is the root node
+ this.name = name;
+ this.metadata = {};
+ this.metadataInvalidated = {};
+ },
- // Now, it's ok to build an of object of FSCacheInner
+ setMetadata: function (key, value, caseStr) {
+ var origValue = this.metadata[key];
+ this.metadata[key] = value;
+ this.metadataInvalidated[key] = false;
- // set private fields
- fsURL = fsURLArg;
- fsURLParsed = parseWFSURL(fsURL);
- dirsToCache = dirsToCacheArg;
- publishing = false;
- mount = webida.fs.mountByFSID(fsURLParsed.fsid);
+ var path = this.getPath();
+ switch (caseStr) {
+ case 'fetched':
+ onMetadataFetched(path, key);
+ break;
+ case 'written':
+ onMetadataSet(path, key, value !== origValue);
+ break;
+ case 'refreshed':
+ onMetadataRefreshed(path, key);
+ break;
+ default:
+ console.assert(false, 'Unreachable');
+ }
+ },
- root = new Directory(null, ''); // no parent, empty name
- root.getByAbsPath = function (absPath) {
- //console.log('hina temp: absPath = ' + absPath);
- if (absPath.indexOf('/') === 0) {
- return absPath === '/' ? this : this.getByRelPath(absPath.substr(1));
- } else {
- console.error('Unreachable: cannot get "' + absPath + '" under "/"');
- throw new Error('Unreachable: cannot get "' + absPath + '" under "/"');
- }
- };
- root.putByAbsPath = function (absPath, caseStr) {
- if (absPath.indexOf('/') === 0 && absPath.length > 1) {
- return this.putByRelPath(absPath.substr(1), caseStr);
- } else {
- console.error('Unreachable: cannot put "' + absPath + '" under "/"');
- throw new Error('Unreachable: cannot put "' + absPath + '" under "/"');
+ refreshMetadata: function (key) {
+ var self = this;
+ Object.keys(this.metadata).forEach(function (k) {
+ if (key === undefined || key === k) {
+ var origVal = self.metadata[k];
+ var path = self.getPath();
+ mount.getMeta(path, k, function (err, newVal) {
+ if (err) {
+ console.error('Cannot get metadata ' + k + ' of ' + path +
+ ' from server: ' + err);
+ } else {
+ if (origVal !== newVal) {
+ this.setMetadata(k, newVal, 'refreshed');
+ }
+ }
+ });
}
- };
- //root.show(0);
+ });
},
- getSummary : function () {
- return root.getSummary();
+ getParentPath : function () {
+ return this.parent ? this.parent.getPath() : EMPTY_PATH;
},
- start : function (summary) {
- if (summary) {
- root.restoreFromSummary(summary);
- root.fetchedSubnodes = false; // TODO: generalize this.
+ getPath : function () {
+ if (!this._path) {
+ // memoize
+ this._path = this.computePath();
}
-
- // add nodes for cache roots
- dirsToCache.forEach(function (dir) {
- root.putByAbsPath(dir, 'cache-root');
- });
-
- //console.log('Starting FS-Cache.');
- //root.show(0);
- publishing = true;
-
- subscribeToNotificationsOnFS(this);
+ return this._path;
},
- invalidateFileContents: function (path) {
- if (isValidAbsPath(path) && withinCache(path)) {
- var node = root.getByAbsPath(path);
- if (!node) {
- throw new Error('Not in the cache: ' + path);
- }
-
- node.invalidateFileContents();
+ computePath : function () {
+ return this.getParentPath() + this.name;
+ },
- } else {
- throw new Error('The path "' + path + '" is not a valid path being cached');
- }
+ getType : function () {
+ return TYPE_UNKNOWN;
},
- invalidateMetadata: function (path, key) {
- if (isValidAbsPath(path) && withinCache(path)) {
- var node = root.getByAbsPath(path);
- if (!node) {
- throw new Error('Not in the cache: ' + path);
+ detach : function (movedTo) {
+ if (this.parent) {
+ var detached = this.parent.removeSubnode(this.name, movedTo);
+ if (this !== detached) {
+ throw new Error('Detached node is wrong.');
}
-
- node.invalidateMetadata(key);
-
} else {
- throw new Error('The path "' + path + '" is not a valid path being cached');
+ throw new Error('Cannot detach the root node');
}
},
- refreshHierarchy: function (path, options, cb) {
- if (isValidAbsPath(path) && withinCache(path)) {
- var node = root.getByAbsPath(path);
- if (!node) {
- throw new Error('Not in the cache: ' + path);
- }
+ satisfyingCond : function (cond) {
- var level;
- if (node.getType() === TYPE_FILE) {
- node = node.parent;
- level = 1;
- } else {
- if (options && 'level' in options) {
- level = Math.floor(options.level);
- } else {
- throw new Error('Level must be given in the options argument');
- }
+ if (cond.types) {
+ if (cond.types.indexOf(this.getType()) < 0) {
+ return false;
}
+ }
- cb = cb || doNothing;
- node.refreshHierarchy(level, cb);
+ return true;
+ },
- } else {
- throw new Error('The path "' + path + '" is not a valid path being cached');
+ collectNodes : function (arr, cond) {
+ if (this.satisfyingCond(cond)) {
+ arr.push(this);
}
},
- refreshFileContents: function (path, options) {
- if (isValidAbsPath(path) && withinCache(path)) {
- var node = root.getByAbsPath(path);
- if (!node) {
- throw new Error('Not in the cache: ' + path);
- }
+ getListInfo : function () {
+ return {
+ name : this.name,
+ isDirectory : this instanceof Directory,
+ isFile : this instanceof File
+ };
+ },
- if (node.getType() === TYPE_FILE) { // only for files
- node.refreshFileContents();
- } else {
- var level;
- if (options && 'level' in options) {
- level = Math.floor(options.level);
- } else {
- throw new Error('Level must be given in the \'options\' argument');
- }
- node.refreshFileContents(level); //
- }
- } else {
- throw new Error('The path "' + path + '" is not a valid path being cached');
+ show : function (level) { // for debugging
+ var arr = [];
+ for (var i = 0; i < level; i++) {
+ arr.push('| ');
}
+
+ arr.push(this.name);
+ console.log(arr.join(''));
},
- refreshMetadata: function (path, key, options) {
- if (isValidAbsPath(path) && withinCache(path)) {
- var node = root.getByAbsPath(path);
- if (!node) {
- throw new Error('Not in the cache: ' + path);
- }
+ invalidateFileContents: function () {
+ console.error('assertion fail: unreachable');
+ },
- if (node.getType() === TYPE_FILE) { // only for files
- node.refreshMetadata(key);
- } else {
- var level;
- if (options && 'level' in options) {
- level = Math.floor(options.level);
- } else {
- throw new Error('Level must be given in the \'options\' argument');
+ invalidateMetadata: function (key) {
+ var keys = Object.keys(this.metadataInvalidated);
+ var path = this.getPath();
+ if (key === undefined) {
+ keys.forEach(function (k) {
+ if (this.metadata[k] !== undefined &&
+ !this.metadataInvalidated[k]) {
+ this.metadataInvalidated[k] = true;
+ onMetadataInvalidated(path, k);
}
- node.refreshMetadata(level, key); //
+ });
+ } else if (keys.indexOf(key) >= 0) {
+ if (this.metadata[key] !== undefined &&
+ !this.metadataInvalidated[key]) {
+ this.metadataInvalidated[key] = true;
+ onMetadataInvalidated(path, key);
}
} else {
- throw new Error('The path "' + path + '" is not a valid path being cached');
+ throw new Error('Metadata ' + key + ' is not set for "' +
+ this.getPath() + '"');
}
- },
+ }
- // convenience API: refresh all (hierarchy, file contents, and metadata)
- refresh : function (path, options, cbWhenHierarchyDone) {
- var opt = { level: 1 };
- if (options) {
- _.extend(opt, options);
- }
+ });
- var self = this;
- this.refreshHierarchy(path, opt, function () {
- if (cbWhenHierarchyDone) {
- cbWhenHierarchyDone();
- }
+ //*******************************
+ // inner class of FSCacheInner: File
+ //*******************************
- self.refreshFileContents(path, opt);
- self.refreshMetadata(path, undefined/* every key */, opt);
- });
+ var File = declare(FSNode, {
+ constructor : function (/*parent, name*/) {
+ this.contentInvalidated = false;
},
- queryPaths : function (dirPath, condition) {
- if (isValidAbsPath(dirPath) && pathUtil.isDirPath(dirPath) && withinCache(dirPath)) {
- var dirNode = root.getByAbsPath(dirPath);
- if (!dirNode) {
- return null;
- }
+ invalidateFileContents: function () {
+ if (this.content !== undefined && !this.contentInvalidated) {
+ this.contentInvalidated = true;
+ onFileInvalidated(this.getPath());
+ }
+ },
- var nodeArr = [];
- dirNode.collectNodes(nodeArr, condition);
- return nodeArr.map(function (node) {
- return node.getPath();
+ refreshFileContents : function () {
+
+ // NOTE: refreshing contents is possible for invalidated contents too
+
+ var origContent = this.content;
+ if (origContent !== undefined) {
+ var path = this.getPath();
+ var self = this;
+ mount.readFile(path, function (err, newContent) {
+ if (err) {
+ console.log('Cannot get content of ' + path +
+ ' from server. cannot refresh the file content (' +
+ err + ')');
+ } else {
+ if (origContent !== newContent) {
+ self.setContent(newContent, 'refreshed');
+ }
+ }
});
+ }
+ },
- } else {
- throw new Error('The path "' + dirPath +
- '" does not represent a directory being cached');
+ setContent : function (content, caseStr) {
+ var origContent = this.content;
+ this.content = content;
+ this.contentInvalidated = false;
+
+ var path = this.getPath();
+ switch (caseStr) {
+ case 'fetched':
+ onFileFetched(path);
+ break;
+ case 'written':
+ onFileWritten(path, content === undefined || content !== origContent);
+ break;
+ case 'refreshed':
+ onFileRefreshed(path);
+ break;
+ default:
+ console.assert(false, 'Unreachable');
}
},
- //---------------------------
- // FS API wrapper - methods WITH update
- //---------------------------
+ getType : function () {
+ return TYPE_FILE;
+ },
- // copy
- copy : function (src, dst, recursive, cb) {
+ getSummary : function () {
+ return this.name;
+ }
+ });
- var srcNode, dstNode;
- function checkValidCopy() {
- var ret = checkTargetPath(src, true, true);
- if (isError(ret)) {
- return ret;
- }
- srcNode = ret;
+ //*******************************
+ // inner class of FSCacheInner: Directory
+ //*******************************
- ret = checkTargetPath(dst, null);
- if (isError(ret)) {
- return ret;
- }
- dstNode = ret;
+ var Directory = declare(FSNode, {
+ constructor : function (/*parent, name*/) {
+ this.dirs = new SortedArray('name');
+ this.files = new SortedArray('name');
+ },
- if (src === dst) {
- return 'Source and destination paths are identical: ' + src + '.';
- }
+ invalidateFileContents: function () {
+ this.dirs.forEach(function (dir) {
+ dir.invalidateFileContents();
+ });
+ this.files.forEach(function (file) {
+ file.invalidateFileContents();
+ });
+ },
- if (dst.indexOf(src + '/') === 0) {
- return 'Cannot copy a directory into its descendant';
- }
+ invalidateMetadata: function (key) {
+ FSNode.prototype.invalidateMetadata.call(this, key);
+ this.dirs.forEach(function (dir) {
+ dir.invalidateMetadata(key);
+ });
+ this.files.forEach(function (file) {
+ file.invalidateMetadata(key);
+ });
+ },
- if (srcNode instanceof Directory && !recursive) {
- return 'Copying a directory with recursive option unset is disallowed.';
- }
+ refreshFileContents : function (level) {
+ if (typeof level !== 'number') { // TODO: remove this check when stabilized
+ throw new Error('assertion fail: unrechable');
+ }
- var divided = pathUtil.dividePath(dst);
- if (root.getByAbsPath(divided[0]) === null) {
- return 'Destination directory "' + divided[0] + '" does not exist.';
- }
+ if (level) {
+ this.dirs.forEach(function (dir) {
+ dir.refreshFileContents(level - 1);
+ });
+ this.files.forEach(function (file) {
+ file.refreshFileContents();
+ });
+ }
+ },
- return null;
+ refreshMetadata: function (level, key) {
+ if (typeof level !== 'number') { // TODO: remove this check when stabilized
+ throw new Error('assertion fail: unrechable');
}
- function callback(err) {
+ FSNode.prototype.refreshMetadata.call(this, key);
+ if (level) {
+ this.dirs.forEach(function (dir) {
+ dir.refreshMetadata(level - 1, key);
+ });
+ this.files.forEach(function (file) {
+ file.refreshMetadata(key);
+ });
+ }
+ },
- function handleCopySuccess(isDir) {
- console.assert(srcNode === root.getByAbsPath(src),
- 'A source node has been modified during a ' +
- 'copy request to server: ' + src);
- console.assert(dstNode === root.getByAbsPath(dst),
- 'A destination node has been modified during a ' +
- 'copy request to server: ' + dst);
+ computePath : function () {
+ return this.getParentPath() + this.name + '/';
+ },
- var t = dst + (isDir ? '/' : '');
- var addedNodes = root.putByAbsPath(t, 'copied');
- if (!addedNodes) { // because the target has been already present.
- fsCache.refresh(t, { level: -1 });
- }
- cb(null);
- }
+ putByRelPath : function (relPath, caseStr) {
+ console.assert(relPath,
+ 'Directory.putByRelPath() was called with a falsy argument');
- if (err) {
- /* TODO: continue 'serverless operations'
- if (err === 'server unreachable' && srcNode && !dstNode) {
+ var i = relPath.indexOf('/');
+ if (i < 0) {
+ // base case
+ var file = this.putSubnode(relPath, false, caseStr);
+ return (file ? [file] : null);
+ } else {
+ console.assert(i > 0, 'i must be a positive integer');
+ var subdirName = relPath.substring(0, i);
+ var subdir = this.putSubnode(subdirName, true, caseStr);
+ var nextPath = relPath.substr(i + 1);
+ if (nextPath) {
+ if (subdir) {
+ // newly added
+ var addedArr = subdir.putByRelPath(nextPath, caseStr);
+ addedArr.unshift(subdir);
+ return addedArr;
} else {
- cb(err);
- return;
+ // already there
+ subdir = this.getSubnode(subdirName);
+ return subdir.putByRelPath(nextPath, caseStr);
}
- */
- cb(err);
} else {
- if (srcNode) {
- handleCopySuccess(srcNode instanceof Directory);
- } else {
- mount.isDirectory(dst, function (err, isDir) {
- if (err) {
- cb(err);
- } else {
- handleCopySuccess(isDir);
- }
- });
- }
+ // base case
+ return (subdir ? [subdir] : null);
}
}
+ },
- if (typeof recursive === 'function') {
- cb = recursive;
- recursive = false; // false is default
- }
+ // If a subnode exists with that name and type, then do nothing and return null.
+ // Otherwise, create the subnode, add it, and return the added subnode.
+ putSubnode : function (name, isDir, caseStr) {
+ console.assert(name);
+ console.assert(name.indexOf('/') === -1);
- src = pathUtil.detachSlash(src);
- var err = checkValidCopy();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
+ var subnode = this.getSubnode(name);
+ if (subnode && (subnode.isInstanceOf(Directory) === isDir)) {
+ return null;
} else {
- mount.copy(src, dst, recursive, withinCache(dst) ? callback : cb);
+ if (subnode) {
+ console.warn('A subnode with the same name "' + name +
+ '" but with different type was detected while putting a ' +
+ (isDir ? 'directory' : 'file') + ' to "' +
+ this.getPath() + '"');
+ return null;
+ } else {
+ var added = this.addSubnode(name, isDir, caseStr);
+ return added;
+ }
}
},
- // move
- move : function (src, dst, cb) {
-
- var srcNode, dstNode;
- function checkValidMove() {
- var ret = checkTargetPath(src, true, true);
- if (isError(ret)) {
- return ret;
- }
- srcNode = ret;
-
- ret = checkTargetPath(dst, null);
- if (isError(ret)) {
- return ret;
- }
- dstNode = ret;
-
- if (src === dst) {
- return 'Source and destination paths are identical: ' + src + '.';
+ addSubnode : function (name, isDir, caseStr) {
+ if (this.getSubnode(name)) { // TODO: remove this check if code is stabilized
+ console.error('Unreachable: Cannot overwrite existing subnode ' + name +
+ ' of ' + this.getPath() + ' by addSubnode()');
+ throw new Error('Unreachable: Cannot overwrite existing subnode ' + name +
+ ' of ' + this.getPath() + ' by addSubnode()');
+ } else {
+ var C = isDir ? Directory : File;
+ var subnode = new C(this, name);
+ if (isDir) {
+ this.dirs.add(subnode);
+ } else {
+ this.files.add(subnode);
}
- if (dst.indexOf(src + '/') === 0) {
- return 'Cannot move a directory into its descendant';
+ var maybeCreated;
+ switch (caseStr) {
+ case 'cache-root':
+ case 'inferred':
+ case 'fetched':
+ case 'restored':
+ maybeCreated = false;
+ break;
+ case 'copied':
+ case 'moved':
+ case 'dir-created':
+ case 'zip-created':
+ case 'zip-extracted':
+ case 'file-written':
+ case 'refreshed':
+ maybeCreated = true;
+ break;
+ default:
+ console.assert(false, 'Unreachable');
}
- var divided = pathUtil.dividePath(dst);
- if (root.getByAbsPath(divided[0]) === null) {
- return 'Destination directory "' + divided[0] + '" does not exist.';
- }
+ onNodeAdded(this.getPath(), name, subnode.getType(), maybeCreated, caseStr === 'moved');
- return null;
+ return subnode;
}
+ },
- function callback(err) {
- function handleMoveSuccess(isDir) {
- console.assert(srcNode === root.getByAbsPath(src),
- 'A source node has been modified ' +
- 'duirng a move request to server: ' + src);
- console.assert(dstNode === root.getByAbsPath(dst),
- 'A destination node has been modified ' +
- 'duirng a move request to server: ' + dst);
+ getByRelPath: function (relPath) {
+ //console.log('hina temp: relPath = ' + relPath);
+ console.assert(relPath,
+ 'Directory.getByRelPath() was called ' +
+ 'with falsy argument');
- if (withinCache(dst)) {
- var t = dst + (isDir ? '/' : '');
- var addedNodes = root.putByAbsPath(t, 'moved');
- if (!addedNodes) { // because the target has been already present.
- fsCache.refresh(t, { level: -1 });
+ var i = relPath.indexOf('/');
+ if (i < 0) {
+ return this.getSubnode(relPath);
+ } else {
+ console.assert(i > 0,
+ 'Directory.getByRelPath() was called ' +
+ 'with an absolute path: ' + relPath);
+ var nextPath;
+ var subnodeName = relPath.substring(0, i);
+ var subnode = this.getSubnode(subnodeName);
+ if (subnode) {
+ nextPath = relPath.substr(i + 1);
+ if (nextPath) {
+ if (subnode instanceof Directory) {
+ return subnode.getByRelPath(nextPath);
+ } else {
+ return null;
}
- }
- if (srcNode) {
- srcNode.detach(withinCache(dst) ? dst : undefined);
- }
- cb(null);
- }
-
- if (err) {
- cb(err);
- } else {
- if (srcNode) {
- handleMoveSuccess(srcNode instanceof Directory);
} else {
- mount.isDirectory(dst, function (err, isDir) {
- if (err) {
- cb(err);
- } else {
- handleMoveSuccess(isDir);
- }
- });
+ return subnode;
}
+ } else {
+ return subnode;
}
}
+ },
- src = pathUtil.detachSlash(src);
- var err = checkValidMove();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
+ getSubnode : function (name) {
+ var queried = { name: name };
+ var ret = this.dirs.query(queried) || this.files.query(queried);
+ if (ret) {
+ return ret;
} else {
- mount.move(src, dst, (srcNode || withinCache(dst)) ? callback : cb);
+ return this.fetchedSubnodes ? null : undefined;
}
},
- // createDirectory
- createDirectory : function (target, recursive, cb) {
- var targetNode;
- function checkValidCreateDirectory() {
- var ret = checkTargetPath(target, false, true);
- if (isError(ret)) {
- return ret;
- }
- targetNode = ret;
-
- if (!recursive) {
- var parentPath = pathUtil.dividePath(target)[0];
- var parentNode = root.getByAbsPath(parentPath);
- if (parentNode === null) {
- return 'Parent directory "' + parentPath +
- '" does not exist and the recursive option is not set.';
- }
- }
-
- return null;
- }
+ removeSubnode : function (name, movedTo) {
+ var ret = this.getSubnode(name);
+ if (ret) {
+ var isDir = ret instanceof Directory;
+ var arr = isDir ? this.dirs : this.files;
+ var i = arr.indexOf(ret);
+ Array.prototype.splice.call(arr, i, 1);
- function callback(err) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'A target node has been modified during a ' +
- 'createDirectory request to server: ' + target);
- if (err) {
- cb(err);
- } else {
- root.putByAbsPath(target + '/', 'dir-created');
- cb(null);
- }
+ onNodeDeleted(this.getPath(), name, ret.getType(), movedTo);
}
+ return ret;
+ },
- if (typeof recursive === 'function') {
- cb = recursive;
- recursive = false; // false is default
- }
+ getType : function () {
+ return TYPE_DIRECTORY;
+ },
- target = pathUtil.detachSlash(target);
- var err = checkValidCreateDirectory();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
- } else {
- mount.createDirectory(target, recursive, withinCache(target) ? callback : cb);
- }
+ isEmpty : function () {
+ return (this.dirs.length === 0) && (this.files.length === 0);
},
- createZip : function (sources, target, cb) {
- var targetNode;
- function checkValidCreateZip() {
- if (sources.some(function (path) { return !isValidAbsPath(path); })) {
- return 'List of sources contains a path which is not a valid absolute path.';
- }
+ updateSubnodes : function (stats, isDir, caseStr) {
+ var subnodes = isDir ? this.dirs : this.files;
+ var names = subnodes.map(getName);
+ var newNames = stats.map(getName);
- var ret = checkTargetPath(target, false);
- if (isError(ret)) {
- return ret;
- }
- targetNode = ret;
+ //console.log('hina temp: names = ' + names);
+ //console.log('hina temp: newNames = ' + newNames);
+ var toAdd = _.difference(newNames, names);
+ var toDel = _.difference(names, newNames);
+ //console.log('hina temp: toAdd = ' + toAdd);
+ //console.log('hina temp: toDel = ' + toDel);
+ var self = this;
+ toDel.forEach(function (name) {
+ self.removeSubnode(name);
+ });
+ toAdd.forEach(function (name) {
+ self.addSubnode(name, isDir, caseStr);
+ });
+ },
- return null;
- }
+ // refresh hierarchy level by level
+ refreshHierarchy : function (level, doWhenAllDone) {
+ //console.log('hina temp: entering refreshHierarchy dirPath = ' + this.getPath());
- function callback(err) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'A target node has been modified during a ' +
- 'createZip request to server: ' + target);
- if (err) {
- cb(err);
- } else {
- root.putByAbsPath(target, 'zip-created');
- cb(null);
- }
- }
+ // NOTE: getByAbsPath() must be invoked on the root.
+ // Nodes (except for the root) can be detached at any time during an
+ // asynchronous method call.
- var err = checkValidCreateZip();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
- } else {
- mount.createZip(sources, target, withinCache(target) ? callback : cb);
- }
- },
+ if (level && this.fetchedSubnodes) {
+ var dirPath = this.getPath();
+ var self = this;
+ mount.list(dirPath, false, function (err, stats) {
- // delete
- 'delete' : function (target, recursive, cb) {
- var targetNode;
- function callback(err) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'A target node has been modified duirng a ' +
- 'delete request to server: ' + target);
- if (err) {
- cb(err);
- } else {
- if (targetNode) {
- targetNode.detach();
+ var subnodeTypesDone = 0;
+ function oneTypeDone() {
+ subnodeTypesDone++;
+ //console.log('hina temp: oneTypeDone for ' + dirPath + ' ' + subnodeTypesDone + ' time ');
+ if (subnodeTypesDone === 2) { // two types (dirs and files)
+ //console.log('hina temp: ' + dirPath + ' is done');
+ doWhenAllDone();
+ }
}
- cb(null);
- }
- }
- if (typeof recursive === 'function') {
- cb = recursive;
- recursive = false; // false is default
- }
+ if (err) {
+ console.warn('Error: FileSystem.list failed while refreshing "' +
+ dirPath + '" (' + err + ')');
+ doWhenAllDone();
+ } else {
+ var newDirs = stats.filter(isDir);
+ self.updateSubnodes(newDirs, true, 'refreshed');
- var ret = checkTargetPath(target, true, true);
- if (isError(ret)) {
- setTimeout(cb.bind(null, ret), 0);
+ var subdirsToRefresh = self.dirs.length;
+ var subdirsRefreshed = 0;
+ if (subdirsToRefresh) {
+ self.dirs.forEach(function (dir) {
+ dir.refreshHierarchy(level - 1, function () {
+ subdirsRefreshed++;
+ if (subdirsRefreshed === subdirsToRefresh) {
+ //console.log('hina temp: subdirs of ' + dirPath + ' are done');
+ oneTypeDone();
+ }
+ });
+ });
+ } else {
+ oneTypeDone();
+ }
+
+ var newFiles = stats.filter(isFile);
+ self.updateSubnodes(newFiles, false, 'refreshed');
+ oneTypeDone();
+ }
+ });
} else {
- targetNode = ret;
- mount.delete(target, recursive, withinCache(target) ? callback : cb);
+ doWhenAllDone();
}
+
+
},
- extractZip : function (source, target, cb) {
- var sourceNode, targetNode;
- function checkValidExtractZip() {
- var ret = checkTargetPath(source, true);
- if (isError(ret)) {
- return ret;
- }
- sourceNode = ret;
+ collectNodes : function (arr, cond) {
+ FSNode.prototype.collectNodes.call(this, arr, cond); // super call
+ this.dirs.forEach(function (dir) {
+ dir.collectNodes(arr, cond);
+ });
+ this.files.forEach(function (file) {
+ file.collectNodes(arr, cond);
+ });
+ },
- ret = checkTargetPath(target, false, true);
- if (isError(ret)) {
- return ret;
- }
- targetNode = ret;
+ list : function () {
+ if (this.fetchedSubnodes) {
+ var arr = [];
- return null;
- }
+ this.dirs.forEach(function (subnode) {
+ arr.push(subnode.getListInfo());
+ });
- function callback(err) {
- console.assert(sourceNode === root.getByAbsPath(source),
- 'A source node has been modified duirng a ' +
- 'extractZip request to server: ' + source);
- console.assert(targetNode === root.getByAbsPath(target),
- 'A target node has been modified duirng a ' +
- 'extractZip request to server: ' + target);
- if (err) {
- cb(err);
- } else {
- root.putByAbsPath(target + '/', 'zip-extracted');
- cb(null);
- }
- }
+ this.files.forEach(function (subnode) {
+ arr.push(subnode.getListInfo());
+ });
- target = pathUtil.detachSlash(target);
- var err = checkValidExtractZip();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
+ return arr;
} else {
- mount.extractZip(source, target, withinCache(target) ? callback : cb);
+ console.error('Unreachable: list should not be called on ' +
+ 'a node which has never fetched subnodes: ' + this.getPath());
+ throw new Error('Unreachable: list should not be called on ' +
+ 'a node which has never fetched subnodes: ' + this.getPath());
}
},
- _writeFile: function (target, data, cb) {
- var file;
- function checkValidWriteFile() {
- var ret = checkTargetPath(target, undefined);
- if (isError(ret)) {
- return ret;
- }
- file = ret;
+ show : function (level) { // for debugging
+ var arr = [];
+ for (var i = 0; i < level; i++) {
+ arr.push('| ');
+ }
+ arr.push(this.name + '/');
+ console.log(arr.join(''));
- if (file && !(file instanceof File)) {
- return 'The path "' + target + '" is not a path of a file';
- }
+ this.dirs.forEach(function (subdir) {
+ subdir.show(level + 1);
+ });
- return null;
+ this.files.forEach(function (subdir) {
+ subdir.show(level + 1);
+ });
+ },
+
+ getSummary : function () {
+ var subSummaries;
+ if (this.listed || !withinCache(this.getPath())) {
+ subSummaries = [];
+ this.dirs.forEach(function (dir) {
+ var val = dir.getSummary();
+ console.assert(typeof val === 'object',
+ 'Summary of a subdir must be an object');
+ subSummaries.push(val);
+ });
+ this.files.forEach(function (file) {
+ var val = file.getSummary();
+ console.assert(typeof val === 'string',
+ 'Summary of a file must be a string');
+ subSummaries.push(val);
+ });
+ } else {
+ subSummaries = null;
}
- function callback(err) {
- console.assert(file === root.getByAbsPath(target),
- 'A target node has been modified duirng a ' +
- 'writeFile request to server: ' + target);
- if (err) {
- cb(err);
- } else {
- if (!file) {
- var added = root.putByAbsPath(target, 'file-written');
- file = added[added.length - 1];
- }
- if (typeof data === 'string') {
- file.setContent(data, 'written');
+ if (this.name) {
+ return { n: this.name, s: subSummaries };
+ } else {
+ // only root can reach here
+ return subSummaries;
+ }
+ },
+
+ restoreFromSummary : function (subSummaries) {
+ if (subSummaries) {
+ console.assert(subSummaries instanceof Array,
+ 'SubSummaries must be an array');
+
+ var self = this;
+ subSummaries.forEach(function (summary) {
+ var type = typeof summary;
+ if (type === 'object') {
+ var added = self.addSubnode(summary.n, true, 'restored');
+ added.restoreFromSummary(summary.s);
+ } else if (type === 'string') {
+ self.addSubnode(summary, false, 'restored');
} else {
- file.setContent(undefined, 'written');
+ console.assert(false,
+ 'Summary must be an object or string');
}
- cb(null);
- }
+ });
+ this.fetchedSubnodes = true;
}
+ }
+ });
- var err = checkValidWriteFile();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
- } else {
- mount.writeFile(target, data, withinCache(target) ? callback : cb);
- }
- },
- // writeFile
- writeFile : function (target, data, cb) {
- //console.log('writeFile('+target+', data, cb)');
- var that = this;
- var path, dir;
- path = target.split(/[\\/]/);
- path.pop();
- dir = path.join('/');
- this.isDirectory(dir, function (error, isDir) {
- if (isDir === true) {
- that._writeFile(target, data, cb);
- } else {
- //console.log('If dir not exists, create dir then write file');
- that.createDirectory(dir, true, function (err) {
- if (err) {
- cb(err);
- } else {
- that._writeFile(target, data, cb);
- }
- });
- }
- });
- },
+ var FSCacheInner = declare(null, {
- // setMeta
- setMeta : function (target, key, val, cb) {
- var targetNode;
- function checkValidSetMeta() {
- var ret = checkTargetPath(target, true, true);
- if (isError(ret)) {
- return ret;
- }
- targetNode = ret;
+ constructor : function () {
+ // dirsToCaches_ must be an array of valid absolute paths
+ if (!dirsToCacheArg.every(function (dir) {
+ return isValidAbsPath(dir) && pathUtil.isDirPath(dir);
+ })) {
- if (!key || typeof key !== 'string') {
- return 'Key must be a non-empty string';
- }
+ throw new Error('The second argument must be an ' +
+ 'array of absolute directory paths');
+ }
- if (typeof val !== 'string') {
- return 'Value must be a string';
+ // they must represent disjoin set of directories.
+ var len = dirsToCacheArg.length;
+ for (var i = 0; i < len - 1; i++) {
+ var di = dirsToCacheArg[i];
+ for (var j = i + 1; j < len; j++) {
+ if (di.indexOf(dirsToCacheArg[j]) === 0) {
+ throw new Error('Directories to cache are not disjoint');
+ }
}
-
- return null;
}
- function callback(err) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'Target node has been modified during a request of ' +
- 'setMeta to server:' + target);
- if (err) {
- cb(err);
+ // Now, it's ok to build an of object of FSCacheInner
+
+ // set private fields
+ fsURL = fsURLArg;
+ fsURLParsed = parseWFSURL(fsURL);
+ dirsToCache = dirsToCacheArg;
+ publishing = false;
+ mount = webida.fs.mountByFSID(fsURLParsed.fsid);
+
+ root = new Directory(null, ''); // no parent, empty name
+ root.getByAbsPath = function (absPath) {
+ //console.log('hina temp: absPath = ' + absPath);
+ if (absPath.indexOf('/') === 0) {
+ return absPath === '/' ? this : this.getByRelPath(absPath.substr(1));
} else {
- if (targetNode) {
- targetNode.setMetadata(key, val, 'written');
- cb(null);
- } else {
- mount.isDirectory(target, function (err, isDir) {
- if (err) {
- console.error('Error in isDirectory call while setting metadata: ' + err);
- } else {
- var added = root.putByAbsPath(
- (isDir ? pathUtil.attachSlash : pathUtil.detachSlash)(target), 'inferred');
- targetNode = added[added.length - 1];
- targetNode.setMetadata(key, val, 'written');
- }
- cb(null);
- });
- }
+ console.error('Unreachable: cannot get "' + absPath + '" under "/"');
+ throw new Error('Unreachable: cannot get "' + absPath + '" under "/"');
}
- }
+ };
+ root.putByAbsPath = function (absPath, caseStr) {
+ if (absPath.indexOf('/') === 0 && absPath.length > 1) {
+ return this.putByRelPath(absPath.substr(1), caseStr);
+ } else {
+ console.error('Unreachable: cannot put "' + absPath + '" under "/"');
+ throw new Error('Unreachable: cannot put "' + absPath + '" under "/"');
+ }
+ };
+ //root.show(0);
+ },
- var err = checkValidSetMeta();
- if (err) {
- setTimeout(cb.bind(null, err), 0);
- } else {
- mount.setMeta(target, key, val, callback);
+ getSummary : function () {
+ return root.getSummary();
+ },
+
+ start : function (summary) {
+ if (summary) {
+ root.restoreFromSummary(summary);
+ root.fetchedSubnodes = false; // TODO: generalize this.
}
+
+ // add nodes for cache roots
+ dirsToCache.forEach(function (dir) {
+ root.putByAbsPath(dir, 'cache-root');
+ });
+
+ //console.log('Starting FS-Cache.');
+ //root.show(0);
+ publishing = true;
+
+ subscribeToNotificationsOnFS(this);
},
- lockFile: function (path, cb) {
- if (isValidAbsPath(path)) {
- mount.lockFile.apply(mount, arguments);
+ invalidateFileContents: function (path) {
+ if (isValidAbsPath(path) && withinCache(path)) {
+ var node = root.getByAbsPath(path);
+ if (!node) {
+ throw new Error('Not in the cache: ' + path);
+ }
+
+ node.invalidateFileContents();
+
} else {
- setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ throw new Error('The path "' + path + '" is not a valid path being cached');
}
},
- unlockFile: function (path, cb) {
- if (isValidAbsPath(path)) {
- mount.unlockFile.apply(mount, arguments);
+ invalidateMetadata: function (path, key) {
+ if (isValidAbsPath(path) && withinCache(path)) {
+ var node = root.getByAbsPath(path);
+ if (!node) {
+ throw new Error('Not in the cache: ' + path);
+ }
+
+ node.invalidateMetadata(key);
+
} else {
- setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ throw new Error('The path "' + path + '" is not a valid path being cached');
}
},
- //---------------------------
- // FS API wrapper - methods WITHOUT update
- //---------------------------
+ refreshHierarchy: function (path, options, cb) {
+ if (isValidAbsPath(path) && withinCache(path)) {
+ var node = root.getByAbsPath(path);
+ if (!node) {
+ throw new Error('Not in the cache: ' + path);
+ }
+
+ var level;
+ if (node.getType() === TYPE_FILE) {
+ node = node.parent;
+ level = 1;
+ } else {
+ if (options && 'level' in options) {
+ level = Math.floor(options.level);
+ } else {
+ throw new Error('Level must be given in the options argument');
+ }
+ }
+
+ cb = cb || doNothing;
+ node.refreshHierarchy(level, cb);
- getLockedFiles: function (path, cb) {
- if (isValidAbsPath(path)) {
- mount.getLockedFiles.apply(mount, arguments);
} else {
- setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ throw new Error('The path "' + path + '" is not a valid path being cached');
}
},
- addAlias: function (path, expireTime, cb) {
- if (isValidAbsPath(path)) {
- mount.addAlias.apply(mount, arguments);
+ refreshFileContents: function (path, options) {
+ if (isValidAbsPath(path) && withinCache(path)) {
+ var node = root.getByAbsPath(path);
+ if (!node) {
+ throw new Error('Not in the cache: ' + path);
+ }
+
+ if (node.getType() === TYPE_FILE) { // only for files
+ node.refreshFileContents();
+ } else {
+ var level;
+ if (options && 'level' in options) {
+ level = Math.floor(options.level);
+ } else {
+ throw new Error('Level must be given in the \'options\' argument');
+ }
+ node.refreshFileContents(level); //
+ }
} else {
- setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ throw new Error('The path "' + path + '" is not a valid path being cached');
}
},
- // deleteAlias
- deleteAlias : function () {
- mount.deleteAlias.apply(mount, arguments);
- },
+ refreshMetadata: function (path, key, options) {
+ if (isValidAbsPath(path) && withinCache(path)) {
+ var node = root.getByAbsPath(path);
+ if (!node) {
+ throw new Error('Not in the cache: ' + path);
+ }
- // exec
- exec : function (path, info, cb) {
- if (isValidAbsPath(path)) {
- mount.exec.apply(mount, arguments);
+ if (node.getType() === TYPE_FILE) { // only for files
+ node.refreshMetadata(key);
+ } else {
+ var level;
+ if (options && 'level' in options) {
+ level = Math.floor(options.level);
+ } else {
+ throw new Error('Level must be given in the \'options\' argument');
+ }
+ node.refreshMetadata(level, key); //
+ }
} else {
- setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ throw new Error('The path "' + path + '" is not a valid path being cached');
}
},
- // exportZip
- exportZip : function (sourceArr/*, fileName*/) {
- if (sourceArr.every(function (src) { return isValidAbsPath(src); })) {
- mount.exportZip.apply(mount, arguments);
+ // convenience API: refresh all (hierarchy, file contents, and metadata)
+ refresh : function (path, options, cbWhenHierarchyDone) {
+ var opt = { level: 1 };
+ if (options) {
+ _.extend(opt, options);
}
+
+ var self = this;
+ this.refreshHierarchy(path, opt, function () {
+ if (cbWhenHierarchyDone) {
+ cbWhenHierarchyDone();
+ }
+
+ self.refreshFileContents(path, opt);
+ self.refreshMetadata(path, undefined/* every key */, opt);
+ });
},
- // exists
- exists : function (target, cb) {
- var ret = checkTargetPath(target);
- if (isError(ret)) {
- setTimeout(cb.bind(null, ret), 0);
- } else {
- var targetNode = ret;
- if (targetNode) {
- setTimeout(cb.bind(null, null, true), 0);
- } else if (targetNode === null) {
- setTimeout(cb.bind(null, null, false), 0);
- } else {
- //console.log('hina temp: exists goes to server');
- mount.exists(target, cb);
+ queryPaths : function (dirPath, condition) {
+ if (isValidAbsPath(dirPath) && pathUtil.isDirPath(dirPath) && withinCache(dirPath)) {
+ var dirNode = root.getByAbsPath(dirPath);
+ if (!dirNode) {
+ return null;
}
+
+ var nodeArr = [];
+ dirNode.collectNodes(nodeArr, condition);
+ return nodeArr.map(function (node) {
+ return node.getPath();
+ });
+
+ } else {
+ throw new Error('The path "' + dirPath +
+ '" does not represent a directory being cached');
}
},
- getAliasInfo : function () {
- mount.getAliasInfo.apply(mount, arguments);
- },
+ //---------------------------
+ // FS API wrapper - methods WITH update
+ //---------------------------
- // getMeta
- getMeta : function (target, key, cb) {
- var targetNode;
+ // copy
+ copy : function (src, dst, recursive, cb) {
- function checkValidGetMeta() {
- var ret = checkTargetPath(target, true, true);
+ var srcNode, dstNode;
+ function checkValidCopy() {
+ var ret = checkTargetPath(src, true, true);
if (isError(ret)) {
return ret;
}
- targetNode = ret;
+ srcNode = ret;
- return null;
- }
+ ret = checkTargetPath(dst, null);
+ if (isError(ret)) {
+ return ret;
+ }
+ dstNode = ret;
- function callback(err, val) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'getMeta request to server : ' + target);
- if (err) {
- cb(err);
- } else {
- if (targetNode) {
- targetNode.setMetadata(key, val, 'fetched');
- cb(null, val);
+ if (src === dst) {
+ return 'Source and destination paths are identical: ' + src + '.';
+ }
+
+ if (dst.indexOf(src + '/') === 0) {
+ return 'Cannot copy a directory into its descendant';
+ }
+
+ if (srcNode instanceof Directory && !recursive) {
+ return 'Copying a directory with recursive option unset is disallowed.';
+ }
+
+ var divided = pathUtil.dividePath(dst);
+ if (root.getByAbsPath(divided[0]) === null) {
+ return 'Destination directory "' + divided[0] + '" does not exist.';
+ }
+
+ return null;
+ }
+
+ function callback(err) {
+
+ function handleCopySuccess(isDir) {
+ console.assert(srcNode === root.getByAbsPath(src),
+ 'A source node has been modified during a ' +
+ 'copy request to server: ' + src);
+ console.assert(dstNode === root.getByAbsPath(dst),
+ 'A destination node has been modified during a ' +
+ 'copy request to server: ' + dst);
+
+ var t = dst + (isDir ? '/' : '');
+ var addedNodes = root.putByAbsPath(t, 'copied');
+ if (!addedNodes) { // because the target has been already present.
+ fsCache.refresh(t, { level: -1 });
+ }
+ cb(null);
+ }
+
+ if (err) {
+ /* TODO: continue 'serverless operations'
+ if (err === 'server unreachable' && srcNode && !dstNode) {
} else {
- mount.isDirectory(target, function (err, isDir) {
+ cb(err);
+ return;
+ }
+ */
+ cb(err);
+ } else {
+ if (srcNode) {
+ handleCopySuccess(srcNode instanceof Directory);
+ } else {
+ mount.isDirectory(dst, function (err, isDir) {
if (err) {
- console.error('Error in isDirectory call while getting metadata: ' + err);
+ cb(err);
} else {
- var added = root.putByAbsPath(
- (isDir ? pathUtil.attachSlash : pathUtil.detachSlash)(target), 'inferred');
- targetNode = added[added.length - 1];
- targetNode.setMetadata(key, val, 'fetched');
+ handleCopySuccess(isDir);
}
- cb(null, val);
});
-
}
}
}
- var ret = checkValidGetMeta(); //checkTargetPath(target, true, true);
- if (isError(ret)) {
- setTimeout(cb.bind(null, ret), 0);
+ if (typeof recursive === 'function') {
+ cb = recursive;
+ recursive = false; // false is default
+ }
+
+ src = pathUtil.detachSlash(src);
+ var err = checkValidCopy();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
} else {
- var val;
- if (targetNode === undefined ||
- (val = targetNode.metadata[key]) === undefined ||
- targetNode.metadataInvalidated[key]) {
- mount.getMeta(target, key, callback);
- } else {
- setTimeout(cb.bind(null, null, val), 0);
- }
+ mount.copy(src, dst, recursive, withinCache(dst) ? callback : cb);
}
},
- // isDirectory
- isDirectory : function (target, cb) {
- var targetNode;
- function callback(err, isDir) {
- console.assert(targetNode === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'isDirectory request to server : ' + target);
+ // move
+ move : function (src, dst, cb) {
+
+ var srcNode, dstNode;
+ function checkValidMove() {
+ var ret = checkTargetPath(src, true, true);
+ if (isError(ret)) {
+ return ret;
+ }
+ srcNode = ret;
+
+ ret = checkTargetPath(dst, null);
+ if (isError(ret)) {
+ return ret;
+ }
+ dstNode = ret;
+
+ if (src === dst) {
+ return 'Source and destination paths are identical: ' + src + '.';
+ }
+
+ if (dst.indexOf(src + '/') === 0) {
+ return 'Cannot move a directory into its descendant';
+ }
+
+ var divided = pathUtil.dividePath(dst);
+ if (root.getByAbsPath(divided[0]) === null) {
+ return 'Destination directory "' + divided[0] + '" does not exist.';
+ }
+
+ return null;
+ }
+
+ function callback(err) {
+ function handleMoveSuccess(isDir) {
+ console.assert(srcNode === root.getByAbsPath(src),
+ 'A source node has been modified ' +
+ 'duirng a move request to server: ' + src);
+ console.assert(dstNode === root.getByAbsPath(dst),
+ 'A destination node has been modified ' +
+ 'duirng a move request to server: ' + dst);
+
+ if (withinCache(dst)) {
+ var t = dst + (isDir ? '/' : '');
+ var addedNodes = root.putByAbsPath(t, 'moved');
+ if (!addedNodes) { // because the target has been already present.
+ fsCache.refresh(t, { level: -1 });
+ }
+ }
+ if (srcNode) {
+ srcNode.detach(withinCache(dst) ? dst : undefined);
+ }
+ cb(null);
+ }
+
if (err) {
cb(err);
} else {
- if (withinCache(target)) {
- console.assert(targetNode === undefined);
- var added = root.putByAbsPath(target + (isDir ? '/' : ''), 'inferred');
- targetNode = added && added[added.length - 1];
- console.assert(targetNode);
+ if (srcNode) {
+ handleMoveSuccess(srcNode instanceof Directory);
+ } else {
+ mount.isDirectory(dst, function (err, isDir) {
+ if (err) {
+ cb(err);
+ } else {
+ handleMoveSuccess(isDir);
+ }
+ });
}
- cb(null, isDir);
}
}
- target = pathUtil.detachSlash(target);
- var ret = checkTargetPath(target, true, true);
- if (isError(ret)) {
- setTimeout(cb.bind(null, ret), 0);
+ src = pathUtil.detachSlash(src);
+ var err = checkValidMove();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
} else {
- targetNode = ret;
- if (targetNode === undefined) {
- mount.isDirectory(target, callback);
- } else {
- console.assert(targetNode);
- setTimeout(cb.bind(null, null, targetNode instanceof Directory), 0);
- }
-
+ mount.move(src, dst, (srcNode || withinCache(dst)) ? callback : cb);
}
},
- // isEmpty
- isEmpty : function (target, cb) {
+ // createDirectory
+ createDirectory : function (target, recursive, cb) {
var targetNode;
- function checkValidIsEmpty() {
- var ret = checkTargetPath(target, true, true);
+ function checkValidCreateDirectory() {
+ var ret = checkTargetPath(target, false, true);
if (isError(ret)) {
return ret;
}
targetNode = ret;
- if (targetNode && !(targetNode instanceof Directory)) {
- return 'The path "' + target + '" does not represent a directory';
+ if (!recursive) {
+ var parentPath = pathUtil.dividePath(target)[0];
+ var parentNode = root.getByAbsPath(parentPath);
+ if (parentNode === null) {
+ return 'Parent directory "' + parentPath +
+ '" does not exist and the recursive option is not set.';
+ }
}
return null;
}
- function callback(err, isEmpty) {
+ function callback(err) {
console.assert(targetNode === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'isEmpty request to server : ' + target);
+ 'A target node has been modified during a ' +
+ 'createDirectory request to server: ' + target);
if (err) {
cb(err);
} else {
- if (withinCache(target)) {
- console.assert(targetNode === undefined);
- var added = root.putByAbsPath(target + '/', 'inferred');
- targetNode = added && added[added.length - 1];
- console.assert(targetNode);
- }
- cb(null, isEmpty);
+ root.putByAbsPath(target + '/', 'dir-created');
+ cb(null);
}
}
+ if (typeof recursive === 'function') {
+ cb = recursive;
+ recursive = false; // false is default
+ }
+
target = pathUtil.detachSlash(target);
- var err = checkValidIsEmpty();
+ var err = checkValidCreateDirectory();
if (err) {
setTimeout(cb.bind(null, err), 0);
} else {
- if (targetNode === undefined) {
- mount.isEmpty(target, callback);
- } else {
- console.assert(targetNode);
- var isEmptyLocal = targetNode.isEmpty();
- if (!isEmptyLocal || targetNode.fetchedSubnodes) {
- setTimeout(cb.bind(null, null, isEmptyLocal), 0);
- } else {
- mount.isEmpty(target, cb);
- }
- }
-
+ mount.createDirectory(target, recursive, withinCache(target) ? callback : cb);
}
},
- // isFile
- isFile : function (target, cb) {
+ createZip : function (sources, target, cb) {
var targetNode;
- function callback(err, isFile) {
+ function checkValidCreateZip() {
+ if (sources.some(function (path) { return !isValidAbsPath(path); })) {
+ return 'List of sources contains a path which is not a valid absolute path.';
+ }
+
+ var ret = checkTargetPath(target, false);
+ if (isError(ret)) {
+ return ret;
+ }
+ targetNode = ret;
+
+ return null;
+ }
+
+ function callback(err) {
console.assert(targetNode === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'isFile request to server : ' + target);
+ 'A target node has been modified during a ' +
+ 'createZip request to server: ' + target);
if (err) {
cb(err);
} else {
- if (withinCache(target)) {
- console.assert(targetNode === undefined);
- var added = root.putByAbsPath(target + (isFile ? '' : '/'), 'inferred');
- targetNode = added && added[added.length - 1];
- console.assert(targetNode);
- }
- cb(null, isFile);
+ root.putByAbsPath(target, 'zip-created');
+ cb(null);
}
}
- var ret = checkTargetPath(target, true);
- if (isError(ret)) {
- setTimeout(cb.bind(null, ret), 0);
+ var err = checkValidCreateZip();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
} else {
- targetNode = ret;
- if (targetNode === undefined) {
- mount.isFile(target, callback);
+ mount.createZip(sources, target, withinCache(target) ? callback : cb);
+ }
+ },
+
+ // delete
+ 'delete' : function (target, recursive, cb) {
+ var targetNode;
+ function callback(err) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'A target node has been modified duirng a ' +
+ 'delete request to server: ' + target);
+ if (err) {
+ cb(err);
} else {
- console.assert(targetNode);
- setTimeout(cb.bind(null, null, targetNode instanceof File), 0);
+ if (targetNode) {
+ targetNode.detach();
+ }
+ cb(null);
}
-
}
- },
- // list
- /*
- list : function (target, recursive, cb) {
if (typeof recursive === 'function') {
cb = recursive;
- recursive = false;
+ recursive = false; // false is default
}
- this.listEx(target, { recursive: recursive }, cb);
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ setTimeout(cb.bind(null, ret), 0);
+ } else {
+ targetNode = ret;
+ mount.delete(target, recursive, withinCache(target) ? callback : cb);
+ }
},
- */
- list : function (target, recursive, cb) {
- var node;
- function checkValidList() {
- var ret = checkTargetPath(target, true, true);
+ extractZip : function (source, target, cb) {
+ var sourceNode, targetNode;
+ function checkValidExtractZip() {
+ var ret = checkTargetPath(source, true);
if (isError(ret)) {
return ret;
}
- node = ret;
+ sourceNode = ret;
- if (node && !(node instanceof Directory)) {
- return 'The path "' + target + '" does not represent a directory.';
+ ret = checkTargetPath(target, false, true);
+ if (isError(ret)) {
+ return ret;
}
+ targetNode = ret;
return null;
}
- function callback0(err, subnodes) {
- console.assert(node === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'list request to server : ' + target);
- if (err) {
- cb(err);
- } else {
- node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
- node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
- node.fetchedSubnodes = true;
- cb(null, subnodes);
- node.listed = true;
- }
- }
-
- function callback1(err, subnodes) {
- console.assert(node === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'list request to server : ' + target);
+ function callback(err) {
+ console.assert(sourceNode === root.getByAbsPath(source),
+ 'A source node has been modified duirng a ' +
+ 'extractZip request to server: ' + source);
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'A target node has been modified duirng a ' +
+ 'extractZip request to server: ' + target);
if (err) {
cb(err);
} else {
- var added = root.putByAbsPath(target, 'inferred');
- node = added && added[added.length - 1];
- node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
- node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
- node.fetchedSubnodes = true;
- cb(null, subnodes);
- node.listed = true;
+ root.putByAbsPath(target + '/', 'zip-extracted');
+ cb(null);
}
}
- if (typeof recursive === 'function') {
- cb = recursive;
- recursive = false;
- }
-
- target = pathUtil.attachSlash(target);
- var err = checkValidList();
+ target = pathUtil.detachSlash(target);
+ var err = checkValidExtractZip();
if (err) {
setTimeout(cb.bind(null, err), 0);
} else {
- if (withinCache(target)) {
- if (node) {
- if (node.fetchedSubnodes && !recursive) {
- //console.log('hina temp: list from fs-cache: ' + target);
- setTimeout(cb.bind(null, null, node.list()), 0);
- node.listed = true;
- } else {
- //console.log('hina temp: list from server (case 0): ' + target);
- mount.list(target, recursive, callback0); // case 0
- }
- } else if (node === undefined) {
- //console.log('hina temp: list from server (case 1): ' + target);
- mount.list(target, recursive, callback1); // case 1
- } else {
- console.assert(false, 'Unreachable');
- }
- } else {
- //console.log('hina temp: list from server (case 2): ' + target);
- mount.list(target, recursive, cb);
- }
+ mount.extractZip(source, target, withinCache(target) ? callback : cb);
}
},
-
- // listEx
- listEx : function (target, options, cb) {
- var node;
- function checkValidListEx() {
- var ret = checkTargetPath(target, true, true);
+ _writeFile: function (target, data, cb) {
+ var file;
+ function checkValidWriteFile() {
+ var ret = checkTargetPath(target, undefined);
if (isError(ret)) {
return ret;
}
- node = ret;
-
- if (node && !(node instanceof Directory)) {
- return 'The path "' + target + '" does not represent a directory.';
- }
+ file = ret;
- if (options.dirOnly && options.fileOnly) {
- return 'Cannot simultaneously be dirOnly and fileOnly';
+ if (file && !(file instanceof File)) {
+ return 'The path "' + target + '" is not a path of a file';
}
return null;
}
- function callback(err, subnodes) {
- console.assert(node === root.getByAbsPath(target),
- 'Target node has been modified during a ' +
- 'list request to server : ' + target);
+ function callback(err) {
+ console.assert(file === root.getByAbsPath(target),
+ 'A target node has been modified duirng a ' +
+ 'writeFile request to server: ' + target);
if (err) {
cb(err);
} else {
- if (!node) {
- var added = root.putByAbsPath(target, 'inferred');
- node = added && added[added.length - 1];
+ if (!file) {
+ var added = root.putByAbsPath(target, 'file-written');
+ file = added[added.length - 1];
}
- node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
- node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
- node.fetchedSubnodes = true;
-
- if (options.dirOnly) {
- subnodes = subnodes.filter(isDir);
- } else if (options.fileOnly) {
- subnodes = subnodes.filter(isFile);
+ if (typeof data === 'string') {
+ file.setContent(data, 'written');
+ } else {
+ file.setContent(undefined, 'written');
}
- cb(null, subnodes);
- node.listed = true;
+ cb(null);
}
}
- if (typeof options === 'function') {
- cb = options;
- options = {};
- }
-
- target = pathUtil.attachSlash(target);
- var err = checkValidListEx();
+ var err = checkValidWriteFile();
if (err) {
setTimeout(cb.bind(null, err), 0);
} else {
- if (withinCache(target)) {
- if (node && node.fetchedSubnodes && !options.recursive) {
- //console.log('hina temp: list from fs-cache: ' + target);
- var subnodes = node.list();
- if (options.dirOnly) {
- subnodes = subnodes.filter(isDir);
- } else if (options.fileOnly) {
- subnodes = subnodes.filter(isFile);
- }
- setTimeout(cb.bind(null, null, subnodes), 0);
- node.listed = true;
- } else {
- //console.log('hina temp: list from server (inside cache): ' + target);
- // ignore dirOnly and fileOnly options.
- mount.listEx(target, { recursive: options.recursive }, callback); // case 0
- }
+ mount.writeFile(target, data, withinCache(target) ? callback : cb);
+ }
+ },
+
+ // writeFile
+ writeFile : function (target, data, cb) {
+ //console.log('writeFile('+target+', data, cb)');
+ var that = this;
+ var path, dir;
+ path = target.split(/[\\/]/);
+ path.pop();
+ dir = path.join('/');
+ this.isDirectory(dir, function (error, isDir) {
+ if (isDir === true) {
+ that._writeFile(target, data, cb);
} else {
- //console.log('hina temp: list from server (outside cache): ' + target);
- mount.listEx(target, options, cb);
+ //console.log('If dir not exists, create dir then write file');
+ that.createDirectory(dir, true, function (err) {
+ if (err) {
+ cb(err);
+ } else {
+ that._writeFile(target, data, cb);
+ }
+ });
}
- }
+ });
},
- // readFile
- readFile : function (target, responseType, cb) {
+ // setMeta
+ setMeta : function (target, key, val, cb) {
var targetNode;
- if (!cb) {
- cb = responseType;
- responseType = '';
- }
- function checkValidReadFile() {
- var ret = checkTargetPath(target, true);
+ function checkValidSetMeta() {
+ var ret = checkTargetPath(target, true, true);
if (isError(ret)) {
return ret;
}
targetNode = ret;
- if (targetNode && !(targetNode instanceof File)) {
- return 'The path "' + target + '" does not represent a file';
+ if (!key || typeof key !== 'string') {
+ return 'Key must be a non-empty string';
+ }
+
+ if (typeof val !== 'string') {
+ return 'Value must be a string';
}
return null;
}
- function callback(err, content) {
- var targetNodeAfter = root.getByAbsPath(target);
- console.assert(targetNode === targetNodeAfter,
- 'Target node has been modified during a ' +
- 'readFile request to server : ' + target +
- ', before(' + targetNode +
- '), after(' + targetNodeAfter + ')');
+ function callback(err) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'Target node has been modified during a request of ' +
+ 'setMeta to server:' + target);
if (err) {
cb(err);
} else {
- if (targetNode === undefined) {
- var added = root.putByAbsPath(target, 'inferred');
- targetNode = (added && added[added.length - 1]) || targetNodeAfter;
+ if (targetNode) {
+ targetNode.setMetadata(key, val, 'written');
+ cb(null);
+ } else {
+ mount.isDirectory(target, function (err, isDir) {
+ if (err) {
+ console.error('Error in isDirectory call while setting metadata: ' + err);
+ } else {
+ var added = root.putByAbsPath(
+ (isDir ? pathUtil.attachSlash : pathUtil.detachSlash)(target), 'inferred');
+ targetNode = added[added.length - 1];
+ targetNode.setMetadata(key, val, 'written');
+ }
+ cb(null);
+ });
}
- console.assert(targetNode);
-
- targetNode.setContent(content, 'fetched');
- cb(null, content);
}
}
- var err = checkValidReadFile();
+ var err = checkValidSetMeta();
if (err) {
setTimeout(cb.bind(null, err), 0);
} else {
- // FIXME: cache and compare responseType too
- if (withinCache(target)) {
- var content;
- if (targetNode === undefined ||
- (content = targetNode.content) === undefined ||
- targetNode.contentInvalidated) {
- mount.readFile(target, responseType, callback);
- } else {
- console.assert(content !== null);
- setTimeout(cb.bind(null, null, content), 0);
- }
- } else {
- mount.readFile(target, responseType, cb);
- }
+ mount.setMeta(target, key, val, callback);
}
},
- // searchFiles
- searchFiles : function (keyword, where, options, cb) {
- if (isValidAbsPath(where)) {
- mount.searchFiles.apply(mount, arguments);
+ lockFile: function (path, cb) {
+ if (isValidAbsPath(path)) {
+ mount.lockFile.apply(mount, arguments);
} else {
- setTimeout(cb.bind(null, 'The path "' + where + '" is not a valid absolute path'), 0);
+ setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
}
},
- // replaceFiles
- replaceFiles : function (keyword, replace, where, options, cb) {
- if (_.every(where, function (path) { return isValidAbsPath(path); })) {
- mount.replaceFiles.apply(mount, arguments);
+ unlockFile: function (path, cb) {
+ if (isValidAbsPath(path)) {
+ mount.unlockFile.apply(mount, arguments);
} else {
- setTimeout(cb.bind(null, 'The list of where contains a string which ' +
- 'is not a valid absolute path.'), 0);
+ setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
}
},
- // stat
- stat : function (pathList, cb) {
- if (pathList.every(function (path) { return isValidAbsPath(path); })) {
- mount.stat.apply(mount, arguments);
+ //---------------------------
+ // FS API wrapper - methods WITHOUT update
+ //---------------------------
+
+ getLockedFiles: function (path, cb) {
+ if (isValidAbsPath(path)) {
+ mount.getLockedFiles.apply(mount, arguments);
} else {
- setTimeout(cb.bind(null, 'The list of paths contains a string which ' +
- 'is not a valid absolute path.'), 0);
+ setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
}
- }
- });
- var fsCache;
-
- //*******************************
- // inner class of FSCacheInner: FSNode
- //*******************************
-
- var FSNode = declare(null, {
-
- constructor : function (parent, name) {
- this.parent = parent; // null iff this is the root node
- this.name = name;
- this.metadata = {};
- this.metadataInvalidated = {};
},
- setMetadata: function (key, value, caseStr) {
- var origValue = this.metadata[key];
- this.metadata[key] = value;
- this.metadataInvalidated[key] = false;
-
- var path = this.getPath();
- switch (caseStr) {
- case 'fetched':
- onMetadataFetched(path, key);
- break;
- case 'written':
- onMetadataSet(path, key, value !== origValue);
- break;
- case 'refreshed':
- onMetadataRefreshed(path, key);
- break;
- default:
- console.assert(false, 'Unreachable');
+ addAlias: function (path, expireTime, cb) {
+ if (isValidAbsPath(path)) {
+ mount.addAlias.apply(mount, arguments);
+ } else {
+ setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
}
},
- refreshMetadata: function (key) {
- var self = this;
- Object.keys(this.metadata).forEach(function (k) {
- if (key === undefined || key === k) {
- var origVal = self.metadata[k];
- var path = self.getPath();
- mount.getMeta(path, k, function (err, newVal) {
- if (err) {
- console.error('Cannot get metadata ' + k + ' of ' + path +
- ' from server: ' + err);
- } else {
- if (origVal !== newVal) {
- this.setMetadata(k, newVal, 'refreshed');
- }
- }
- });
- }
- });
+ // deleteAlias
+ deleteAlias : function () {
+ mount.deleteAlias.apply(mount, arguments);
},
- getParentPath : function () {
- return this.parent ? this.parent.getPath() : EMPTY_PATH;
+ // exec
+ exec : function (path, info, cb) {
+ if (isValidAbsPath(path)) {
+ mount.exec.apply(mount, arguments);
+ } else {
+ setTimeout(cb.bind(null, 'The path "' + path + '" is not a valid absolute path'), 0);
+ }
},
- getPath : function () {
- if (!this._path) {
- // memoize
- this._path = this.computePath();
+ // exportZip
+ exportZip : function (sourceArr/*, fileName*/) {
+ if (sourceArr.every(function (src) { return isValidAbsPath(src); })) {
+ mount.exportZip.apply(mount, arguments);
}
- return this._path;
},
- computePath : function () {
- return this.getParentPath() + this.name;
+ // exists
+ exists : function (target, cb) {
+ var ret = checkTargetPath(target);
+ if (isError(ret)) {
+ setTimeout(cb.bind(null, ret), 0);
+ } else {
+ var targetNode = ret;
+ if (targetNode) {
+ setTimeout(cb.bind(null, null, true), 0);
+ } else if (targetNode === null) {
+ setTimeout(cb.bind(null, null, false), 0);
+ } else {
+ //console.log('hina temp: exists goes to server');
+ mount.exists(target, cb);
+ }
+ }
},
- getType : function () {
- return TYPE_UNKNOWN;
+ getAliasInfo : function () {
+ mount.getAliasInfo.apply(mount, arguments);
},
- detach : function (movedTo) {
- if (this.parent) {
- var detached = this.parent.removeSubnode(this.name, movedTo);
- if (this !== detached) {
- throw new Error('Detached node is wrong.');
+ // getMeta
+ getMeta : function (target, key, cb) {
+ var targetNode;
+
+ function checkValidGetMeta() {
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ return ret;
}
- } else {
- throw new Error('Cannot detach the root node');
+ targetNode = ret;
+
+ return null;
}
- },
- satisfyingCond : function (cond) {
+ function callback(err, val) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'getMeta request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ if (targetNode) {
+ targetNode.setMetadata(key, val, 'fetched');
+ cb(null, val);
+ } else {
+ mount.isDirectory(target, function (err, isDir) {
+ if (err) {
+ console.error('Error in isDirectory call while getting metadata: ' + err);
+ } else {
+ var added = root.putByAbsPath(
+ (isDir ? pathUtil.attachSlash : pathUtil.detachSlash)(target), 'inferred');
+ targetNode = added[added.length - 1];
+ targetNode.setMetadata(key, val, 'fetched');
+ }
+ cb(null, val);
+ });
- if (cond.types) {
- if (cond.types.indexOf(this.getType()) < 0) {
- return false;
+ }
}
}
- return true;
- },
-
- collectNodes : function (arr, cond) {
- if (this.satisfyingCond(cond)) {
- arr.push(this);
+ var ret = checkValidGetMeta(); //checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ setTimeout(cb.bind(null, ret), 0);
+ } else {
+ var val;
+ if (targetNode === undefined ||
+ (val = targetNode.metadata[key]) === undefined ||
+ targetNode.metadataInvalidated[key]) {
+ mount.getMeta(target, key, callback);
+ } else {
+ setTimeout(cb.bind(null, null, val), 0);
+ }
}
},
- getListInfo : function () {
- return {
- name : this.name,
- isDirectory : this instanceof Directory,
- isFile : this instanceof File
- };
- },
-
- show : function (level) { // for debugging
- var arr = [];
- for (var i = 0; i < level; i++) {
- arr.push('| ');
- }
-
- arr.push(this.name);
- console.log(arr.join(''));
- },
-
- invalidateFileContents: function () {
- console.error('assertion fail: unreachable');
- },
-
- invalidateMetadata: function (key) {
- var keys = Object.keys(this.metadataInvalidated);
- var path = this.getPath();
- if (key === undefined) {
- keys.forEach(function (k) {
- if (this.metadata[k] !== undefined &&
- !this.metadataInvalidated[k]) {
- this.metadataInvalidated[k] = true;
- onMetadataInvalidated(path, k);
+ // isDirectory
+ isDirectory : function (target, cb) {
+ var targetNode;
+ function callback(err, isDir) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'isDirectory request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ if (withinCache(target)) {
+ console.assert(targetNode === undefined);
+ var added = root.putByAbsPath(target + (isDir ? '/' : ''), 'inferred');
+ targetNode = added && added[added.length - 1];
+ console.assert(targetNode);
}
- });
- } else if (keys.indexOf(key) >= 0) {
- if (this.metadata[key] !== undefined &&
- !this.metadataInvalidated[key]) {
- this.metadataInvalidated[key] = true;
- onMetadataInvalidated(path, key);
+ cb(null, isDir);
}
- } else {
- throw new Error('Metadata ' + key + ' is not set for "' +
- this.getPath() + '"');
}
- }
-
- });
-
- //*******************************
- // inner class of FSCacheInner: File
- //*******************************
- var File = declare(FSNode, {
- constructor : function (/*parent, name*/) {
- this.contentInvalidated = false;
- },
+ target = pathUtil.detachSlash(target);
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ setTimeout(cb.bind(null, ret), 0);
+ } else {
+ targetNode = ret;
+ if (targetNode === undefined) {
+ mount.isDirectory(target, callback);
+ } else {
+ console.assert(targetNode);
+ setTimeout(cb.bind(null, null, targetNode instanceof Directory), 0);
+ }
- invalidateFileContents: function () {
- if (this.content !== undefined && !this.contentInvalidated) {
- this.contentInvalidated = true;
- onFileInvalidated(this.getPath());
}
},
- refreshFileContents : function () {
+ // isEmpty
+ isEmpty : function (target, cb) {
+ var targetNode;
+ function checkValidIsEmpty() {
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ return ret;
+ }
+ targetNode = ret;
- // NOTE: refreshing contents is possible for invalidated contents too
+ if (targetNode && !(targetNode instanceof Directory)) {
+ return 'The path "' + target + '" does not represent a directory';
+ }
- var origContent = this.content;
- if (origContent !== undefined) {
- var path = this.getPath();
- var self = this;
- mount.readFile(path, function (err, newContent) {
- if (err) {
- console.log('Cannot get content of ' + path +
- ' from server. cannot refresh the file content (' +
- err + ')');
- } else {
- if (origContent !== newContent) {
- self.setContent(newContent, 'refreshed');
- }
+ return null;
+ }
+
+ function callback(err, isEmpty) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'isEmpty request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ if (withinCache(target)) {
+ console.assert(targetNode === undefined);
+ var added = root.putByAbsPath(target + '/', 'inferred');
+ targetNode = added && added[added.length - 1];
+ console.assert(targetNode);
}
- });
+ cb(null, isEmpty);
+ }
}
- },
- setContent : function (content, caseStr) {
- var origContent = this.content;
- this.content = content;
- this.contentInvalidated = false;
+ target = pathUtil.detachSlash(target);
+ var err = checkValidIsEmpty();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
+ } else {
+ if (targetNode === undefined) {
+ mount.isEmpty(target, callback);
+ } else {
+ console.assert(targetNode);
+ var isEmptyLocal = targetNode.isEmpty();
+ if (!isEmptyLocal || targetNode.fetchedSubnodes) {
+ setTimeout(cb.bind(null, null, isEmptyLocal), 0);
+ } else {
+ mount.isEmpty(target, cb);
+ }
+ }
- var path = this.getPath();
- switch (caseStr) {
- case 'fetched':
- onFileFetched(path);
- break;
- case 'written':
- onFileWritten(path, content === undefined || content !== origContent);
- break;
- case 'refreshed':
- onFileRefreshed(path);
- break;
- default:
- console.assert(false, 'Unreachable');
}
},
- getType : function () {
- return TYPE_FILE;
- },
-
- getSummary : function () {
- return this.name;
- }
- });
+ // isFile
+ isFile : function (target, cb) {
+ var targetNode;
+ function callback(err, isFile) {
+ console.assert(targetNode === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'isFile request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ if (withinCache(target)) {
+ console.assert(targetNode === undefined);
+ var added = root.putByAbsPath(target + (isFile ? '' : '/'), 'inferred');
+ targetNode = added && added[added.length - 1];
+ console.assert(targetNode);
+ }
+ cb(null, isFile);
+ }
+ }
- //*******************************
- // inner class of FSCacheInner: Directory
- //*******************************
+ var ret = checkTargetPath(target, true);
+ if (isError(ret)) {
+ setTimeout(cb.bind(null, ret), 0);
+ } else {
+ targetNode = ret;
+ if (targetNode === undefined) {
+ mount.isFile(target, callback);
+ } else {
+ console.assert(targetNode);
+ setTimeout(cb.bind(null, null, targetNode instanceof File), 0);
+ }
- var Directory = declare(FSNode, {
- constructor : function (/*parent, name*/) {
- this.dirs = new SortedArray('name');
- this.files = new SortedArray('name');
+ }
},
- invalidateFileContents: function () {
- this.dirs.forEach(function (dir) {
- dir.invalidateFileContents();
- });
- this.files.forEach(function (file) {
- file.invalidateFileContents();
- });
- },
+ // list
+ /*
+ list : function (target, recursive, cb) {
+ if (typeof recursive === 'function') {
+ cb = recursive;
+ recursive = false;
+ }
- invalidateMetadata: function (key) {
- FSNode.prototype.invalidateMetadata.call(this, key);
- this.dirs.forEach(function (dir) {
- dir.invalidateMetadata(key);
- });
- this.files.forEach(function (file) {
- file.invalidateMetadata(key);
- });
+ this.listEx(target, { recursive: recursive }, cb);
},
+ */
- refreshFileContents : function (level) {
- if (typeof level !== 'number') { // TODO: remove this check when stabilized
- throw new Error('assertion fail: unrechable');
- }
+ list : function (target, recursive, cb) {
+ var node;
+ function checkValidList() {
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ return ret;
+ }
+ node = ret;
- if (level) {
- this.dirs.forEach(function (dir) {
- dir.refreshFileContents(level - 1);
- });
- this.files.forEach(function (file) {
- file.refreshFileContents();
- });
- }
- },
+ if (node && !(node instanceof Directory)) {
+ return 'The path "' + target + '" does not represent a directory.';
+ }
- refreshMetadata: function (level, key) {
- if (typeof level !== 'number') { // TODO: remove this check when stabilized
- throw new Error('assertion fail: unrechable');
+ return null;
}
- FSNode.prototype.refreshMetadata.call(this, key);
- if (level) {
- this.dirs.forEach(function (dir) {
- dir.refreshMetadata(level - 1, key);
- });
- this.files.forEach(function (file) {
- file.refreshMetadata(key);
- });
- }
- },
+ function callback0(err, subnodes) {
+ console.assert(node === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'list request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
+ node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
+ node.fetchedSubnodes = true;
+ cb(null, subnodes);
+ node.listed = true;
+ }
+ }
- computePath : function () {
- return this.getParentPath() + this.name + '/';
- },
+ function callback1(err, subnodes) {
+ console.assert(node === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'list request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ var added = root.putByAbsPath(target, 'inferred');
+ node = added && added[added.length - 1];
+ node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
+ node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
+ node.fetchedSubnodes = true;
+ cb(null, subnodes);
+ node.listed = true;
+ }
+ }
- putByRelPath : function (relPath, caseStr) {
- console.assert(relPath,
- 'Directory.putByRelPath() was called with a falsy argument');
+ if (typeof recursive === 'function') {
+ cb = recursive;
+ recursive = false;
+ }
- var i = relPath.indexOf('/');
- if (i < 0) {
- // base case
- var file = this.putSubnode(relPath, false, caseStr);
- return (file ? [file] : null);
- } else {
- console.assert(i > 0, 'i must be a positive integer');
- var subdirName = relPath.substring(0, i);
- var subdir = this.putSubnode(subdirName, true, caseStr);
- var nextPath = relPath.substr(i + 1);
- if (nextPath) {
- if (subdir) {
- // newly added
- var addedArr = subdir.putByRelPath(nextPath, caseStr);
- addedArr.unshift(subdir);
- return addedArr;
+ target = pathUtil.attachSlash(target);
+ var err = checkValidList();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
+ } else {
+ if (withinCache(target)) {
+ if (node) {
+ if (node.fetchedSubnodes && !recursive) {
+ //console.log('hina temp: list from fs-cache: ' + target);
+ setTimeout(cb.bind(null, null, node.list()), 0);
+ node.listed = true;
+ } else {
+ //console.log('hina temp: list from server (case 0): ' + target);
+ mount.list(target, recursive, callback0); // case 0
+ }
+ } else if (node === undefined) {
+ //console.log('hina temp: list from server (case 1): ' + target);
+ mount.list(target, recursive, callback1); // case 1
} else {
- // already there
- subdir = this.getSubnode(subdirName);
- return subdir.putByRelPath(nextPath, caseStr);
+ console.assert(false, 'Unreachable');
}
} else {
- // base case
- return (subdir ? [subdir] : null);
+ //console.log('hina temp: list from server (case 2): ' + target);
+ mount.list(target, recursive, cb);
}
}
},
- // If a subnode exists with that name and type, then do nothing and return null.
- // Otherwise, create the subnode, add it, and return the added subnode.
- putSubnode : function (name, isDir, caseStr) {
- console.assert(name);
- console.assert(name.indexOf('/') === -1);
- var subnode = this.getSubnode(name);
- if (subnode && (subnode.isInstanceOf(Directory) === isDir)) {
- return null;
- } else {
- if (subnode) {
- console.warn('A subnode with the same name "' + name +
- '" but with different type was detected while putting a ' +
- (isDir ? 'directory' : 'file') + ' to "' +
- this.getPath() + '"');
- return null;
- } else {
- var added = this.addSubnode(name, isDir, caseStr);
- return added;
+ // listEx
+ listEx : function (target, options, cb) {
+ var node;
+ function checkValidListEx() {
+ var ret = checkTargetPath(target, true, true);
+ if (isError(ret)) {
+ return ret;
}
- }
- },
+ node = ret;
- addSubnode : function (name, isDir, caseStr) {
- if (this.getSubnode(name)) { // TODO: remove this check if code is stabilized
- console.error('Unreachable: Cannot overwrite existing subnode ' + name +
- ' of ' + this.getPath() + ' by addSubnode()');
- throw new Error('Unreachable: Cannot overwrite existing subnode ' + name +
- ' of ' + this.getPath() + ' by addSubnode()');
- } else {
- var C = isDir ? Directory : File;
- var subnode = new C(this, name);
- if (isDir) {
- this.dirs.add(subnode);
- } else {
- this.files.add(subnode);
+ if (node && !(node instanceof Directory)) {
+ return 'The path "' + target + '" does not represent a directory.';
}
- var maybeCreated;
- switch (caseStr) {
- case 'cache-root':
- case 'inferred':
- case 'fetched':
- case 'restored':
- maybeCreated = false;
- break;
- case 'copied':
- case 'moved':
- case 'dir-created':
- case 'zip-created':
- case 'zip-extracted':
- case 'file-written':
- case 'refreshed':
- maybeCreated = true;
- break;
- default:
- console.assert(false, 'Unreachable');
+ if (options.dirOnly && options.fileOnly) {
+ return 'Cannot simultaneously be dirOnly and fileOnly';
}
- onNodeAdded(this.getPath(), name, subnode.getType(), maybeCreated, caseStr === 'moved');
+ return null;
+ }
- return subnode;
+ function callback(err, subnodes) {
+ console.assert(node === root.getByAbsPath(target),
+ 'Target node has been modified during a ' +
+ 'list request to server : ' + target);
+ if (err) {
+ cb(err);
+ } else {
+ if (!node) {
+ var added = root.putByAbsPath(target, 'inferred');
+ node = added && added[added.length - 1];
+ }
+ node.updateSubnodes(subnodes.filter(isDir), true, 'fetched');
+ node.updateSubnodes(subnodes.filter(isFile), false, 'fetched');
+ node.fetchedSubnodes = true;
+
+ if (options.dirOnly) {
+ subnodes = subnodes.filter(isDir);
+ } else if (options.fileOnly) {
+ subnodes = subnodes.filter(isFile);
+ }
+ cb(null, subnodes);
+ node.listed = true;
+ }
}
- },
- getByRelPath: function (relPath) {
- //console.log('hina temp: relPath = ' + relPath);
- console.assert(relPath,
- 'Directory.getByRelPath() was called ' +
- 'with falsy argument');
+ if (typeof options === 'function') {
+ cb = options;
+ options = {};
+ }
- var i = relPath.indexOf('/');
- if (i < 0) {
- return this.getSubnode(relPath);
+ target = pathUtil.attachSlash(target);
+ var err = checkValidListEx();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
} else {
- console.assert(i > 0,
- 'Directory.getByRelPath() was called ' +
- 'with an absolute path: ' + relPath);
- var nextPath;
- var subnodeName = relPath.substring(0, i);
- var subnode = this.getSubnode(subnodeName);
- if (subnode) {
- nextPath = relPath.substr(i + 1);
- if (nextPath) {
- if (subnode instanceof Directory) {
- return subnode.getByRelPath(nextPath);
- } else {
- return null;
+ if (withinCache(target)) {
+ if (node && node.fetchedSubnodes && !options.recursive) {
+ //console.log('hina temp: list from fs-cache: ' + target);
+ var subnodes = node.list();
+ if (options.dirOnly) {
+ subnodes = subnodes.filter(isDir);
+ } else if (options.fileOnly) {
+ subnodes = subnodes.filter(isFile);
}
+ setTimeout(cb.bind(null, null, subnodes), 0);
+ node.listed = true;
} else {
- return subnode;
+ //console.log('hina temp: list from server (inside cache): ' + target);
+ // ignore dirOnly and fileOnly options.
+ mount.listEx(target, { recursive: options.recursive }, callback); // case 0
}
} else {
- return subnode;
+ //console.log('hina temp: list from server (outside cache): ' + target);
+ mount.listEx(target, options, cb);
}
}
},
- getSubnode : function (name) {
- var queried = { name: name };
- var ret = this.dirs.query(queried) || this.files.query(queried);
- if (ret) {
- return ret;
- } else {
- return this.fetchedSubnodes ? null : undefined;
+ // readFile
+ readFile : function (target, responseType, cb) {
+ var targetNode;
+ if (!cb) {
+ cb = responseType;
+ responseType = '';
}
- },
+ function checkValidReadFile() {
+ var ret = checkTargetPath(target, true);
+ if (isError(ret)) {
+ return ret;
+ }
+ targetNode = ret;
- removeSubnode : function (name, movedTo) {
- var ret = this.getSubnode(name);
- if (ret) {
- var isDir = ret instanceof Directory;
- var arr = isDir ? this.dirs : this.files;
- var i = arr.indexOf(ret);
- Array.prototype.splice.call(arr, i, 1);
+ if (targetNode && !(targetNode instanceof File)) {
+ return 'The path "' + target + '" does not represent a file';
+ }
- onNodeDeleted(this.getPath(), name, ret.getType(), movedTo);
+ return null;
}
- return ret;
- },
- getType : function () {
- return TYPE_DIRECTORY;
- },
-
- isEmpty : function () {
- return (this.dirs.length === 0) && (this.files.length === 0);
- },
-
- updateSubnodes : function (stats, isDir, caseStr) {
- var subnodes = isDir ? this.dirs : this.files;
- var names = subnodes.map(getName);
- var newNames = stats.map(getName);
-
- //console.log('hina temp: names = ' + names);
- //console.log('hina temp: newNames = ' + newNames);
- var toAdd = _.difference(newNames, names);
- var toDel = _.difference(names, newNames);
- //console.log('hina temp: toAdd = ' + toAdd);
- //console.log('hina temp: toDel = ' + toDel);
- var self = this;
- toDel.forEach(function (name) {
- self.removeSubnode(name);
- });
- toAdd.forEach(function (name) {
- self.addSubnode(name, isDir, caseStr);
- });
- },
-
- // refresh hierarchy level by level
- refreshHierarchy : function (level, doWhenAllDone) {
- //console.log('hina temp: entering refreshHierarchy dirPath = ' + this.getPath());
-
- // NOTE: getByAbsPath() must be invoked on the root.
- // Nodes (except for the root) can be detached at any time during an
- // asynchronous method call.
-
- if (level && this.fetchedSubnodes) {
- var dirPath = this.getPath();
- var self = this;
- mount.list(dirPath, false, function (err, stats) {
-
- var subnodeTypesDone = 0;
- function oneTypeDone() {
- subnodeTypesDone++;
- //console.log('hina temp: oneTypeDone for ' + dirPath + ' ' + subnodeTypesDone + ' time ');
- if (subnodeTypesDone === 2) { // two types (dirs and files)
- //console.log('hina temp: ' + dirPath + ' is done');
- doWhenAllDone();
- }
+ function callback(err, content) {
+ var targetNodeAfter = root.getByAbsPath(target);
+ console.assert(targetNode === targetNodeAfter,
+ 'Target node has been modified during a ' +
+ 'readFile request to server : ' + target +
+ ', before(' + targetNode +
+ '), after(' + targetNodeAfter + ')');
+ if (err) {
+ cb(err);
+ } else {
+ if (targetNode === undefined) {
+ var added = root.putByAbsPath(target, 'inferred');
+ targetNode = (added && added[added.length - 1]) || targetNodeAfter;
}
+ console.assert(targetNode);
- if (err) {
- console.warn('Error: FileSystem.list failed while refreshing "' +
- dirPath + '" (' + err + ')');
- doWhenAllDone();
- } else {
- var newDirs = stats.filter(isDir);
- self.updateSubnodes(newDirs, true, 'refreshed');
-
- var subdirsToRefresh = self.dirs.length;
- var subdirsRefreshed = 0;
- if (subdirsToRefresh) {
- self.dirs.forEach(function (dir) {
- dir.refreshHierarchy(level - 1, function () {
- subdirsRefreshed++;
- if (subdirsRefreshed === subdirsToRefresh) {
- //console.log('hina temp: subdirs of ' + dirPath + ' are done');
- oneTypeDone();
- }
- });
- });
- } else {
- oneTypeDone();
- }
-
- var newFiles = stats.filter(isFile);
- self.updateSubnodes(newFiles, false, 'refreshed');
- oneTypeDone();
- }
- });
- } else {
- doWhenAllDone();
+ targetNode.setContent(content, 'fetched');
+ cb(null, content);
+ }
}
-
- },
-
- collectNodes : function (arr, cond) {
- FSNode.prototype.collectNodes.call(this, arr, cond); // super call
- this.dirs.forEach(function (dir) {
- dir.collectNodes(arr, cond);
- });
- this.files.forEach(function (file) {
- file.collectNodes(arr, cond);
- });
- },
-
- list : function () {
- if (this.fetchedSubnodes) {
- var arr = [];
-
- this.dirs.forEach(function (subnode) {
- arr.push(subnode.getListInfo());
- });
-
- this.files.forEach(function (subnode) {
- arr.push(subnode.getListInfo());
- });
-
- return arr;
+ var err = checkValidReadFile();
+ if (err) {
+ setTimeout(cb.bind(null, err), 0);
} else {
- console.error('Unreachable: list should not be called on ' +
- 'a node which has never fetched subnodes: ' + this.getPath());
- throw new Error('Unreachable: list should not be called on ' +
- 'a node which has never fetched subnodes: ' + this.getPath());
- }
- },
-
- show : function (level) { // for debugging
- var arr = [];
- for (var i = 0; i < level; i++) {
- arr.push('| ');
+ // FIXME: cache and compare responseType too
+ if (withinCache(target)) {
+ var content;
+ if (targetNode === undefined ||
+ (content = targetNode.content) === undefined ||
+ targetNode.contentInvalidated) {
+ mount.readFile(target, responseType, callback);
+ } else {
+ console.assert(content !== null);
+ setTimeout(cb.bind(null, null, content), 0);
+ }
+ } else {
+ mount.readFile(target, responseType, cb);
+ }
}
- arr.push(this.name + '/');
- console.log(arr.join(''));
-
- this.dirs.forEach(function (subdir) {
- subdir.show(level + 1);
- });
-
- this.files.forEach(function (subdir) {
- subdir.show(level + 1);
- });
},
- getSummary : function () {
- var subSummaries;
- if (this.listed || !withinCache(this.getPath())) {
- subSummaries = [];
- this.dirs.forEach(function (dir) {
- var val = dir.getSummary();
- console.assert(typeof val === 'object',
- 'Summary of a subdir must be an object');
- subSummaries.push(val);
- });
- this.files.forEach(function (file) {
- var val = file.getSummary();
- console.assert(typeof val === 'string',
- 'Summary of a file must be a string');
- subSummaries.push(val);
- });
+ // searchFiles
+ searchFiles : function (keyword, where, options, cb) {
+ if (isValidAbsPath(where)) {
+ mount.searchFiles.apply(mount, arguments);
} else {
- subSummaries = null;
+ setTimeout(cb.bind(null, 'The path "' + where + '" is not a valid absolute path'), 0);
}
+ },
- if (this.name) {
- return { n: this.name, s: subSummaries };
+ // replaceFiles
+ replaceFiles : function (keyword, replace, where, options, cb) {
+ if (_.every(where, function (path) { return isValidAbsPath(path); })) {
+ mount.replaceFiles.apply(mount, arguments);
} else {
- // only root can reach here
- return subSummaries;
+ setTimeout(cb.bind(null, 'The list of where contains a string which ' +
+ 'is not a valid absolute path.'), 0);
}
},
- restoreFromSummary : function (subSummaries) {
- if (subSummaries) {
- console.assert(subSummaries instanceof Array,
- 'SubSummaries must be an array');
-
- var self = this;
- subSummaries.forEach(function (summary) {
- var type = typeof summary;
- if (type === 'object') {
- var added = self.addSubnode(summary.n, true, 'restored');
- added.restoreFromSummary(summary.s);
- } else if (type === 'string') {
- self.addSubnode(summary, false, 'restored');
- } else {
- console.assert(false,
- 'Summary must be an object or string');
- }
- });
- this.fetchedSubnodes = true;
+ // stat
+ stat : function (pathList, cb) {
+ if (pathList.every(function (path) { return isValidAbsPath(path); })) {
+ mount.stat.apply(mount, arguments);
+ } else {
+ setTimeout(cb.bind(null, 'The list of paths contains a string which ' +
+ 'is not a valid absolute path.'), 0);
}
}
});
-
- //---------------------------
- //---------------------------
- // private methods of FSCacheInner
- //---------------------------
- //---------------------------
-
- //---------------------------
- // utility functions
- //---------------------------
-
- function parseWFSURL(fsURL) {
- var uri = new URI(fsURL);
- var ret = {
- fsServer: uri.host(),
- fsid: uri.segment(0)
- };
- uri.segment(0, ''); // drop the fsid
- ret.path = uri.path(true);
-
- return ret;
- }
- function subscribeToNotificationsOnFS(fsCache) {
- function isIgnoredNotification(data, checkedURLs) {
- // ignore changed caused by myself
- var mySessionID = webida.auth.getSessionID();
- if (!data.sid) {
- console.error('The session id of a notification is unknown');
- return true;
- }
-
- if (mySessionID === data.sid) {
- console.log('notification ignored: changes by the current app');
- return true;
- }
-
- if (checkedURLs.every(function (url) { return !withinCache(data[url]); })) {
- console.log('notification ignored: changes outside cache');
- return true;
- }
-
- return false;
- }
-
- topic.subscribe('sys.fs.file.written', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
-
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- // file created
- if (existing === null) {
- root.putByAbsPath(urlParsed.path, 'file-written');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.written] for "' +
- urlParsed.path + '" (as a file creation)');
- topic.publish('#REQUEST.log', '');
- }
- } else if (existing.getType() === TYPE_FILE) {
- // file written
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.written] for "' +
- urlParsed.path + '" (as a file cache invalidation)');
- topic.publish('#REQUEST.log', '');
- } else {
- console.error('sys.fs.file.written arrived for a non-file "' +
- urlParsed.path + '"');
- }
-
- });
- topic.subscribe('sys.fs.file.deleted', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
-
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.file.deleted arrived for an absent file "' +
- urlParsed.path + '"');
- }
- } else if (existing.getType() === TYPE_FILE) {
- existing.detach();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.file.deleted] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- } else {
- console.error('sys.fs.file.deleted arrived for a non-file "' +
- urlParsed.path + '"');
- }
-
- });
- topic.subscribe('sys.fs.dir.created', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
-
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- root.putByAbsPath(pathUtil.attachSlash(urlParsed.path), 'dir-created');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.dir.created] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- } else if (existing.getType() === TYPE_DIRECTORY) {
- console.error('sys.fs.dir.created arrived for an existing directory "' +
- urlParsed.path + '"');
- } else {
- console.error('sys.fs.dir.created arrived for a non-directory "' +
- urlParsed.path + '"');
- }
- });
- topic.subscribe('sys.fs.dir.deleted', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
-
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.dir.deleted arrived for an absent directory "' +
- urlParsed.path + '"');
- }
- } else if (existing.getType() === TYPE_DIRECTORY) {
- existing.detach();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.dir.deleted] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- } else {
- console.error('sys.fs.dir.deleted arrived for a non-directory "' +
- urlParsed.path + '"');
- }
- });
- topic.subscribe('sys.fs.node.intractableChanges', function (data) {
- if (isIgnoredNotification(data, ['url'])) {
- return;
- }
-
- var urlParsed = parseWFSURL(data.url);
- var existing = root.getByAbsPath(urlParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.dir.intractableChanges arrived for an absent directory "' +
- urlParsed.path + '"');
- }
- } else if (existing.getType() === TYPE_DIRECTORY) {
- fsCache.refresh(urlParsed.path, { level: -1 }, function () {
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.intractableChanges] for "' +
- urlParsed.path + '"');
- topic.publish('#REQUEST.log', '');
-
- onNodeChanges(urlParsed.path);
- });
- } else {
- console.error('sys.fs.dir.intractable-changes arrived for a non-directory "' +
- urlParsed.path + '"');
- }
-
- });
- topic.subscribe('sys.fs.node.moved', function (data) {
- if (isIgnoredNotification(data, ['srcURL', 'dstURL'])) {
- return;
- }
-
- var dstURLParsed;
- if (withinCache(data.dstURL)) {
- dstURLParsed = parseWFSURL(data.dstURL);
- mount.isDirectory(dstURLParsed.path, function (err, isDir) {
- if (err) {
- console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
- '" of a notification sys.fs.node.moved is a directory or not: ' + err);
- console.log('The notification is ignored.');
- } else {
- var existing = root.getByAbsPath(dstURLParsed.path);
- if (existing) {
- if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
- if (isDir) {
- console.error('sys.fs.node.moved arraived for an existing "' +
- dstURLParsed.path + '" as its destination');
- } else {
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] ' +
- 'for its overwritten target file "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- } else {
- console.error('The type of the destination of a notification sys.fs.node.moved ' +
- 'does not match that of the corresponding node in the fs-cache for "' +
- dstURLParsed.path + '"');
- }
- } else {
- if (existing === null) {
- root.putByAbsPath((isDir ?
- pathUtil.attachSlash :
- pathUtil.detachSlash)(dstURLParsed.path),
- 'moved');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] for its target "' +
- dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- }
- }
- });
- }
-
- if (withinCache(data.srcURL)) {
- var srcURLParsed = parseWFSURL(data.srcURL);
- var existing = root.getByAbsPath(srcURLParsed.path);
- if (!existing) {
- if (existing === null) {
- console.error('sys.fs.node.moved arrived for an absent "' +
- srcURLParsed.path + '" as its source');
- }
- } else {
- existing.detach(withinCache(data.dstURL) ? dstURLParsed.path : undefined);
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.moved] for its source "' +
- srcURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- }
-
- // TODO: need to publish fs.cache.node.moved?
- // But the topic does not support the case when the source is out of the current file system.
- });
- topic.subscribe('sys.fs.node.copied', function (data) {
- if (isIgnoredNotification(data, ['dstURL'])) {
- return;
- }
-
- var existing;
- var dstURLParsed = parseWFSURL(data.dstURL);
- if (withinCache(dstURLParsed.path)) {
- mount.isDirectory(dstURLParsed.path, function (err, isDir) {
- if (err) {
- console.log('Cannot figure out whether the destination "' + dstURLParsed.path +
- '" of a notification sys.fs.node.copied is a directory or not: ' + err);
- console.log('The notification is ignored.');
- } else {
- existing = root.getByAbsPath(dstURLParsed.path);
- if (existing) {
- if ((existing.getType() === TYPE_DIRECTORY) === isDir) {
- if (isDir) {
- fsCache.refresh(dstURLParsed.path, { level: -1 });
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its merged target directory "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- } else {
- existing.invalidateFileContents();
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its overwritten target file "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- } else {
- console.error('The type of the destination of a notification sys.fs.node.copied ' +
- 'does not match that of the corresponding node in the fs-cache for "' +
- dstURLParsed.path + '"');
- }
- } else {
- if (existing === null) {
- root.putByAbsPath((isDir ?
- pathUtil.attachSlash :
- pathUtil.detachSlash)(dstURLParsed.path),
- 'copied');
- topic.publish('#REQUEST.log',
- 'Handled a notification [sys.fs.node.copied] ' +
- 'for its target "' + dstURLParsed.path + '"');
- topic.publish('#REQUEST.log', '');
- }
- }
- }
- });
- }
-
- // TODO: need to publish fs.cache.node.copied?
- // But the topic does not support the case when the source is out of the current file system.
- });
- }
-
- function withinCache(path) {
- if (path.indexOf('wfs://') === 0) {
- // path is given in Webida File System URL
- var pathParsed = parseWFSURL(path);
- if (fsURLParsed.fsServer !== pathParsed.fsServer ||
- fsURLParsed.fsid !== pathParsed.fsid) {
- return false;
- }
- path = pathParsed.path;
- }
- return dirsToCache.some(function (cached) { return path.indexOf(cached) === 0; });
- }
- function getName(obj) { return obj.name; }
- function isDir(stat) { return stat.isDirectory; }
- function isFile(stat) { return stat.isFile; }
- function checkTargetPath(path, exists, allowsDirPath) {
- if (!isValidAbsPath(path)) {
- return 'The path "' + path + '" is not a valid absolute path';
- }
-
- var node = root.getByAbsPath(path);
- if (typeof exists === 'boolean') {
- if ((exists && node === null) || (!exists && node)) {
- return 'The path "' + path + '" must be ' + (exists ? 'present' : 'absent');
- }
- }
-
- if (!allowsDirPath && pathUtil.isDirPath(path)) {
- return 'The path "' + path + '" ends with a slash, which is disallowed';
- }
-
- return node;
- }
-
- //---------------------------
- //---------------------------
- // end of private methods of FSCacheInner
- //---------------------------
- //---------------------------
-
-
//---------------------------
//---------------------------
// private methods of FSCacheInner
From 573ada78f95b34177e555dfd9dc249952b6d072f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 17 Jun 2016 16:30:23 +0900
Subject: [PATCH 09/15] last fixing on FSCache
- added jshint directives to set latedef = false
---
common/src/webida/FSCache-0.1.js | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/common/src/webida/FSCache-0.1.js b/common/src/webida/FSCache-0.1.js
index ea802561..32bfb86d 100644
--- a/common/src/webida/FSCache-0.1.js
+++ b/common/src/webida/FSCache-0.1.js
@@ -50,6 +50,8 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
var TYPE_DIRECTORY = 'dir';
var TYPE_UNKNOWN = 'unknown';
+ // due to cyclc dependencies among FSNode/File/Directory class
+ /*jshint latedef: false */
function FSCache(fsURLArg, dirsToCacheArg) {
//*******************************
@@ -689,7 +691,6 @@ function (webida, SortedArray, pathUtil, _, URI, declare, topic) {
}
});
-
var FSCacheInner = declare(null, {
constructor : function () {
From 81d3c96523ca64bfcb73a046f835ca2586f5bd3a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Wed, 22 Jun 2016 16:00:12 +0900
Subject: [PATCH 10/15] implemented access token refreshing logic
- reflect API changes, including login & issueToken
- new class, TokenManager has been introduced
- added APL license for each source file, except generated sources
(we will move the sources into separated project to use with bower)
- now, ready to implement pubsub messaging events
---
.eslintrc => .eslintrc_reserved | 0
common/src/webida/server-api-0.1-lib/Stats.js | 25 ++-
.../webida/server-api-0.1-lib/TokenManager.js | 159 ++++++++++++++++++
.../src/webida/server-api-0.1-lib/WfsEntry.js | 46 ++++-
.../src/webida/server-api-0.1-lib/WfsMount.js | 60 ++++---
common/src/webida/server-api-0.1-lib/auth.js | 100 +++++++----
.../src/webida/server-api-0.1-lib/common.js | 80 ++++-----
common/src/webida/server-api-0.1-lib/fs.js | 23 ++-
.../webida-service-api-0.1/.jshintignore | 2 +-
.../webida-service-api-0.1/README.md | 15 +-
.../docs/AccessToken.md | 9 -
.../webida-service-api-0.1/docs/AuthApi.md | 79 ++-------
.../webida-service-api-0.1/docs/Credential.md | 10 ++
.../docs/ExecAsyncResponse.md | 10 --
.../docs/ExecRequest.md | 11 +-
.../docs/ExecResponse.md | 6 +-
.../docs/LoginRequest.md | 10 --
.../docs/LoginResponse.md | 11 --
.../docs/MasterToken.md | 8 -
.../webida-service-api-0.1/docs/Session.md | 6 +-
.../webida-service-api-0.1/docs/SessionApi.md | 15 +-
.../webida-service-api-0.1/docs/Token.md | 5 +-
.../webida-service-api-0.1/docs/WfsApi.md | 2 +-
.../webida-service-api-0.1/docs/Workspace.md | 5 +-
.../docs/WorkspaceApi.md | 18 +-
.../webida-service-api-0.1/src/api/AuthApi.js | 76 ++-------
.../src/api/SessionApi.js | 29 ++--
.../webida-service-api-0.1/src/api/WfsApi.js | 2 +-
.../src/api/WorkspaceApi.js | 22 ++-
.../webida-service-api-0.1/src/index.js | 32 +---
.../src/model/AccessToken.js | 85 ----------
.../model/{LoginRequest.js => Credential.js} | 19 ++-
.../src/model/ExecAsyncResponse.js | 90 ----------
.../src/model/ExecRequest.js | 35 ++--
.../src/model/ExecResponse.js | 8 +-
.../src/model/LoginResponse.js | 96 -----------
.../src/model/MasterToken.js | 75 ---------
.../src/model/Session.js | 6 +-
.../webida-service-api-0.1/src/model/Token.js | 34 +++-
.../webida-service-api-0.1/src/model/User.js | 2 +-
.../src/model/Workspace.js | 29 ++--
.../webida/server-api-0.1-lib/wfs-utils.js | 23 ++-
common/src/webida/server-api-0.1.js | 8 +-
common/src/webida/server-pubsub-0.1.js | 9 -
44 files changed, 620 insertions(+), 775 deletions(-)
rename .eslintrc => .eslintrc_reserved (100%)
create mode 100644 common/src/webida/server-api-0.1-lib/TokenManager.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
create mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
rename common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/{LoginRequest.js => Credential.js} (69%)
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
diff --git a/.eslintrc b/.eslintrc_reserved
similarity index 100%
rename from .eslintrc
rename to .eslintrc_reserved
diff --git a/common/src/webida/server-api-0.1-lib/Stats.js b/common/src/webida/server-api-0.1-lib/Stats.js
index 653287fd..96d303d6 100644
--- a/common/src/webida/server-api-0.1-lib/Stats.js
+++ b/common/src/webida/server-api-0.1-lib/Stats.js
@@ -1,6 +1,27 @@
-"use strict"
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file Stats.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([ ], function() {
+ 'use strict';
function Stats (serverStats, path, name) {
this.path = path;
@@ -14,7 +35,7 @@ define([ ], function() {
this.nlink = serverStats.nlink;
this.type = serverStats.type;
- };
+ }
Stats.prorotype = {
get isFile() { return (this.type !== 'DIRECTORY'); },
diff --git a/common/src/webida/server-api-0.1-lib/TokenManager.js b/common/src/webida/server-api-0.1-lib/TokenManager.js
new file mode 100644
index 00000000..b00abf96
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/TokenManager.js
@@ -0,0 +1,159 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file TokenManager.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+// we don't want cyclic dependencies between common and TokenManager.
+// so, instead of requiring just ./common, we require all dependencies directly
+// the only instance of TokenManager is saved in common
+define([
+ 'external/eventEmitter/EventEmitter',
+ 'webida-lib/util/genetic',
+ 'webida-lib/util/logger/logger-client',
+ './webida-service-api-0.1/src/index'
+], function (
+ EventEmitter,
+ genetic,
+ Logger,
+ WebidaServiceApi
+) {
+ 'use strict';
+
+ var logger = new Logger();
+ if (!logger.debug) {
+ logger.debug = logger.log;
+ }
+
+ // issueToken() can take 'timeout' msec
+ // so, we should begin calling issueToken(), at least 30 secs
+
+ var MARGIN_TO_EXPIRE = WebidaServiceApi.ApiClient.instance.timeout + (30 * 1000);
+ var RETRY_AFTER = 5 * 1000;
+ var authApi = new WebidaServiceApi.AuthApi();
+
+ // IDE does not use master token except login with master token
+ // so, TokenManager handles access token only
+
+ function TokenManager(accessToken) {
+ this._updateTimer = null;
+ if (accessToken) {
+ this.updateAccessToken(accessToken);
+ }
+ }
+
+ genetic.inherits(TokenManager, EventEmitter, {
+ updateAccessToken: function updateAccessToken(newAccessToken) {
+ this.accessToken = newAccessToken;
+ if (!this.accessToken) {
+ return;
+ }
+
+ var ttl = this.getRemainingTTL();
+ if(ttl < MARGIN_TO_EXPIRE) {
+ // this error is very serious. if happens, fix server configuration
+ // we recommend at least 2 min, usually 10 min.
+ throw new Error('Token has too short expiration time ' + ttl);
+ } else {
+ this.emit('updated', this.accessToken);
+ // ttl == expire - current
+ // after == expire - current - margin == ttl - margin
+ this._setUpdateTimer(ttl - MARGIN_TO_EXPIRE);
+ }
+ },
+
+ _setUpdateTimer: function(after) {
+ if (this._updateTimer !== null ) {
+ window.clearTimeout(this._updateTimer);
+ this._updateTimer = null;
+ }
+
+ var ttl = this.getRemainingTTL();
+ if (ttl < after) {
+ var nextUpdateTime = new Date().getTime() + after;
+ nextUpdateTime = new Date(nextUpdateTime);
+ var updateError = new Error(
+ 'cannot schedule next update time - time over :' +
+ ' next update time = ' + nextUpdateTime +
+ ' expiration time = ' + this.accessToken.expiresAt
+ );
+ logger.log(updateError);
+ this.emit('lost', updateError);
+ return;
+ }
+
+ logger.log('next update will start after ' + after + ' msec');
+ this._updateTimer = window.setTimeout(this._doUpdate.bind(this), after);
+ },
+
+ // events
+ // updated : normally updated token via schedule
+ // retry : could not update token, but will retry
+ // lost : update failed and there's no chance to get token again.
+ // app should login again.
+
+ _doUpdate: function _doUpdate() {
+ logger.log('start updating tokens');
+ var self = this;
+ authApi.issueToken( 'ACCESS', {}, function (error, result, response) {
+ if(!error) {
+ try {
+ logger.log('new token arrived', result);
+ self.updateAccessToken(result);
+ } catch (updateError) {
+ logger.log('new token has serious error', updateError);
+ self.emit('lost', updateError);
+ // should we have to retry?
+ // no, this error is 'serious' configuration problem.
+ }
+ } else {
+ // there can be serveral types of error
+ // server refused - should not retry (status 4xx, usually)
+ // server had error (5xx, 0)
+ logger.log('could not get new token ', error);
+ if (error.timeout || response.status === 503) {
+ self.emit('retry', error);
+ self._setUpdateTimer(RETRY_AFTER);
+ } else {
+ logger.log('server refused to issue new token', error);
+ self.emit('lost', error);
+ }
+ }
+ });
+ },
+
+ //
+ getRemainingTTL : function() {
+ var expireTime = this.accessToken.expiresAt.getTime();
+ var currentTime = new Date().getTime();
+ return expireTime - currentTime;
+ },
+
+ dispose : function disposeTokenManager() {
+ if (this._updateTimer) {
+ window.clearTimeout(this._updateTimer);
+ this.accessToken = null;
+ }
+ }
+ });
+
+ TokenManager.instance = new TokenManager();
+ return TokenManager;
+
+});
diff --git a/common/src/webida/server-api-0.1-lib/WfsEntry.js b/common/src/webida/server-api-0.1-lib/WfsEntry.js
index cb760be9..fcc2b8cc 100644
--- a/common/src/webida/server-api-0.1-lib/WfsEntry.js
+++ b/common/src/webida/server-api-0.1-lib/WfsEntry.js
@@ -1,9 +1,30 @@
-"use strict"
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsEntry.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([
], function(
) {
-
+ 'use strict';
+
function WfsEntry (stats, name, parent) {
// currently hidden stats property that controls everthing
@@ -46,16 +67,17 @@ define([
},
get basepath() {
- if (this._basepath) {
- return this._basepath;
- } else {
- return this.parent ? this.parent.basepath() : null;
- }
-
+ return this.parent ? null : this._basepath;
},
+ // basepath should be set to root of tree, only
set basepath(value) {
- this._basepath = value;
+ if (!this.parent) {
+ // when tree is /some/path/dir
+ // this.name = dir
+ // basepath = /some/path
+ this._basepath = value.split('/');
+ }
},
get isFile() { return !this.isDirectory; },
@@ -76,6 +98,12 @@ define([
return entry;
};
+ WfsEntry.getBasePathOf = function getBasePathOf(path) {
+ var segments = path.split('/');
+ segments.pop();
+ return segments.join('/');
+ };
+
// later, we should extend this class to WfsFile & WfsDirectory
// we also need WfsTree to handle WfsEntry trees and subtree
//
diff --git a/common/src/webida/server-api-0.1-lib/WfsMount.js b/common/src/webida/server-api-0.1-lib/WfsMount.js
index 078cc450..f6ca2430 100644
--- a/common/src/webida/server-api-0.1-lib/WfsMount.js
+++ b/common/src/webida/server-api-0.1-lib/WfsMount.js
@@ -1,29 +1,50 @@
-"use strict"
-
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsEntry.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([
'./common',
+ './Stats',
'./WfsEntry',
'./wfs-utils'
], function (
common,
+ Stats,
WfsEntry,
wfsUtils
) {
+ 'use strict';
- //
// provides subset of legacy FileSystem object
// some methods are not supported, completely
// we should create better interface in next api 0.2 with cleaner spec and Promise
- //
+
var logger = common.logger;
var wfsApi = new common.api.WfsApi();
function abstractify(name) {
return function abstractMethod() {
- var methodName = name || 'method'
+ var methodName = name || 'method';
throw new Error(methodName + ' is abstract');
- }
+ };
}
function WfsMount(fsid) {
@@ -38,7 +59,7 @@ define([
// result handler is (result, xhr) => desired (processed) result
// usually, some json object will be transformed into a class instance
- _createApiCallback(apiName, resultHandler, callback) {
+ _createApiCallback: function (apiName, resultHandler, callback) {
function echo(x) {
return x;
}
@@ -76,7 +97,7 @@ define([
var callable = wfsApi[apiName];
var wfsPath = this._fromLegacyPath(path);
var args = [ this.wfsId, wfsPath ];
- for (let i = 2; i < arguments.length; i++) {
+ for (var i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
var callback = args.pop();
@@ -120,13 +141,14 @@ define([
recursive = false;
}
this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
+ if (!err) {
+ console.log('wfsList final result', tree.children);
+ }
callback(err, tree.children);
});
},
dirTree: function wfsDirTree(path, maxDepth, callback) {
- var self = this;
-
// TODO: 'full recursive' seems to be dangerous
// server might suffer from stack overflow or starvation with disk i/o
// so, server may response with incomplete tree
@@ -137,10 +159,10 @@ define([
this._callSimpleApi('dirTree', path, maxDepth,
function (result) {
// re-constructing a very large tree in a single tick looks dangerous
- // we need a fromServerResultAsync, which checks height of tree and take some
- // reasonable delays while converting response DirEntry object to WfsEntry
- // or, introduce som 'builder' class to handle large tree
- return WfsEntry.fromJson(result);
+ // we need a fromServerResultAsync, who injects some reasonable delays
+ // while building tree from json
+ var ret = WfsEntry.fromJson(result);
+ ret.basepath = WfsEntry.getBasePathOf(path);
},
callback
);
@@ -174,11 +196,7 @@ define([
);
},
- writeFile : function wfsWriteFile(path, data, ensure, callback) {
- if (!callback) {
- callback = ensure;
- ensure = true; // in next relase, default value for ensure will be changed to false
- }
+ writeFile : function wfsWriteFile(path, data, callback) {
var dataType = typeof(data);
// TODO : support plain object serialization, using AsyncApi class from swagger
@@ -194,7 +212,7 @@ define([
default:
throw new Error('invalid data type - should be string or Blob');
}
-
+ // TODO: change 'ensure' default value to false, adding ensure parameter
this._callSimpleApi('writeFile', path, data, { ensure: true }, null, callback);
},
@@ -220,7 +238,7 @@ define([
// deprecated. use dirTree or never call this method
isEmpty: function wfsIsEmpty(path, callback) {
- this._callSimpleApi('listDir', path, {recursive: true},
+ this._callSimpleApi('dirTree', path, {recursive: true},
function (result) {
return result.children && result.children.length > 0;
},
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
index c44ff02f..4b4fd463 100644
--- a/common/src/webida/server-api-0.1-lib/auth.js
+++ b/common/src/webida/server-api-0.1-lib/auth.js
@@ -1,5 +1,23 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
/**
- * Created by lunaris on 2016-05-23.
+ * @file auth.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
*/
define([
@@ -7,50 +25,62 @@ define([
], function (
common
) {
- "use strict";
+ 'use strict';
var logger = common.logger;
var AuthApi = common.api.AuthApi;
var authApi = new AuthApi();
+
+ // TODO : introduce webida.initializeAsync() that handles all init things,
+ // with credential provider that interacts with UI,
+ // and remove initAuth or make it a legacy-compatibility helper
+ // - ALL webida.*** should be accessible during initialization, without NPE.
+ // - SOME webida.***.****() functions may throw error during initialization,
+ // - We should have no no 'pending' operation due to auth.
+
+
+ // we may need to move this to common or somewhere else
+ common.tokenManager.on('lost', function(error) {
+ alert('TOKEN LOST. LOGIN AGAIN \n ' + error.toString() );
+ });
+
+ common.tokenManager.on('updated', function(token) {
+ console.log('updated token', token);
+ });
// initAuth is called by app.js at first, before loading any other plugins
- // it's good place to initialize swagger client
function initAuth(clientId, redirectUrl, tokenGenerator, callback) {
var masterToken = common.bootArgs.masterToken;
+ logger.log('initAuth starts');
+
if (!masterToken) {
throw new Error('in-app login is not implemented yet');
- // TODO : respect webida-0.3.js TokenGenerator class
}
- console.log("webida auth service api", authApi);
- var loginRequest = common.api.LoginRequest.constructFromObject({
- loginId: 'bogus',
- loginPassword: 'bogus',
+ authApi.login( {
+ loginId:'bogus',
+ loginPassword:'bogus',
masterToken: masterToken
- });
-
- authApi.login(loginRequest, function (error, data, response) {
- if (!error) {
- common.setLoginResponse(data);
- // Oddly, there's no error-fist-callback for initAuth
- callback(data.sessionId);
- } else {
- logger.error('initAuth failed', error);
- callback(error)
+ }, function(err, data) {
+ if (err) {
+ // given callback is NOT a error-first-callback function
+ logger.error('auth error', err);
+ throw(err);
}
- });
+ common.tokenManager.updateAccessToken(data);
+ // Oddly, there's no error-fist-callback for initAuth
+ logger.log('initAuth registered access token', data);
+ callback(data.sessionId);
+ });
}
function getMyInfo(callback) {
-
- authApi.getInfo(function (error, data, response) {
+ authApi.getInfo(function (error, data) {
if (!error) {
- // TODO : add common.userInfo and check it before sending request
- // don't forget to invoke callback with setTimeout(0)
callback(null, data);
} else {
logger.debug('getMyInfo failed', error);
- callback(error)
+ callback(error);
}
});
}
@@ -59,23 +89,29 @@ define([
initAuth : initAuth,
getMyInfo : getMyInfo,
- // for compatiblity
- getTokenObj : function getTokenObject() {
- let token = common.loginResponse.accessToken;
+ // for compatiblity with legacies
+ getTokenObj : function getTokenObj() {
+ var token = common.accessToken;
if (token) {
return {
- issueTime : common.loginResponse.decodedAccessToken.issuedAt,
- data : common.loginResponse.accessToken
- }
+ issueTime : token.issuedAt,
+ data : token.text
+ };
}
},
getToken : function getToken() {
- return common.loginResponse.accessToken;
+ var token = common.accessToken;
+ if (token) {
+ return token.text;
+ }
},
getSessionID : function getSessionID() {
- return common.loginResponse.decodedAccessToken.sessionId;
+ var token = common.accessToken;
+ if (token) {
+ return token.sessionId;
+ }
}
};
});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/common.js b/common/src/webida/server-api-0.1-lib/common.js
index 0584166b..000f30b5 100644
--- a/common/src/webida/server-api-0.1-lib/common.js
+++ b/common/src/webida/server-api-0.1-lib/common.js
@@ -1,15 +1,36 @@
-"use strict";
-
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file common.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([
'URIjs',
'webida-lib/util/logger/logger-client',
- './webida-service-api-0.1/src/index'
+ './webida-service-api-0.1/src/index',
+ './TokenManager'
], function (
URI,
Logger,
- WebidaServiceApi
+ WebidaServiceApi,
+ TokenManager
) {
- "use strict";
+ 'use strict';
var logger = new Logger();
if (!logger.debug) {
@@ -18,45 +39,25 @@ define([
var privates = {
bootArgs : null,
- isDebugging : false,
-
// comes from boot args. need public accessor
serverUri : null,
serverUrl : null,
- // comes from login response, need public accessor for each properties
- loginResponse : {},
-
+ // comes from login response. no need of public accessor
+ tokenManager : TokenManager.instance
};
var publics = {
// accessors to privates. getters only, no setters
-
get logger() { return logger; },
get bootArgs() { return privates.bootArgs; },
- get loginResponse() { return privates.loginResponse },
-
- // TODO - break login response object into tokens
- setLoginResponse : function setLoginResponse(loginResponse) {
- if (!loginResponse) {
- logger.error('should not set empty login response');
- throw new Error('empty login response');
- }
- privates.loginResponse = loginResponse; // believe swagger client
- Object.freeze(privates.loginResponse);
- },
-
+ get tokenManager() { return privates.tokenManager;},
get api() {
return WebidaServiceApi;
}
};
- function initialize() {
- // for embedded server
- // - main process will set some 'boot token', randomly chosen when webida desktop starts
- // - embedded server understands boot token and convert it to actual jwt for any webida client
- // - auth.initAuth() will send boot token to server if set
- // (in next version, initAuth will be removed & auth.login() will handle it directly)
+ function initializeThisModule() {
var locationUri = new URI(window.location.href);
var bootArgs = locationUri.query(true);
@@ -66,32 +67,31 @@ define([
privates.serverUri = new URI(bootArgs.serverUrl).normalize().resource('').path('');
privates.serverUrl = privates.serverUri.toString().slice(0, -1);
- logger.log("webida service url base is " + privates.serverUrl);
// by default, generated js client uses 'http://localhost/api' as base url
- // we should replace
+ // we should replace it to real server url
var defaultClient = WebidaServiceApi.ApiClient.instance;
defaultClient.basePath = privates.serverUrl + '/api';
+
+ // webidaSimpleAuth.apiKey is not a 'fixed' value.
+ // so, we should define property getter (maybe proxy, later)
var webidaSimpleAuth = defaultClient.authentications['webida-simple-auth'];
Object.defineProperty(webidaSimpleAuth, 'apiKey', {
enumerable: true,
get : function getSimpleAuthApiKey() {
- if (privates.loginResponse.accessToken) {
- return privates.loginResponse.accessToken;
+ if (privates.tokenManager.accessToken) {
+ return privates.tokenManager.accessToken.text;
} else {
- logger.debug('sending api request without access token', obj);
+ logger.log('has no access token yet');
return 'not-a-token';
}
}
});
-
- console.log("defaultClient", defaultClient);
-
+ console.log('swagger api default client', defaultClient);
}
- /* module script */
-
- initialize();
+ /* module main script */
+ initializeThisModule();
return publics;
});
diff --git a/common/src/webida/server-api-0.1-lib/fs.js b/common/src/webida/server-api-0.1-lib/fs.js
index c381663b..9fc69716 100644
--- a/common/src/webida/server-api-0.1-lib/fs.js
+++ b/common/src/webida/server-api-0.1-lib/fs.js
@@ -1,4 +1,24 @@
-'use strict';
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file fs.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([
'./common',
@@ -7,6 +27,7 @@ define([
common,
WfsMount
) {
+ 'use strict';
var privates = {
mounts : {}
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
index 23cbdf1a..f7ffeddf 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
@@ -1 +1 @@
-generated via swagger-codegen. no need to check style
\ No newline at end of file
+./src
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
index 60e6c69d..9e30ea1c 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
@@ -6,7 +6,7 @@ This SDK is automatically generated by the [Swagger Codegen](https://github.com/
- API version: 0.1
- Package version: 0.1
-- Build date: 2016-06-16T12:58:21.441Z
+- Build date: 2016-06-21T07:28:56.954Z
- Build package: class io.swagger.codegen.languages.JavascriptClientCodegen
## Installation
@@ -63,10 +63,6 @@ webida-simple-auth.apiKey = "YOUR API KEY"
var api = new WebidaServiceApi.AuthApi()
-var opts = {
- 'tokenText': "tokenText_example" // {String} token text to decode. if not given, access token in request will be used
-};
-
var callback = function(error, data, response) {
if (error) {
console.error(error);
@@ -74,7 +70,7 @@ var callback = function(error, data, response) {
console.log('API called successfully. Returned data: ' + data);
}
};
-api.decodeToken(opts, callback);
+api.getInfo(callback);
```
@@ -84,7 +80,6 @@ All URIs are relative to *https://localhost/api*
Class | Method | HTTP request | Description
------------ | ------------- | ------------- | -------------
-*WebidaServiceApi.AuthApi* | [**decodeToken**](docs/AuthApi.md#decodeToken) | **GET** /auth/token |
*WebidaServiceApi.AuthApi* | [**getInfo**](docs/AuthApi.md#getInfo) | **GET** /auth/info |
*WebidaServiceApi.AuthApi* | [**issueToken**](docs/AuthApi.md#issueToken) | **POST** /auth/token |
*WebidaServiceApi.AuthApi* | [**login**](docs/AuthApi.md#login) | **POST** /auth/login |
@@ -113,14 +108,10 @@ Class | Method | HTTP request | Description
## Documentation for Models
- - [WebidaServiceApi.AccessToken](docs/AccessToken.md)
+ - [WebidaServiceApi.Credential](docs/Credential.md)
- [WebidaServiceApi.DirEntry](docs/DirEntry.md)
- - [WebidaServiceApi.ExecAsyncResponse](docs/ExecAsyncResponse.md)
- [WebidaServiceApi.ExecRequest](docs/ExecRequest.md)
- [WebidaServiceApi.ExecResponse](docs/ExecResponse.md)
- - [WebidaServiceApi.LoginRequest](docs/LoginRequest.md)
- - [WebidaServiceApi.LoginResponse](docs/LoginResponse.md)
- - [WebidaServiceApi.MasterToken](docs/MasterToken.md)
- [WebidaServiceApi.Match](docs/Match.md)
- [WebidaServiceApi.RestError](docs/RestError.md)
- [WebidaServiceApi.RestOK](docs/RestOK.md)
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
deleted file mode 100644
index ca366d8d..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AccessToken.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# WebidaServiceApi.AccessToken
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**sessionId** | **String** | An access token should not be shared between ide sessions, for each sessions requires distinct websocket connection, identified with session id. To change session id, call login again. Any Websocket connection will be rejected if requested upgrade does not contains proper access token data |
-**workspaceId** | **String** | the workspaceId inherited from master token | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
index 5afec9da..64e62115 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
@@ -4,66 +4,11 @@ All URIs are relative to *https://localhost/api*
Method | HTTP request | Description
------------- | ------------- | -------------
-[**decodeToken**](AuthApi.md#decodeToken) | **GET** /auth/token |
[**getInfo**](AuthApi.md#getInfo) | **GET** /auth/info |
[**issueToken**](AuthApi.md#issueToken) | **POST** /auth/token |
[**login**](AuthApi.md#login) | **POST** /auth/login |
-
-# **decodeToken**
-> Token decodeToken(opts)
-
-
-
-decode token to get data.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.AuthApi();
-
-var opts = {
- 'tokenText': "tokenText_example" // String | token text to decode. if not given, access token in request will be used
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.decodeToken(opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **tokenText** | **String**| token text to decode. if not given, access token in request will be used | [optional]
-
-### Return type
-
-[**Token**](Token.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
# **getInfo**
> User getInfo()
@@ -113,11 +58,11 @@ This endpoint does not need any parameter.
# **issueToken**
-> Token issueToken(tokenType, opts)
+> Token issueToken(type, opts)
-Creates new token - Any restrictions are inherited Clients cannot create new access token from exiting one via this operation. Call login with master token. When user logs in without master token, login api response alwyas contains master token
+Creates new token from current access token, inheriting workspace id & session id Duration of generated token is not (and should be) parameterizable.
### Example
```javascript
@@ -132,10 +77,10 @@ webida-simple-auth.apiKey = 'YOUR API KEY';
var apiInstance = new WebidaServiceApi.AuthApi();
-var tokenType = "tokenType_example"; // String | 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt.
+var type = "type_example"; // String |
var opts = {
- 'workspaceId': "workspaceId_example" // String | mandatory to issue a 'MASTER' type token, restricted to some workspace
+ 'workspaceId': "workspaceId_example" // String | mandatory to issue a MASTER type token
};
var callback = function(error, data, response) {
@@ -145,15 +90,15 @@ var callback = function(error, data, response) {
console.log('API called successfully. Returned data: ' + data);
}
};
-apiInstance.issueToken(tokenType, opts, callback);
+apiInstance.issueToken(type, opts, callback);
```
### Parameters
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **tokenType** | **String**| 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt. |
- **workspaceId** | **String**| mandatory to issue a 'MASTER' type token, restricted to some workspace | [optional]
+ **type** | **String**| |
+ **workspaceId** | **String**| mandatory to issue a MASTER type token | [optional]
### Return type
@@ -170,11 +115,11 @@ Name | Type | Description | Notes
# **login**
-> LoginResponse login(body)
+> Token login(body)
-Basic authentication to support webida-simple-auth security scheme defined in this spec. Service / Product implementations who need better security, should override this operation or add their own login api and security definitions. see webida devloper guide to read details about webida-simpe-auth security sceheme.
+A 'VERY' basic authentication, required to use webida-simple-auth security scheme. Service / Product implementations who need better security, should override this operation or add their own login api or some other specs like OAuth2. Simple auth is not suitable for large-sacle, multi-tennant service. Generated accss token inherits all restriction from master token. In normal login, unrestricted access token will be granted with reasonably short expiration time. Every client should respawn another access token with issueToken API before current access token expires.
### Example
```javascript
@@ -182,7 +127,7 @@ var WebidaServiceApi = require('webida-service-api');
var apiInstance = new WebidaServiceApi.AuthApi();
-var body = new WebidaServiceApi.LoginRequest(); // LoginRequest |
+var body = new WebidaServiceApi.Credential(); // Credential |
var callback = function(error, data, response) {
@@ -199,11 +144,11 @@ apiInstance.login(body, callback);
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **body** | [**LoginRequest**](LoginRequest.md)| |
+ **body** | [**Credential**](Credential.md)| |
### Return type
-[**LoginResponse**](LoginResponse.md)
+[**Token**](Token.md)
### Authorization
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
new file mode 100644
index 00000000..804bd9a5
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
@@ -0,0 +1,10 @@
+# WebidaServiceApi.Credential
+
+## Properties
+Name | Type | Description | Notes
+------------ | ------------- | ------------- | -------------
+**loginId** | **String** | |
+**loginPassword** | **String** | |
+**masterToken** | **String** | a master token is issued when user wants to access webida api without id/password from remote or local desktop app. When masterToken is set, client should put some bogus id/password, non-empty. (The values can be used to identify client type) | [optional]
+
+
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
deleted file mode 100644
index ab2b7dd1..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecAsyncResponse.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.ExecAsyncResponse
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**exitCode** | **Integer** | exit code of child process. for async operation, it's always 0 |
-**stdout** | **String** | standard out of child process |
-**stderr** | **String** | standard error of child process |
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
index 2910e650..4907fb28 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
@@ -3,10 +3,11 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**command** | **String** | name or path of executable file to run. should not contain any arguments. |
-**args** | **[String]** | the command line arguments for the command. if 'shell' property is true, this args will be joined with ' ' and appended to command string | [optional]
-**cwd** | **String** | Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept shell-variable form like $HOME, %USERPROFILE% | [optional]
-**input** | **String** | The value which will be passed as stdin to the spawned process. If abscent, server will not write to input anything | [optional]
-**maxBuffer** | **String** | largest amount of data (in bytes) allowed on stdout or stderr. if exceeded child process is killed by server. if async is true, this arguments will be ignored by spawn() | [optional]
+**id** | **String** | unique identifier of execution, to demux response stream or cancel request |
+**command** | **String** | command to run. should not contain any arguments, pipes, redirections |
+**args** | **[String]** | the arguments array |
+**cwd** | **String** | Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept any evaluatable form like $HOME, %USERPROFILE%. If absolute, heading / will be discarded. should be unixified. | [optional]
+**input** | **String** | input string for child process. if falsy in async execution, async input messages will be pasted into the child's stdin. since we don't use tty, it's recommended to use input string anyway. | [optional]
+**timeout** | **Integer** | The value which In 'milliseconds' the maximum amount of time the child is allowed to run. (not idle time of stdout / stderr stream) if undefined, server will not kill the child process until receiving cancel request if it doesn't exit by self. | [optional]
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
index 6672f2f7..5f3df93e 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
@@ -3,8 +3,8 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**exitCode** | **Integer** | exit code of child process. for async operation, it's always 0 |
-**stdout** | **String** | standard out of child process |
-**stderr** | **String** | standard error of child process |
+**exitCode** | **Integer** | exit code of child process. always 0 for async exec |
+**stdout** | **String** | standard out of child process. empty for async exec |
+**stderr** | **String** | standard error of child process. empty for async exec |
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
deleted file mode 100644
index 6e49b269..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginRequest.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.LoginRequest
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**loginId** | **String** | |
-**loginPassword** | **String** | |
-**masterToken** | **String** | If master token is set and valid, login Id / Password will be ignored but still required. Put some bogus values to pass argument validation. Bogus master token in request will not make server issue a new master token. | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
deleted file mode 100644
index e9807e87..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/LoginResponse.md
+++ /dev/null
@@ -1,11 +0,0 @@
-# WebidaServiceApi.LoginResponse
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**accessToken** | **String** | actual token text which should be included in header or cookie |
-**decodedAccessToken** | [**AccessToken**](AccessToken.md) | |
-**masterToken** | **String** | unrestricted master token when user has logged in with valid credential | [optional]
-**decodedMasterToken** | [**MasterToken**](MasterToken.md) | | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
deleted file mode 100644
index 7e669b21..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/MasterToken.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# WebidaServiceApi.MasterToken
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**workspaceId** | **String** | Some MASTER tokens has some 'restricted' access rights, bound to specific workspace, with as issueToken() operation specifies. Any access tokens created from a restricted master token inherits same restriction. If this value is falsy, token has no restriction and can be used to access all apis. If truthy, some api calls that touches internal access registry or session registry will have met 403 error. Some filesystem apis will be rejected, too. | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
index 0bc3568c..d04a80c7 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
@@ -3,11 +3,11 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**id** | **String** | the id of a session. usually same to socket id |
+**id** | **String** | the id of a session. usually same to socket id. |
**name** | **String** | human readable name, usually derived from workspace name. |
-**state** | **String** | state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout. |
+**state** | **String** | state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout. |
**workspaceId** | **String** | the id of workspace that this sessions is working on. |
-**clientAddress** | **String** | absolute path of this workspace in server |
+**clientAddress** | **String** | the peer address of session connection. not always |
**connectedAt** | **Date** | the time when socket connection is established |
**disconnectedAt** | **Date** | the time when socket is closed. |
**willCloseAt** | **Date** | when state becomes CLOSING, actual closing time will be updated by server. | [optional]
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
index cf45d357..c896abe3 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
@@ -11,7 +11,7 @@ Method | HTTP request | Description
# **deleteSession**
-> [Session] deleteSession(sessionId)
+> RestOK deleteSession(sessionId, closeAfter)
@@ -32,6 +32,8 @@ var apiInstance = new WebidaServiceApi.SessionApi();
var sessionId = "sessionId_example"; // String | webida session id (usually different from socket id from sock.io)
+var closeAfter = 56; // Integer | waiting time before actual closing, to let client save files and prevent reconnect
+
var callback = function(error, data, response) {
if (error) {
@@ -40,7 +42,7 @@ var callback = function(error, data, response) {
console.log('API called successfully. Returned data: ' + data);
}
};
-apiInstance.deleteSession(sessionId, callback);
+apiInstance.deleteSession(sessionId, closeAfter, callback);
```
### Parameters
@@ -48,10 +50,11 @@ apiInstance.deleteSession(sessionId, callback);
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**sessionId** | **String**| webida session id (usually different from socket id from sock.io) |
+ **closeAfter** | **Integer**| waiting time before actual closing, to let client save files and prevent reconnect |
### Return type
-[**[Session]**](Session.md)
+[**RestOK**](RestOK.md)
### Authorization
@@ -64,7 +67,7 @@ Name | Type | Description | Notes
# **getSession**
-> [Session] getSession(sessionId)
+> Session getSession(sessionId, )
@@ -93,7 +96,7 @@ var callback = function(error, data, response) {
console.log('API called successfully. Returned data: ' + data);
}
};
-apiInstance.getSession(sessionId, callback);
+apiInstance.getSession(sessionId, , callback);
```
### Parameters
@@ -104,7 +107,7 @@ Name | Type | Description | Notes
### Return type
-[**[Session]**](Session.md)
+[**Session**](Session.md)
### Authorization
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
index fae05360..ec1c3862 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
@@ -3,9 +3,12 @@
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
-**tokenType** | **String** | MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a 'side-way' to create an 'unrestricted' master token before starting IDE instances. So, every ide client has a master token. If client want to access remote workspace directly, it should call login api with given master token which is generated from the remote login credential when adding remote workspace in main ui. Switching from a remote workspace to local one requires a local master token. It's not desirable to mix local and remote tokens in a single client instance in the view point of security. So, it's recommended to save local master token in session storage. |
+**text** | **String** | actual token text that should be shipped in header or query |
+**tokenType** | **String** | MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a side-way to create an unrestricted master token before starting IDE instances. |
**expiresAt** | **Date** | |
**issuedAt** | **Date** | |
+**sessionId** | **String** | mandatory for ACCESS token, identifying client instance | [optional]
+**workspaceId** | **String** | If truthy, access rights are restricted to specified workspace only. | [optional]
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
index e948fecf..3d38df5e 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
@@ -21,7 +21,7 @@ Method | HTTP request | Description
-Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error Copying from sockets, fifo, .. and any other type of file system object is not supported.
+Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error if removeExisting is false Copying from sockets, fifo, .. and any other type of file system object is not supported.
### Example
```javascript
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
index 517324a2..76f0762e 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
@@ -4,9 +4,10 @@
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**id** | **String** | the id of a workspace. usually same to file system id |
-**name** | **String** | display text of this workspace. should not conflit to other workspaces |
-**workspacePath** | **String** | absolute path of this workspace in server |
+**name** | **String** | display text of this workspace for UI |
+**description** | **String** | human readable description on this workspace |
**createdAt** | **Date** | the time when this workspace is created (registered from local file system) |
**accessedAt** | **Date** | the time when the last session on this workspace was made |
+**workspacePath** | **String** | absolute path of this workspace in server. not always available | [optional]
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
index 6af8fe67..276968d5 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
@@ -19,7 +19,7 @@ Method | HTTP request | Description
-cancels a async execution
+cancels an execution, if possible. Killing process may not be graceful.
### Example
```javascript
@@ -36,7 +36,7 @@ var apiInstance = new WebidaServiceApi.WorkspaceApi();
var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-var execId = "execId_example"; // String | the execId property in ExecResponse
+var execId = "execId_example"; // String | the execId property in ExecRequest
var callback = function(error, data, response) {
@@ -54,7 +54,7 @@ apiInstance.cancel(workspaceId, execId, callback);
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
- **execId** | **String**| the execId property in ExecResponse |
+ **execId** | **String**| the execId property in ExecRequest |
### Return type
@@ -90,7 +90,7 @@ webida-simple-auth.apiKey = 'YOUR API KEY';
var apiInstance = new WebidaServiceApi.WorkspaceApi();
-var workspacePath = "workspacePath_example"; // String | a real path of the system or relative path to workspace cellar
+var workspacePath = "workspacePath_example"; // String | a real/local path of the system
var callback = function(error, data, response) {
@@ -107,7 +107,7 @@ apiInstance.createWorkspace(workspacePath, callback);
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
- **workspacePath** | **String**| a real path of the system or relative path to workspace cellar |
+ **workspacePath** | **String**| a real/local path of the system |
### Return type
@@ -148,8 +148,7 @@ var workspaceId = "workspaceId_example"; // String | webida workspace id (usuall
var body = new WebidaServiceApi.ExecRequest(); // ExecRequest |
var opts = {
- 'async': false, // Boolean | Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel.
- 'execId': "execId_example" // String | mandatory for async execution. the result stream will be identified with this id
+ 'async': false // Boolean | Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session.
};
var callback = function(error, data, response) {
@@ -168,8 +167,7 @@ Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
**workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
**body** | [**ExecRequest**](ExecRequest.md)| |
- **async** | **Boolean**| Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel. | [optional] [default to false]
- **execId** | **String**| mandatory for async execution. the result stream will be identified with this id | [optional]
+ **async** | **Boolean**| Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session. | [optional] [default to false]
### Return type
@@ -190,7 +188,7 @@ Name | Type | Description | Notes
-get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
+get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
### Example
```javascript
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
index c786c63a..858cf440 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
@@ -1,18 +1,18 @@
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestError', '../model/Token', '../model/User', '../model/LoginResponse', '../model/LoginRequest'], factory);
+ define(['../ApiClient', '../model/User', '../model/RestError', '../model/Token', '../model/Credential'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Token'), require('../model/User'), require('../model/LoginResponse'), require('../model/LoginRequest'));
+ module.exports = factory(require('../ApiClient'), require('../model/User'), require('../model/RestError'), require('../model/Token'), require('../model/Credential'));
} else {
// Browser globals (root is window)
if (!root.WebidaServiceApi) {
root.WebidaServiceApi = {};
}
- root.WebidaServiceApi.AuthApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Token, root.WebidaServiceApi.User, root.WebidaServiceApi.LoginResponse, root.WebidaServiceApi.LoginRequest);
+ root.WebidaServiceApi.AuthApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.User, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Token, root.WebidaServiceApi.Credential);
}
-}(this, function(ApiClient, RestError, Token, User, LoginResponse, LoginRequest) {
+}(this, function(ApiClient, User, RestError, Token, Credential) {
'use strict';
/**
@@ -32,48 +32,6 @@
this.apiClient = apiClient || ApiClient.instance;
- /**
- * Callback function to receive the result of the decodeToken operation.
- * @callback module:api/AuthApi~decodeTokenCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Token} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * decode token to get data.
- * @param {Object} opts Optional parameters
- * @param {String} opts.tokenText token text to decode. if not given, access token in request will be used
- * @param {module:api/AuthApi~decodeTokenCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Token}
- */
- this.decodeToken = function(opts, callback) {
- opts = opts || {};
- var postBody = null;
-
-
- var pathParams = {
- };
- var queryParams = {
- 'tokenText': opts['tokenText']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Token;
-
- return this.apiClient.callApi(
- '/auth/token', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
/**
* Callback function to receive the result of the getInfo operation.
* @callback module:api/AuthApi~getInfoCallback
@@ -121,27 +79,27 @@
*/
/**
- * Creates new token - Any restrictions are inherited Clients cannot create new access token from exiting one via this operation. Call login with master token. When user logs in without master token, login api response alwyas contains master token
- * @param {module:model/String} tokenType 'MASTER' type requires workspaceId parameter 'ACCESS' type will return inherited access token with all same property except issuedAt & expiredAt.
+ * Creates new token from current access token, inheriting workspace id & session id Duration of generated token is not (and should be) parameterizable.
+ * @param {module:model/String} type
* @param {Object} opts Optional parameters
- * @param {String} opts.workspaceId mandatory to issue a 'MASTER' type token, restricted to some workspace
+ * @param {String} opts.workspaceId mandatory to issue a MASTER type token
* @param {module:api/AuthApi~issueTokenCallback} callback The callback function, accepting three arguments: error, data, response
* data is of type: {module:model/Token}
*/
- this.issueToken = function(tokenType, opts, callback) {
+ this.issueToken = function(type, opts, callback) {
opts = opts || {};
var postBody = null;
- // verify the required parameter 'tokenType' is set
- if (tokenType == undefined || tokenType == null) {
- throw "Missing the required parameter 'tokenType' when calling issueToken";
+ // verify the required parameter 'type' is set
+ if (type == undefined || type == null) {
+ throw "Missing the required parameter 'type' when calling issueToken";
}
var pathParams = {
};
var queryParams = {
- 'tokenType': tokenType,
+ 'type': type,
'workspaceId': opts['workspaceId']
};
var headerParams = {
@@ -165,15 +123,15 @@
* Callback function to receive the result of the login operation.
* @callback module:api/AuthApi~loginCallback
* @param {String} error Error message, if any.
- * @param {module:model/LoginResponse} data The data returned by the service call.
+ * @param {module:model/Token} data The data returned by the service call.
* @param {String} response The complete HTTP response.
*/
/**
- * Basic authentication to support webida-simple-auth security scheme defined in this spec. Service / Product implementations who need better security, should override this operation or add their own login api and security definitions. see webida devloper guide to read details about webida-simpe-auth security sceheme.
- * @param {module:model/LoginRequest} body
+ * A 'VERY' basic authentication, required to use webida-simple-auth security scheme. Service / Product implementations who need better security, should override this operation or add their own login api or some other specs like OAuth2. Simple auth is not suitable for large-sacle, multi-tennant service. Generated accss token inherits all restriction from master token. In normal login, unrestricted access token will be granted with reasonably short expiration time. Every client should respawn another access token with issueToken API before current access token expires.
+ * @param {module:model/Credential} body
* @param {module:api/AuthApi~loginCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/LoginResponse}
+ * data is of type: {module:model/Token}
*/
this.login = function(body, callback) {
var postBody = body;
@@ -196,7 +154,7 @@
var authNames = [];
var contentTypes = ['application/json'];
var accepts = ['application/json', 'application/octet-stream'];
- var returnType = LoginResponse;
+ var returnType = Token;
return this.apiClient.callApi(
'/auth/login', 'POST',
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
index 198676b8..0e2b0184 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
@@ -1,18 +1,18 @@
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestError', '../model/Session'], factory);
+ define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Session'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Session'));
+ module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Session'));
} else {
// Browser globals (root is window)
if (!root.WebidaServiceApi) {
root.WebidaServiceApi = {};
}
- root.WebidaServiceApi.SessionApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Session);
+ root.WebidaServiceApi.SessionApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Session);
}
-}(this, function(ApiClient, RestError, Session) {
+}(this, function(ApiClient, RestOK, RestError, Session) {
'use strict';
/**
@@ -36,17 +36,18 @@
* Callback function to receive the result of the deleteSession operation.
* @callback module:api/SessionApi~deleteSessionCallback
* @param {String} error Error message, if any.
- * @param {Array.} data The data returned by the service call.
+ * @param {module:model/RestOK} data The data returned by the service call.
* @param {String} response The complete HTTP response.
*/
/**
* close session with timeout
* @param {String} sessionId webida session id (usually different from socket id from sock.io)
+ * @param {Integer} closeAfter waiting time before actual closing, to let client save files and prevent reconnect
* @param {module:api/SessionApi~deleteSessionCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {Array.}
+ * data is of type: {module:model/RestOK}
*/
- this.deleteSession = function(sessionId, callback) {
+ this.deleteSession = function(sessionId, closeAfter, callback) {
var postBody = null;
// verify the required parameter 'sessionId' is set
@@ -54,11 +55,17 @@
throw "Missing the required parameter 'sessionId' when calling deleteSession";
}
+ // verify the required parameter 'closeAfter' is set
+ if (closeAfter == undefined || closeAfter == null) {
+ throw "Missing the required parameter 'closeAfter' when calling deleteSession";
+ }
+
var pathParams = {
'sessionId': sessionId
};
var queryParams = {
+ 'closeAfter': closeAfter
};
var headerParams = {
};
@@ -68,7 +75,7 @@
var authNames = ['webida-simple-auth'];
var contentTypes = ['application/json'];
var accepts = ['application/json', 'application/octet-stream'];
- var returnType = [Session];
+ var returnType = RestOK;
return this.apiClient.callApi(
'/sessions/{sessionId}', 'DELETE',
@@ -81,7 +88,7 @@
* Callback function to receive the result of the getSession operation.
* @callback module:api/SessionApi~getSessionCallback
* @param {String} error Error message, if any.
- * @param {Array.} data The data returned by the service call.
+ * @param {module:model/Session} data The data returned by the service call.
* @param {String} response The complete HTTP response.
*/
@@ -89,7 +96,7 @@
* get a session object by id
* @param {String} sessionId webida session id (usually different from socket id from sock.io)
* @param {module:api/SessionApi~getSessionCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {Array.}
+ * data is of type: {module:model/Session}
*/
this.getSession = function(sessionId, callback) {
var postBody = null;
@@ -113,7 +120,7 @@
var authNames = ['webida-simple-auth'];
var contentTypes = ['application/json'];
var accepts = ['application/json', 'application/octet-stream'];
- var returnType = [Session];
+ var returnType = Session;
return this.apiClient.callApi(
'/sessions/{sessionId}', 'GET',
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
index 3bbf3c4d..247530ae 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
@@ -41,7 +41,7 @@
*/
/**
- * Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error Copying from sockets, fifo, .. and any other type of file system object is not supported.
+ * Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error if removeExisting is false Copying from sockets, fifo, .. and any other type of file system object is not supported.
* @param {String} wfsId webida file system id (same to workspace id) to access.
* @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
* @param {String} srcPath source data path of some operations, with have heading /
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
index a9d6351d..d5318274 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
@@ -1,18 +1,18 @@
(function(root, factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Workspace', '../model/ExecRequest', '../model/ExecResponse', '../model/ExecAsyncResponse'], factory);
+ define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Workspace', '../model/ExecRequest', '../model/ExecResponse'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Workspace'), require('../model/ExecRequest'), require('../model/ExecResponse'), require('../model/ExecAsyncResponse'));
+ module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Workspace'), require('../model/ExecRequest'), require('../model/ExecResponse'));
} else {
// Browser globals (root is window)
if (!root.WebidaServiceApi) {
root.WebidaServiceApi = {};
}
- root.WebidaServiceApi.WorkspaceApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Workspace, root.WebidaServiceApi.ExecRequest, root.WebidaServiceApi.ExecResponse, root.WebidaServiceApi.ExecAsyncResponse);
+ root.WebidaServiceApi.WorkspaceApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Workspace, root.WebidaServiceApi.ExecRequest, root.WebidaServiceApi.ExecResponse);
}
-}(this, function(ApiClient, RestOK, RestError, Workspace, ExecRequest, ExecResponse, ExecAsyncResponse) {
+}(this, function(ApiClient, RestOK, RestError, Workspace, ExecRequest, ExecResponse) {
'use strict';
/**
@@ -41,9 +41,9 @@
*/
/**
- * cancels a async execution
+ * cancels an execution, if possible. Killing process may not be graceful.
* @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {String} execId the execId property in ExecResponse
+ * @param {String} execId the execId property in ExecRequest
* @param {module:api/WorkspaceApi~cancelCallback} callback The callback function, accepting three arguments: error, data, response
* data is of type: {module:model/RestOK}
*/
@@ -94,7 +94,7 @@
/**
* create a new workspace at given path
- * @param {String} workspacePath a real path of the system or relative path to workspace cellar
+ * @param {String} workspacePath a real/local path of the system
* @param {module:api/WorkspaceApi~createWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
* data is of type: {module:model/Workspace}
*/
@@ -142,8 +142,7 @@
* @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
* @param {module:model/ExecRequest} body
* @param {Object} opts Optional parameters
- * @param {Boolean} opts.async Execute a command and returns a dummy response immediatlely, and send actual output (stream of message) with web socket channel of current session. At the end of execution, ExecResponse object with empty stdout/stderr will be delivered at the channel. (default to false)
- * @param {String} opts.execId mandatory for async execution. the result stream will be identified with this id
+ * @param {Boolean} opts.async Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session. (default to false)
* @param {module:api/WorkspaceApi~execCallback} callback The callback function, accepting three arguments: error, data, response
* data is of type: {module:model/ExecResponse}
*/
@@ -166,8 +165,7 @@
'workspaceId': workspaceId
};
var queryParams = {
- 'async': opts['async'],
- 'execId': opts['execId']
+ 'async': opts['async']
};
var headerParams = {
};
@@ -195,7 +193,7 @@
*/
/**
- * get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
+ * get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
* @param {Object} opts Optional parameters
* @param {Boolean} opts.disposable include disposable workspaces in response (default to false)
* @param {module:api/WorkspaceApi~getAllWorkspacesCallback} callback The callback function, accepting three arguments: error, data, response
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
index 4920edff..bf4cf98f 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
@@ -1,12 +1,12 @@
(function(factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
- define(['./ApiClient', './model/AccessToken', './model/DirEntry', './model/ExecAsyncResponse', './model/ExecRequest', './model/ExecResponse', './model/LoginRequest', './model/LoginResponse', './model/MasterToken', './model/Match', './model/RestError', './model/RestOK', './model/Session', './model/Stats', './model/Token', './model/User', './model/Workspace', './api/AuthApi', './api/DefaultApi', './api/OpsApi', './api/SessionApi', './api/WfsApi', './api/WorkspaceApi'], factory);
+ define(['./ApiClient', './model/Credential', './model/DirEntry', './model/ExecRequest', './model/ExecResponse', './model/Match', './model/RestError', './model/RestOK', './model/Session', './model/Stats', './model/Token', './model/User', './model/Workspace', './api/AuthApi', './api/DefaultApi', './api/OpsApi', './api/SessionApi', './api/WfsApi', './api/WorkspaceApi'], factory);
} else if (typeof module === 'object' && module.exports) {
// CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('./ApiClient'), require('./model/AccessToken'), require('./model/DirEntry'), require('./model/ExecAsyncResponse'), require('./model/ExecRequest'), require('./model/ExecResponse'), require('./model/LoginRequest'), require('./model/LoginResponse'), require('./model/MasterToken'), require('./model/Match'), require('./model/RestError'), require('./model/RestOK'), require('./model/Session'), require('./model/Stats'), require('./model/Token'), require('./model/User'), require('./model/Workspace'), require('./api/AuthApi'), require('./api/DefaultApi'), require('./api/OpsApi'), require('./api/SessionApi'), require('./api/WfsApi'), require('./api/WorkspaceApi'));
+ module.exports = factory(require('./ApiClient'), require('./model/Credential'), require('./model/DirEntry'), require('./model/ExecRequest'), require('./model/ExecResponse'), require('./model/Match'), require('./model/RestError'), require('./model/RestOK'), require('./model/Session'), require('./model/Stats'), require('./model/Token'), require('./model/User'), require('./model/Workspace'), require('./api/AuthApi'), require('./api/DefaultApi'), require('./api/OpsApi'), require('./api/SessionApi'), require('./api/WfsApi'), require('./api/WorkspaceApi'));
}
-}(function(ApiClient, AccessToken, DirEntry, ExecAsyncResponse, ExecRequest, ExecResponse, LoginRequest, LoginResponse, MasterToken, Match, RestError, RestOK, Session, Stats, Token, User, Workspace, AuthApi, DefaultApi, OpsApi, SessionApi, WfsApi, WorkspaceApi) {
+}(function(ApiClient, Credential, DirEntry, ExecRequest, ExecResponse, Match, RestError, RestOK, Session, Stats, Token, User, Workspace, AuthApi, DefaultApi, OpsApi, SessionApi, WfsApi, WorkspaceApi) {
'use strict';
/**
@@ -47,20 +47,15 @@
*/
ApiClient: ApiClient,
/**
- * The AccessToken model constructor.
- * @property {module:model/AccessToken}
+ * The Credential model constructor.
+ * @property {module:model/Credential}
*/
- AccessToken: AccessToken,
+ Credential: Credential,
/**
* The DirEntry model constructor.
* @property {module:model/DirEntry}
*/
DirEntry: DirEntry,
- /**
- * The ExecAsyncResponse model constructor.
- * @property {module:model/ExecAsyncResponse}
- */
- ExecAsyncResponse: ExecAsyncResponse,
/**
* The ExecRequest model constructor.
* @property {module:model/ExecRequest}
@@ -71,21 +66,6 @@
* @property {module:model/ExecResponse}
*/
ExecResponse: ExecResponse,
- /**
- * The LoginRequest model constructor.
- * @property {module:model/LoginRequest}
- */
- LoginRequest: LoginRequest,
- /**
- * The LoginResponse model constructor.
- * @property {module:model/LoginResponse}
- */
- LoginResponse: LoginResponse,
- /**
- * The MasterToken model constructor.
- * @property {module:model/MasterToken}
- */
- MasterToken: MasterToken,
/**
* The Match model constructor.
* @property {module:model/Match}
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
deleted file mode 100644
index 3c92b878..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/AccessToken.js
+++ /dev/null
@@ -1,85 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/Token'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('./Token'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.AccessToken = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.Token);
- }
-}(this, function(ApiClient, Token) {
- 'use strict';
-
-
-
-
- /**
- * The AccessToken model module.
- * @module model/AccessToken
- * @version 0.1
- */
-
- /**
- * Constructs a new AccessToken.
- * @alias module:model/AccessToken
- * @class
- * @extends module:model/Token
- * @param tokenType
- * @param expiresAt
- * @param issuedAt
- * @param sessionId
- */
- var exports = function(tokenType, expiresAt, issuedAt, sessionId) {
- var _this = this;
- Token.call(_this, tokenType, expiresAt, issuedAt);
- _this['sessionId'] = sessionId;
-
- };
-
- /**
- * Constructs a AccessToken from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/AccessToken} obj Optional instance to populate.
- * @return {module:model/AccessToken} The populated AccessToken instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
- Token.constructFromObject(data, obj);
- if (data.hasOwnProperty('sessionId')) {
- obj['sessionId'] = ApiClient.convertToType(data['sessionId'], 'String');
- }
- if (data.hasOwnProperty('workspaceId')) {
- obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
- }
- }
- return obj;
- }
-
- exports.prototype = Object.create(Token.prototype);
- exports.prototype.constructor = exports;
-
- /**
- * An access token should not be shared between ide sessions, for each sessions requires distinct websocket connection, identified with session id. To change session id, call login again. Any Websocket connection will be rejected if requested upgrade does not contains proper access token data
- * @member {String} sessionId
- */
- exports.prototype['sessionId'] = undefined;
- /**
- * the workspaceId inherited from master token
- * @member {String} workspaceId
- */
- exports.prototype['workspaceId'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
similarity index 69%
rename from common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js
rename to common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
index 335231b1..3de27e3d 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginRequest.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
@@ -10,7 +10,7 @@
if (!root.WebidaServiceApi) {
root.WebidaServiceApi = {};
}
- root.WebidaServiceApi.LoginRequest = factory(root.WebidaServiceApi.ApiClient);
+ root.WebidaServiceApi.Credential = factory(root.WebidaServiceApi.ApiClient);
}
}(this, function(ApiClient) {
'use strict';
@@ -19,14 +19,15 @@
/**
- * The LoginRequest model module.
- * @module model/LoginRequest
+ * The Credential model module.
+ * @module model/Credential
* @version 0.1
*/
/**
- * Constructs a new LoginRequest.
- * @alias module:model/LoginRequest
+ * Constructs a new Credential.
+ * user credential to login. Use https to protect credential.
+ * @alias module:model/Credential
* @class
* @param loginId
* @param loginPassword
@@ -40,11 +41,11 @@
};
/**
- * Constructs a LoginRequest from a plain JavaScript object, optionally creating a new instance.
+ * Constructs a Credential from a plain JavaScript object, optionally creating a new instance.
* Copies all relevant properties from data to obj if supplied or a new instance if not.
* @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/LoginRequest} obj Optional instance to populate.
- * @return {module:model/LoginRequest} The populated LoginRequest instance.
+ * @param {module:model/Credential} obj Optional instance to populate.
+ * @return {module:model/Credential} The populated Credential instance.
*/
exports.constructFromObject = function(data, obj) {
if (data) {
@@ -72,7 +73,7 @@
*/
exports.prototype['loginPassword'] = undefined;
/**
- * If master token is set and valid, login Id / Password will be ignored but still required. Put some bogus values to pass argument validation. Bogus master token in request will not make server issue a new master token.
+ * a master token is issued when user wants to access webida api without id/password from remote or local desktop app. When masterToken is set, client should put some bogus id/password, non-empty. (The values can be used to identify client type)
* @member {String} masterToken
*/
exports.prototype['masterToken'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
deleted file mode 100644
index 4a812e1f..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecAsyncResponse.js
+++ /dev/null
@@ -1,90 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.ExecAsyncResponse = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The ExecAsyncResponse model module.
- * @module model/ExecAsyncResponse
- * @version 0.1
- */
-
- /**
- * Constructs a new ExecAsyncResponse.
- * execution response with output and exit code
- * @alias module:model/ExecAsyncResponse
- * @class
- * @param exitCode
- * @param stdout
- * @param stderr
- */
- var exports = function(exitCode, stdout, stderr) {
- var _this = this;
-
- _this['exitCode'] = exitCode;
- _this['stdout'] = stdout;
- _this['stderr'] = stderr;
- };
-
- /**
- * Constructs a ExecAsyncResponse from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/ExecAsyncResponse} obj Optional instance to populate.
- * @return {module:model/ExecAsyncResponse} The populated ExecAsyncResponse instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('exitCode')) {
- obj['exitCode'] = ApiClient.convertToType(data['exitCode'], 'Integer');
- }
- if (data.hasOwnProperty('stdout')) {
- obj['stdout'] = ApiClient.convertToType(data['stdout'], 'String');
- }
- if (data.hasOwnProperty('stderr')) {
- obj['stderr'] = ApiClient.convertToType(data['stderr'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * exit code of child process. for async operation, it's always 0
- * @member {Integer} exitCode
- */
- exports.prototype['exitCode'] = undefined;
- /**
- * standard out of child process
- * @member {String} stdout
- */
- exports.prototype['stdout'] = undefined;
- /**
- * standard error of child process
- * @member {String} stderr
- */
- exports.prototype['stderr'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
index 559074ba..286b91c2 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
@@ -26,16 +26,19 @@
/**
* Constructs a new ExecRequest.
- * execution request, simlilar to node.js child_proc.exec / spawn see node.js documentation for details of each properties. some properties are not configurable for portability - encoding : fixed to utf-8 - shell : fixed to system default. Using shell env variables in command is not recommended. - killSignal : fixed to default (SIGTERM) - uid, gid : will not be set - stdio : does not support 'ignore' and 'inherit'. all streams are handled by server.
+ * execution request, simlilar to node.js spawn(). see node.js documentation for details of each properties. some properties are not configurable for portability - encoding : fixed to utf-8 - shell : fixed to system default. Using shell variables in command may not work. - killSignal : fixed to SIGTERM. If process does not die, server can send SIGKILL or invoke taskkill to ensure chlid process is killed. - uid & gid : will not be set - stdio : all streams are handled by server. no options are avaliable to client. - shell : always false. - detached : always false
* @alias module:model/ExecRequest
* @class
+ * @param id
* @param command
+ * @param args
*/
- var exports = function(command) {
+ var exports = function(id, command, args) {
var _this = this;
+ _this['id'] = id;
_this['command'] = command;
-
+ _this['args'] = args;
@@ -52,6 +55,9 @@
if (data) {
obj = obj || new exports();
+ if (data.hasOwnProperty('id')) {
+ obj['id'] = ApiClient.convertToType(data['id'], 'String');
+ }
if (data.hasOwnProperty('command')) {
obj['command'] = ApiClient.convertToType(data['command'], 'String');
}
@@ -64,38 +70,43 @@
if (data.hasOwnProperty('input')) {
obj['input'] = ApiClient.convertToType(data['input'], 'String');
}
- if (data.hasOwnProperty('maxBuffer')) {
- obj['maxBuffer'] = ApiClient.convertToType(data['maxBuffer'], 'String');
+ if (data.hasOwnProperty('timeout')) {
+ obj['timeout'] = ApiClient.convertToType(data['timeout'], 'Integer');
}
}
return obj;
}
/**
- * name or path of executable file to run. should not contain any arguments.
+ * unique identifier of execution, to demux response stream or cancel request
+ * @member {String} id
+ */
+ exports.prototype['id'] = undefined;
+ /**
+ * command to run. should not contain any arguments, pipes, redirections
* @member {String} command
*/
exports.prototype['command'] = undefined;
/**
- * the command line arguments for the command. if 'shell' property is true, this args will be joined with ' ' and appended to command string
+ * the arguments array
* @member {Array.} args
*/
exports.prototype['args'] = undefined;
/**
- * Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept shell-variable form like $HOME, %USERPROFILE%
+ * Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept any evaluatable form like $HOME, %USERPROFILE%. If absolute, heading / will be discarded. should be unixified.
* @member {String} cwd
*/
exports.prototype['cwd'] = undefined;
/**
- * The value which will be passed as stdin to the spawned process. If abscent, server will not write to input anything
+ * input string for child process. if falsy in async execution, async input messages will be pasted into the child's stdin. since we don't use tty, it's recommended to use input string anyway.
* @member {String} input
*/
exports.prototype['input'] = undefined;
/**
- * largest amount of data (in bytes) allowed on stdout or stderr. if exceeded child process is killed by server. if async is true, this arguments will be ignored by spawn()
- * @member {String} maxBuffer
+ * The value which In 'milliseconds' the maximum amount of time the child is allowed to run. (not idle time of stdout / stderr stream) if undefined, server will not kill the child process until receiving cancel request if it doesn't exit by self.
+ * @member {Integer} timeout
*/
- exports.prototype['maxBuffer'] = undefined;
+ exports.prototype['timeout'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
index 135877f3..9811aab0 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
@@ -26,7 +26,7 @@
/**
* Constructs a new ExecResponse.
- * execution response with output and exit code
+ * execution response
* @alias module:model/ExecResponse
* @class
* @param exitCode
@@ -66,17 +66,17 @@
}
/**
- * exit code of child process. for async operation, it's always 0
+ * exit code of child process. always 0 for async exec
* @member {Integer} exitCode
*/
exports.prototype['exitCode'] = undefined;
/**
- * standard out of child process
+ * standard out of child process. empty for async exec
* @member {String} stdout
*/
exports.prototype['stdout'] = undefined;
/**
- * standard error of child process
+ * standard error of child process. empty for async exec
* @member {String} stderr
*/
exports.prototype['stderr'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
deleted file mode 100644
index 156f3800..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/LoginResponse.js
+++ /dev/null
@@ -1,96 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/AccessToken', '../model/MasterToken'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('./AccessToken'), require('./MasterToken'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.LoginResponse = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.AccessToken, root.WebidaServiceApi.MasterToken);
- }
-}(this, function(ApiClient, AccessToken, MasterToken) {
- 'use strict';
-
-
-
-
- /**
- * The LoginResponse model module.
- * @module model/LoginResponse
- * @version 0.1
- */
-
- /**
- * Constructs a new LoginResponse.
- * login response for clients to use in service access. use 'decode' api to see detail
- * @alias module:model/LoginResponse
- * @class
- * @param accessToken
- * @param decodedAccessToken
- */
- var exports = function(accessToken, decodedAccessToken) {
- var _this = this;
-
- _this['accessToken'] = accessToken;
- _this['decodedAccessToken'] = decodedAccessToken;
-
-
- };
-
- /**
- * Constructs a LoginResponse from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/LoginResponse} obj Optional instance to populate.
- * @return {module:model/LoginResponse} The populated LoginResponse instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('accessToken')) {
- obj['accessToken'] = ApiClient.convertToType(data['accessToken'], 'String');
- }
- if (data.hasOwnProperty('decodedAccessToken')) {
- obj['decodedAccessToken'] = AccessToken.constructFromObject(data['decodedAccessToken']);
- }
- if (data.hasOwnProperty('masterToken')) {
- obj['masterToken'] = ApiClient.convertToType(data['masterToken'], 'String');
- }
- if (data.hasOwnProperty('decodedMasterToken')) {
- obj['decodedMasterToken'] = MasterToken.constructFromObject(data['decodedMasterToken']);
- }
- }
- return obj;
- }
-
- /**
- * actual token text which should be included in header or cookie
- * @member {String} accessToken
- */
- exports.prototype['accessToken'] = undefined;
- /**
- * @member {module:model/AccessToken} decodedAccessToken
- */
- exports.prototype['decodedAccessToken'] = undefined;
- /**
- * unrestricted master token when user has logged in with valid credential
- * @member {String} masterToken
- */
- exports.prototype['masterToken'] = undefined;
- /**
- * @member {module:model/MasterToken} decodedMasterToken
- */
- exports.prototype['decodedMasterToken'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
deleted file mode 100644
index c177646c..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/MasterToken.js
+++ /dev/null
@@ -1,75 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/Token'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('./Token'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.MasterToken = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.Token);
- }
-}(this, function(ApiClient, Token) {
- 'use strict';
-
-
-
-
- /**
- * The MasterToken model module.
- * @module model/MasterToken
- * @version 0.1
- */
-
- /**
- * Constructs a new MasterToken.
- * @alias module:model/MasterToken
- * @class
- * @extends module:model/Token
- * @param tokenType
- * @param expiresAt
- * @param issuedAt
- */
- var exports = function(tokenType, expiresAt, issuedAt) {
- var _this = this;
- Token.call(_this, tokenType, expiresAt, issuedAt);
-
- };
-
- /**
- * Constructs a MasterToken from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/MasterToken} obj Optional instance to populate.
- * @return {module:model/MasterToken} The populated MasterToken instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
- Token.constructFromObject(data, obj);
- if (data.hasOwnProperty('workspaceId')) {
- obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
- }
- }
- return obj;
- }
-
- exports.prototype = Object.create(Token.prototype);
- exports.prototype.constructor = exports;
-
- /**
- * Some MASTER tokens has some 'restricted' access rights, bound to specific workspace, with as issueToken() operation specifies. Any access tokens created from a restricted master token inherits same restriction. If this value is falsy, token has no restriction and can be used to access all apis. If truthy, some api calls that touches internal access registry or session registry will have met 403 error. Some filesystem apis will be rejected, too.
- * @member {String} workspaceId
- */
- exports.prototype['workspaceId'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
index 65606f30..fc7d4352 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
@@ -94,7 +94,7 @@
}
/**
- * the id of a session. usually same to socket id
+ * the id of a session. usually same to socket id.
* @member {String} id
*/
exports.prototype['id'] = undefined;
@@ -104,7 +104,7 @@
*/
exports.prototype['name'] = undefined;
/**
- * state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout.
+ * state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout.
* @member {module:model/Session.StateEnum} state
*/
exports.prototype['state'] = undefined;
@@ -114,7 +114,7 @@
*/
exports.prototype['workspaceId'] = undefined;
/**
- * absolute path of this workspace in server
+ * the peer address of session connection. not always
* @member {String} clientAddress
*/
exports.prototype['clientAddress'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
index ee58d9dc..82cc27ef 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
@@ -26,19 +26,23 @@
/**
* Constructs a new Token.
- * Decoded token's data accessible to client apps
+ * a json webtoken and accessible data
* @alias module:model/Token
* @class
+ * @param text
* @param tokenType
* @param expiresAt
* @param issuedAt
*/
- var exports = function(tokenType, expiresAt, issuedAt) {
+ var exports = function(text, tokenType, expiresAt, issuedAt) {
var _this = this;
+ _this['text'] = text;
_this['tokenType'] = tokenType;
_this['expiresAt'] = expiresAt;
_this['issuedAt'] = issuedAt;
+
+
};
/**
@@ -52,6 +56,9 @@
if (data) {
obj = obj || new exports();
+ if (data.hasOwnProperty('text')) {
+ obj['text'] = ApiClient.convertToType(data['text'], 'String');
+ }
if (data.hasOwnProperty('tokenType')) {
obj['tokenType'] = ApiClient.convertToType(data['tokenType'], 'String');
}
@@ -61,12 +68,23 @@
if (data.hasOwnProperty('issuedAt')) {
obj['issuedAt'] = ApiClient.convertToType(data['issuedAt'], 'Date');
}
+ if (data.hasOwnProperty('sessionId')) {
+ obj['sessionId'] = ApiClient.convertToType(data['sessionId'], 'String');
+ }
+ if (data.hasOwnProperty('workspaceId')) {
+ obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
+ }
}
return obj;
}
/**
- * MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a 'side-way' to create an 'unrestricted' master token before starting IDE instances. So, every ide client has a master token. If client want to access remote workspace directly, it should call login api with given master token which is generated from the remote login credential when adding remote workspace in main ui. Switching from a remote workspace to local one requires a local master token. It's not desirable to mix local and remote tokens in a single client instance in the view point of security. So, it's recommended to save local master token in session storage.
+ * actual token text that should be shipped in header or query
+ * @member {String} text
+ */
+ exports.prototype['text'] = undefined;
+ /**
+ * MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a side-way to create an unrestricted master token before starting IDE instances.
* @member {module:model/Token.TokenTypeEnum} tokenType
*/
exports.prototype['tokenType'] = undefined;
@@ -78,6 +96,16 @@
* @member {Date} issuedAt
*/
exports.prototype['issuedAt'] = undefined;
+ /**
+ * mandatory for ACCESS token, identifying client instance
+ * @member {String} sessionId
+ */
+ exports.prototype['sessionId'] = undefined;
+ /**
+ * If truthy, access rights are restricted to specified workspace only.
+ * @member {String} workspaceId
+ */
+ exports.prototype['workspaceId'] = undefined;
/**
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
index 43b2b5e6..1bfb7164 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
@@ -26,7 +26,7 @@
/**
* Constructs a new User.
- * Any services/products should define some admin apis to manage users in the system and expose what should be exposed to client app. So, no properties are mandatory. Current properties are defined for compatiblity with legacy clients. Access token data can be decoded with another operations.
+ * Any services/products should define some admin apis to manage users in the system and expose what should be exposed to client app. So, no properties are mandatory. Currently, properties are defined for compatiblity with legacy clients.
* @alias module:model/User
* @class
*/
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
index 2ff81145..ef7a4aaa 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
@@ -26,23 +26,24 @@
/**
* Constructs a new Workspace.
- * Users' workspace in server
+ * A workspace in server
* @alias module:model/Workspace
* @class
* @param id
* @param name
- * @param workspacePath
+ * @param description
* @param createdAt
* @param accessedAt
*/
- var exports = function(id, name, workspacePath, createdAt, accessedAt) {
+ var exports = function(id, name, description, createdAt, accessedAt) {
var _this = this;
_this['id'] = id;
_this['name'] = name;
- _this['workspacePath'] = workspacePath;
+ _this['description'] = description;
_this['createdAt'] = createdAt;
_this['accessedAt'] = accessedAt;
+
};
/**
@@ -62,8 +63,8 @@
if (data.hasOwnProperty('name')) {
obj['name'] = ApiClient.convertToType(data['name'], 'String');
}
- if (data.hasOwnProperty('workspacePath')) {
- obj['workspacePath'] = ApiClient.convertToType(data['workspacePath'], 'String');
+ if (data.hasOwnProperty('description')) {
+ obj['description'] = ApiClient.convertToType(data['description'], 'String');
}
if (data.hasOwnProperty('createdAt')) {
obj['createdAt'] = ApiClient.convertToType(data['createdAt'], 'Date');
@@ -71,6 +72,9 @@
if (data.hasOwnProperty('accessedAt')) {
obj['accessedAt'] = ApiClient.convertToType(data['accessedAt'], 'Date');
}
+ if (data.hasOwnProperty('workspacePath')) {
+ obj['workspacePath'] = ApiClient.convertToType(data['workspacePath'], 'String');
+ }
}
return obj;
}
@@ -81,15 +85,15 @@
*/
exports.prototype['id'] = undefined;
/**
- * display text of this workspace. should not conflit to other workspaces
+ * display text of this workspace for UI
* @member {String} name
*/
exports.prototype['name'] = undefined;
/**
- * absolute path of this workspace in server
- * @member {String} workspacePath
+ * human readable description on this workspace
+ * @member {String} description
*/
- exports.prototype['workspacePath'] = undefined;
+ exports.prototype['description'] = undefined;
/**
* the time when this workspace is created (registered from local file system)
* @member {Date} createdAt
@@ -100,6 +104,11 @@
* @member {Date} accessedAt
*/
exports.prototype['accessedAt'] = undefined;
+ /**
+ * absolute path of this workspace in server. not always available
+ * @member {String} workspacePath
+ */
+ exports.prototype['workspacePath'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/wfs-utils.js b/common/src/webida/server-api-0.1-lib/wfs-utils.js
index 0b391ea5..77459e0f 100644
--- a/common/src/webida/server-api-0.1-lib/wfs-utils.js
+++ b/common/src/webida/server-api-0.1-lib/wfs-utils.js
@@ -1,10 +1,31 @@
-"use strict";
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file wfs-utils.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
define([
'URIjs'
], function (
URI
) {
+ 'use strict';
var internals = {
createWfsUrl : function createWfsUrl(parsed) {
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
index 0f240752..d48dd9d4 100644
--- a/common/src/webida/server-api-0.1.js
+++ b/common/src/webida/server-api-0.1.js
@@ -18,8 +18,7 @@
/**
* @fileOverview Webida Server API binding library for Webida 1.x client
*
-* This module should not be used in Webida 2.x
-* This module implements some sub-set of webida-0.3.js
+* This module implements some sub-set of webida-0.3.js with new webida service api spec.
* @module server-api
* @version 0.1
*/
@@ -53,6 +52,7 @@ define([
// via window.__ELECTRON_BROWSER__ variable
// - PM should not load .user_info/plugin-settings.json file directly while initializing
// and may use local storage instead of using server api
+
getPluginSettingsPath : function(callback) {
// plugin-settings-desktop.json : to connect embedded server from desktop (0.1)
// : to connect server from desktop (0.2)
@@ -61,9 +61,9 @@ define([
// this is version 0.1. (simple but enough, for we don't access legacy server as guest)
if(common.bootArgs.legacy) {
- return callback('plugins/plugin-setting.json')
+ return callback('plugins/plugin-setting.json');
} else {
- return callback('plugins/plugin-settings-desktop.json')
+ return callback('plugins/plugin-settings-desktop.json');
}
}
};
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-0.1.js
index 9eb87214..dc8c3b38 100644
--- a/common/src/webida/server-pubsub-0.1.js
+++ b/common/src/webida/server-pubsub-0.1.js
@@ -22,15 +22,6 @@
* @version: 0.1
*/
-
-
-/**
-* messaging api for Javascript module.
-*
-* This module provides JavaScript API's for message service.
-* It depends on socket.io in external/socket.io-client/
-* @module msg
-*/
define([
'./server-api-0.1',
'external/socket.io-client/socket.io',
From 6c208f25455328d4fb27f54f129a8d9860203d8a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Mon, 4 Jul 2016 14:04:45 +0900
Subject: [PATCH 11/15] implemented session handling & file system events
- fixed some bugs on fs-command plugin's invalid command id
- fixed some bugs on editor context menu typos.
- fixed editors/DataSourceHandler to use data source with correct URN, fixing '//' to '/'
- refactoring : moved some wfs related files to server-api-0.1-lib/wfs
- refactoring : renamed Stats to WfsStats
- added 'AbstractSocketClient' class, socket-io client wrapper
- added session module & SessionSocketClient, handling session connection and reconectting
- added new plugin, session-event-dispatcher, replacing 'resources' plugin
(can be used with new server api lib only )
- added WfsEventGate & WfsEventHolder to handle server's file system event from session client
- added some properties in server api (webida) interface,
to use session client & some useful informations
---
apps/ide/src/dojoConfig.js | 37 +--
apps/ide/src/index.html | 57 ++--
.../src/plugins/plugin-settings-desktop.json | 16 +-
.../webida.editor.code-editor/menus.js | 4 +-
common/src/webida/app.js | 13 +-
.../command-system/command/command-factory.js | 5 +-
.../plugins/editors/DataSourceHandler.js | 22 +-
.../webida/plugins/fs-commands/commands.js | 8 +-
.../plugins/resources/resource-event.js | 2 +-
.../dispatch-legacy-resource-topics.js | 135 +++++++++
.../session-event-dispatcher/plugin.js | 77 +++++
.../session-event-dispatcher/plugin.json | 6 +
.../AbstractSocketClient.js | 271 ++++++++++++++++++
.../webida/server-api-0.1-lib/TokenManager.js | 7 +-
common/src/webida/server-api-0.1-lib/auth.js | 13 +-
.../src/webida/server-api-0.1-lib/common.js | 13 +-
common/src/webida/server-api-0.1-lib/fs.js | 3 +-
.../webida/server-api-0.1-lib/messaging.js | 46 +++
.../src/webida/server-api-0.1-lib/session.js | 95 ++++++
.../src/model/Session.js | 2 +-
.../server-api-0.1-lib/{ => wfs}/WfsEntry.js | 35 +--
.../server-api-0.1-lib/wfs/WfsEventGate.js | 238 +++++++++++++++
.../server-api-0.1-lib/wfs/WfsEventHolder.js | 264 +++++++++++++++++
.../server-api-0.1-lib/{ => wfs}/WfsMount.js | 130 +++++----
.../{Stats.js => wfs/WfsStats.js} | 24 +-
.../server-api-0.1-lib/{ => wfs}/wfs-utils.js | 57 ++--
common/src/webida/server-api-0.1.js | 56 +++-
common/src/webida/server-pubsub-0.1.js | 22 +-
28 files changed, 1432 insertions(+), 226 deletions(-)
create mode 100644 common/src/webida/plugins/session-event-dispatcher/dispatch-legacy-resource-topics.js
create mode 100644 common/src/webida/plugins/session-event-dispatcher/plugin.js
create mode 100644 common/src/webida/plugins/session-event-dispatcher/plugin.json
create mode 100644 common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
create mode 100644 common/src/webida/server-api-0.1-lib/messaging.js
create mode 100644 common/src/webida/server-api-0.1-lib/session.js
rename common/src/webida/server-api-0.1-lib/{ => wfs}/WfsEntry.js (75%)
create mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
create mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
rename common/src/webida/server-api-0.1-lib/{ => wfs}/WfsMount.js (65%)
rename common/src/webida/server-api-0.1-lib/{Stats.js => wfs/WfsStats.js} (79%)
rename common/src/webida/server-api-0.1-lib/{ => wfs}/wfs-utils.js (68%)
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index 2146901f..c49557e2 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -21,8 +21,8 @@
// to make dojo & other amd module work
// how can we detect that we're working in electron?
if (typeof(globalObject.process) === 'object' &&
- typeof(globalObject.require) === 'function' &&
- typeof(globalObject.module) === 'object') {
+ typeof(globalObject.require) === 'function' &&
+ typeof(globalObject.module) === 'object') {
globalObject.nrequire = globalObject.require;
globalObject.nmodule = globalObject.module;
delete globalObject.require;
@@ -44,8 +44,6 @@
{name: 'jquery', location: './jquery/dist', main: 'jquery.min'},
{name: 'put-selector', location: './put-selector'},
{name: 'showdown', location: './showdown/dist', main: 'showdown.min'},
- {name: 'superagent', location: './superagent/lib', main: 'client'},
-
{name: 'URIjs', location:'./URIjs/src', main:'URI'},
{name: 'xstyle', location: './xstyle'}
],
@@ -75,28 +73,21 @@
]
};
- // default.html (new index.html for new server) should set
- // session storage variable 'webida-workspace-type'
- // to 'legacy' for 1.x clients who uses webida-0.4 API as default
- if (globalObject.nrequire) {
+ // twick requirejs alias to use new server-api when not using using legacy server
+ if (window.location.href.indexOf('legacy=') < 0 ) {
+ globalObject.dojoConfig.aliases.pop();
+ globalObject.dojoConfig.aliases.pop();
+ globalObject.dojoConfig.aliases.push(['webida-lib/server-api' , 'webida-lib/server-api-0.1']);
+ globalObject.dojoConfig.aliases.push(['webida-lib/server-pubsub' , 'webida-lib/server-pubsub-0.1']);
+ globalObject.dojoConfig.aliases.push(['top/site-config.json' , 'top/site-config-desktop.json']);
+ }
- // dojo may understand cjs require() by building option
- // but some bower modules works under amd system only
- // we don't allow to mix amd/cjs modules with same require function
+ if (globalObject.__ELECTRON_BROWSER__) {
+ // Although dojo may understand cjs require() by building option,
+ // some bower modules works under amd system only.
+ // So, we don't allow to mix amd/cjs modules with same require function
globalObject.dojoConfig.has = {
'host-node': false // Prevent dojo from being fooled by Electron
};
- // twick requirejs alias to use new server-api
- // when using legacy server
-
- if (window.location.href.indexOf('legacy=') < 0 ) {
- globalObject.dojoConfig.aliases.pop();
- globalObject.dojoConfig.aliases.pop();
- globalObject.dojoConfig.aliases.push(['webida-lib/server-api' , 'webida-lib/server-api-0.1']);
- globalObject.dojoConfig.aliases.push(['webida-lib/server-pubsub' , 'webida-lib/server-pubsub-0.1']);
- globalObject.dojoConfig.aliases.push(['top/site-config.json' , 'top/site-config-desktop.json']);
- console.log('under electrion re-wrote some requirejs aliases');
- }
- console.log('dojoConfig is now ready for electron');
}
})(window);
diff --git a/apps/ide/src/index.html b/apps/ide/src/index.html
index ea863726..5e454e94 100644
--- a/apps/ide/src/index.html
+++ b/apps/ide/src/index.html
@@ -40,41 +40,44 @@
ga('send', 'pageview');
}
- // dojoConfig.js has handled some tricks for window.nrequire and set __ELECTRON_BROWSER__ already
- // so, within electron, there's always a window.nrequire for node.js
- if (window.__ELECTRON_BROWSER__) {
- var uri = new URI(window.location.href);
- var bootArgs = uri.query(true);
- var desktopConfig = window.localStorage.getItem('webida-desktop-config');
- if (desktopConfig) {
- console.log('loaded desktop config ' + desktopConfig);
- desktopConfig = JSON.parse(desktopConfig);
+ var uri = new URI(window.location.href);
+ var bootArgs = uri.query(true);
+
+ if (bootArgs.legacy) {
+ window.legacySiteServerConfig = desktopConfig.legacySiteConfigs[bootArgs.legacy];
+ if (!window.legacySiteServerConfig) {
+ alert('cannot read site configuration for legacy remote server');
}
- var browserWindowStatusStorageKey = 'webida-desktop-window-status-' + bootArgs.workspace;
- var browserWindowStatus = window.localStorage.getItem(browserWindowStatusStorageKey);
- var browserWindowStatus = browserWindowStatus ? JSON.parse(browserWindowStatus)
- : desktopConfig.ideWindowDefaults;
+ }
+
+ if (window.__ELECTRON_BROWSER__) {
var browserWindow = window.nrequire('electron').remote.getCurrentWindow();
- if(browserWindowStatus.x) {
- browserWindow.setBounds(browserWindowStatus);
+ var storageKey = 'webida-desktop-window-status-' + bootArgs.workspace;
+ var winStatus = localStorage.getItem(storageKey);
+ if (!winStatus) {
+ console.log('unable to load window status - fallback to config defaults ');
+ var desktopConfig = localStorage.getItem('webida-desktop-config');
+ if (desktopConfig) {
+ desktopConfig = JSON.parse(desktopConfig);
+ }
+ winStatus = desktopConfig.ideWindowDefaults;
} else {
- browserWindow.setSize(browserWindowStatus.width, browserWindowStatus.height);
+ winStatus = JSON.parse(winStatus);
}
- if (browserWindowStatus.maximized) {
- browserWindow.maximze();
+
+ if (winStatus.x) {
+ browserWindow.setBounds(winStatus);
+ } else {
+ browserWindow.setSize(winStatus.width, winStatus.height);
}
- if (bootArgs.legacy) {
- window.legacySiteServerConfig = desktopConfig.legacySiteConfigs[bootArgs.legacy];
- if (!window.legacySiteServerConfig) {
- alert('cannot read site configuration for legacy remote server');
- }
+ if (winStatus.isMaximized) {
+ browserWindow.maximze();
}
+
browserWindow.on('close', function(event) {
var newStatus = browserWindow.getBounds();
- newStatus.maximized = browserWindow.isMaximized();
- newStatus = JSON.stringify(newStatus);
- console.log('saving browser window status for closing ' + newStatus);
- window.localStorage.setItem(browserWindowStatusStorageKey, newStatus);
+ newStatus.isMaximized = browserWindow.isMaximized();
+ localStorage.setItem(storageKey, JSON.stringify(newStatus));
});
}
});
diff --git a/apps/ide/src/plugins/plugin-settings-desktop.json b/apps/ide/src/plugins/plugin-settings-desktop.json
index 4e87a1b5..4310b199 100644
--- a/apps/ide/src/plugins/plugin-settings-desktop.json
+++ b/apps/ide/src/plugins/plugin-settings-desktop.json
@@ -16,29 +16,33 @@
"plugins/webida.editor.code-editor.content-assist.tern",
"plugins/webida.editor.example.simple-editor",
"plugins/webida.viewer.image-viewer",
- "plugins/help",
- "plugins/webida.preference",
+ "plugins/webida.editor.example.svg",
+ "plugins/webida.editor.example.multi-content",
"plugins/project-configurator",
"plugins/webida.ide.project-management.run",
- "plugins/webida.ide.project-management.run.java",
+ "plugins/webida.ide.project.deploy",
+ "plugins/help",
+ "plugins/webida.preference",
+ "plugins/webida.plugin-setting",
"plugins/webida.ide.search-result",
"plugins/webida.locale",
"plugins/uid-menu-items",
+ "plugins/webida.terminal",
"plugins/webida.ide.notification.view",
"plugins/webida.ide.notification.toast",
- "plugins/webida.plugin-setting",
"webida-lib/plugins/command-system",
"webida-lib/plugins/editors",
"webida-lib/plugins/fs-commands",
"webida-lib/plugins/git",
"webida-lib/plugins/output",
"webida-lib/plugins/preview",
+ "webida-lib/plugins/session-event-dispatcher",
"webida-lib/plugins/workspace",
- "webida-lib/plugins/workbench",
- "webida-lib/plugins/resources"
+ "webida-lib/plugins/workbench"
],
"start-plugins" : [
"webida-lib/plugins/command-system",
+ "webida-lib/plugins/session-event-dispatcher",
"webida-lib/plugins/workbench",
"plugins/webida.ide.notification.toast"
]
diff --git a/apps/ide/src/plugins/webida.editor.code-editor/menus.js b/apps/ide/src/plugins/webida.editor.code-editor/menus.js
index 3b24ace1..888d83e7 100644
--- a/apps/ide/src/plugins/webida.editor.code-editor/menus.js
+++ b/apps/ide/src/plugins/webida.editor.code-editor/menus.js
@@ -73,7 +73,7 @@ define([
blockCommentMenuItem.disabled = true;
}
if (delegator.canExecute('request')) {
- delegator.exeCommand('request', widget,
+ delegator.execCommand('request', widget,
{ type: 'rename', newName: 'someName', fullDocs: true },
function (error) {
if (!error) {
@@ -198,7 +198,7 @@ define([
commentOutSelectionMenuItem.invisible = true;
}
if (delegator.canExecute('request')) {
- delegator.exeCommand('request', widget,
+ delegator.execCommand('request', widget,
{ type: 'rename', newName: 'someName', fullDocs: true },
function (error) {
if (!error) {
diff --git a/common/src/webida/app.js b/common/src/webida/app.js
index 44ccbde8..cd8055e0 100644
--- a/common/src/webida/app.js
+++ b/common/src/webida/app.js
@@ -122,7 +122,11 @@ define([
}
function saveStatusSync() {
- logger.info('saveStatusSync()');
+ if (webida.VERSION && webida.VERSION === '0.1') {
+ logger.info('current server api does not support synchronous file writing');
+ return;
+ }
+
var statusString = getStatusStringToSave();
if (statusString) {
var formData = new FormData();
@@ -373,13 +377,12 @@ define([
logger.error('failed to connect to conn server');
} else {
logger.log('connected to conn server');
-
- // sys.fs.change notification subscribe
// note from webida-desktop
// new server-api-*.js has no acl service and does not require
- // explicit subscription for default server events fs.change
- // And, since
+ // explicit subscription for default server events like fs.change
+ // So, msgAgent.init() actually do nothing but returns some dummy
+ // stuffs & real event processing will be handled without app.js
if (typeof webida.acl !== 'object') {
logger.log('no need to subscribe and topic relay with new api ');
diff --git a/common/src/webida/plugins/command-system/command/command-factory.js b/common/src/webida/plugins/command-system/command/command-factory.js
index 7c0048a8..f094f742 100644
--- a/common/src/webida/plugins/command-system/command/command-factory.js
+++ b/common/src/webida/plugins/command-system/command/command-factory.js
@@ -52,7 +52,10 @@ define([
return new Promise(function (resolve) {
var registry = commandRegistry.getCommand(id);
if (registry) {
- require([registry.plugin + '/commands'], function (extension) {
+ console.warn('create command from ' + registry.plugin + '/commands');
+ console.warn('create command id ' + id , option);
+ require([registry.plugin + '/commands'], function (extension) {
+ console.warn('create command with extension ', extension);
var Constructor = extension[toPascalCase(id) + 'Command'];
if (!Constructor) {
var changedId = id.split(':')[0];
diff --git a/common/src/webida/plugins/editors/DataSourceHandler.js b/common/src/webida/plugins/editors/DataSourceHandler.js
index bb8df9e0..ee560fc3 100644
--- a/common/src/webida/plugins/editors/DataSourceHandler.js
+++ b/common/src/webida/plugins/editors/DataSourceHandler.js
@@ -54,7 +54,7 @@ define([
logger.info('new DataSourceHandler()');
/** @type {Object} */
- this.subscribed = [];
+ this.subscriptionHandles = [];
/** @type {Array.} */
this.deletedNodesSet = [];
this._subscribe();
@@ -78,11 +78,14 @@ define([
*/
_subscribe: function () {
//on deleted
- this.subscribed.push(topic.subscribe('workspace/nodes/deleting', this._onNodesDeleted.bind(this)));
- this.subscribed.push(topic.subscribe('fs/cache/node/deleted', this._checkCase.bind(this)));
+ this.subscriptionHandles.push(topic.subscribe('workspace/nodes/deleting',
+ this._onNodesDeleted.bind(this)));
+ this.subscriptionHandles.push(topic.subscribe('fs/cache/node/deleted',
+ this._checkCase.bind(this)));
//on content changed
- this.subscribed.push(topic.subscribe('remote/persistence/updated', this._onContentChange.bind(this)));
+ this.subscriptionHandles.push(topic.subscribe('remote/persistence/updated',
+ this._onContentChange.bind(this)));
},
/**
@@ -90,8 +93,8 @@ define([
* @protected
*/
_unsubscribe: function () {
- this.subscribed.forEach(function (subscribed) {
- subscribed.remove();
+ this.subscriptionHandles.forEach(function (handle) {
+ handle.remove();
});
},
@@ -232,8 +235,11 @@ define([
//https://github.com/webida/webida-client/issues/670
//Changing dataSourceId as URI format
var dsRegistry = _getWorkbench().getDataSourceRegistry();
- var dataSource = dsRegistry.getDataSourceById(dataSourceId.replace('wfs:/', ''));
- _askReload(dataSource);
+ var dsid = dataSourceId.replace('wfs:', '');
+ var dataSource = dsRegistry.getDataSourceById(dsid);
+ if (dataSource) {
+ _askReload(dataSource);
+ }
},
/**
diff --git a/common/src/webida/plugins/fs-commands/commands.js b/common/src/webida/plugins/fs-commands/commands.js
index 4e152a34..4e16c4ac 100644
--- a/common/src/webida/plugins/fs-commands/commands.js
+++ b/common/src/webida/plugins/fs-commands/commands.js
@@ -1070,10 +1070,10 @@ define([
}
});
- function DeleteCommand(id) {
- DeleteCommand.id = id;
+ function DeleteFileCommand(id) {
+ DeleteFileCommand.id = id;
}
- genetic.inherits(DeleteCommand, Command, {
+ genetic.inherits(DeleteFileCommand, Command, {
execute : function () {
return new Promise(function (resolve) {
wv.removeInteractively();
@@ -1099,6 +1099,6 @@ define([
CopyCommand: CopyCommand,
CutCommand: CutCommand,
PasteCommand: PasteCommand,
- DeleteCommand: DeleteCommand
+ DeleteFileCommand: DeleteFileCommand
};
});
diff --git a/common/src/webida/plugins/resources/resource-event.js b/common/src/webida/plugins/resources/resource-event.js
index 62b018fa..be9e2e7f 100644
--- a/common/src/webida/plugins/resources/resource-event.js
+++ b/common/src/webida/plugins/resources/resource-event.js
@@ -61,7 +61,7 @@ define([
function getWfsUri(path) {
if (typeof path === 'string') {
- return 'wfs:/' + path;
+ return 'wfs:' + path;
} else {
return null;
}
diff --git a/common/src/webida/plugins/session-event-dispatcher/dispatch-legacy-resource-topics.js b/common/src/webida/plugins/session-event-dispatcher/dispatch-legacy-resource-topics.js
new file mode 100644
index 00000000..05c50c4f
--- /dev/null
+++ b/common/src/webida/plugins/session-event-dispatcher/dispatch-legacy-resource-topics.js
@@ -0,0 +1,135 @@
+/*
+* Copyright (c) 2012-2015 S-Core Co., Ltd.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+/**
+ * Legacy resource topic dispatcher for sys.fs.* and resource/*, remote/* events
+ * This module dispatches dojo topics from new server api events
+ *
+ * @since: 2016.06.30
+ */
+
+define([
+ 'dojo/topic',
+ 'external/URIjs/src/URI',
+ 'webida-lib/util/logger/logger-client',
+ 'webida-lib/server-api'
+], function (
+ topic,
+ URI,
+ Logger,
+ webida
+) {
+ 'use strict';
+
+ var logger = Logger.getSingleton();
+ logger.debug = logger.log;
+
+ // All event names that begin with '__' is now deprecated.
+ // New Event Bus will not publish __* events to any channels
+
+ var LEGACY_FS_TOPIC_NAMES = {
+ // events generated by sever
+ addDir: 'sys.fs.dir.created',
+ unlinkDir: 'sys.fs.dir.deleted',
+ add:'sys.fs.file.written', // sys.fs.file.created seems to have no effects.
+ change:'sys.fs.file.written',
+ unlink:'sys.fs.file.deleted',
+
+ // events generated by client, as a result of api call
+ _addDir: 'sys.fs.dir.created',
+ _unlinkDir: 'sys.fs.dir.deleted',
+ _add:'sys.fs.file.created',
+ _change:'sys.fs.file.written',
+ _unlink:'sys.fs.file.deleted',
+
+ // fake events generated by client, as a result of api call
+ __refresh: 'sys.fs.node.interactableChanges',
+ __moved: 'sys.fs.node.moved',
+ __copied: 'sys.fs.node.copied',
+ __exec : 'sys.fs.node.interactableChanges'
+ };
+
+ var LEGACY_RESOURCES_TOPIC_NAMES = {
+ // events generated by sever
+ addDir: 'remote/directory/created',
+ unlinkDir: 'remote/directory/deleted',
+ add:'remote/persistence/created',
+ change:'remote/persistence/updated',
+ unlink:'remote/persistence/deleted',
+
+ // events generated by client, as a result of api call
+ _addDir: 'resources/directory/created',
+ _unlinkDir: 'resources/directory/deleted',
+ _add:'resources/persistence/created',
+ _change:'resources/persistence/updated',
+ _unlink:'resources/persistence/deleted'
+ };
+
+ // we don't map 'remote' topics for now.
+ // editors
+
+ function WfsEvent(wfsId, type, wfsPath) {
+ this.wfsId = wfsId;
+ this.type = type;
+ this.wfsPath = wfsPath;
+ }
+
+ WfsEvent.prototype = {
+ getLegacyWfsUrl : function getLegacyWfsUrl() {
+ var wfsUriPath = this.wfsId + '/' + this.wfsPath;
+ var wfsUri = webida.info.serverUri.protocol('wfs').path(wfsUriPath).normalize();
+ return wfsUri.toString();
+ },
+
+ getResourceWfsUrn : function getLegacyWfsUrl() {
+ return 'wfs:' + '/' + this.wfsPath; // path should be absolute in urn
+ },
+
+ // reserved to next release - wfs events will have 'independent' channels per fsid
+ // getEventChannelName : function getEventChannelName() {
+ // return 'server/wfs/' + this.wfsId;
+ // },
+
+ getLegacyFsTopicData : function getLegacyFsTopicData(eventType) {
+ return {
+ sid: eventType[0] === '_' ? webida.info.sessionId : 'out-of-session',
+ url: this.getLegacyWfsUrl()
+ };
+ }
+ };
+
+ //See https://github.com/webida/webida-developer-guide-english/wiki/Event-System
+ function dispatchLegacyResourceTopics() {
+
+ // since no legacy events are using stats, we discard stats here
+ var wfsEvent = new WfsEvent(arguments[0], arguments[1], arguments[2]);
+ var legacyFsTopicName = LEGACY_FS_TOPIC_NAMES[wfsEvent.type];
+ var legacyResourcesTopicName = LEGACY_RESOURCES_TOPIC_NAMES[wfsEvent.type];
+
+ if (legacyFsTopicName) {
+ var topicData = wfsEvent.getLegacyFsTopicData(wfsEvent.type);
+ logger.debug('dispatching ' + legacyFsTopicName, topicData);
+ topic.publish(legacyFsTopicName, topicData);
+ }
+ if (legacyResourcesTopicName) {
+ var topicUrn = wfsEvent.getResourceWfsUrn();
+ logger.debug('dispatching ' + legacyResourcesTopicName, topicUrn);
+ topic.publish(legacyResourcesTopicName, topicUrn);
+ }
+ }
+
+ return dispatchLegacyResourceTopics;
+});
diff --git a/common/src/webida/plugins/session-event-dispatcher/plugin.js b/common/src/webida/plugins/session-event-dispatcher/plugin.js
new file mode 100644
index 00000000..0709271c
--- /dev/null
+++ b/common/src/webida/plugins/session-event-dispatcher/plugin.js
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file handles server api events and publish client level topics/events
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ 'external/URIjs/src/URI',
+ 'dojo/topic',
+ 'webida-lib/server-api',
+ 'webida-lib/util/logger/logger-client',
+ './dispatch-legacy-resource-topics'
+], function (
+ URI,
+ topic,
+ webida,
+ Logger,
+ dispatchLegacyResourceTopics
+) {
+ 'use strict';
+
+ var logger = Logger.getSingleton();
+ logger.debug = logger.log;
+ var sessionClient = webida.session;
+
+ function dispatchTopic(topicName) {
+ return function __reflectingTopicDispatcher(eventName) {
+ var args = [];
+ args.push(eventName);
+ for (var i=1; i < arguments.length; i++) {
+ args.push(arguments[i]);
+ }
+ logger.debug('reflecting event ' + eventName + ' to topic ' + topicName, args);
+ topic.publish.apply(topic, args);
+ };
+ }
+
+ sessionClient.on('announcement', dispatchTopic('server/session/announcement'));
+ sessionClient.on('closing', dispatchTopic('server/session/closing'));
+ sessionClient.on('connect', dispatchTopic('server/session/'));
+ sessionClient.on('disconnect', dispatchTopic('server/session/disconnect'));
+ sessionClient.on('reconnect', dispatchTopic('server/session/reconnect'));
+ sessionClient.on('connect_error', dispatchTopic('server/session/connect/error'));
+ sessionClient.on('connect_timeout', dispatchTopic('server/session/connect/timeout'));
+ sessionClient.on('reconnect_failed', dispatchTopic('server/session/reconnect/failed'));
+
+ sessionClient.on('wfs', dispatchLegacyResourceTopics);
+
+ // need some 'toasting' plugin for basic session events, but not here.
+ // for this plugins should work without toaster.
+ // we may need a 'session-manager' plugin, using workbench, toaster and other plugins
+ // to show & manage session-related user actions.
+ // for examples
+ // 1) pop-up login dialogs and send credentials to api
+ // 2) pop-up some warning message when server begins knight-fall protocol (closing)
+ // 3) pop-up some warning message when client lost session client connection to server
+ // 4) pop-up some 'off-line' warning and show some status bar message
+
+ logger.debug('initialized session event dispatcher plugin');
+ return {};
+});
diff --git a/common/src/webida/plugins/session-event-dispatcher/plugin.json b/common/src/webida/plugins/session-event-dispatcher/plugin.json
new file mode 100644
index 00000000..41972abf
--- /dev/null
+++ b/common/src/webida/plugins/session-event-dispatcher/plugin.json
@@ -0,0 +1,6 @@
+{
+ "name": "webida.common.session-event-dispatcher",
+ "description": "Plugin that handles server/service level events to publish plugin topics",
+ "version": "0.1.0",
+ "requirement": ""
+}
diff --git a/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js b/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
new file mode 100644
index 00000000..582cb547
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
@@ -0,0 +1,271 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file AbstractSocketClient.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+// we don't want cyclic dependencies between common and TokenManager.
+// so, instead of requiring just ./common, we require all dependencies directly
+// the only instance of TokenManager is saved in common
+define([
+ 'URIjs',
+ 'external/eventEmitter/EventEmitter',
+ 'external/lodash/lodash.min',
+ 'external/socket.io-client/socket.io',
+ 'webida-lib/util/genetic',
+ './common'
+], function (
+ URI,
+ EventEmitter,
+ _,
+ io,
+ genetic,
+ common
+) {
+ 'use strict';
+
+ var logger = common.logger;
+
+ // to protect session token from outage,
+ // token manager should care about 'maximum recovery time'
+ // since we use socket.io's reconnection mechanism, calculation is quite complex.
+
+ var CONNECT_OPTIONS = {
+ multiplex: true, // each socket share web socket connection (need testing)
+ timeout : 5000, // before connect_error and connect_timeout are emitted.
+ transports : ['websocket'], // forces the transport to be only websocket.
+ reconnection: true,
+ reconnectionDelay: 500, // delay grows 0.5, 1.0, 1.5, to 3.0
+ reconnectionDelayMax : 3000,
+ reconnectionAttempts: 20,
+ };
+
+ // connectOptions.query is object, not string
+ function AbstractSocketClient(namespace, connectOptions) {
+ EventEmitter.call(this);
+ this._connectOptions = _.defaults({}, CONNECT_OPTIONS, connectOptions);
+ this._namespace = namespace;
+ this.socket = null;
+ this.isConnected = false;
+ this.reconnectingCount = 0;
+ this.disconnectedWhen = new Date().getTime();
+ }
+
+ genetic.inherits(AbstractSocketClient, EventEmitter, {
+
+ connect: function connect() {
+ // connect options cannot be changed after socket object is made
+ // even if we put a getter for this._connectOptions.query, socket.io will not
+ // read the query string again.
+ this._connectOptions.query = this._buildConnectQueryString();
+ var connectUrl = common.serverUrl + '/' + this._namespace;
+ logger.debug(this.constructor.name + ' connecting to ' + connectUrl,
+ this._connectOptions);
+ this.socket = io(common.serverUrl + '/' + this._namespace, this._connectOptions);
+ this._registerConnectionEventHandlers();
+ this._registerEventHandlers();
+ },
+
+ disconnect: function disconnect() {
+ this.socket.disconnect();
+ },
+
+ // OVERRIDE ME! don't call super._getEventHandlers!
+ _getEventHandlers: function () {
+ logger.warn(this.constructor.name + ' has no event handlers');
+ return {};
+ },
+
+ // should return true to emit event
+ _onConnect : function onConnect(error, isTimeout) {
+ var info = {
+ isTimeout : isTimeout,
+ took : (new Date().getTime() - this.disconnectedWhen) + 'msec'
+ };
+ var ret = false;
+ if (error) {
+ // ignores reconnecting error for it will be handled in onReconnect
+ if (this.reconnectingCount === 0) {
+ logger.error(this.constructor.name + ' connect error ', error, info);
+ ret = true;
+ }
+ } else {
+ logger.debug(this.constructor.name + ' connected to server', info);
+ ret = true;
+ }
+ return ret;
+ },
+
+ _onDisconnect : function onDisconnect() {
+ logger.debug(this.constructor.name + ' disconnected from server');
+ return true;
+ },
+
+ // error, false => retrying error (will try again)
+ // error, true => recovery failed. completely lost (will not try again)
+ // null, false => retrying
+ // null, true => recovery success
+ _onReconnect : function onReconnect(error, done) {
+ var reconnectingFor = new Date().getTime() - this.disconnectedWhen;
+ var reconnectingInfo = {
+ reconnectingCount : this.reconnectingCount,
+ reconnectingFor : reconnectingFor + ' msec'
+ };
+ var ret = false;
+ var name = this.constructor.name;
+ if (error) {
+ if (done) {
+ logger.error(name + ' LOST CONNECTION', error, reconnectingInfo);
+ ret = true;
+ this.reconnectingCount = 0;
+ } else {
+ logger.warn(name + ' reconnecting attempt failed', error, reconnectingInfo);
+ }
+ } else {
+ if (done) {
+ logger.debug(name + ' recovered connection ', reconnectingInfo);
+ ret = true;
+ } else {
+ logger.debug(name + ' is trying to recover connection', reconnectingInfo);
+ }
+ }
+ return ret;
+ },
+
+ // calculating recovery time (without max delay)
+ // - worst case : every reconnecting fails with timeout
+ // - best case : every reconnecting fails immediately
+ // = (n*t) + (d*n*(n-1)/2)
+ // With maximum reconnecting delay time, calculation is a bit more complex
+ // second term of f(n,d,t) becomes
+ // d*m*(m+1)/2 + D*(n-m-1) where D = maximum delay time, m = D/d
+ // = D*(m+1)/2 * D*(n-m-1) = D*(n-(m+1)/2)
+ calculateRecoveryTime : function calculateRecoveryTime() {
+ var opt = this._connectOptions;
+
+ if (!opt.reconnect) {
+ return {
+ best : 0,
+ worst: 0
+ };
+ }
+
+ var n = opt.reconnectionAttempts;
+ var t = opt.timeout;
+ var d = opt.reconnectionDelay;
+ var D = opt.reconnectionDealyMax;
+ var m = D/d;
+
+ var best = D * (n - (m + 1) / 2);
+ var worst = best + (n * t);
+
+ // if we set n = 20, t=5, d = 0.5, D=3 ,in default
+ // best : 3* (20 - 7/2) = 3*16.5 = 49.5
+ // worst : 149.5
+ return {
+ best : best,
+ worst: worst
+ };
+ },
+
+ _buildConnectQueryString: function _buildConnectQueryString() {
+ var uri = new URI();
+ var queryObject = _.defaults({}, CONNECT_OPTIONS.query, this._connectOptions.query);
+
+ logger.debug('building query object', queryObject,
+ CONNECT_OPTIONS.query, this._connectOptions.query);
+
+ queryObject.token = common.tokenManager.accessToken.text;
+ return uri.query(queryObject).query();
+ },
+
+ _registerConnectionEventHandlers: function _registerConnectionEventHandlers () {
+ var myself = this;
+ var socket = this.socket;
+
+ socket.on('connect', function () {
+ myself.isConnected = true;
+ myself.reconnectingCount = 0;
+
+ // we don't need to handle manager events
+ var shouldEmit = myself._onConnect();
+ if (shouldEmit) {
+ myself.emit('connect');
+ }
+ });
+
+ socket.on('connect_error', function (err) {
+ var shouldEmit = myself._onConnect(err);
+ if (shouldEmit) {
+ myself.emit('connect_error', err);
+ }
+ });
+
+ socket.on('connect_timeout', function (err) {
+ var shouldEmit = myself._onConnect(err, true);
+ if (shouldEmit) {
+ myself.emit('connect_timeout', err);
+ }
+ });
+
+ socket.on('reconnect_attempt', function (count) {
+ myself.reconnectingCount = count;
+ myself._onReconnect(null, false);
+ });
+
+ // seems not fired
+ socket.on('reconnect_error', function (err) {
+ myself._onReconnect(err, false);
+ });
+
+ socket.on('reconnect', function () {
+ myself.isConnected = true;
+ myself._onReconnect(null, true);
+ myself.disconnectedWhen = 0;
+ myself.reconnectingCount = 0;
+ myself.emit('reconnect');
+ });
+
+ socket.on('reconnect_failed', function (err) {
+ err = err || new Error('too much retry - reached to limit');
+ myself._onReconnect(err, true);
+ myself.emit('reconnect_failed', err);
+ });
+
+ socket.on('disconnect', function () {
+ myself.disconnectedWhen = new Date().getTime();
+ myself.isConnected = false;
+ myself._onDisconnect();
+ myself.emit('disconnect');
+ });
+ },
+
+ _registerEventHandlers: function _registerEventHandlers() {
+ var handlers = this._getEventHandlers();
+ // handlers should map event name to handler function
+ // handler function does not have to bind 'this'
+ var myself = this;
+ _.forEach(handlers, function(handler, eventName) {
+ myself.socket.on(eventName, handler.bind(myself));
+ });
+ }
+ });
+
+ return AbstractSocketClient;
+});
diff --git a/common/src/webida/server-api-0.1-lib/TokenManager.js b/common/src/webida/server-api-0.1-lib/TokenManager.js
index b00abf96..76a60342 100644
--- a/common/src/webida/server-api-0.1-lib/TokenManager.js
+++ b/common/src/webida/server-api-0.1-lib/TokenManager.js
@@ -29,7 +29,7 @@ define([
'webida-lib/util/logger/logger-client',
'./webida-service-api-0.1/src/index'
], function (
- EventEmitter,
+ EventEmitter,
genetic,
Logger,
WebidaServiceApi
@@ -46,12 +46,13 @@ define([
var MARGIN_TO_EXPIRE = WebidaServiceApi.ApiClient.instance.timeout + (30 * 1000);
var RETRY_AFTER = 5 * 1000;
- var authApi = new WebidaServiceApi.AuthApi();
+ var authApi = new WebidaServiceApi.AuthApi();
// IDE does not use master token except login with master token
// so, TokenManager handles access token only
function TokenManager(accessToken) {
+ EventEmitter.call(this);
this._updateTimer = null;
if (accessToken) {
this.updateAccessToken(accessToken);
@@ -138,7 +139,6 @@ define([
});
},
- //
getRemainingTTL : function() {
var expireTime = this.accessToken.expiresAt.getTime();
var currentTime = new Date().getTime();
@@ -155,5 +155,4 @@ define([
TokenManager.instance = new TokenManager();
return TokenManager;
-
});
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
index 4b4fd463..e4f34703 100644
--- a/common/src/webida/server-api-0.1-lib/auth.js
+++ b/common/src/webida/server-api-0.1-lib/auth.js
@@ -21,15 +21,17 @@
*/
define([
- './common'
+ './common',
+ './session'
], function (
- common
+ common,
+ session
) {
'use strict';
var logger = common.logger;
var AuthApi = common.api.AuthApi;
var authApi = new AuthApi();
-
+
// TODO : introduce webida.initializeAsync() that handles all init things,
// with credential provider that interacts with UI,
// and remove initAuth or make it a legacy-compatibility helper
@@ -44,7 +46,7 @@ define([
});
common.tokenManager.on('updated', function(token) {
- console.log('updated token', token);
+ logger.debug('updated token', token);
});
// initAuth is called by app.js at first, before loading any other plugins
@@ -68,6 +70,7 @@ define([
throw(err);
}
common.tokenManager.updateAccessToken(data);
+ session.connect();
// Oddly, there's no error-fist-callback for initAuth
logger.log('initAuth registered access token', data);
callback(data.sessionId);
@@ -88,7 +91,7 @@ define([
return {
initAuth : initAuth,
getMyInfo : getMyInfo,
-
+
// for compatiblity with legacies
getTokenObj : function getTokenObj() {
var token = common.accessToken;
diff --git a/common/src/webida/server-api-0.1-lib/common.js b/common/src/webida/server-api-0.1-lib/common.js
index 000f30b5..354c2077 100644
--- a/common/src/webida/server-api-0.1-lib/common.js
+++ b/common/src/webida/server-api-0.1-lib/common.js
@@ -21,11 +21,13 @@
*/
define([
'URIjs',
+ 'external/eventEmitter/EventEmitter',
'webida-lib/util/logger/logger-client',
'./webida-service-api-0.1/src/index',
'./TokenManager'
], function (
URI,
+ EventEmitter,
Logger,
WebidaServiceApi,
TokenManager
@@ -39,11 +41,9 @@ define([
var privates = {
bootArgs : null,
- // comes from boot args. need public accessor
serverUri : null,
serverUrl : null,
-
- // comes from login response. no need of public accessor
+ session: null,
tokenManager : TokenManager.instance
};
@@ -51,7 +51,11 @@ define([
// accessors to privates. getters only, no setters
get logger() { return logger; },
get bootArgs() { return privates.bootArgs; },
+ get serverUri() { return privates.serverUri; },
+ get serverUrl() { return privates.serverUrl; },
+ get session() { return privates.session; },
get tokenManager() { return privates.tokenManager;},
+ get accessToken() { return privates.tokenManager.accessToken; },
get api() {
return WebidaServiceApi;
}
@@ -87,11 +91,12 @@ define([
}
}
});
- console.log('swagger api default client', defaultClient);
+ logger.debug('swagger api default client', defaultClient);
}
/* module main script */
initializeThisModule();
+
return publics;
});
diff --git a/common/src/webida/server-api-0.1-lib/fs.js b/common/src/webida/server-api-0.1-lib/fs.js
index 9fc69716..5d1227c9 100644
--- a/common/src/webida/server-api-0.1-lib/fs.js
+++ b/common/src/webida/server-api-0.1-lib/fs.js
@@ -22,7 +22,7 @@
define([
'./common',
- './WfsMount'
+ './wfs/WfsMount'
], function (
common,
WfsMount
@@ -56,5 +56,4 @@ define([
return {
mountByFSID : mountByFSID
};
-
});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/messaging.js b/common/src/webida/server-api-0.1-lib/messaging.js
new file mode 100644
index 00000000..878fe22a
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/messaging.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file messaging.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ 'external/eventEmitter/EventEmitter',
+ 'webida-lib/util/genetic',
+ './common',
+ './AbstractSocketClient'
+], function (
+ EventEmitter,
+ io,
+ common
+) {
+ 'use strict';
+ var logger = common.logger;
+
+ // for some 'plugin specific socket client', we need
+ // 1) generic name space, 'ide' or 'plugins', 'app', 'generic', ... etc
+ // 2) a socket client (with space-specific protocol) that can
+ // create/join/leave/remove room
+ // broadcast to all, broadcast all but self
+ // send direct message to someone
+ // block/unblock message from someone
+ // 3) an abstract class to use the socket client
+
+ return {};
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/session.js b/common/src/webida/server-api-0.1-lib/session.js
new file mode 100644
index 00000000..d09dbcf6
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/session.js
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file TokenManager.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+// we don't want cyclic dependencies between common and TokenManager.
+// so, instead of requiring just ./common, we require all dependencies directly
+// the only instance of TokenManager is saved in common
+define([
+ 'webida-lib/util/genetic',
+ './common',
+ './AbstractSocketClient'
+], function (
+ genetic,
+ common,
+ AbstractSocketClient
+) {
+ 'use strict';
+
+ var logger = common.logger;
+ var SESSION_NAME_SPACE = 'session';
+
+ // some api modules will listen events from session client
+ // a plugin, called session-event-dispatcher, will listen for session client
+ // and will 'translate' session events into dojo topic
+
+ function SessionSocketClient() {
+ AbstractSocketClient.call(this, SESSION_NAME_SPACE, {
+ query : {
+ workspaceId:common.bootArgs.workspaceId
+ }
+ });
+ }
+
+ genetic.inherits(SessionSocketClient, AbstractSocketClient, {
+
+ // session events (should be handled by this class)
+ // wfsWatcher(wfsId, start/stop)
+ // wfsRaw(wfsId, fsEventName, path, stats)
+ // announcement(msg)
+ // closing(msg, after)
+ // basic events on connection (handled in AbstractSocketClient class)
+ // connect
+ // connect_error(error)
+ // connect_timeout(error)
+ // disconnect
+ // reconnect
+ // reconnect_failed(err)
+
+ _getEventHandlers: function () {
+ return {
+ // wfs-watch event is subscribed by fs module
+ // stats object is not wfs/WfsStats instance.
+ wfsWatcher: function(wfsId, event) {
+ logger.debug('session got wfsWatcher event', arguments);
+ this.emit('wfsWatcher', wfsId, event);
+ },
+
+ // wfs events will be fired through WFS Mount,
+ wfsRaw: function(wfsId, event, path, stats) {
+ logger.debug('session got wfsRaw event', arguments);
+ this.emit('wfsRaw', wfsId, event, path, stats);
+ },
+
+ announcement: function(msg) {
+ logger.debug('session got announcement event', arguments);
+ this.emit('announcement', msg);
+ },
+ closing: function(msg, after) {
+ logger.debug('session got closing event', arguments);
+ this.emit('closing', msg, after);
+ }
+ };
+ }
+ });
+
+ return new SessionSocketClient();
+});
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
index fc7d4352..d00b802b 100644
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
+++ b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
@@ -109,7 +109,7 @@
*/
exports.prototype['state'] = undefined;
/**
- * the id of workspace that this sessions is working on.
+ * the id of workspace that this workspaces is working on.
* @member {String} workspaceId
*/
exports.prototype['workspaceId'] = undefined;
diff --git a/common/src/webida/server-api-0.1-lib/WfsEntry.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
similarity index 75%
rename from common/src/webida/server-api-0.1-lib/WfsEntry.js
rename to common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
index fcc2b8cc..9a8d1796 100644
--- a/common/src/webida/server-api-0.1-lib/WfsEntry.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
@@ -34,12 +34,9 @@ define([
enumerable : false,
configurable : false
});
-
this.children = [];
-
this.name = name;
-
- this._basepath = null; // will be filled later
+ this._path = null; // will be filled later
// when building tree with entries
// parent property will be set later and initially undefined
@@ -58,25 +55,19 @@ define([
// for compatiblity with webida 1.x client
// (will be replaced to function as node.js does, later )
get path() {
- if (this.parent) {
- return this.parent.path + '/' + this.name;
+ if (this.isRoot()) {
+ return this._path || '/';
} else {
- var basePath = this.basePath || '/';
- return basePath + this.name;
+ return this.parent._path + this.name;
}
},
- get basepath() {
- return this.parent ? null : this._basepath;
- },
-
- // basepath should be set to root of tree, only
- set basepath(value) {
- if (!this.parent) {
- // when tree is /some/path/dir
- // this.name = dir
- // basepath = /some/path
- this._basepath = value.split('/');
+ set path(value) {
+ if (this.isRoot()) {
+ if (value.length > 1 && value[value.length-1] !== '/') {
+ value += '/';
+ }
+ this._path = value;
}
},
@@ -98,12 +89,6 @@ define([
return entry;
};
- WfsEntry.getBasePathOf = function getBasePathOf(path) {
- var segments = path.split('/');
- segments.pop();
- return segments.join('/');
- };
-
// later, we should extend this class to WfsFile & WfsDirectory
// we also need WfsTree to handle WfsEntry trees and subtree
//
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
new file mode 100644
index 00000000..72093474
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsEntry.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ '../common',
+ './WfsEventHolder',
+ './WfsStats',
+ './wfs-utils'
+], function (
+ common,
+ WfsEventHolder,
+ WfsStats,
+ wfsUtils
+) {
+ 'use strict';
+
+ // provides subset of legacy FileSystem object
+ // some methods are not supported, completely
+ // we should create better interface in next api 0.2 with cleaner spec and Promise
+
+ var logger = common.logger;
+ var POLLING_THRESHOLD = 2;
+ var POLLING_PERIOD = 100;
+
+ function WfsEventGate(session, wfsId) {
+ this.wfsId = wfsId;
+ this.session = session;
+ this.masks = {}; // when masked /a/b, /a/b and /a/b/* will be masked
+ this.holders = {}; // path -> mutating event
+
+ this.pollTimer = null;
+ this.eventSequence = 0;
+ this._pollEventsBound = this._pollEvents.bind(this);
+ this._onWatcherEventBound = this._onWatcherEvent.bind(this);
+
+ session.on('wfsRaw', this._onWatcherEventBound);
+ }
+
+ WfsEventGate.prototype = {
+
+ stopListening: function stopListening() {
+ if (this.session) {
+ this.session.off('wfsRaw', this._onWatcherEventBound);
+ logger.debug('stopped listening event on wfs ' + this.wfsId);
+ }
+ },
+
+ // When WfsMount calls some server api, it calls maskEvents() to hold events from server
+ // on api target(src/dst) paths, masking events on the path and it's descendants.
+ // (e.g. masking '/a/b' will mask events from /a/b and /a/b/**/*)
+
+ // Masking will fais if given path is already holded by some holder. That means, some
+ // API call is not completed on the path, or server has some command (build, git works...)
+ // on the path. If masking failes, WfsMount should not proceed api call and invoke
+ // failure callback with proper message.
+
+ maskEvents: function maskEvents(path, apiName) {
+ var holder = this.holders[path];
+ if (holder) {
+ if (holder.maskedBy) {
+ throw new Error(path + 'is locked by other api call ' + holder.maskedBy);
+ } else {
+ throw new Error(path + 'is locked by other processes in server');
+ }
+ }
+ // If there's no holder but a mask exists - events are not arrived for the path.
+ // If we omit checking, api may call unmask() twice with 'different' policies,
+ // and users will see somewhat weird things, maybe.
+ var mask = this.masks[path];
+ if (mask) {
+ throw new Error(path + 'is locked by other api call ' + mask.apiName);
+ } else {
+ this.masks[path] = {
+ apiName : apiName,
+ holders: []
+ };
+ logger.debug('added event mask for path ' + path);
+ }
+ },
+
+ // when unmasking, wfs api should pass unmasking policy
+ // 1) call was successful, discard held events and api wil emit a virtual event'
+ // 2) call was successful, flip event types to make them 'local, known changes'
+ // (flipping will prefix '_' at every normal held event)
+ // 3) call was unsuccessful. emit all held events as 'remote, unknown changes'
+ // (without flipping, every held event will be emitted as it is)
+
+ unmaskEvents: function unmaskEvents(path, succeeded, discardEventsFromHolders) {
+ var mask = this.masks[path];
+ var myself = this;
+ if (!succeeded) {
+ discardEventsFromHolders = false;
+ }
+ if (mask) {
+ var unhold = function unhold() {
+ mask.holders.forEach(function(holder) {
+ holder.unmask(succeeded, discardEventsFromHolders);
+ });
+ delete myself.masks[path];
+ };
+ // if we have no holders in the mask object yet, that means
+ // api calls unmask too fast, while no events has been arrived yet.
+ if (mask.holders.length === 0 ) {
+ logger.debug('postponed unmasking for no events has arrived yet');
+ setTimeout(unhold, POLLING_PERIOD);
+ } else {
+ unhold();
+ }
+ }
+ },
+
+ _findMask: function _isMasked(path) {
+ var ancestors = wfsUtils.getAncestors(path, { includeSelf:true } );
+ var myself = this;
+ var mask = null;
+ ancestors.some(function(ancestorPath) {
+ mask = myself.masks[ancestorPath];
+ return mask ? true : false;
+ });
+ return mask;
+ },
+
+ _addNewHolder : function _addNewHolder(path) {
+ var mask = this._findMask(path);
+ var holder = null;
+ if (mask) {
+ holder = new WfsEventHolder(this.wfsId, path, mask.apiName);
+ mask.holders.push(holder);
+ } else {
+ holder = new WfsEventHolder(this.wfsId, path);
+ }
+ this.holders[path] = holder;
+ return holder;
+ },
+
+ _onWatcherEvent : function _onWatcherEvent(wfsId, type, path, stats) {
+ if (wfsId !== this.wfsId) {
+ return;
+ }
+ logger.debug('event gate got wfsRaw event', arguments);
+ var holder = this.holders[path];
+ if (!holder) {
+ holder = this._addNewHolder(path);
+ }
+ // all sequence numbers from getWfsEvents() has positive number, excluding 0.
+ this.eventSequence++;
+ holder.holdServerEvent(type, stats, this.eventSequence);
+ if (!this.pollTimer) {
+ this.eventSequence = 0;
+ this.pollTimer = setInterval(this._pollEventsBound, POLLING_PERIOD);
+ logger.debug('polling holded events - started');
+ }
+ },
+
+ _fireEvents: function _fireEvents(events,startedAt) {
+ var myself = this;
+ events.forEach(function(event) {
+ var wstats = event.stats ? new WfsStats(event.stats) : undefined;
+ logger.debug('fire wfs event', event);
+ myself.session.emit('wfs', myself.wfsId, event.type, event.path, wstats);
+ });
+ var elapsedTime = new Date().getTime() - startedAt;
+ if (elapsedTime >= POLLING_PERIOD) {
+ // TODO: make polling interval & threshold adaptive, if possible
+ logger.warn('polling takes too long time ', {
+ polled: events.length,
+ elapsedTime: elapsedTime
+ });
+ }
+ },
+
+ _pollEvents : function _pollEvents() {
+ var startedAt = new Date().getTime();
+ var events = [];
+ var myself = this;
+ var allPaths = Object.keys(this.holders);
+
+ allPaths.forEach(function(path) {
+ var holder = myself.holders[path];
+ if (holder.poll(POLLING_THRESHOLD)) {
+ // when a holder has some missing events, all events held by the holder
+ // will not be emitted for app should reload stats of the path manually
+ // refreshing can be done anytime, but sequence will be set to 0,
+ // to refresh needed stats as soon as possible.
+ // Currently, the value of missingEventsBefore is not used but if we
+ // changes policy on missing events the number will be quite useful.
+ if (holder.missingEventsBefore) {
+ events.push({
+ path: holder.path,
+ type: '__refresh',
+ sequence : 0
+ });
+ } else {
+ holder.getWfsEvents().forEach(function (event) {
+ events.push(event);
+ });
+ }
+ delete myself.holders[holder.path];
+ }
+ });
+
+ if (events.length > 0 ) {
+ events.sort( function(ev1, ev2) {
+ return ev1.sequence - ev2.sequence;
+ });
+ this._fireEvents(events, startedAt);
+ }
+
+ if (allPaths.length <= 0) {
+ clearInterval(this.pollTimer);
+ this.pollTimer = null;
+ logger.debug('no more pollable holders - stopped timer');
+ }
+ }
+ };
+
+
+ return WfsEventGate;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
new file mode 100644
index 00000000..d4e75bff
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
@@ -0,0 +1,264 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file MutatingEvent.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ '../common'
+], function(
+ common
+) {
+ 'use strict';
+
+ var logger = common.logger;
+
+ function WfsEventHolder(wfsId, path, maskedBy) {
+ this.events = [];
+ this.path = path;
+ this.wfsId = wfsId;
+
+ this.discardEvents = false;
+ this.shouldFlipEventType = false;
+ this.maskedBy = maskedBy;
+ this.missingEventsBefore = 0;
+ // when counter is negative, poll() should not increase counter
+ this.pollCounter = 0;
+ }
+
+ // while stabilizing or masked
+ WfsEventHolder.prototype = {
+
+ get latest() {
+ if (this.events.length > 0) {
+ return this.events[this.events.length-1];
+ } else {
+ return null;
+ }
+ },
+
+ // returns true when this holder is 'stable' enough to fire events
+ // if poll returns true, gateway should fire events and remove holder
+ // when holder works under mask, (this.maskedBy is truthy)
+ // poll() will not work until this holder is freed by unmask() method.
+ poll: function pollToFireEvent(threshold) {
+ if (!this.maskedBy) {
+ this.pollCounter++;
+ if (this.pollCounter >= threshold) {
+ this.pollCounter = -9999; // to make enough time before being polled again.
+ return true;
+ }
+ }
+ return false;
+ },
+
+ // when path is 'unmasked' then this holder should become 'pollable'
+ unmask: function unmask(shouldFlipEventType, discardEvents) {
+ if (this.maskedBy) {
+ this.discardEvents = discardEvents;
+ this.shouldFlipEventType = shouldFlipEventType;
+ this.maskedBy = false;
+ }
+ },
+
+ getWfsEvents : function getWfsEvents() {
+ var myself = this;
+ if (this.discardEvents) {
+ return [];
+ } else {
+ return this.events.map( function(event) {
+ return {
+ path: myself.path,
+ type: myself.shouldFlipEventType ? '_' + event.type : event.type,
+ stats: event.stats,
+ sequence : event.sequence
+ };
+ });
+ }
+ },
+
+ holdServerEvent : function(newType, newStats, sequence) {
+ var latest = this.latest;
+ var current = {
+ type : newType,
+ stats : newStats,
+ sequence : sequence
+ };
+
+ if (!latest) {
+ this.events.push(current);
+ return;
+ }
+
+ // If we miss some events from server (due to connection problem)
+ // then events will be messed up (e.g. addDir->unlink->change->unlinkDir ..)
+ // Guessing what happened in 'the blank of history' is NOT SAFE
+ // and will make more complicated problems, probably.
+ // So, in that case, holder produces final wfs events '_refresh' only
+ // to force app to refresh the stats of path, manually.
+
+ switch(latest.type) {
+ case 'addDir':
+ this._holdAfterAddDir(latest, current);
+ break;
+ case 'unlinkDir':
+ this._holdAfterUnlinkDir(latest, current);
+ break;
+ case 'add':
+ this._holdAfterAdd(latest, current);
+ break;
+ case 'change':
+ this._holdAfterChange(latest, current);
+ break;
+ case 'unlink':
+ this._holdAfterUnlink(latest, current);
+ break;
+ default:
+ logger.error('unknown event type detected on ' + this.path, latest);
+ break;
+ }
+ this.pollCounter = 0;
+ },
+
+ _holdAfterAddDir: function _holdAfterAddDir(latest, current) {
+ switch(current.type) {
+ case 'unlinkDir':
+ // there has been a 'very short lived' directory
+ this.events.pop();
+ break;
+ case 'addDir':
+ case 'add':
+ case 'change':
+ case 'unlink':
+ this._markMissingEvents(latest, current);
+ this.events.push(current);
+ break;
+ default:
+ logger.error('new event has invalid type', current);
+ break; //
+ }
+ },
+
+ _holdAfterUnlinkDir: function _holdAfterUnlinkDir(latest, current){
+ switch(current.type) {
+ case 'add': // a dir is removed and a file replaced that path. very normal.
+ case 'addDir':
+ // if we discard this event as we do in addDir event, new stats of addedDir
+ // cannot be set to upper layer. Guess what happens if we have events,
+ // addDir1 -> unlinkDir -> addDir2 : addDir2 remains with new stats
+ // unlinkDir1 -> addDir -> unlinkDir2 : unlinkDir 1 remains, without stats. OK.
+ this.events.push(current);
+ break;
+ case 'unlinkDir': // maybe missing addDir
+ case 'change': // maybe missing add
+ case 'unlink': // maybe missing add and some changes
+ this._markMissingEvents(latest, current);
+ this.events.push(current);
+ break;
+ default:
+ logger.error('new event has invalid type', current);
+ break; //
+ }
+ },
+
+ _holdAfterAdd: function _holdAfterAdd(latest, current) {
+ switch(current.type) {
+ case 'change':
+ // when a file is added and changed, then it means is still 'writing' contents.
+ // in that case, we preserve previous add event, replacing stats only
+ latest.stats = current.stats;
+ break;
+ case 'unlink': // file is added and removed. same as handling unlinkDir after addDir
+ this.events.pop();
+ break;
+ case 'add': // maybe missing unlink
+ case 'addDir': // maybe missing unlink
+ case 'unlinkDir': // maybe missing unlink and addDir
+ this._markMissingEvents(latest, current);
+ this.events.push(current);
+ break;
+ default:
+ logger.error('new event has invalid type', current);
+ break; //
+ }
+ },
+
+ _holdAfterChange: function _holdAfterChange(latest, current) {
+ switch(current.type) {
+ case 'change':
+ // it's still writing.
+ latest.stats = current.stats;
+ break;
+ case 'unlink':
+ // no need to keep 'changing' history - we have 2 possible cases
+ // 1) add -> change -> unlink ==> discard all
+ // 2) change -> unlink ==> unlink remains.
+ // case 1 does not happens for _holdAfterAdd merges 'change' event into add.
+ this.events.pop();
+ this.events.push(current);
+ break;
+ case 'add': // maybe missing unlink
+ case 'addDir': // maybe missing unlink
+ case 'unlinkDir': // maybe missing unlink and addDir
+ this._markMissingEvents(latest, current);
+ this.events.push(current);
+ break;
+ default:
+ logger.error('new event has invalid type', current);
+ break; //
+ }
+ },
+
+ _holdAfterUnlink: function _holdAfterUnlink(latest, current) {
+ switch(current.type) {
+ case 'add':
+ // it's usually 'atomic writing'
+ latest.type = 'change';
+ latest.stats = current.stats;
+ // if server is creating a new directory and write a file atomically
+ // then this 'chage' event should be fired after creating the directory.
+ // if we don't change sequence number, such natural order might be broken.
+ latest.sequence = current.sequence;
+ break;
+ case 'addDir': // very normal. just removed a file and replaced to a dir.
+ this.events.push(current);
+ break;
+ case 'change': // maybe missing 'add'
+ case 'unlink': // maybe missing 'add'
+ case 'unlinkDir': // maybe missing 'addDir'
+ this._markMissingEvents(latest, current);
+ this.events.push(current);
+ break;
+ default:
+ logger.error('new event has invalid type', current);
+ break; //
+ }
+ },
+
+ _markMissingEvents : function(latest, current) {
+ logger.warn(this.path + ' has lost some events between latest and current event',
+ latest, current );
+ if (!this.missingEventsBefore) {
+ this.missingEventsBefore = current.sequence;
+ }
+ }
+ };
+
+ return WfsEventHolder;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/WfsMount.js b/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
similarity index 65%
rename from common/src/webida/server-api-0.1-lib/WfsMount.js
rename to common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
index f6ca2430..3f802243 100644
--- a/common/src/webida/server-api-0.1-lib/WfsMount.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
@@ -21,14 +21,18 @@
*/
define([
- './common',
- './Stats',
+ '../common',
+ '../session',
+ './WfsStats',
'./WfsEntry',
+ './WfsEventGate',
'./wfs-utils'
], function (
common,
- Stats,
+ session,
+ WfsStats,
WfsEntry,
+ WfsEventGate,
wfsUtils
) {
'use strict';
@@ -43,78 +47,107 @@ define([
function abstractify(name) {
return function abstractMethod() {
var methodName = name || 'method';
- throw new Error(methodName + ' is abstract');
+ var callback = arguments[arguments.length-1];
+ var err = new Error(methodName + ' is abstract');
+ if (typeof(callback) === 'function') {
+ return callback(err);
+ } else {
+ throw err;
+ }
};
}
function WfsMount(fsid) {
this.wfsId = fsid;
- }
+ this.eventGate = new WfsEventGate(session, fsid);
+ var myself = this;
+
+ // if watcher has already started by other client
+ // wfsWatcher#start event will never be delivered to session socket
+ session.on('wfsWatcher', function(wfsId, event) {
+ if (myself.eventGate && myself.wfsId === wfsId && event === 'stop') {
+ myself.eventGate.stopListening();
+ myself.eventGate = null;
+ }
+ });
+ }
WfsMount.prototype = {
_fromLegacyPath: function _fromLegacyPath(legacyPath, allowUrl) {
- return wfsUtils.fromLegacyPath(legacyPath, allowUrl ? this.wfsId : undefined);
+ try {
+ return wfsUtils.fromLegacyPath(legacyPath, allowUrl ? this.wfsId : undefined);
+ } catch (e) {
+ console.error('legacy path seems to be invalid : ' + legacyPath);
+ }
},
// result handler is (result, xhr) => desired (processed) result
// usually, some json object will be transformed into a class instance
-
- _createApiCallback: function (apiName, resultHandler, callback) {
- function echo(x) {
- return x;
- }
+ _createApiCallback: function (apiName, resultHandler, callback, maskingPath) {
+ var myself = this;
+ function echo(x) { return x; }
function invokeCallback(callback, err, result) {
try {
callback(err, result);
} catch(e) {
- logger.debug('app layer callback for ' + apiName + '() had error', e);
+ logger.warn('app layer callback for ' + apiName + '() threw error', e);
}
}
- return function (err, result, response) {
+ return function generatedCallback(err, result, response) {
if (err) {
logger.debug('wfsapi.' + apiName + '() error', err);
- callback(err);
+ if (maskingPath && myself.eventGate) {
+ myself.eventGate.unmaskEvents(maskingPath, false);
+ }
+ invokeCallback(callback, err);
} else {
- // if no handler is given, we use incoming result, unmodified
- resultHandler = resultHandler || echo;
- // some error handler will takes somewhat long gime
- // we should accept promise as result of the handler
- Promise.resolve( resultHandler(result, response.xhr) )
- .then( function(finalResult) {
- // if callback throws some unexpected error,
- // following catch function will catch it and some bad logs will be left.
- invokeCallback(callback, null, finalResult);
- })
- .catch( function (err) {
- logger.debug('result handler for ' + apiName + '() had error', err);
- invokeCallback(callback, err);
- });
+ if (maskingPath && myself.eventGate) {
+ myself.eventGate.unmaskEvents(maskingPath, true, false);
+ }
+ var handler = resultHandler || echo; // echo is default result hander
+ try {
+ var handled = handler(result, response.xhr);
+ invokeCallback(callback, null, handled);
+ } catch (err) {
+ logger.warn('result handler for ' + apiName + '() error', err);
+ invokeCallback(callback, err);
+ }
}
};
},
- _callSimpleApi : function (apiName, path /*, .... , result handler, callback */ ) {
+ _callRestApi : function (apiName, path /*, .... , result handler, callback */ ) {
var callable = wfsApi[apiName];
+
var wfsPath = this._fromLegacyPath(path);
var args = [ this.wfsId, wfsPath ];
for (var i = 2; i < arguments.length; i++) {
args.push(arguments[i]);
}
+
var callback = args.pop();
var resultHandler = args.pop();
- var apiCallback = this._createApiCallback(apiName, resultHandler, callback);
+ var apiCallback = null;
+ if (callback.useEventMasking && this.eventGate) {
+ this.eventGate.maskEvents(wfsPath, apiName);
+ apiCallback = this._createApiCallback(apiName, resultHandler, callback, wfsPath);
+ delete callback.useEventMasking;
+ } else {
+ apiCallback = this._createApiCallback(apiName, resultHandler, callback);
+ }
args.push(apiCallback);
-
- logger.log('call WfsApi.' + apiName + '()' , args);
return callable.apply(wfsApi, args);
},
+ // do we need to set mask on path?
+ // this simple operation may not cause any harmful effect, probably
createDirectory: function wfsCreateDir(path, recursive, callback) {
- this._callSimpleApi('createDir', path, {ensure : recursive}, null, callback);
+ callback.useEventMasking = true;
+ this._callRestApi('createDir', path, {ensure:recursive}, null, callback);
},
exists: function wfsExists(path, callback) {
- this._callSimpleApi('stat', path, {ignoreError: true},
+ this._callRestApi('stat', path, {ignoreError: true},
function(result) {
return (result.type !== 'DUMMY');
},
@@ -125,15 +158,14 @@ define([
// legacy stat is renamed to mstat
// TODO : change operation id of stats to stat, in swagger spec
stat: function wfsStat(path, callback) {
- this._callSimpleApi('stat', path, { /* no option */ },
+ this._callRestApi('stat', path, { /* no option */ },
function (result) {
- return new Stats(result);
+ return new WfsStats(result);
},
callback
);
},
-
// prefer dirTree
list : function wfsList(path, recursive, callback) {
if (!callback) {
@@ -141,9 +173,6 @@ define([
recursive = false;
}
this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
- if (!err) {
- console.log('wfsList final result', tree.children);
- }
callback(err, tree.children);
});
},
@@ -156,13 +185,15 @@ define([
// 2) add timeout parameter in spec
// 3) in server, find a way to limit concurrency
- this._callSimpleApi('dirTree', path, maxDepth,
+ this._callRestApi('dirTree', path, maxDepth,
function (result) {
// re-constructing a very large tree in a single tick looks dangerous
// we need a fromServerResultAsync, who injects some reasonable delays
// while building tree from json
var ret = WfsEntry.fromJson(result);
- ret.basepath = WfsEntry.getBasePathOf(path);
+ ret.path = path;
+ // logger.debug('wfsDirTree got dir tree on path ', result, ret);
+ return ret;
},
callback
);
@@ -170,7 +201,8 @@ define([
remove : function wfsRemove(path, recursive, callback ) {
- this._callSimpleApi('remove', path, {recursive : recursive}, null, callback);
+ callback.useEventMasking = true;
+ this._callRestApi('remove', path, {recursive : recursive}, null, callback);
} ,
readFile : function wfsReadFile(path, responseType, callback) {
@@ -184,7 +216,7 @@ define([
responseType = 'text';
}
- this._callSimpleApi('readFile', path,
+ this._callRestApi('readFile', path,
function (noUseResult, xhr) {
if (responseType === '' || responseType === 'text') {
return xhr.responseText;
@@ -213,12 +245,13 @@ define([
throw new Error('invalid data type - should be string or Blob');
}
// TODO: change 'ensure' default value to false, adding ensure parameter
- this._callSimpleApi('writeFile', path, data, { ensure: true }, null, callback);
+ callback.useEventMasking = true;
+ this._callRestApi('writeFile', path, data, { ensure: true }, null, callback);
},
// deprecated. use stat, instead
isDirectory: function wfsIsDirectory(path, callback) {
- this._callSimpleApi('stat', path, {/* no option */},
+ this._callRestApi('stat', path, {/* no option */},
function (result) {
return result.type === 'DIRECTORY';
},
@@ -228,7 +261,7 @@ define([
// deprecated. use stat, instead
isFile: function wfsIsFile(path, callback) {
- this._callSimpleApi('stat', path, {/* no option */},
+ this._callRestApi('stat', path, {/* no option */},
function (result) {
return result.type !== 'DIRECTORY';
},
@@ -238,7 +271,7 @@ define([
// deprecated. use dirTree or never call this method
isEmpty: function wfsIsEmpty(path, callback) {
- this._callSimpleApi('dirTree', path, {recursive: true},
+ this._callRestApi('dirTree', path, {recursive: true},
function (result) {
return result.children && result.children.length > 0;
},
@@ -246,7 +279,6 @@ define([
);
},
-
// deprecated. use 'remove'
'delete' : function wfsDelete(path, recursive, callback ) {
return this.remove(path, recursive, callback);
diff --git a/common/src/webida/server-api-0.1-lib/Stats.js b/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
similarity index 79%
rename from common/src/webida/server-api-0.1-lib/Stats.js
rename to common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
index 96d303d6..dbbc5d78 100644
--- a/common/src/webida/server-api-0.1-lib/Stats.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
@@ -15,7 +15,7 @@
*/
/**
- * @file Stats.js
+ * @file WfsStats.js
* @since 1.7.0
* @author jh1977.kim@samsung.com
*/
@@ -23,29 +23,31 @@
define([ ], function() {
'use strict';
- function Stats (serverStats, path, name) {
- this.path = path;
- this.name = name || this.path.split('/').pop();
-
- // all other properties are inherited from server stats object
+ function WfsStats (serverStats) {
+ // all other properties are inherited from server stats object
this.size = serverStats.size;
this.mtime = serverStats.mtime;
this.birthtime = serverStats.birthtime;
this.mode = serverStats.mode;
this.nlink = serverStats.nlink;
- this.type = serverStats.type;
-
+ this.type = serverStats.type;
}
- Stats.prorotype = {
+ WfsStats.prorotype = {
get isFile() { return (this.type !== 'DIRECTORY'); },
get isDirectory() { return (this.type === 'DIRECTORY'); },
get isBlockDevice() { return (this.type === 'BLOCK_DEVICE'); },
get isCharacterDevice() { return (this.type === 'CHARACTER_DEVICE'); },
get isSymbolicLink() { return (this.type === 'LINK'); },
get isFIFO() { return (this.type === 'FIFO'); },
- get isSocket() { return (this.type === 'SOCKET'); }
+ get isSocket() { return (this.type === 'SOCKET'); },
+
+ setPath : function setPath(value) {
+ this.path = value;
+ this.name = value ? value.split('/').pop() : undefined;
+ }
};
- return Stats;
+
+ return WfsStats;
});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs-utils.js b/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
similarity index 68%
rename from common/src/webida/server-api-0.1-lib/wfs-utils.js
rename to common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
index 77459e0f..4a71e31c 100644
--- a/common/src/webida/server-api-0.1-lib/wfs-utils.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
@@ -78,33 +78,52 @@ define([
return ret;
}
- function devideArrayWithFilter (array, propertyNameToFilter) {
- var ret = {
- truthy:[],
- falsy:[]
- };
+ // expected examples)
+ // '/' || '' => [] (has no ancestors)
+ // 'aaa' => [''] (has no ancestors in relative form)
+ // 'aaa/bbb' => ['aaa']
+ // 'aaa/bbb/ccc' || 'aaa/bbb/ccc/' => ['aaa/bbb', 'aaa']
+ // '/aaa/bbb/ccc' || '/aaa/bbb/ccc/' => [ '/aaa/bbb', '/aaa', '/' ]
+ // options {
+ // includeSelf: true to include path itself
+ // includeRoot: true to include '/' or '' in result
+ function getAncestors(path, opts) {
+ var options = opts || {includeSelf:true};
- array.forEach( function (item) {
- var property;
- if (!propertyNameToFilter) {
- property = item;
+ if (path === '/' || path === '' ) {
+ return options.includeSelf? [path] : [];
+ }
+
+ var isAbsolute = path[0] === '/';
+ var ret = [];
+ var segments = path.split('/');
+ var p = '';
+
+ // removes tailing / side effects
+ if (segments.length > 1 && segments[segments.length-1] === '') {
+ segments.pop();
+ }
+
+ while(segments.length >= 1) {
+ if (options.includeSelf) {
+ p = segments.join('/');
+ segments.pop();
} else {
- property = item ? item[propertyNameToFilter] : undefined;
+ segments.pop();
+ p = segments.join('/');
}
- if (property) {
- ret.truthy.push(item);
- } else {
- if (item) {
- ret.falsy.push(item);
- }
+ if (p) {
+ ret.push(p);
}
- });
-
+ }
+ if (options.includeRoot) {
+ ret.push(isAbsolute? '/' : '');
+ }
return ret;
}
return {
fromLegacyPath : fromLegacyPath,
- devideArrayWithFilter : devideArrayWithFilter
+ getAncestors : getAncestors
};
});
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
index d48dd9d4..c4b94654 100644
--- a/common/src/webida/server-api-0.1.js
+++ b/common/src/webida/server-api-0.1.js
@@ -26,40 +26,59 @@
define([
'./server-api-0.1-lib/common',
'./server-api-0.1-lib/auth',
- './server-api-0.1-lib/fs'
+ './server-api-0.1-lib/fs',
+ './server-api-0.1-lib/messaging',
+ './server-api-0.1-lib/session',
], function (
common,
auth,
- fs
+ fs,
+ messaging,
+ session
) {
'use strict';
- var serverUrl = common.bootArgs.serverUrl;
var mod = {
+ VERSION: '0.1',
auth : auth,
fs : fs,
- // for compatibility with plugisn who are dependent to webida-0.3.js conf object
+ // incompatible properties, which webida-0.3.js does not have
+ messaging: messaging,
+ info : {
+ serverUrl : common.serverUrl,
+ serverUri : common.serverUri,
+ get accessToken() {
+ return common.tokenManager.accessToken;
+ },
+ get sessionId() {
+ if (common.tokenManager.accessToken) {
+ return common.tokenManager.accessToken.sessionId;
+ }
+ }
+ },
+ session : session,
+
+ // for compatibility with plugin who are dependent to webida-0.3.js conf object
conf : {
- fsServer : serverUrl,
- connServer: serverUrl,
- fsApiBaseUrl: serverUrl + '/vfs'
+ fsServer : common.serverUrl,
+ connServer: common.serverUrl,
+ fsApiBaseUrl: common.serverUrl + '/api/wfs'
},
// for compatibility with current plugin manager
- // - should be removed in next version
+ // - should be removed in next version (0.2 and later)
// - PM should should decide which plugin catalog to load by itself
// via window.__ELECTRON_BROWSER__ variable
// - PM should not load .user_info/plugin-settings.json file directly while initializing
// and may use local storage instead of using server api
getPluginSettingsPath : function(callback) {
- // plugin-settings-desktop.json : to connect embedded server from desktop (0.1)
- // : to connect server from desktop (0.2)
- // plugin-settings.json : to connect legacy server from desktop/browser (0.1)
- // : to connect server from browser (0.2)
+ // plugin-settings-desktop.json : to use embedded server from desktop
+ // plugin-settings.json : to use legacy server from desktop/browser (0.1)
+ // to connect remote server from desktop/browser (0.2~)
+ // plugin-settings-legacy: to connect legacy server from desktop/browser (0.2~)
- // this is version 0.1. (simple but enough, for we don't access legacy server as guest)
if(common.bootArgs.legacy) {
return callback('plugins/plugin-setting.json');
} else {
@@ -67,8 +86,15 @@ define([
}
}
};
-
- // for debugging purpose only in debugger js console
+
+ // for debugging purpose only, in debugger js console.
+
+ // TODO : add bootArgs.debug
+ // - debugging mode should be customizable in runtime, not build time.
+ // - debugging mode will change Logger's singleton logger debugging level, too.
+ // in production mode, log level of logger should adjusted to 'error' or 'off'
+ // every new Logger() instance will respect global log level.
+
window.__webida = mod;
mod.common = common;
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-0.1.js
index dc8c3b38..2e55c21f 100644
--- a/common/src/webida/server-pubsub-0.1.js
+++ b/common/src/webida/server-pubsub-0.1.js
@@ -16,19 +16,15 @@
/**
* @module server-pubsub
- * @fileoverview messaging pub/sub library for webida 1.x client
+ * @fileoverview dummy api for legacy client using webida-0.3.js
*
- * Ths module provides some sub-set of msgs.js
+ * This module provides some sub-set of msgs.js, doing nothing
* @version: 0.1
*/
define([
- './server-api-0.1',
- 'external/socket.io-client/socket.io',
'webida-lib/util/logger/logger-client'
], function (
- serverApi,
- sio,
Logger
) {
'use strict';
@@ -43,20 +39,19 @@ define([
this.uid = uid;
this.token = token;
};
- var systemNotificationCallback;
-
- var init = function (uid, token, host, callbackFunctions, cb) {
+
+ var init = function messagingInit(uid, token, host, callbackFunctions, cb) {
+
var user = new User('nick', 'email', uid, token);
- logger.log('pubsub init - new user', user);
+ logger.log('pubsub init#- new user', user);
// dummy stuffs
- systemNotificationCallback = callbackFunctions.topicsysnotify_callback;
window.setTimeout( function() {
- cb(user);
+ cb(null, user);
}, 0);
};
- var sub2 = function (user, topics, cb) {
+ var sub2 = function messagingSubscribe(user, topics, cb) {
// dummy stuffs
var subscriptionResult = {
'topics': topics
@@ -70,5 +65,4 @@ define([
init: init,
sub2: sub2
};
-
});
From e7a080be35619ae28592f3969f047680108ecb17 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Wed, 20 Jul 2016 16:16:19 +0900
Subject: [PATCH 12/15] extracted restful api source to bower component
- removed webida-service-api-0.1 dir and added webida-restful-api bower dependency
- removed uid-menu plugin in plugin-settings-desktop.json
- fixed some errors due to removing uid-menu-plugin
- implemented off-line cache service (not applied to fs module yet)
- removed some too-verbose logs
- fixed many misc. bugs.
---
apps/ide/src/dojoConfig.js | 18 +-
.../src/plugins/plugin-settings-desktop.json | 6 -
.../run-configuration-manager.js | 2 +
bower.json | 1 +
.../command-system/command/command-factory.js | 3 -
common/src/webida/plugins/git/commands.js | 4 +-
.../plugins/workbench/views-controller.js | 46 +-
.../AbstractSocketClient.js | 22 +-
.../webida/server-api-0.1-lib/TokenManager.js | 23 +-
common/src/webida/server-api-0.1-lib/auth.js | 9 +-
.../server-api-0.1-lib/cache-db-manager.js | 233 +++
.../src/webida/server-api-0.1-lib/common.js | 13 +-
.../src/webida/server-api-0.1-lib/session.js | 2 +-
.../webida-service-api-0.1/.jshintignore | 1 -
.../.swagger-codegen-ignore | 23 -
.../webida-service-api-0.1/LICENSE | 201 ---
.../webida-service-api-0.1/README.md | 133 --
.../webida-service-api-0.1/docs/AuthApi.md | 161 --
.../webida-service-api-0.1/docs/Credential.md | 10 -
.../webida-service-api-0.1/docs/DefaultApi.md | 77 -
.../webida-service-api-0.1/docs/DirEntry.md | 10 -
.../docs/ExecRequest.md | 13 -
.../docs/ExecResponse.md | 10 -
.../webida-service-api-0.1/docs/Match.md | 9 -
.../webida-service-api-0.1/docs/OpsApi.md | 74 -
.../webida-service-api-0.1/docs/RestError.md | 9 -
.../webida-service-api-0.1/docs/RestOK.md | 8 -
.../webida-service-api-0.1/docs/Session.md | 29 -
.../webida-service-api-0.1/docs/SessionApi.md | 174 --
.../webida-service-api-0.1/docs/Stats.md | 37 -
.../webida-service-api-0.1/docs/Token.md | 26 -
.../webida-service-api-0.1/docs/User.md | 10 -
.../webida-service-api-0.1/docs/WfsApi.md | 570 ------
.../webida-service-api-0.1/docs/Workspace.md | 13 -
.../docs/WorkspaceApi.md | 401 -----
.../webida-service-api-0.1/git_push.sh | 52 -
.../webida-service-api-0.1/package.json | 18 -
.../webida-service-api-0.1/src/ApiClient.js | 501 ------
.../webida-service-api-0.1/src/api/AuthApi.js | 168 --
.../src/api/DefaultApi.js | 109 --
.../webida-service-api-0.1/src/api/OpsApi.js | 102 --
.../src/api/SessionApi.js | 176 --
.../webida-service-api-0.1/src/api/WfsApi.js | 574 ------
.../src/api/WorkspaceApi.js | 370 ----
.../webida-service-api-0.1/src/index.js | 142 --
.../src/model/Credential.js | 87 -
.../src/model/DirEntry.js | 87 -
.../src/model/ExecRequest.js | 117 --
.../src/model/ExecResponse.js | 90 -
.../webida-service-api-0.1/src/model/Match.js | 78 -
.../src/model/RestError.js | 77 -
.../src/model/RestOK.js | 67 -
.../src/model/Session.js | 169 --
.../webida-service-api-0.1/src/model/Stats.js | 163 --
.../webida-service-api-0.1/src/model/Token.js | 137 --
.../webida-service-api-0.1/src/model/User.js | 85 -
.../src/model/Workspace.js | 119 --
.../webida-service-api-0.1/src/superagent.js | 1569 -----------------
.../server-api-0.1-lib/wfs/WfsDirForest.js | 112 ++
.../server-api-0.1-lib/wfs/WfsDirTree.js | 86 +
.../webida/server-api-0.1-lib/wfs/WfsEntry.js | 44 +-
.../server-api-0.1-lib/wfs/WfsEventGate.js | 16 +-
.../server-api-0.1-lib/wfs/WfsEventHolder.js | 3 +-
.../webida/server-api-0.1-lib/wfs/WfsMount.js | 406 +++--
.../server-api-0.1-lib/wfs/WfsOfflineCache.js | 356 ++++
.../webida/server-api-0.1-lib/wfs/WfsStats.js | 30 +-
.../server-api-0.1-lib/wfs/wfs-utils.js | 8 +-
.../server-api-0.1-lib/workspace-service.js | 123 ++
common/src/webida/server-api-0.1.js | 17 +-
69 files changed, 1331 insertions(+), 7308 deletions(-)
create mode 100644 common/src/webida/server-api-0.1-lib/cache-db-manager.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
delete mode 100644 common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
create mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
create mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
create mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
create mode 100644 common/src/webida/server-api-0.1-lib/workspace-service.js
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index c49557e2..e3fcc189 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -74,12 +74,19 @@
};
// twick requirejs alias to use new server-api when not using using legacy server
+ // &, for new server api, additional package 'webida-restful-api' is required.
if (window.location.href.indexOf('legacy=') < 0 ) {
- globalObject.dojoConfig.aliases.pop();
- globalObject.dojoConfig.aliases.pop();
- globalObject.dojoConfig.aliases.push(['webida-lib/server-api' , 'webida-lib/server-api-0.1']);
- globalObject.dojoConfig.aliases.push(['webida-lib/server-pubsub' , 'webida-lib/server-pubsub-0.1']);
- globalObject.dojoConfig.aliases.push(['top/site-config.json' , 'top/site-config-desktop.json']);
+ var dojoConfig = globalObject.dojoConfig;
+ dojoConfig.aliases.pop();
+ dojoConfig.aliases.pop();
+ dojoConfig.aliases.push(['webida-lib/server-api', 'webida-lib/server-api-0.1']);
+ dojoConfig.aliases.push(['webida-lib/server-pubsub', 'webida-lib/server-pubsub-0.1']);
+ dojoConfig.aliases.push(['top/site-config.json', 'top/site-config-desktop.json']);
+ dojoConfig.packages.push( {
+ name: 'webida-restful-api',
+ location: './webida-restful-api',
+ main: 'api-bundle'
+ });
}
if (globalObject.__ELECTRON_BROWSER__) {
@@ -90,4 +97,5 @@
'host-node': false // Prevent dojo from being fooled by Electron
};
}
+
})(window);
diff --git a/apps/ide/src/plugins/plugin-settings-desktop.json b/apps/ide/src/plugins/plugin-settings-desktop.json
index 4310b199..82551e41 100644
--- a/apps/ide/src/plugins/plugin-settings-desktop.json
+++ b/apps/ide/src/plugins/plugin-settings-desktop.json
@@ -14,10 +14,6 @@
"plugins/webida.editor.code-editor.content-assist.html.html-link",
"plugins/webida.editor.code-editor.content-assist.html.default",
"plugins/webida.editor.code-editor.content-assist.tern",
- "plugins/webida.editor.example.simple-editor",
- "plugins/webida.viewer.image-viewer",
- "plugins/webida.editor.example.svg",
- "plugins/webida.editor.example.multi-content",
"plugins/project-configurator",
"plugins/webida.ide.project-management.run",
"plugins/webida.ide.project.deploy",
@@ -26,8 +22,6 @@
"plugins/webida.plugin-setting",
"plugins/webida.ide.search-result",
"plugins/webida.locale",
- "plugins/uid-menu-items",
- "plugins/webida.terminal",
"plugins/webida.ide.notification.view",
"plugins/webida.ide.notification.toast",
"webida-lib/plugins/command-system",
diff --git a/apps/ide/src/plugins/webida.ide.project-management.run/run-configuration-manager.js b/apps/ide/src/plugins/webida.ide.project-management.run/run-configuration-manager.js
index ee154c12..67250f86 100644
--- a/apps/ide/src/plugins/webida.ide.project-management.run/run-configuration-manager.js
+++ b/apps/ide/src/plugins/webida.ide.project-management.run/run-configuration-manager.js
@@ -110,6 +110,8 @@ define([
if (err) {
next(err);
} else if (!exist) {
+ runConfigurationFileCache = '{}';
+ runConfigurations = [];
next(locale.formatMessage('messageNotExist', {target: PATH_RUN_CONFIG}));
} else {
next();
diff --git a/bower.json b/bower.json
index ec803c7f..d406913d 100644
--- a/bower.json
+++ b/bower.json
@@ -34,6 +34,7 @@
"tern": "webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
"toastr": "~2.1.1",
"URIjs": "~1.15.2",
+ "webida-restful-api": "webida/webida-restful-api#~0.6.0",
"xstyle": "~0.3.1"
}
}
diff --git a/common/src/webida/plugins/command-system/command/command-factory.js b/common/src/webida/plugins/command-system/command/command-factory.js
index f094f742..70cb26c1 100644
--- a/common/src/webida/plugins/command-system/command/command-factory.js
+++ b/common/src/webida/plugins/command-system/command/command-factory.js
@@ -52,10 +52,7 @@ define([
return new Promise(function (resolve) {
var registry = commandRegistry.getCommand(id);
if (registry) {
- console.warn('create command from ' + registry.plugin + '/commands');
- console.warn('create command id ' + id , option);
require([registry.plugin + '/commands'], function (extension) {
- console.warn('create command with extension ', extension);
var Constructor = extension[toPascalCase(id) + 'Command'];
if (!Constructor) {
var changedId = id.split(':')[0];
diff --git a/common/src/webida/plugins/git/commands.js b/common/src/webida/plugins/git/commands.js
index be89f47b..73e80d3d 100644
--- a/common/src/webida/plugins/git/commands.js
+++ b/common/src/webida/plugins/git/commands.js
@@ -59,7 +59,7 @@ define([
'webida-lib/util/genetic',
'webida-lib/util/notify',
'webida-lib/util/path',
- 'webida-lib/webida-0.3',
+ 'webida-lib/server-api',
'webida-lib/widgets/dialogs/buttoned-dialog/ButtonedDialog',
'./git-core',
'./git-icon',
@@ -6307,7 +6307,7 @@ define([
}
genetic.inherits(GitRunCommand, Command, {
execute: function (resolve) {
- return new Promise(function () {
+ return new Promise(function (resolve) {
var selectedPath = workspace.getSelectedPath();
if (selectedPath) {
var gitRootPath = git.findGitRootPath(selectedPath);
diff --git a/common/src/webida/plugins/workbench/views-controller.js b/common/src/webida/plugins/workbench/views-controller.js
index 2b3cc8fb..3dcbcfdd 100644
--- a/common/src/webida/plugins/workbench/views-controller.js
+++ b/common/src/webida/plugins/workbench/views-controller.js
@@ -630,6 +630,12 @@ define([
this.collapsePanel('bottom');
}
+ // FIXME : workbench should not depend on auth api.
+ // need refactoring to move api-centric jobs to model or separated controller
+ // let menu view have more flexible layout, including 'filler',
+ // and make uid plugin contribute to workbench in the usual way.
+ // current work-around is just skipping create uid-menu.
+
Webida.auth.getMyInfo(function (e, data) {
if (e) {
console.error('getMyInfo error: ' + e);
@@ -642,25 +648,29 @@ define([
], function (
commandSystem
) {
- var menu = new DropDownMenu({style: 'display: none;' });
- var model = commandSystem.service.getUserIdMenuModel().items[0];
- model.items.forEach(function (item) {
- var menuItem = new MenuItem({
- label: item.name,
- onClick: function () {
- commandSystem.service.requestExecution(item.commandId);
- }
+ var parentModel = commandSystem.service.getUserIdMenuModel();
+ // TODO : service should provide a 'clean' way to check menu model exists
+ if (parentModel && parentModel.id !== 'root') {
+ var menu = new DropDownMenu({style: 'display: none;' });
+ var model = parentModel.items[0];
+ model.items.forEach(function (item) {
+ var menuItem = new MenuItem({
+ label: item.name,
+ onClick: function () {
+ commandSystem.service.requestExecution(item.commandId);
+ }
+ });
+ menu.addChild(menuItem);
});
- menu.addChild(menuItem);
- });
- menu.startup();
- var button = new DropDownButton({
- label: data.email,
- name: 'userinfo',
- dropDown: menu,
- id: 'userinfoButton'
- });
- dom.byId('dropDownUserinfo').appendChild(button.domNode);
+ menu.startup();
+ var button = new DropDownButton({
+ label: data.email,
+ name: 'userinfo',
+ dropDown: menu,
+ id: 'userinfoButton'
+ });
+ dom.byId('dropDownUserinfo').appendChild(button.domNode);
+ }
});
}
});
diff --git a/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js b/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
index 582cb547..71ac33ba 100644
--- a/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
+++ b/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
@@ -71,8 +71,8 @@ define([
connect: function connect() {
// connect options cannot be changed after socket object is made
- // even if we put a getter for this._connectOptions.query, socket.io will not
- // read the query string again.
+ // even if we put a getter for this._connectOptions.query,
+ // socket.io will not read the query string again.
this._connectOptions.query = this._buildConnectQueryString();
var connectUrl = common.serverUrl + '/' + this._namespace;
logger.debug(this.constructor.name + ' connecting to ' + connectUrl,
@@ -92,28 +92,28 @@ define([
return {};
},
- // should return true to emit event
_onConnect : function onConnect(error, isTimeout) {
var info = {
isTimeout : isTimeout,
took : (new Date().getTime() - this.disconnectedWhen) + 'msec'
};
- var ret = false;
+ var shouldEmitEvent = false;
if (error) {
// ignores reconnecting error for it will be handled in onReconnect
if (this.reconnectingCount === 0) {
logger.error(this.constructor.name + ' connect error ', error, info);
- ret = true;
+ shouldEmitEvent = true;
}
} else {
logger.debug(this.constructor.name + ' connected to server', info);
- ret = true;
+ shouldEmitEvent = true;
}
- return ret;
+ return shouldEmitEvent;
},
_onDisconnect : function onDisconnect() {
logger.debug(this.constructor.name + ' disconnected from server');
+ this.isConnected = false;
return true;
},
@@ -127,12 +127,12 @@ define([
reconnectingCount : this.reconnectingCount,
reconnectingFor : reconnectingFor + ' msec'
};
- var ret = false;
+ var shouldEmitEvent = false;
var name = this.constructor.name;
if (error) {
if (done) {
logger.error(name + ' LOST CONNECTION', error, reconnectingInfo);
- ret = true;
+ shouldEmitEvent = true;
this.reconnectingCount = 0;
} else {
logger.warn(name + ' reconnecting attempt failed', error, reconnectingInfo);
@@ -140,12 +140,12 @@ define([
} else {
if (done) {
logger.debug(name + ' recovered connection ', reconnectingInfo);
- ret = true;
+ shouldEmitEvent = true;
} else {
logger.debug(name + ' is trying to recover connection', reconnectingInfo);
}
}
- return ret;
+ return shouldEmitEvent;
},
// calculating recovery time (without max delay)
diff --git a/common/src/webida/server-api-0.1-lib/TokenManager.js b/common/src/webida/server-api-0.1-lib/TokenManager.js
index 76a60342..ef3dfb4d 100644
--- a/common/src/webida/server-api-0.1-lib/TokenManager.js
+++ b/common/src/webida/server-api-0.1-lib/TokenManager.js
@@ -24,15 +24,15 @@
// so, instead of requiring just ./common, we require all dependencies directly
// the only instance of TokenManager is saved in common
define([
+ 'webida-restful-api',
'external/eventEmitter/EventEmitter',
'webida-lib/util/genetic',
- 'webida-lib/util/logger/logger-client',
- './webida-service-api-0.1/src/index'
+ 'webida-lib/util/logger/logger-client'
], function (
+ WebidaRestfulApi,
EventEmitter,
genetic,
- Logger,
- WebidaServiceApi
+ Logger
) {
'use strict';
@@ -44,9 +44,9 @@ define([
// issueToken() can take 'timeout' msec
// so, we should begin calling issueToken(), at least 30 secs
- var MARGIN_TO_EXPIRE = WebidaServiceApi.ApiClient.instance.timeout + (30 * 1000);
+ var MARGIN_TO_EXPIRE = WebidaRestfulApi.ApiClient.instance.timeout + (30 * 1000);
var RETRY_AFTER = 5 * 1000;
- var authApi = new WebidaServiceApi.AuthApi();
+ var authApi = new WebidaRestfulApi.AuthApi();
// IDE does not use master token except login with master token
// so, TokenManager handles access token only
@@ -84,22 +84,23 @@ define([
window.clearTimeout(this._updateTimer);
this._updateTimer = null;
}
-
+ var expiresAt = this.accessToken.expiresAt;
var ttl = this.getRemainingTTL();
+ logger.debug('token expires at ' + expiresAt + ' , ttl = ' + ttl);
if (ttl < after) {
var nextUpdateTime = new Date().getTime() + after;
nextUpdateTime = new Date(nextUpdateTime);
var updateError = new Error(
'cannot schedule next update time - time over :' +
- ' next update time = ' + nextUpdateTime +
- ' expiration time = ' + this.accessToken.expiresAt
+ ' requested update time = ' + nextUpdateTime +
+ ' , expiration time = ' + expiresAt
);
logger.log(updateError);
this.emit('lost', updateError);
return;
}
-
- logger.log('next update will start after ' + after + ' msec');
+ var willUpdateAt = new Date( new Date().getTime() + after );
+ logger.debug('next update will start after ' + after + ' msec ', willUpdateAt);
this._updateTimer = window.setTimeout(this._doUpdate.bind(this), after);
},
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
index e4f34703..41b0f84d 100644
--- a/common/src/webida/server-api-0.1-lib/auth.js
+++ b/common/src/webida/server-api-0.1-lib/auth.js
@@ -73,12 +73,17 @@ define([
session.connect();
// Oddly, there's no error-fist-callback for initAuth
logger.log('initAuth registered access token', data);
- callback(data.sessionId);
- });
+ try {
+ callback(data.sessionId);
+ } catch (e) {
+ logger.error('initAuth callback had error', e);
+ }
+ });
}
function getMyInfo(callback) {
authApi.getInfo(function (error, data) {
+ logger.debug('AuthApi.getInfo callback with ', error, data);
if (!error) {
callback(null, data);
} else {
diff --git a/common/src/webida/server-api-0.1-lib/cache-db-manager.js b/common/src/webida/server-api-0.1-lib/cache-db-manager.js
new file mode 100644
index 00000000..0753c02a
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/cache-db-manager.js
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file cache-db-manager.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+// we don't want cyclic dependencies between common and TokenManager.
+// so, instead of requiring just ./common, we require all dependencies directly
+// the only instance of TokenManager is saved in common
+define([
+ './common'
+], function (
+ common
+) {
+ 'use strict';
+
+ var logger = common.logger;
+ var CACHE_DB_STORAGE_KEY = 'webida-offline-cache-db';
+ var CACHE_DB_VERSION = 1;
+ var CACHE_DB_NAME_PREFIX = 'webida-offline-cache-';
+ var ITEM_STORE_NAME = 'items';
+ var CHANGE_STORE_NAME = 'changes';
+
+ function rejector() {
+ return Promise.reject(new Error('local storage is not available'));
+ }
+
+ if (!window.localStorage) {
+ return {
+ catalog: {},
+ open : rejector,
+ remove : rejector,
+ clean : rejector
+ };
+ }
+
+ var privates = {
+ catalog : null,
+
+ loadCatalog: function loadCaches() {
+ var loaded = window.localStorage.getItem(CACHE_DB_STORAGE_KEY);
+ if (loaded) {
+ privates.catalog = JSON.parse(loaded);
+ } else {
+ privates.catalog = {};
+ privates.saveCatalog();
+ }
+ return privates.catalog;
+ },
+
+ saveCatalog: function saveCaches(data) {
+ var toWrite = data || privates.catalog || {};
+ window.localStorage.setItem(CACHE_DB_STORAGE_KEY, JSON.strintify(toWrite));
+ },
+
+ getCacheDBName : function (workspaceId) {
+ return CACHE_DB_NAME_PREFIX + workspaceId;
+ },
+
+ // makes IDBRequest object to call given resolve/reject, in a promise constructor
+ // basically works on IDBRequest, but also supports IDBOpenDBRequest type.
+ // setting a transaction object as request will not work.
+ // for transaction, use publics.util.begin() instead.
+ swear: function (request, targetName, apiName, resolve, reject, isOpenDBRequest) {
+ request.onerror = function (event) {
+ if (isOpenDBRequest) {
+ logger.error(targetName + ' ' + apiName + ' error', event);
+ }
+ if (typeof reject === 'function') {
+ reject(request.error);
+ }
+ };
+
+ request.onsuccess = function (event) {
+ if (isOpenDBRequest) {
+ logger.debug(targetName + ' ' + apiName + ' success', event);
+ }
+ if (typeof resolve === 'function') {
+ resolve(request.result);
+ }
+ };
+
+ if (isOpenDBRequest) {
+ request.onblocked = function (event) {
+ logger.debug(targetName + ' ' + apiName + ' blocked', event);
+ if (typeof reject === 'function') {
+ reject(new Error(apiName + ' request ' + targetName + ' is blocked'));
+ }
+ };
+ }
+ },
+
+ createSchema: function createDBSchema(db, name) {
+ // item { wfsPath,timestamp, data, stats }
+ // timestamp is the time when data is updated, long int from Date.getTime() ;
+ var itemStore = db.createObjectStore('items', { keyPath: 'wfsPath' });
+ itemStore.createIndex('timestamp', 'timestamp', { unique:false });
+
+ // change { wfsPath, timestamp, data }
+ // We should separate data of change from item, to process upload/download in parallel.
+ // If we don't, updating cache items can overwrite local change not uploaded yet.
+ // That will be a really critical and hard-to-find bug.
+ var changeStore = db.createObjectStore('changes', { keyPath: 'wfsPath' });
+ changeStore.createIndex('timestamp', 'timestamp', { unique: false });
+ logger.info('created cache db schema for ' + name);
+ },
+
+ // Usually, we need some 'serial' conversions, from 1 to version x.
+ // Problem: if converting takes very long time, what should we do?
+ // Since 'db' object will not wait for the tasks complete, and will fire success event
+ // when it has no pending tx, we can't support any upgrade tasks that need any async
+ // jobs other than db transaction. (for example, changing blob to string...)
+ // SOLUTION : Do not upgrade if upgrading requires some external async tasks.
+ // Rename db and let open()/clean() handle the rest of our works.
+ // And, abandon data, sorry.
+ upgradeSchema: function upgradeDBSchema(db, name, oldVersion, newVersion) {
+ if (newVersion !== CACHE_DB_VERSION) {
+ throw new Error('invalid db version ' + newVersion + ' to ' + name);
+ }
+ // no need to implement upgrade, yet.
+ },
+
+ openDB : function (workspaceId) {
+ return new Promise(function (resolve, reject) {
+ var name = privates.getCacheDBName(workspaceId);
+ var openRequest = window.indexedDB.open(name, CACHE_DB_VERSION);
+ openRequest.onupgradeneeded = function (event) {
+ var db = event.target.result;
+ // setting db.onsuccess, db.onerror does not work. request fires all events.
+ if (event.oldVersion) {
+ privates.upgradeSchema(db, name, event.oldVersion, event.newVersion);
+ } else {
+ privates.createSchema(db, name);
+ }
+ };
+ privates.swear(openRequest, name, 'open', resolve, reject, true);
+ });
+ },
+
+ removeDB : function(workspaceId) {
+ var name = privates.getCacheDBName(workspaceId);
+ return new Promise(function (resolve, reject) {
+ var delRequest = window.indexedDB.deleteDatabase(name);
+ privates.swear(delRequest, name, 'deleteDatabase', resolve, reject, true);
+ });
+ }
+ };
+
+ var publics = {
+
+ // resolves to IDBDatabase object
+ open : function openCacheDB(workspaceId) {
+ return privates.openDB(workspaceId).then(function(db) {
+ var name = privates.getCacheDBName(workspaceId);
+ if (!privates.catalog[name]) {
+ privates.catalog[name] = CACHE_DB_VERSION;
+ privates.saveCatalog();
+ }
+ return db;
+ });
+ },
+
+ clean: function cleanCacheDB(workspaceIds) {
+ var promises = [];
+ workspaceIds.forEach(function(id) {
+ var name = privates.getCacheDBName(id);
+ promises.push(privates.removeDB(id).then( function() {
+ if (privates.catalog[name]) {
+ delete privates.catalog[name];
+ privates.saveCatalog();
+ }
+ }));
+ });
+ return Promise.all(promises);
+ },
+
+ utils: {
+ swear: function setPinkyFingers() {
+ return privates.swear.apply(null, arguments);
+ },
+
+ begin: function beginCacheTransaction(db, txName, resolve, reject) {
+ var tx = db.transaction(db.objectStoreNames, 'readwrite');
+ tx.__name = txName;
+ tx.onerror = function (event) {
+ logger.debug(txName + ' error', event);
+ reject(tx.error);
+ };
+ tx.oncomplete = function (event) {
+ logger.debug( txName + ' complete', event);
+ resolve(); // resolves null, on alwyas.
+ };
+ return tx;
+ },
+ },
+
+ constants: {
+ ITEM_STORE_NAME: ITEM_STORE_NAME,
+ CHANGE_STORE_NAME: CHANGE_STORE_NAME
+ }
+ };
+
+ privates.loadCatalog();
+
+ // if we don't listen storage event, clean() may hit dangling db.
+ // There's no portable API like IDBFactory#getDatabaseNames(), we should avoid.
+
+ window.addEventListener('storage', function(event) {
+ if (event.storageArea === window.localStorage) {
+ var value = event.newValue;
+ logger.debug('DB catalog change', event);
+ privates.catalog = value ? JSON.parse(value) : {};
+ }
+ });
+
+ return publics;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/common.js b/common/src/webida/server-api-0.1-lib/common.js
index 354c2077..c4d925e8 100644
--- a/common/src/webida/server-api-0.1-lib/common.js
+++ b/common/src/webida/server-api-0.1-lib/common.js
@@ -21,15 +21,15 @@
*/
define([
'URIjs',
+ 'webida-restful-api',
'external/eventEmitter/EventEmitter',
'webida-lib/util/logger/logger-client',
- './webida-service-api-0.1/src/index',
'./TokenManager'
], function (
URI,
- EventEmitter,
+ WebidaRestfulApi,
+ EventEmitter,
Logger,
- WebidaServiceApi,
TokenManager
) {
'use strict';
@@ -44,7 +44,7 @@ define([
serverUri : null,
serverUrl : null,
session: null,
- tokenManager : TokenManager.instance
+ tokenManager : TokenManager.instance,
};
var publics = {
@@ -53,11 +53,10 @@ define([
get bootArgs() { return privates.bootArgs; },
get serverUri() { return privates.serverUri; },
get serverUrl() { return privates.serverUrl; },
- get session() { return privates.session; },
get tokenManager() { return privates.tokenManager;},
get accessToken() { return privates.tokenManager.accessToken; },
get api() {
- return WebidaServiceApi;
+ return WebidaRestfulApi;
}
};
@@ -74,7 +73,7 @@ define([
// by default, generated js client uses 'http://localhost/api' as base url
// we should replace it to real server url
- var defaultClient = WebidaServiceApi.ApiClient.instance;
+ var defaultClient = WebidaRestfulApi.ApiClient.instance;
defaultClient.basePath = privates.serverUrl + '/api';
// webidaSimpleAuth.apiKey is not a 'fixed' value.
diff --git a/common/src/webida/server-api-0.1-lib/session.js b/common/src/webida/server-api-0.1-lib/session.js
index d09dbcf6..9e594a2d 100644
--- a/common/src/webida/server-api-0.1-lib/session.js
+++ b/common/src/webida/server-api-0.1-lib/session.js
@@ -15,7 +15,7 @@
*/
/**
- * @file TokenManager.js
+ * @file session.js
* @since 1.7.0
* @author jh1977.kim@samsung.com
*/
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
deleted file mode 100644
index f7ffeddf..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.jshintignore
+++ /dev/null
@@ -1 +0,0 @@
-./src
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
deleted file mode 100644
index 19d33771..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/.swagger-codegen-ignore
+++ /dev/null
@@ -1,23 +0,0 @@
-# Swagger Codegen Ignore
-# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
-
-# Use this file to prevent files from being overwritten by the generator.
-# The patterns follow closely to .gitignore or .dockerignore.
-
-# As an example, the C# client generator defines ApiClient.cs.
-# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
-#ApiClient.cs
-
-# You can match any string of characters against a directory, file or extension with a single asterisk (*):
-#foo/*/qux
-# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
-
-# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
-#foo/**/qux
-# Thsi matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
-
-# You can also negate patterns with an exclamation (!).
-# For example, you can ignore all files in a docs folder with the file extension .md:
-#docs/*.md
-# Then explicitly reverse the ignore rule for a single file:
-#!docs/README.md
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
deleted file mode 100644
index 8dada3ed..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/LICENSE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "{}"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright {yyyy} {name of copyright owner}
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
deleted file mode 100644
index 9e30ea1c..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/README.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# webida-service-api
-
-WebidaServiceApi - JavaScript client for webida-service-api
-Webida Service API specfication
-This SDK is automatically generated by the [Swagger Codegen](https://github.com/swagger-api/swagger-codegen) project:
-
-- API version: 0.1
-- Package version: 0.1
-- Build date: 2016-06-21T07:28:56.954Z
-- Build package: class io.swagger.codegen.languages.JavascriptClientCodegen
-
-## Installation
-
-### For [Node.js](https://nodejs.org/)
-
-#### npm
-
-To publish the library as a [npm](https://www.npmjs.com/),
-please follow the procedure in ["Publishing npm packages"](https://docs.npmjs.com/getting-started/publishing-npm-packages).
-
-Then install it via:
-
-```shell
-npm install webida-service-api --save
-```
-
-#### git
-#
-If the library is hosted at a git repository, e.g.
-https://github.com/YOUR_USERNAME/webida-service-api
-then install it via:
-
-```shell
- npm install YOUR_USERNAME/webida-service-api --save
-```
-
-### For browser
-
-The library also works in the browser environment via npm and [browserify](http://browserify.org/). After following
-the above steps with Node.js and installing browserify with `npm install -g browserify`,
-perform the following (assuming *main.js* is your entry file):
-
-```shell
-browserify main.js > bundle.js
-```
-
-Then include *bundle.js* in the HTML pages.
-
-## Getting Started
-
-Please follow the [installation](#installation) instruction and execute the following JS code:
-
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = "YOUR API KEY"
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix['Authorization'] = "Token"
-
-var api = new WebidaServiceApi.AuthApi()
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-api.getInfo(callback);
-
-```
-
-## Documentation for API Endpoints
-
-All URIs are relative to *https://localhost/api*
-
-Class | Method | HTTP request | Description
------------- | ------------- | ------------- | -------------
-*WebidaServiceApi.AuthApi* | [**getInfo**](docs/AuthApi.md#getInfo) | **GET** /auth/info |
-*WebidaServiceApi.AuthApi* | [**issueToken**](docs/AuthApi.md#issueToken) | **POST** /auth/token |
-*WebidaServiceApi.AuthApi* | [**login**](docs/AuthApi.md#login) | **POST** /auth/login |
-*WebidaServiceApi.DefaultApi* | [**replace**](docs/DefaultApi.md#replace) | **POST** /wfs/{wfsId}/ops/replace |
-*WebidaServiceApi.OpsApi* | [**search**](docs/OpsApi.md#search) | **GET** /wfs/{wfsId}/ops/search/{wfsPath} |
-*WebidaServiceApi.SessionApi* | [**deleteSession**](docs/SessionApi.md#deleteSession) | **DELETE** /sessions/{sessionId} |
-*WebidaServiceApi.SessionApi* | [**getSession**](docs/SessionApi.md#getSession) | **GET** /sessions/{sessionId} |
-*WebidaServiceApi.SessionApi* | [**getSessions**](docs/SessionApi.md#getSessions) | **GET** /sessions |
-*WebidaServiceApi.WfsApi* | [**copy**](docs/WfsApi.md#copy) | **PUT** /wfs/{wfsId}/any/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**createDir**](docs/WfsApi.md#createDir) | **PUT** /wfs/{wfsId}/dir/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**dirTree**](docs/WfsApi.md#dirTree) | **GET** /wfs/{wfsId}/dir/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**move**](docs/WfsApi.md#move) | **POST** /wfs/{wfsId}/dir/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**readFile**](docs/WfsApi.md#readFile) | **GET** /wfs/{wfsId}/file/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**remove**](docs/WfsApi.md#remove) | **DELETE** /wfs/{wfsId}/any/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**rename**](docs/WfsApi.md#rename) | **POST** /wfs/{wfsId}/file/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**stat**](docs/WfsApi.md#stat) | **GET** /wfs/{wfsId}/any/{wfsPath} |
-*WebidaServiceApi.WfsApi* | [**writeFile**](docs/WfsApi.md#writeFile) | **PUT** /wfs/{wfsId}/file/{wfsPath} |
-*WebidaServiceApi.WorkspaceApi* | [**cancel**](docs/WorkspaceApi.md#cancel) | **DELETE** /workspaces/{workspaceId}/exec |
-*WebidaServiceApi.WorkspaceApi* | [**createWorkspace**](docs/WorkspaceApi.md#createWorkspace) | **POST** /workspaces |
-*WebidaServiceApi.WorkspaceApi* | [**exec**](docs/WorkspaceApi.md#exec) | **POST** /workspaces/{workspaceId}/exec |
-*WebidaServiceApi.WorkspaceApi* | [**getAllWorkspaces**](docs/WorkspaceApi.md#getAllWorkspaces) | **GET** /workspaces |
-*WebidaServiceApi.WorkspaceApi* | [**getWorkspace**](docs/WorkspaceApi.md#getWorkspace) | **GET** /workspaces/{workspaceId} |
-*WebidaServiceApi.WorkspaceApi* | [**removeWorkspace**](docs/WorkspaceApi.md#removeWorkspace) | **DELETE** /workspaces/{workspaceId} |
-*WebidaServiceApi.WorkspaceApi* | [**updateWorkspace**](docs/WorkspaceApi.md#updateWorkspace) | **PUT** /workspaces/{workspaceId} |
-
-
-## Documentation for Models
-
- - [WebidaServiceApi.Credential](docs/Credential.md)
- - [WebidaServiceApi.DirEntry](docs/DirEntry.md)
- - [WebidaServiceApi.ExecRequest](docs/ExecRequest.md)
- - [WebidaServiceApi.ExecResponse](docs/ExecResponse.md)
- - [WebidaServiceApi.Match](docs/Match.md)
- - [WebidaServiceApi.RestError](docs/RestError.md)
- - [WebidaServiceApi.RestOK](docs/RestOK.md)
- - [WebidaServiceApi.Session](docs/Session.md)
- - [WebidaServiceApi.Stats](docs/Stats.md)
- - [WebidaServiceApi.Token](docs/Token.md)
- - [WebidaServiceApi.User](docs/User.md)
- - [WebidaServiceApi.Workspace](docs/Workspace.md)
-
-
-## Documentation for Authorization
-
-
-### webida-simple-auth
-
-- **Type**: API key
-- **API key parameter name**: Authorization
-- **Location**: HTTP header
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
deleted file mode 100644
index 64e62115..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/AuthApi.md
+++ /dev/null
@@ -1,161 +0,0 @@
-# WebidaServiceApi.AuthApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**getInfo**](AuthApi.md#getInfo) | **GET** /auth/info |
-[**issueToken**](AuthApi.md#issueToken) | **POST** /auth/token |
-[**login**](AuthApi.md#login) | **POST** /auth/login |
-
-
-
-# **getInfo**
-> User getInfo()
-
-
-
-Gets user information of that can be identified with current access token. Implementations should provide a more restful api based on domain data model. Don't override this operation for multi-user system.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.AuthApi();
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.getInfo(callback);
-```
-
-### Parameters
-This endpoint does not need any parameter.
-
-### Return type
-
-[**User**](User.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **issueToken**
-> Token issueToken(type, opts)
-
-
-
-Creates new token from current access token, inheriting workspace id & session id Duration of generated token is not (and should be) parameterizable.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.AuthApi();
-
-var type = "type_example"; // String |
-
-var opts = {
- 'workspaceId': "workspaceId_example" // String | mandatory to issue a MASTER type token
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.issueToken(type, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **type** | **String**| |
- **workspaceId** | **String**| mandatory to issue a MASTER type token | [optional]
-
-### Return type
-
-[**Token**](Token.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **login**
-> Token login(body)
-
-
-
-A 'VERY' basic authentication, required to use webida-simple-auth security scheme. Service / Product implementations who need better security, should override this operation or add their own login api or some other specs like OAuth2. Simple auth is not suitable for large-sacle, multi-tennant service. Generated accss token inherits all restriction from master token. In normal login, unrestricted access token will be granted with reasonably short expiration time. Every client should respawn another access token with issueToken API before current access token expires.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-
-var apiInstance = new WebidaServiceApi.AuthApi();
-
-var body = new WebidaServiceApi.Credential(); // Credential |
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.login(body, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **body** | [**Credential**](Credential.md)| |
-
-### Return type
-
-[**Token**](Token.md)
-
-### Authorization
-
-No authorization required
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
deleted file mode 100644
index 804bd9a5..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Credential.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.Credential
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**loginId** | **String** | |
-**loginPassword** | **String** | |
-**masterToken** | **String** | a master token is issued when user wants to access webida api without id/password from remote or local desktop app. When masterToken is set, client should put some bogus id/password, non-empty. (The values can be used to identify client type) | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
deleted file mode 100644
index 024997e4..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DefaultApi.md
+++ /dev/null
@@ -1,77 +0,0 @@
-# WebidaServiceApi.DefaultApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**replace**](DefaultApi.md#replace) | **POST** /wfs/{wfsId}/ops/replace |
-
-
-
-# **replace**
-> RestOK replace(wfsId, wfsPathList, patternreplaceTo, opts)
-
-
-
-replace file contents with regex matching
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.DefaultApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPathList = ["wfsPathList_example"]; // [String] | array of wfsPath, with heading / (collection format may be changed by implementation)
-
-var pattern = "pattern_example"; // String | regex pattern to match
-
-var replaceTo = "replaceTo_example"; // String | string to replace with
-
-var opts = {
- 'ignoreCase': false, // Boolean | regex matching option to ignore case
- 'wholeWord': false // Boolean | regex matching option to match whole word
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.replace(wfsId, wfsPathList, patternreplaceTo, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPathList** | [**[String]**](String.md)| array of wfsPath, with heading / (collection format may be changed by implementation) |
- **pattern** | **String**| regex pattern to match |
- **replaceTo** | **String**| string to replace with |
- **ignoreCase** | **Boolean**| regex matching option to ignore case | [optional] [default to false]
- **wholeWord** | **Boolean**| regex matching option to match whole word | [optional] [default to false]
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
deleted file mode 100644
index 1ab01913..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/DirEntry.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.DirEntry
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**name** | **String** | |
-**stats** | [**Stats**](Stats.md) | |
-**children** | [**[DirEntry]**](DirEntry.md) | |
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
deleted file mode 100644
index 4907fb28..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecRequest.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# WebidaServiceApi.ExecRequest
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **String** | unique identifier of execution, to demux response stream or cancel request |
-**command** | **String** | command to run. should not contain any arguments, pipes, redirections |
-**args** | **[String]** | the arguments array |
-**cwd** | **String** | Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept any evaluatable form like $HOME, %USERPROFILE%. If absolute, heading / will be discarded. should be unixified. | [optional]
-**input** | **String** | input string for child process. if falsy in async execution, async input messages will be pasted into the child's stdin. since we don't use tty, it's recommended to use input string anyway. | [optional]
-**timeout** | **Integer** | The value which In 'milliseconds' the maximum amount of time the child is allowed to run. (not idle time of stdout / stderr stream) if undefined, server will not kill the child process until receiving cancel request if it doesn't exit by self. | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
deleted file mode 100644
index 5f3df93e..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/ExecResponse.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.ExecResponse
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**exitCode** | **Integer** | exit code of child process. always 0 for async exec |
-**stdout** | **String** | standard out of child process. empty for async exec |
-**stderr** | **String** | standard error of child process. empty for async exec |
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
deleted file mode 100644
index 6207cd26..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Match.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# WebidaServiceApi.Match
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**line** | **Integer** | |
-**text** | **String** | |
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
deleted file mode 100644
index 37142e90..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/OpsApi.md
+++ /dev/null
@@ -1,74 +0,0 @@
-# WebidaServiceApi.OpsApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**search**](OpsApi.md#search) | **GET** /wfs/{wfsId}/ops/search/{wfsPath} |
-
-
-
-# **search**
-> {'String': Match} search(wfsId, wfsPath, pattern, opts)
-
-
-
-search files in some path, with given pattern
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.OpsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var pattern = "pattern_example"; // String | regex pattern to match
-
-var opts = {
- 'ignoreCase': false, // Boolean | regex matching option to ignore case
- 'wholeWord': false // Boolean | regex matching option to match whole word
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.search(wfsId, wfsPath, pattern, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **pattern** | **String**| regex pattern to match |
- **ignoreCase** | **Boolean**| regex matching option to ignore case | [optional] [default to false]
- **wholeWord** | **Boolean**| regex matching option to match whole word | [optional] [default to false]
-
-### Return type
-
-[**{'String': Match}**](Match.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
deleted file mode 100644
index 5c9bc12d..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestError.md
+++ /dev/null
@@ -1,9 +0,0 @@
-# WebidaServiceApi.RestError
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**code** | **String** | | [optional]
-**message** | **String** | |
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
deleted file mode 100644
index 19679959..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/RestOK.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# WebidaServiceApi.RestOK
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**message** | **String** | | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
deleted file mode 100644
index d04a80c7..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Session.md
+++ /dev/null
@@ -1,29 +0,0 @@
-# WebidaServiceApi.Session
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **String** | the id of a session. usually same to socket id. |
-**name** | **String** | human readable name, usually derived from workspace name. |
-**state** | **String** | state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout. |
-**workspaceId** | **String** | the id of workspace that this sessions is working on. |
-**clientAddress** | **String** | the peer address of session connection. not always |
-**connectedAt** | **Date** | the time when socket connection is established |
-**disconnectedAt** | **Date** | the time when socket is closed. |
-**willCloseAt** | **Date** | when state becomes CLOSING, actual closing time will be updated by server. | [optional]
-**willLoseAt** | **Date** | when state becomes LOSING, server will not wait for reconnection after this time. | [optional]
-
-
-
-## Enum: StateEnum
-
-
-* `NORMAL` (value: `"NORMAL"`)
-
-* `LOSING` (value: `"LOSING"`)
-
-* `CLOSING` (value: `"CLOSING"`)
-
-
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
deleted file mode 100644
index c896abe3..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/SessionApi.md
+++ /dev/null
@@ -1,174 +0,0 @@
-# WebidaServiceApi.SessionApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**deleteSession**](SessionApi.md#deleteSession) | **DELETE** /sessions/{sessionId} |
-[**getSession**](SessionApi.md#getSession) | **GET** /sessions/{sessionId} |
-[**getSessions**](SessionApi.md#getSessions) | **GET** /sessions |
-
-
-
-# **deleteSession**
-> RestOK deleteSession(sessionId, closeAfter)
-
-
-
-close session with timeout
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.SessionApi();
-
-var sessionId = "sessionId_example"; // String | webida session id (usually different from socket id from sock.io)
-
-var closeAfter = 56; // Integer | waiting time before actual closing, to let client save files and prevent reconnect
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.deleteSession(sessionId, closeAfter, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **sessionId** | **String**| webida session id (usually different from socket id from sock.io) |
- **closeAfter** | **Integer**| waiting time before actual closing, to let client save files and prevent reconnect |
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **getSession**
-> Session getSession(sessionId, )
-
-
-
-get a session object by id
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.SessionApi();
-
-var sessionId = "sessionId_example"; // String | webida session id (usually different from socket id from sock.io)
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.getSession(sessionId, , callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **sessionId** | **String**| webida session id (usually different from socket id from sock.io) |
-
-### Return type
-
-[**Session**](Session.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **getSessions**
-> [Session] getSessions(opts)
-
-
-
-get all / some webida sessions established to server
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.SessionApi();
-
-var opts = {
- 'workspaceId': "workspaceId_example" // String | only include sessions working on some given workspace
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.getSessions(opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| only include sessions working on some given workspace | [optional]
-
-### Return type
-
-[**[Session]**](Session.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
deleted file mode 100644
index c00ce85f..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Stats.md
+++ /dev/null
@@ -1,37 +0,0 @@
-# WebidaServiceApi.Stats
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**type** | **String** | |
-**birthtime** | **Date** | | [optional]
-**mtime** | **Date** | | [optional]
-**mode** | **String** | | [optional]
-**size** | **Integer** | | [optional]
-**nlink** | **Integer** | | [optional]
-**error** | [**RestError**](RestError.md) | | [optional]
-
-
-
-## Enum: TypeEnum
-
-
-* `DUMMY` (value: `"DUMMY"`)
-
-* `FILE` (value: `"FILE"`)
-
-* `DIRECTORY` (value: `"DIRECTORY"`)
-
-* `BLOCK_DEVICE` (value: `"BLOCK_DEVICE"`)
-
-* `CHARACTER_DEVICE` (value: `"CHARACTER_DEVICE"`)
-
-* `LINK` (value: `"LINK"`)
-
-* `FIFO` (value: `"FIFO"`)
-
-* `SOCKET` (value: `"SOCKET"`)
-
-
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
deleted file mode 100644
index ec1c3862..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Token.md
+++ /dev/null
@@ -1,26 +0,0 @@
-# WebidaServiceApi.Token
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**text** | **String** | actual token text that should be shipped in header or query |
-**tokenType** | **String** | MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a side-way to create an unrestricted master token before starting IDE instances. |
-**expiresAt** | **Date** | |
-**issuedAt** | **Date** | |
-**sessionId** | **String** | mandatory for ACCESS token, identifying client instance | [optional]
-**workspaceId** | **String** | If truthy, access rights are restricted to specified workspace only. | [optional]
-
-
-
-## Enum: TokenTypeEnum
-
-
-* `MASTER` (value: `"MASTER"`)
-
-* `ACCESS` (value: `"ACCESS"`)
-
-* `ADMIN` (value: `"ADMIN"`)
-
-
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
deleted file mode 100644
index 32ae9e64..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/User.md
+++ /dev/null
@@ -1,10 +0,0 @@
-# WebidaServiceApi.User
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **String** | unique id per user (email is also unique) | [optional]
-**email** | **String** | | [optional]
-**name** | **String** | | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
deleted file mode 100644
index 3d38df5e..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WfsApi.md
+++ /dev/null
@@ -1,570 +0,0 @@
-# WebidaServiceApi.WfsApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**copy**](WfsApi.md#copy) | **PUT** /wfs/{wfsId}/any/{wfsPath} |
-[**createDir**](WfsApi.md#createDir) | **PUT** /wfs/{wfsId}/dir/{wfsPath} |
-[**dirTree**](WfsApi.md#dirTree) | **GET** /wfs/{wfsId}/dir/{wfsPath} |
-[**move**](WfsApi.md#move) | **POST** /wfs/{wfsId}/dir/{wfsPath} |
-[**readFile**](WfsApi.md#readFile) | **GET** /wfs/{wfsId}/file/{wfsPath} |
-[**remove**](WfsApi.md#remove) | **DELETE** /wfs/{wfsId}/any/{wfsPath} |
-[**rename**](WfsApi.md#rename) | **POST** /wfs/{wfsId}/file/{wfsPath} |
-[**stat**](WfsApi.md#stat) | **GET** /wfs/{wfsId}/any/{wfsPath} |
-[**writeFile**](WfsApi.md#writeFile) | **PUT** /wfs/{wfsId}/file/{wfsPath} |
-
-
-
-# **copy**
-> RestOK copy(wfsId, wfsPath, srcPath, opts)
-
-
-
-Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error if removeExisting is false Copying from sockets, fifo, .. and any other type of file system object is not supported.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
-
-var opts = {
- 'removeExisting': false // Boolean | remove any existing file/dir before writing.
- 'followSymbolicLinks': false, // Boolean | dereference symlinks or not
- 'noPreserveTimestamps': false, // Boolean | to change default behavior, keep mtime/atime of source files in destination
- 'filterPattern': "filterPattern_example" // String | execute copy if source matches to this regex pattern.
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.copy(wfsId, wfsPath, srcPath, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **srcPath** | **String**| source data path of some operations, with have heading / |
- **removeExisting** | **Boolean**| remove any existing file/dir before writing. | [optional] [default to false]
- **followSymbolicLinks** | **Boolean**| dereference symlinks or not | [optional] [default to false]
- **noPreserveTimestamps** | **Boolean**| to change default behavior, keep mtime/atime of source files in destination | [optional] [default to false]
- **filterPattern** | **String**| execute copy if source matches to this regex pattern. | [optional]
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **createDir**
-> RestOK createDir(wfsId, wfsPath, , opts)
-
-
-
-create a directory at the path. will return error when wfsPath exists and not empty
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var opts = {
- 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.createDir(wfsId, wfsPath, , opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **dirTree**
-> DirEntry dirTree(wfsId, wfsPath, maxDepth)
-
-
-
-returns a directory tree of given path, for listing dir and managing file system
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var maxDepth = 56; // Integer | Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list.
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.dirTree(wfsId, wfsPath, maxDepth, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **maxDepth** | **Integer**| Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list. |
-
-### Return type
-
-[**DirEntry**](DirEntry.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **move**
-> RestOK move(wfsId, wfsPath, srcPath, opts)
-
-
-
-move file or directory to given path. works like mv command
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
-
-var opts = {
- 'removeExisting': false // Boolean | remove any existing file/dir before writing.
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.move(wfsId, wfsPath, srcPath, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **srcPath** | **String**| source data path of some operations, with have heading / |
- **removeExisting** | **Boolean**| remove any existing file/dir before writing. | [optional] [default to false]
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **readFile**
-> File readFile(wfsId, wfsPath, )
-
-
-
-read file data on path
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.readFile(wfsId, wfsPath, , callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
-
-### Return type
-
-**File**
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **remove**
-> RestOK remove(wfsId, wfsPath, , opts)
-
-
-
-delete file or directory
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var opts = {
- 'recursive': false // Boolean | flag to set copy with
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.remove(wfsId, wfsPath, , opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **recursive** | **Boolean**| flag to set copy with | [optional] [default to false]
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **rename**
-> File rename(wfsId, wfsPath, srcPath, opts)
-
-
-
-Rename a file or directory to. This api does not remove an existing one.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var srcPath = "srcPath_example"; // String | source data path of some operations, with have heading /
-
-var opts = {
- 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.rename(wfsId, wfsPath, srcPath, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **srcPath** | **String**| source data path of some operations, with have heading / |
- **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
-
-### Return type
-
-**File**
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **stat**
-> Stats stat(wfsId, wfsPath, , opts)
-
-
-
-get stats of given path. (stat returns 'stats' object in node and POSIX)
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var opts = {
- 'ignoreError': false // Boolean | flag to ignore stat errors to check existence only
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.stat(wfsId, wfsPath, , opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **ignoreError** | **Boolean**| flag to ignore stat errors to check existence only | [optional] [default to false]
-
-### Return type
-
-[**Stats**](Stats.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **writeFile**
-> File writeFile(wfsId, wfsPath, data, opts)
-
-
-
-create / update file with body data
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WfsApi();
-
-var wfsId = "wfsId_example"; // String | webida file system id (same to workspace id) to access.
-
-var wfsPath = "wfsPath_example"; // String | webida file system path to access. without heading /. should be placed at the end of path arguments
-
-var data = "/path/to/file.txt"; // File | file contents to write.
-
-var opts = {
- 'ensure': false // Boolean | flag to create all parent directories to create file or dir, like mkdir -p
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.writeFile(wfsId, wfsPath, data, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **wfsId** | **String**| webida file system id (same to workspace id) to access. |
- **wfsPath** | **String**| webida file system path to access. without heading /. should be placed at the end of path arguments |
- **data** | **File**| file contents to write. |
- **ensure** | **Boolean**| flag to create all parent directories to create file or dir, like mkdir -p | [optional] [default to false]
-
-### Return type
-
-**File**
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: multipart/form-data
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
deleted file mode 100644
index 76f0762e..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/Workspace.md
+++ /dev/null
@@ -1,13 +0,0 @@
-# WebidaServiceApi.Workspace
-
-## Properties
-Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------
-**id** | **String** | the id of a workspace. usually same to file system id |
-**name** | **String** | display text of this workspace for UI |
-**description** | **String** | human readable description on this workspace |
-**createdAt** | **Date** | the time when this workspace is created (registered from local file system) |
-**accessedAt** | **Date** | the time when the last session on this workspace was made |
-**workspacePath** | **String** | absolute path of this workspace in server. not always available | [optional]
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
deleted file mode 100644
index 276968d5..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/docs/WorkspaceApi.md
+++ /dev/null
@@ -1,401 +0,0 @@
-# WebidaServiceApi.WorkspaceApi
-
-All URIs are relative to *https://localhost/api*
-
-Method | HTTP request | Description
-------------- | ------------- | -------------
-[**cancel**](WorkspaceApi.md#cancel) | **DELETE** /workspaces/{workspaceId}/exec |
-[**createWorkspace**](WorkspaceApi.md#createWorkspace) | **POST** /workspaces |
-[**exec**](WorkspaceApi.md#exec) | **POST** /workspaces/{workspaceId}/exec |
-[**getAllWorkspaces**](WorkspaceApi.md#getAllWorkspaces) | **GET** /workspaces |
-[**getWorkspace**](WorkspaceApi.md#getWorkspace) | **GET** /workspaces/{workspaceId} |
-[**removeWorkspace**](WorkspaceApi.md#removeWorkspace) | **DELETE** /workspaces/{workspaceId} |
-[**updateWorkspace**](WorkspaceApi.md#updateWorkspace) | **PUT** /workspaces/{workspaceId} |
-
-
-
-# **cancel**
-> RestOK cancel(workspaceId, execId)
-
-
-
-cancels an execution, if possible. Killing process may not be graceful.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-
-var execId = "execId_example"; // String | the execId property in ExecRequest
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.cancel(workspaceId, execId, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
- **execId** | **String**| the execId property in ExecRequest |
-
-### Return type
-
-[**RestOK**](RestOK.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **createWorkspace**
-> Workspace createWorkspace(workspacePath)
-
-
-
-create a new workspace at given path
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspacePath = "workspacePath_example"; // String | a real/local path of the system
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.createWorkspace(workspacePath, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspacePath** | **String**| a real/local path of the system |
-
-### Return type
-
-[**Workspace**](Workspace.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **exec**
-> ExecResponse exec(workspaceId, body, opts)
-
-
-
-execute a shell command
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-
-var body = new WebidaServiceApi.ExecRequest(); // ExecRequest |
-
-var opts = {
- 'async': false // Boolean | Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session.
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.exec(workspaceId, body, opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
- **body** | [**ExecRequest**](ExecRequest.md)| |
- **async** | **Boolean**| Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session. | [optional] [default to false]
-
-### Return type
-
-[**ExecResponse**](ExecResponse.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **getAllWorkspaces**
-> [Workspace] getAllWorkspaces(opts)
-
-
-
-get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var opts = {
- 'disposable': false // Boolean | include disposable workspaces in response
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.getAllWorkspaces(opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **disposable** | **Boolean**| include disposable workspaces in response | [optional] [default to false]
-
-### Return type
-
-[**[Workspace]**](Workspace.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **getWorkspace**
-> Workspace getWorkspace(workspaceId, )
-
-
-
-get all workspaces registerd (non-disposable) in the server
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.getWorkspace(workspaceId, , callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
-
-### Return type
-
-[**Workspace**](Workspace.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **removeWorkspace**
-> Workspace removeWorkspace(workspaceId, , opts)
-
-
-
-remove a workspace. all sessions on this workspace will be closed.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-
-var opts = {
- 'wait': 0 // Integer | Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely.
-};
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.removeWorkspace(workspaceId, , opts, callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
- **wait** | **Integer**| Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely. | [optional] [default to 0]
-
-### Return type
-
-[**Workspace**](Workspace.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
-
-# **updateWorkspace**
-> Workspace updateWorkspace(workspaceId, )
-
-
-
-update workspace information. some properties will not be updated by this api.
-
-### Example
-```javascript
-var WebidaServiceApi = require('webida-service-api');
-var defaultClient = WebidaServiceApi.ApiClient.default;
-
-// Configure API key authorization: webida-simple-auth
-var webida-simple-auth = defaultClient.authentications['webida-simple-auth'];
-webida-simple-auth.apiKey = 'YOUR API KEY';
-// Uncomment the following line to set a prefix for the API key, e.g. "Token" (defaults to null)
-//webida-simple-auth.apiKeyPrefix = 'Token';
-
-var apiInstance = new WebidaServiceApi.WorkspaceApi();
-
-var workspaceId = "workspaceId_example"; // String | webida workspace id (usually same to file system id, wfsId)
-
-
-var callback = function(error, data, response) {
- if (error) {
- console.error(error);
- } else {
- console.log('API called successfully. Returned data: ' + data);
- }
-};
-apiInstance.updateWorkspace(workspaceId, , callback);
-```
-
-### Parameters
-
-Name | Type | Description | Notes
-------------- | ------------- | ------------- | -------------
- **workspaceId** | **String**| webida workspace id (usually same to file system id, wfsId) |
-
-### Return type
-
-[**Workspace**](Workspace.md)
-
-### Authorization
-
-[webida-simple-auth](../README.md#webida-simple-auth)
-
-### HTTP request headers
-
- - **Content-Type**: application/json
- - **Accept**: application/json, application/octet-stream
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
deleted file mode 100644
index 0f1f2144..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/git_push.sh
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/bin/sh
-# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
-#
-# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
-
-git_user_id=$1
-git_repo_id=$2
-release_note=$3
-
-if [ "$git_user_id" = "" ]; then
- git_user_id=""
- echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
-fi
-
-if [ "$git_repo_id" = "" ]; then
- git_repo_id=""
- echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
-fi
-
-if [ "$release_note" = "" ]; then
- release_note=""
- echo "[INFO] No command line input provided. Set \$release_note to $release_note"
-fi
-
-# Initialize the local directory as a Git repository
-git init
-
-# Adds the files in the local repository and stages them for commit.
-git add .
-
-# Commits the tracked changes and prepares them to be pushed to a remote repository.
-git commit -m "$release_note"
-
-# Sets the new remote
-git_remote=`git remote`
-if [ "$git_remote" = "" ]; then # git remote not defined
-
- if [ "$GIT_TOKEN" = "" ]; then
- echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the Git credential in your environment."
- git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
- else
- git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
- fi
-
-fi
-
-git pull origin master
-
-# Pushes (Forces) the changes in the local repository up to the remote repository
-echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
-git push origin master 2>&1 | grep -v 'To https'
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
deleted file mode 100644
index a130ea7b..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "webida-service-api",
- "version": "0.1",
- "description": "Webida Service API specfication",
- "license": "Apache-2.0",
- "main": "src/index.js",
- "scripts": {
- "test": "./node_modules/mocha/bin/mocha --recursive"
- },
- "dependencies": {
- "superagent": "1.7.1"
- },
- "devDependencies": {
- "mocha": "~2.3.4",
- "sinon": "1.17.3",
- "expect.js": "~0.3.1"
- }
-}
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
deleted file mode 100644
index 72c58d15..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/ApiClient.js
+++ /dev/null
@@ -1,501 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['./superagent'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('superagent'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.ApiClient = factory(root.superagent);
- }
-}(this, function(superagent) {
- 'use strict';
-
- /**
- * @module ApiClient
- * @version 0.1
- */
-
- /**
- * Manages low level client-server communications, parameter marshalling, etc. There should not be any need for an
- * application to use this class directly - the *Api and model classes provide the public API for the service. The
- * contents of this file should be regarded as internal but are documented for completeness.
- * @alias module:ApiClient
- * @class
- */
- var exports = function() {
- /**
- * The base URL against which to resolve every API call's (relative) path.
- * @type {String}
- * @default https://localhost/api
- */
- this.basePath = 'https://localhost/api'.replace(/\/+$/, '');
-
- /**
- * The authentication methods to be included for all API calls.
- * @type {Array.}
- */
- this.authentications = {
- 'webida-simple-auth': {type: 'apiKey', 'in': 'header', name: 'Authorization'}
- };
- /**
- * The default HTTP headers to be included for all API calls.
- * @type {Array.}
- * @default {}
- */
- this.defaultHeaders = {};
-
- /**
- * The default HTTP timeout for all API calls.
- * @type {Number}
- * @default 60000
- */
- this.timeout = 60000;
- };
-
- /**
- * Returns a string representation for an actual parameter.
- * @param param The actual parameter.
- * @returns {String} The string representation of param.
- */
- exports.prototype.paramToString = function(param) {
- if (param == undefined || param == null) {
- return '';
- }
- if (param instanceof Date) {
- return param.toJSON();
- }
- return param.toString();
- };
-
- /**
- * Builds full URL by appending the given path to the base URL and replacing path parameter place-holders with parameter values.
- * NOTE: query parameters are not handled here.
- * @param {String} path The path to append to the base URL.
- * @param {Object} pathParams The parameter values to append.
- * @returns {String} The encoded path with parameter values substituted.
- */
- exports.prototype.buildUrl = function(path, pathParams) {
- if (!path.match(/^\//)) {
- path = '/' + path;
- }
- var url = this.basePath + path;
- var _this = this;
- url = url.replace(/\{([\w-]+)\}/g, function(fullMatch, key) {
- var value;
- if (pathParams.hasOwnProperty(key)) {
- value = _this.paramToString(pathParams[key]);
- } else {
- value = fullMatch;
- }
- return encodeURIComponent(value);
- });
- return url;
- };
-
- /**
- * Checks whether the given content type represents JSON.
- * JSON content type examples:
- *
- * - application/json
- * - application/json; charset=UTF8
- * - APPLICATION/JSON
- *
- * @param {String} contentType The MIME content type to check.
- * @returns {Boolean} true if contentType represents JSON, otherwise false.
- */
- exports.prototype.isJsonMime = function(contentType) {
- return Boolean(contentType != null && contentType.match(/^application\/json(;.*)?$/i));
- };
-
- /**
- * Chooses a content type from the given array, with JSON preferred; i.e. return JSON if included, otherwise return the first.
- * @param {Array.} contentTypes
- * @returns {String} The chosen content type, preferring JSON.
- */
- exports.prototype.jsonPreferredMime = function(contentTypes) {
- for (var i = 0; i < contentTypes.length; i++) {
- if (this.isJsonMime(contentTypes[i])) {
- return contentTypes[i];
- }
- }
- return contentTypes[0];
- };
-
- /**
- * Checks whether the given parameter value represents file-like content.
- * @param param The parameter to check.
- * @returns {Boolean} true if param represents a file.
- */
- exports.prototype.isFileParam = function(param) {
- // fs.ReadStream in Node.js (but not in runtime like browserify)
- if (typeof window === 'undefined' &&
- typeof require === 'function' &&
- require('fs') &&
- param instanceof require('fs').ReadStream) {
- return true;
- }
- // Buffer in Node.js
- if (typeof Buffer === 'function' && param instanceof Buffer) {
- return true;
- }
- // Blob in browser
- if (typeof Blob === 'function' && param instanceof Blob) {
- return true;
- }
- // File in browser (it seems File object is also instance of Blob, but keep this for safe)
- if (typeof File === 'function' && param instanceof File) {
- return true;
- }
- return false;
- };
-
- /**
- * Normalizes parameter values:
- *
- * - remove nils
- * - keep files and arrays
- * - format to string with `paramToString` for other cases
- *
- * @param {Object.} params The parameters as object properties.
- * @returns {Object.} normalized parameters.
- */
- exports.prototype.normalizeParams = function(params) {
- var newParams = {};
- for (var key in params) {
- if (params.hasOwnProperty(key) && params[key] != undefined && params[key] != null) {
- var value = params[key];
- if (this.isFileParam(value) || Array.isArray(value)) {
- newParams[key] = value;
- } else {
- newParams[key] = this.paramToString(value);
- }
- }
- }
- return newParams;
- };
-
- /**
- * Enumeration of collection format separator strategies.
- * @enum {String}
- * @readonly
- */
- exports.CollectionFormatEnum = {
- /**
- * Comma-separated values. Value: csv
- * @const
- */
- CSV: ',',
- /**
- * Space-separated values. Value: ssv
- * @const
- */
- SSV: ' ',
- /**
- * Tab-separated values. Value: tsv
- * @const
- */
- TSV: '\t',
- /**
- * Pipe(|)-separated values. Value: pipes
- * @const
- */
- PIPES: '|',
- /**
- * Native array. Value: multi
- * @const
- */
- MULTI: 'multi'
- };
-
- /**
- * Builds a string representation of an array-type actual parameter, according to the given collection format.
- * @param {Array} param An array parameter.
- * @param {module:ApiClient.CollectionFormatEnum} collectionFormat The array element separator strategy.
- * @returns {String|Array} A string representation of the supplied collection, using the specified delimiter. Returns
- * param as is if collectionFormat is multi.
- */
- exports.prototype.buildCollectionParam = function buildCollectionParam(param, collectionFormat) {
- if (param == null) {
- return null;
- }
- switch (collectionFormat) {
- case 'csv':
- return param.map(this.paramToString).join(',');
- case 'ssv':
- return param.map(this.paramToString).join(' ');
- case 'tsv':
- return param.map(this.paramToString).join('\t');
- case 'pipes':
- return param.map(this.paramToString).join('|');
- case 'multi':
- // return the array directly as SuperAgent will handle it as expected
- return param.map(this.paramToString);
- default:
- throw new Error('Unknown collection format: ' + collectionFormat);
- }
- };
-
- /**
- * Applies authentication headers to the request.
- * @param {Object} request The request object created by a superagent() call.
- * @param {Array.} authNames An array of authentication method names.
- */
- exports.prototype.applyAuthToRequest = function(request, authNames) {
- var _this = this;
- authNames.forEach(function(authName) {
- var auth = _this.authentications[authName];
- switch (auth.type) {
- case 'basic':
- if (auth.username || auth.password) {
- request.auth(auth.username || '', auth.password || '');
- }
- break;
- case 'apiKey':
- if (auth.apiKey) {
- var data = {};
- if (auth.apiKeyPrefix) {
- data[auth.name] = auth.apiKeyPrefix + ' ' + auth.apiKey;
- } else {
- data[auth.name] = auth.apiKey;
- }
- if (auth['in'] === 'header') {
- request.set(data);
- } else {
- request.query(data);
- }
- }
- break;
- case 'oauth2':
- if (auth.accessToken) {
- request.set({'Authorization': 'Bearer ' + auth.accessToken});
- }
- break;
- default:
- throw new Error('Unknown authentication type: ' + auth.type);
- }
- });
- };
-
- /**
- * Deserializes an HTTP response body into a value of the specified type.
- * @param {Object} response A SuperAgent response object.
- * @param {(String|Array.|Object.|Function)} returnType The type to return. Pass a string for simple types
- * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
- * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
- * all properties on data will be converted to this type.
- * @returns A value of the specified type.
- */
- exports.prototype.deserialize = function deserialize(response, returnType) {
- if (response == null || returnType == null) {
- return null;
- }
- // Rely on SuperAgent for parsing response body.
- // See http://visionmedia.github.io/superagent/#parsing-response-bodies
- var data = response.body;
- if (data == null) {
- // SuperAgent does not always produce a body; use the unparsed response as a fallback
- data = response.text;
- }
- return exports.convertToType(data, returnType);
- };
-
- /**
- * Callback function to receive the result of the operation.
- * @callback module:ApiClient~callApiCallback
- * @param {String} error Error message, if any.
- * @param data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * Invokes the REST service using the supplied settings and parameters.
- * @param {String} path The base URL to invoke.
- * @param {String} httpMethod The HTTP method to use.
- * @param {Object.} pathParams A map of path parameters and their values.
- * @param {Object.} queryParams A map of query parameters and their values.
- * @param {Object.} headerParams A map of header parameters and their values.
- * @param {Object.} formParams A map of form parameters and their values.
- * @param {Object} bodyParam The value to pass as the request body.
- * @param {Array.} authNames An array of authentication type names.
- * @param {Array.} contentTypes An array of request MIME types.
- * @param {Array.} accepts An array of acceptable response MIME types.
- * @param {(String|Array|ObjectFunction)} returnType The required type to return; can be a string for simple types or the
- * constructor for a complex type.
- * @param {module:ApiClient~callApiCallback} callback The callback function.
- * @returns {Object} The SuperAgent request object.
- */
- exports.prototype.callApi = function callApi(path, httpMethod, pathParams,
- queryParams, headerParams, formParams, bodyParam, authNames, contentTypes, accepts,
- returnType, callback) {
-
- var _this = this;
- var url = this.buildUrl(path, pathParams);
- var request = superagent(httpMethod, url);
-
- // apply authentications
- this.applyAuthToRequest(request, authNames);
-
- // set query parameters
- request.query(this.normalizeParams(queryParams));
-
- // set header parameters
- request.set(this.defaultHeaders).set(this.normalizeParams(headerParams));
-
- // set request timeout
- request.timeout(this.timeout);
-
- // FIX 3 - should not set 'multipart/form-data' header too early
- // for superagent will not add 'boundary' string for the header automatically
- // let the agent handle multipart/form-data
- var contentType = this.jsonPreferredMime(contentTypes);
- if (contentType !== 'multipart/form-data') {
- if (contentType) {
- request.type(contentType);
- } else if (!request.header['Content-Type']) {
- request.type('application/json');
- }
- }
-
- if (contentType === 'application/x-www-form-urlencoded') {
- request.send(this.normalizeParams(formParams));
- } else if (contentType == 'multipart/form-data') {
- var _formParams = this.normalizeParams(formParams);
- for (var key in _formParams) {
- if (_formParams.hasOwnProperty(key)) {
- if (this.isFileParam(_formParams[key])) {
- // file field
- request.attach(key, _formParams[key]);
- } else {
- request.field(key, _formParams[key]);
- }
- }
- }
- } else if (bodyParam) {
- request.send(bodyParam);
- }
-
- var accept = this.jsonPreferredMime(accepts);
- if (accept) {
- request.accept(accept);
- }
-
-
- request.end(function(error, response) {
- if (callback) {
- var data = null;
- if (!error) {
- data = _this.deserialize(response, returnType);
- }
- callback(error, data, response);
- }
- });
-
- return request;
- };
-
- /**
- * Parses an ISO-8601 string representation of a date value.
- * @param {String} str The date value as a string.
- * @returns {Date} The parsed date object.
- */
- exports.parseDate = function(str) {
- return new Date(str.replace(/T/i, ' '));
- };
-
- /**
- * Converts a value to the specified type.
- * @param {(String|Object)} data The data to convert, as a string or object.
- * @param {(String|Array.|Object.|Function)} type The type to return. Pass a string for simple types
- * or the constructor function for a complex type. Pass an array containing the type name to return an array of that type. To
- * return an object, pass an object with one property whose name is the key type and whose value is the corresponding value type:
- * all properties on data will be converted to this type.
- * @returns An instance of the specified type.
- */
- exports.convertToType = function(data, type) {
- switch (type) {
- case 'Boolean':
- return Boolean(data);
- case 'Integer':
- return parseInt(data, 10);
- case 'Number':
- return parseFloat(data);
- case 'String':
- return String(data);
- case 'Date':
- return this.parseDate(String(data));
- default:
- // FIXED 1 - when type is File, do not convert
- if (type === Object || type === File ) {
- // generic object, return directly
- return data;
- } else if (typeof type === 'function') {
- // for model type like: User
- // FIXED 2 - consruct only when it's available
- if (typeof type.constructFromObject !== 'function')
- return data;
- else
- return type.constructFromObject(data);
- } else if (Array.isArray(type)) {
- // for array type like: ['String']
- var itemType = type[0];
- return data.map(function(item) {
- return exports.convertToType(item, itemType);
- });
- } else if (typeof type === 'object') {
- // for plain object type like: {'String': 'Integer'}
- var keyType, valueType;
- for (var k in type) {
- if (type.hasOwnProperty(k)) {
- keyType = k;
- valueType = type[k];
- break;
- }
- }
- var result = {};
- for (var k in data) {
- if (data.hasOwnProperty(k)) {
- var key = exports.convertToType(k, keyType);
- var value = exports.convertToType(data[k], valueType);
- result[key] = value;
- }
- }
- return result;
- } else {
- // for unknown type, return the data directly
- return data;
- }
- }
- };
-
- /**
- * Constructs a new map or array model from REST data.
- * @param data {Object|Array} The REST data.
- * @param obj {Object|Array} The target object or array.
- */
- exports.constructFromObject = function(data, obj, itemType) {
- if (Array.isArray(data)) {
- for (var i = 0; i < data.length; i++) {
- if (data.hasOwnProperty(i))
- obj[i] = exports.convertToType(data[i], itemType);
- }
- } else {
- for (var k in data) {
- if (data.hasOwnProperty(k))
- result[k] = exports.convertToType(data[k], itemType);
- }
- }
- };
-
- /**
- * The default API client implementation.
- * @type {module:ApiClient}
- */
- exports.instance = new exports();
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
deleted file mode 100644
index 858cf440..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/AuthApi.js
+++ /dev/null
@@ -1,168 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/User', '../model/RestError', '../model/Token', '../model/Credential'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/User'), require('../model/RestError'), require('../model/Token'), require('../model/Credential'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.AuthApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.User, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Token, root.WebidaServiceApi.Credential);
- }
-}(this, function(ApiClient, User, RestError, Token, Credential) {
- 'use strict';
-
- /**
- * Auth service.
- * @module api/AuthApi
- * @version 0.1
- */
-
- /**
- * Constructs a new AuthApi.
- * @alias module:api/AuthApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the getInfo operation.
- * @callback module:api/AuthApi~getInfoCallback
- * @param {String} error Error message, if any.
- * @param {module:model/User} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * Gets user information of that can be identified with current access token. Implementations should provide a more restful api based on domain data model. Don't override this operation for multi-user system.
- * @param {module:api/AuthApi~getInfoCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/User}
- */
- this.getInfo = function(callback) {
- var postBody = null;
-
-
- var pathParams = {
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = User;
-
- return this.apiClient.callApi(
- '/auth/info', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the issueToken operation.
- * @callback module:api/AuthApi~issueTokenCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Token} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * Creates new token from current access token, inheriting workspace id & session id Duration of generated token is not (and should be) parameterizable.
- * @param {module:model/String} type
- * @param {Object} opts Optional parameters
- * @param {String} opts.workspaceId mandatory to issue a MASTER type token
- * @param {module:api/AuthApi~issueTokenCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Token}
- */
- this.issueToken = function(type, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'type' is set
- if (type == undefined || type == null) {
- throw "Missing the required parameter 'type' when calling issueToken";
- }
-
-
- var pathParams = {
- };
- var queryParams = {
- 'type': type,
- 'workspaceId': opts['workspaceId']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Token;
-
- return this.apiClient.callApi(
- '/auth/token', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the login operation.
- * @callback module:api/AuthApi~loginCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Token} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * A 'VERY' basic authentication, required to use webida-simple-auth security scheme. Service / Product implementations who need better security, should override this operation or add their own login api or some other specs like OAuth2. Simple auth is not suitable for large-sacle, multi-tennant service. Generated accss token inherits all restriction from master token. In normal login, unrestricted access token will be granted with reasonably short expiration time. Every client should respawn another access token with issueToken API before current access token expires.
- * @param {module:model/Credential} body
- * @param {module:api/AuthApi~loginCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Token}
- */
- this.login = function(body, callback) {
- var postBody = body;
-
- // verify the required parameter 'body' is set
- if (body == undefined || body == null) {
- throw "Missing the required parameter 'body' when calling login";
- }
-
-
- var pathParams = {
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = [];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Token;
-
- return this.apiClient.callApi(
- '/auth/login', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
deleted file mode 100644
index 5fe4f7b6..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/DefaultApi.js
+++ /dev/null
@@ -1,109 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestOK', '../model/RestError'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.DefaultApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError);
- }
-}(this, function(ApiClient, RestOK, RestError) {
- 'use strict';
-
- /**
- * Default service.
- * @module api/DefaultApi
- * @version 0.1
- */
-
- /**
- * Constructs a new DefaultApi.
- * @alias module:api/DefaultApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the replace operation.
- * @callback module:api/DefaultApi~replaceCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * replace file contents with regex matching
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {Array.} wfsPathList array of wfsPath, with heading / (collection format may be changed by implementation)
- * @param {String} pattern regex pattern to match
- * @param {String} replaceTo string to replace with
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ignoreCase regex matching option to ignore case (default to false)
- * @param {Boolean} opts.wholeWord regex matching option to match whole word (default to false)
- * @param {module:api/DefaultApi~replaceCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.replace = function(wfsId, wfsPathList, pattern, replaceTo, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling replace";
- }
-
- // verify the required parameter 'wfsPathList' is set
- if (wfsPathList == undefined || wfsPathList == null) {
- throw "Missing the required parameter 'wfsPathList' when calling replace";
- }
-
- // verify the required parameter 'pattern' is set
- if (pattern == undefined || pattern == null) {
- throw "Missing the required parameter 'pattern' when calling replace";
- }
-
- // verify the required parameter 'replaceTo' is set
- if (replaceTo == undefined || replaceTo == null) {
- throw "Missing the required parameter 'replaceTo' when calling replace";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId
- };
- var queryParams = {
- 'wfsPathList': this.apiClient.buildCollectionParam(wfsPathList, 'multi'),
- 'pattern': pattern,
- 'replaceTo': replaceTo,
- 'ignoreCase': opts['ignoreCase'],
- 'wholeWord': opts['wholeWord']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/ops/replace', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
deleted file mode 100644
index 4534edba..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/OpsApi.js
+++ /dev/null
@@ -1,102 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestError', '../model/Match'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestError'), require('../model/Match'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.OpsApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Match);
- }
-}(this, function(ApiClient, RestError, Match) {
- 'use strict';
-
- /**
- * Ops service.
- * @module api/OpsApi
- * @version 0.1
- */
-
- /**
- * Constructs a new OpsApi.
- * @alias module:api/OpsApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the search operation.
- * @callback module:api/OpsApi~searchCallback
- * @param {String} error Error message, if any.
- * @param {Object.} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * search files in some path, with given pattern
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {String} pattern regex pattern to match
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ignoreCase regex matching option to ignore case (default to false)
- * @param {Boolean} opts.wholeWord regex matching option to match whole word (default to false)
- * @param {module:api/OpsApi~searchCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {Object.}
- */
- this.search = function(wfsId, wfsPath, pattern, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling search";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling search";
- }
-
- // verify the required parameter 'pattern' is set
- if (pattern == undefined || pattern == null) {
- throw "Missing the required parameter 'pattern' when calling search";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'pattern': pattern,
- 'ignoreCase': opts['ignoreCase'],
- 'wholeWord': opts['wholeWord']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = {'String': Match};
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/ops/search/{wfsPath}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
deleted file mode 100644
index 0e2b0184..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/SessionApi.js
+++ /dev/null
@@ -1,176 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Session'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Session'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.SessionApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Session);
- }
-}(this, function(ApiClient, RestOK, RestError, Session) {
- 'use strict';
-
- /**
- * Session service.
- * @module api/SessionApi
- * @version 0.1
- */
-
- /**
- * Constructs a new SessionApi.
- * @alias module:api/SessionApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the deleteSession operation.
- * @callback module:api/SessionApi~deleteSessionCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * close session with timeout
- * @param {String} sessionId webida session id (usually different from socket id from sock.io)
- * @param {Integer} closeAfter waiting time before actual closing, to let client save files and prevent reconnect
- * @param {module:api/SessionApi~deleteSessionCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.deleteSession = function(sessionId, closeAfter, callback) {
- var postBody = null;
-
- // verify the required parameter 'sessionId' is set
- if (sessionId == undefined || sessionId == null) {
- throw "Missing the required parameter 'sessionId' when calling deleteSession";
- }
-
- // verify the required parameter 'closeAfter' is set
- if (closeAfter == undefined || closeAfter == null) {
- throw "Missing the required parameter 'closeAfter' when calling deleteSession";
- }
-
-
- var pathParams = {
- 'sessionId': sessionId
- };
- var queryParams = {
- 'closeAfter': closeAfter
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/sessions/{sessionId}', 'DELETE',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the getSession operation.
- * @callback module:api/SessionApi~getSessionCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Session} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * get a session object by id
- * @param {String} sessionId webida session id (usually different from socket id from sock.io)
- * @param {module:api/SessionApi~getSessionCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Session}
- */
- this.getSession = function(sessionId, callback) {
- var postBody = null;
-
- // verify the required parameter 'sessionId' is set
- if (sessionId == undefined || sessionId == null) {
- throw "Missing the required parameter 'sessionId' when calling getSession";
- }
-
-
- var pathParams = {
- 'sessionId': sessionId
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Session;
-
- return this.apiClient.callApi(
- '/sessions/{sessionId}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the getSessions operation.
- * @callback module:api/SessionApi~getSessionsCallback
- * @param {String} error Error message, if any.
- * @param {Array.} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * get all / some webida sessions established to server
- * @param {Object} opts Optional parameters
- * @param {String} opts.workspaceId only include sessions working on some given workspace
- * @param {module:api/SessionApi~getSessionsCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {Array.}
- */
- this.getSessions = function(opts, callback) {
- opts = opts || {};
- var postBody = null;
-
-
- var pathParams = {
- };
- var queryParams = {
- 'workspaceId': opts['workspaceId']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = [Session];
-
- return this.apiClient.callApi(
- '/sessions', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
deleted file mode 100644
index 247530ae..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WfsApi.js
+++ /dev/null
@@ -1,574 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/DirEntry', '../model/Stats'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/DirEntry'), require('../model/Stats'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.WfsApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.DirEntry, root.WebidaServiceApi.Stats);
- }
-}(this, function(ApiClient, RestOK, RestError, DirEntry, Stats) {
- 'use strict';
-
- /**
- * Wfs service.
- * @module api/WfsApi
- * @version 0.1
- */
-
- /**
- * Constructs a new WfsApi.
- * @alias module:api/WfsApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the copy operation.
- * @callback module:api/WfsApi~copyCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * Copy to given path. works like cp -r command, with some funny options Copying a dir on to existing file will return error if removeExisting is false Copying from sockets, fifo, .. and any other type of file system object is not supported.
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {String} srcPath source data path of some operations, with have heading /
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.removeExisting remove any existing file/dir before writing. (default to false)
- * @param {Boolean} opts.followSymbolicLinks dereference symlinks or not (default to false)
- * @param {Boolean} opts.noPreserveTimestamps to change default behavior, keep mtime/atime of source files in destination (default to false)
- * @param {String} opts.filterPattern execute copy if source matches to this regex pattern.
- * @param {module:api/WfsApi~copyCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.copy = function(wfsId, wfsPath, srcPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling copy";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling copy";
- }
-
- // verify the required parameter 'srcPath' is set
- if (srcPath == undefined || srcPath == null) {
- throw "Missing the required parameter 'srcPath' when calling copy";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'srcPath': srcPath,
- 'removeExisting': opts['removeExisting'],
- 'followSymbolicLinks': opts['followSymbolicLinks'],
- 'noPreserveTimestamps': opts['noPreserveTimestamps'],
- 'filterPattern': opts['filterPattern']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/any/{wfsPath}', 'PUT',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the createDir operation.
- * @callback module:api/WfsApi~createDirCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * create a directory at the path. will return error when wfsPath exists and not empty
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
- * @param {module:api/WfsApi~createDirCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.createDir = function(wfsId, wfsPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling createDir";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling createDir";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'ensure': opts['ensure']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/dir/{wfsPath}', 'PUT',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the dirTree operation.
- * @callback module:api/WfsApi~dirTreeCallback
- * @param {String} error Error message, if any.
- * @param {module:model/DirEntry} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * returns a directory tree of given path, for listing dir and managing file system
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {Integer} maxDepth Maximum depth of tree. Set -1 to build a full tree, 0 to stat, 1 to plain list.
- * @param {module:api/WfsApi~dirTreeCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/DirEntry}
- */
- this.dirTree = function(wfsId, wfsPath, maxDepth, callback) {
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling dirTree";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling dirTree";
- }
-
- // verify the required parameter 'maxDepth' is set
- if (maxDepth == undefined || maxDepth == null) {
- throw "Missing the required parameter 'maxDepth' when calling dirTree";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'maxDepth': maxDepth
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = DirEntry;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/dir/{wfsPath}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the move operation.
- * @callback module:api/WfsApi~moveCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * move file or directory to given path. works like mv command
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {String} srcPath source data path of some operations, with have heading /
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.removeExisting remove any existing file/dir before writing. (default to false)
- * @param {module:api/WfsApi~moveCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.move = function(wfsId, wfsPath, srcPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling move";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling move";
- }
-
- // verify the required parameter 'srcPath' is set
- if (srcPath == undefined || srcPath == null) {
- throw "Missing the required parameter 'srcPath' when calling move";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'srcPath': srcPath,
- 'removeExisting': opts['removeExisting']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/dir/{wfsPath}', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the readFile operation.
- * @callback module:api/WfsApi~readFileCallback
- * @param {String} error Error message, if any.
- * @param {File} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * read file data on path
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {module:api/WfsApi~readFileCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {File}
- */
- this.readFile = function(wfsId, wfsPath, callback) {
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling readFile";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling readFile";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = File;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/file/{wfsPath}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the remove operation.
- * @callback module:api/WfsApi~removeCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * delete file or directory
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.recursive flag to set copy with (default to false)
- * @param {module:api/WfsApi~removeCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.remove = function(wfsId, wfsPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling remove";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling remove";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'recursive': opts['recursive']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/any/{wfsPath}', 'DELETE',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the rename operation.
- * @callback module:api/WfsApi~renameCallback
- * @param {String} error Error message, if any.
- * @param {File} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * Rename a file or directory to. This api does not remove an existing one.
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {String} srcPath source data path of some operations, with have heading /
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
- * @param {module:api/WfsApi~renameCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {File}
- */
- this.rename = function(wfsId, wfsPath, srcPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling rename";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling rename";
- }
-
- // verify the required parameter 'srcPath' is set
- if (srcPath == undefined || srcPath == null) {
- throw "Missing the required parameter 'srcPath' when calling rename";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'srcPath': srcPath,
- 'ensure': opts['ensure']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = File;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/file/{wfsPath}', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the stat operation.
- * @callback module:api/WfsApi~statCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Stats} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * get stats of given path. (stat returns 'stats' object in node and POSIX)
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ignoreError flag to ignore stat errors to check existence only (default to false)
- * @param {module:api/WfsApi~statCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Stats}
- */
- this.stat = function(wfsId, wfsPath, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling stat";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling stat";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'ignoreError': opts['ignoreError']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Stats;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/any/{wfsPath}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the writeFile operation.
- * @callback module:api/WfsApi~writeFileCallback
- * @param {String} error Error message, if any.
- * @param {File} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * create / update file with body data
- * @param {String} wfsId webida file system id (same to workspace id) to access.
- * @param {String} wfsPath webida file system path to access. without heading /. should be placed at the end of path arguments
- * @param {File} data file contents to write.
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.ensure flag to create all parent directories to create file or dir, like mkdir -p (default to false)
- * @param {module:api/WfsApi~writeFileCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {File}
- */
- this.writeFile = function(wfsId, wfsPath, data, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'wfsId' is set
- if (wfsId == undefined || wfsId == null) {
- throw "Missing the required parameter 'wfsId' when calling writeFile";
- }
-
- // verify the required parameter 'wfsPath' is set
- if (wfsPath == undefined || wfsPath == null) {
- throw "Missing the required parameter 'wfsPath' when calling writeFile";
- }
-
- // verify the required parameter 'data' is set
- if (data == undefined || data == null) {
- throw "Missing the required parameter 'data' when calling writeFile";
- }
-
-
- var pathParams = {
- 'wfsId': wfsId,
- 'wfsPath': wfsPath
- };
- var queryParams = {
- 'ensure': opts['ensure']
- };
- var headerParams = {
- };
- var formParams = {
- 'data': data
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['multipart/form-data'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = File;
-
- return this.apiClient.callApi(
- '/wfs/{wfsId}/file/{wfsPath}', 'PUT',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
deleted file mode 100644
index d5318274..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/api/WorkspaceApi.js
+++ /dev/null
@@ -1,370 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestOK', '../model/RestError', '../model/Workspace', '../model/ExecRequest', '../model/ExecResponse'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('../model/RestOK'), require('../model/RestError'), require('../model/Workspace'), require('../model/ExecRequest'), require('../model/ExecResponse'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.WorkspaceApi = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestOK, root.WebidaServiceApi.RestError, root.WebidaServiceApi.Workspace, root.WebidaServiceApi.ExecRequest, root.WebidaServiceApi.ExecResponse);
- }
-}(this, function(ApiClient, RestOK, RestError, Workspace, ExecRequest, ExecResponse) {
- 'use strict';
-
- /**
- * Workspace service.
- * @module api/WorkspaceApi
- * @version 0.1
- */
-
- /**
- * Constructs a new WorkspaceApi.
- * @alias module:api/WorkspaceApi
- * @class
- * @param {module:ApiClient} apiClient Optional API client implementation to use,
- * default to {@link module:ApiClient#instance} if unspecified.
- */
- var exports = function(apiClient) {
- this.apiClient = apiClient || ApiClient.instance;
-
-
- /**
- * Callback function to receive the result of the cancel operation.
- * @callback module:api/WorkspaceApi~cancelCallback
- * @param {String} error Error message, if any.
- * @param {module:model/RestOK} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * cancels an execution, if possible. Killing process may not be graceful.
- * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {String} execId the execId property in ExecRequest
- * @param {module:api/WorkspaceApi~cancelCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/RestOK}
- */
- this.cancel = function(workspaceId, execId, callback) {
- var postBody = null;
-
- // verify the required parameter 'workspaceId' is set
- if (workspaceId == undefined || workspaceId == null) {
- throw "Missing the required parameter 'workspaceId' when calling cancel";
- }
-
- // verify the required parameter 'execId' is set
- if (execId == undefined || execId == null) {
- throw "Missing the required parameter 'execId' when calling cancel";
- }
-
-
- var pathParams = {
- 'workspaceId': workspaceId
- };
- var queryParams = {
- 'execId': execId
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = RestOK;
-
- return this.apiClient.callApi(
- '/workspaces/{workspaceId}/exec', 'DELETE',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the createWorkspace operation.
- * @callback module:api/WorkspaceApi~createWorkspaceCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Workspace} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * create a new workspace at given path
- * @param {String} workspacePath a real/local path of the system
- * @param {module:api/WorkspaceApi~createWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Workspace}
- */
- this.createWorkspace = function(workspacePath, callback) {
- var postBody = null;
-
- // verify the required parameter 'workspacePath' is set
- if (workspacePath == undefined || workspacePath == null) {
- throw "Missing the required parameter 'workspacePath' when calling createWorkspace";
- }
-
-
- var pathParams = {
- };
- var queryParams = {
- 'workspacePath': workspacePath
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Workspace;
-
- return this.apiClient.callApi(
- '/workspaces', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the exec operation.
- * @callback module:api/WorkspaceApi~execCallback
- * @param {String} error Error message, if any.
- * @param {module:model/ExecResponse} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * execute a shell command
- * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {module:model/ExecRequest} body
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.async Spawn a child process for given command and returns a dummy response immediatlely, Actual output (stream of message) will be pasted to web socket channel of current session. (default to false)
- * @param {module:api/WorkspaceApi~execCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/ExecResponse}
- */
- this.exec = function(workspaceId, body, opts, callback) {
- opts = opts || {};
- var postBody = body;
-
- // verify the required parameter 'workspaceId' is set
- if (workspaceId == undefined || workspaceId == null) {
- throw "Missing the required parameter 'workspaceId' when calling exec";
- }
-
- // verify the required parameter 'body' is set
- if (body == undefined || body == null) {
- throw "Missing the required parameter 'body' when calling exec";
- }
-
-
- var pathParams = {
- 'workspaceId': workspaceId
- };
- var queryParams = {
- 'async': opts['async']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = ExecResponse;
-
- return this.apiClient.callApi(
- '/workspaces/{workspaceId}/exec', 'POST',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the getAllWorkspaces operation.
- * @callback module:api/WorkspaceApi~getAllWorkspacesCallback
- * @param {String} error Error message, if any.
- * @param {Array.} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * get all registerd (non-disposable) workspaces in the server. since webida is not designed to host so many workspaces, there's no good 'find' or 'query' API. Service/product implementations may create a better opeation.
- * @param {Object} opts Optional parameters
- * @param {Boolean} opts.disposable include disposable workspaces in response (default to false)
- * @param {module:api/WorkspaceApi~getAllWorkspacesCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {Array.}
- */
- this.getAllWorkspaces = function(opts, callback) {
- opts = opts || {};
- var postBody = null;
-
-
- var pathParams = {
- };
- var queryParams = {
- 'disposable': opts['disposable']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = [Workspace];
-
- return this.apiClient.callApi(
- '/workspaces', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the getWorkspace operation.
- * @callback module:api/WorkspaceApi~getWorkspaceCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Workspace} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * get all workspaces registerd (non-disposable) in the server
- * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {module:api/WorkspaceApi~getWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Workspace}
- */
- this.getWorkspace = function(workspaceId, callback) {
- var postBody = null;
-
- // verify the required parameter 'workspaceId' is set
- if (workspaceId == undefined || workspaceId == null) {
- throw "Missing the required parameter 'workspaceId' when calling getWorkspace";
- }
-
-
- var pathParams = {
- 'workspaceId': workspaceId
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Workspace;
-
- return this.apiClient.callApi(
- '/workspaces/{workspaceId}', 'GET',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the removeWorkspace operation.
- * @callback module:api/WorkspaceApi~removeWorkspaceCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Workspace} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * remove a workspace. all sessions on this workspace will be closed.
- * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {Object} opts Optional parameters
- * @param {Integer} opts.wait Time in seconds to wait for all sessions save & close their data. zero or negative value will close the sessions immediatlely. (default to 0)
- * @param {module:api/WorkspaceApi~removeWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Workspace}
- */
- this.removeWorkspace = function(workspaceId, opts, callback) {
- opts = opts || {};
- var postBody = null;
-
- // verify the required parameter 'workspaceId' is set
- if (workspaceId == undefined || workspaceId == null) {
- throw "Missing the required parameter 'workspaceId' when calling removeWorkspace";
- }
-
-
- var pathParams = {
- 'workspaceId': workspaceId
- };
- var queryParams = {
- 'wait': opts['wait']
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Workspace;
-
- return this.apiClient.callApi(
- '/workspaces/{workspaceId}', 'DELETE',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
-
- /**
- * Callback function to receive the result of the updateWorkspace operation.
- * @callback module:api/WorkspaceApi~updateWorkspaceCallback
- * @param {String} error Error message, if any.
- * @param {module:model/Workspace} data The data returned by the service call.
- * @param {String} response The complete HTTP response.
- */
-
- /**
- * update workspace information. some properties will not be updated by this api.
- * @param {String} workspaceId webida workspace id (usually same to file system id, wfsId)
- * @param {module:api/WorkspaceApi~updateWorkspaceCallback} callback The callback function, accepting three arguments: error, data, response
- * data is of type: {module:model/Workspace}
- */
- this.updateWorkspace = function(workspaceId, callback) {
- var postBody = null;
-
- // verify the required parameter 'workspaceId' is set
- if (workspaceId == undefined || workspaceId == null) {
- throw "Missing the required parameter 'workspaceId' when calling updateWorkspace";
- }
-
-
- var pathParams = {
- 'workspaceId': workspaceId
- };
- var queryParams = {
- };
- var headerParams = {
- };
- var formParams = {
- };
-
- var authNames = ['webida-simple-auth'];
- var contentTypes = ['application/json'];
- var accepts = ['application/json', 'application/octet-stream'];
- var returnType = Workspace;
-
- return this.apiClient.callApi(
- '/workspaces/{workspaceId}', 'PUT',
- pathParams, queryParams, headerParams, formParams, postBody,
- authNames, contentTypes, accepts, returnType, callback
- );
- }
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
deleted file mode 100644
index bf4cf98f..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/index.js
+++ /dev/null
@@ -1,142 +0,0 @@
-(function(factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['./ApiClient', './model/Credential', './model/DirEntry', './model/ExecRequest', './model/ExecResponse', './model/Match', './model/RestError', './model/RestOK', './model/Session', './model/Stats', './model/Token', './model/User', './model/Workspace', './api/AuthApi', './api/DefaultApi', './api/OpsApi', './api/SessionApi', './api/WfsApi', './api/WorkspaceApi'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('./ApiClient'), require('./model/Credential'), require('./model/DirEntry'), require('./model/ExecRequest'), require('./model/ExecResponse'), require('./model/Match'), require('./model/RestError'), require('./model/RestOK'), require('./model/Session'), require('./model/Stats'), require('./model/Token'), require('./model/User'), require('./model/Workspace'), require('./api/AuthApi'), require('./api/DefaultApi'), require('./api/OpsApi'), require('./api/SessionApi'), require('./api/WfsApi'), require('./api/WorkspaceApi'));
- }
-}(function(ApiClient, Credential, DirEntry, ExecRequest, ExecResponse, Match, RestError, RestOK, Session, Stats, Token, User, Workspace, AuthApi, DefaultApi, OpsApi, SessionApi, WfsApi, WorkspaceApi) {
- 'use strict';
-
- /**
- * Webida Service API specfication.
- * The index module provides access to constructors for all the classes which comprise the public API.
- *
- * An AMD (recommended!) or CommonJS application will generally do something equivalent to the following:
- *
- * var WebidaServiceApi = require('index'); // See note below*.
- * var xxxSvc = new WebidaServiceApi.XxxApi(); // Allocate the API class we're going to use.
- * var yyyModel = new WebidaServiceApi.Yyy(); // Construct a model instance.
- * yyyModel.someProperty = 'someValue';
- * ...
- * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
- * ...
- *
- * *NOTE: For a top-level AMD script, use require(['index'], function(){...})
- * and put the application logic within the callback function.
- *
- *
- * A non-AMD browser application (discouraged) might do something like this:
- *
- * var xxxSvc = new WebidaServiceApi.XxxApi(); // Allocate the API class we're going to use.
- * var yyy = new WebidaServiceApi.Yyy(); // Construct a model instance.
- * yyyModel.someProperty = 'someValue';
- * ...
- * var zzz = xxxSvc.doSomething(yyyModel); // Invoke the service.
- * ...
- *
- *
- * @module index
- * @version 0.1
- */
- var exports = {
- /**
- * The ApiClient constructor.
- * @property {module:ApiClient}
- */
- ApiClient: ApiClient,
- /**
- * The Credential model constructor.
- * @property {module:model/Credential}
- */
- Credential: Credential,
- /**
- * The DirEntry model constructor.
- * @property {module:model/DirEntry}
- */
- DirEntry: DirEntry,
- /**
- * The ExecRequest model constructor.
- * @property {module:model/ExecRequest}
- */
- ExecRequest: ExecRequest,
- /**
- * The ExecResponse model constructor.
- * @property {module:model/ExecResponse}
- */
- ExecResponse: ExecResponse,
- /**
- * The Match model constructor.
- * @property {module:model/Match}
- */
- Match: Match,
- /**
- * The RestError model constructor.
- * @property {module:model/RestError}
- */
- RestError: RestError,
- /**
- * The RestOK model constructor.
- * @property {module:model/RestOK}
- */
- RestOK: RestOK,
- /**
- * The Session model constructor.
- * @property {module:model/Session}
- */
- Session: Session,
- /**
- * The Stats model constructor.
- * @property {module:model/Stats}
- */
- Stats: Stats,
- /**
- * The Token model constructor.
- * @property {module:model/Token}
- */
- Token: Token,
- /**
- * The User model constructor.
- * @property {module:model/User}
- */
- User: User,
- /**
- * The Workspace model constructor.
- * @property {module:model/Workspace}
- */
- Workspace: Workspace,
- /**
- * The AuthApi service constructor.
- * @property {module:api/AuthApi}
- */
- AuthApi: AuthApi,
- /**
- * The DefaultApi service constructor.
- * @property {module:api/DefaultApi}
- */
- DefaultApi: DefaultApi,
- /**
- * The OpsApi service constructor.
- * @property {module:api/OpsApi}
- */
- OpsApi: OpsApi,
- /**
- * The SessionApi service constructor.
- * @property {module:api/SessionApi}
- */
- SessionApi: SessionApi,
- /**
- * The WfsApi service constructor.
- * @property {module:api/WfsApi}
- */
- WfsApi: WfsApi,
- /**
- * The WorkspaceApi service constructor.
- * @property {module:api/WorkspaceApi}
- */
- WorkspaceApi: WorkspaceApi
- };
-
- return exports;
-}));
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
deleted file mode 100644
index 3de27e3d..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Credential.js
+++ /dev/null
@@ -1,87 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Credential = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The Credential model module.
- * @module model/Credential
- * @version 0.1
- */
-
- /**
- * Constructs a new Credential.
- * user credential to login. Use https to protect credential.
- * @alias module:model/Credential
- * @class
- * @param loginId
- * @param loginPassword
- */
- var exports = function(loginId, loginPassword) {
- var _this = this;
-
- _this['loginId'] = loginId;
- _this['loginPassword'] = loginPassword;
-
- };
-
- /**
- * Constructs a Credential from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Credential} obj Optional instance to populate.
- * @return {module:model/Credential} The populated Credential instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('loginId')) {
- obj['loginId'] = ApiClient.convertToType(data['loginId'], 'String');
- }
- if (data.hasOwnProperty('loginPassword')) {
- obj['loginPassword'] = ApiClient.convertToType(data['loginPassword'], 'String');
- }
- if (data.hasOwnProperty('masterToken')) {
- obj['masterToken'] = ApiClient.convertToType(data['masterToken'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * @member {String} loginId
- */
- exports.prototype['loginId'] = undefined;
- /**
- * @member {String} loginPassword
- */
- exports.prototype['loginPassword'] = undefined;
- /**
- * a master token is issued when user wants to access webida api without id/password from remote or local desktop app. When masterToken is set, client should put some bogus id/password, non-empty. (The values can be used to identify client type)
- * @member {String} masterToken
- */
- exports.prototype['masterToken'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
deleted file mode 100644
index a2c1b0be..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/DirEntry.js
+++ /dev/null
@@ -1,87 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/DirEntry', '../model/Stats'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('./DirEntry'), require('./Stats'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.DirEntry = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.DirEntry, root.WebidaServiceApi.Stats);
- }
-}(this, function(ApiClient, DirEntry, Stats) {
- 'use strict';
-
-
-
-
- /**
- * The DirEntry model module.
- * @module model/DirEntry
- * @version 0.1
- */
-
- /**
- * Constructs a new DirEntry.
- * a directory entry (file or directory) with children that represents a (sub) tree
- * @alias module:model/DirEntry
- * @class
- * @param name
- * @param stats
- * @param children
- */
- var exports = function(name, stats, children) {
- var _this = this;
-
- _this['name'] = name;
- _this['stats'] = stats;
- _this['children'] = children;
- };
-
- /**
- * Constructs a DirEntry from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/DirEntry} obj Optional instance to populate.
- * @return {module:model/DirEntry} The populated DirEntry instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('name')) {
- obj['name'] = ApiClient.convertToType(data['name'], 'String');
- }
- if (data.hasOwnProperty('stats')) {
- obj['stats'] = Stats.constructFromObject(data['stats']);
- }
- if (data.hasOwnProperty('children')) {
- obj['children'] = ApiClient.convertToType(data['children'], [DirEntry]);
- }
- }
- return obj;
- }
-
- /**
- * @member {String} name
- */
- exports.prototype['name'] = undefined;
- /**
- * @member {module:model/Stats} stats
- */
- exports.prototype['stats'] = undefined;
- /**
- * @member {Array.} children
- */
- exports.prototype['children'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
deleted file mode 100644
index 286b91c2..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecRequest.js
+++ /dev/null
@@ -1,117 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.ExecRequest = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The ExecRequest model module.
- * @module model/ExecRequest
- * @version 0.1
- */
-
- /**
- * Constructs a new ExecRequest.
- * execution request, simlilar to node.js spawn(). see node.js documentation for details of each properties. some properties are not configurable for portability - encoding : fixed to utf-8 - shell : fixed to system default. Using shell variables in command may not work. - killSignal : fixed to SIGTERM. If process does not die, server can send SIGKILL or invoke taskkill to ensure chlid process is killed. - uid & gid : will not be set - stdio : all streams are handled by server. no options are avaliable to client. - shell : always false. - detached : always false
- * @alias module:model/ExecRequest
- * @class
- * @param id
- * @param command
- * @param args
- */
- var exports = function(id, command, args) {
- var _this = this;
-
- _this['id'] = id;
- _this['command'] = command;
- _this['args'] = args;
-
-
-
- };
-
- /**
- * Constructs a ExecRequest from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/ExecRequest} obj Optional instance to populate.
- * @return {module:model/ExecRequest} The populated ExecRequest instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('id')) {
- obj['id'] = ApiClient.convertToType(data['id'], 'String');
- }
- if (data.hasOwnProperty('command')) {
- obj['command'] = ApiClient.convertToType(data['command'], 'String');
- }
- if (data.hasOwnProperty('args')) {
- obj['args'] = ApiClient.convertToType(data['args'], ['String']);
- }
- if (data.hasOwnProperty('cwd')) {
- obj['cwd'] = ApiClient.convertToType(data['cwd'], 'String');
- }
- if (data.hasOwnProperty('input')) {
- obj['input'] = ApiClient.convertToType(data['input'], 'String');
- }
- if (data.hasOwnProperty('timeout')) {
- obj['timeout'] = ApiClient.convertToType(data['timeout'], 'Integer');
- }
- }
- return obj;
- }
-
- /**
- * unique identifier of execution, to demux response stream or cancel request
- * @member {String} id
- */
- exports.prototype['id'] = undefined;
- /**
- * command to run. should not contain any arguments, pipes, redirections
- * @member {String} command
- */
- exports.prototype['command'] = undefined;
- /**
- * the arguments array
- * @member {Array.} args
- */
- exports.prototype['args'] = undefined;
- /**
- * Current working directory of child process, relative to workspace root. If abscent, CWD will be the workspace root directory. Does not accept any evaluatable form like $HOME, %USERPROFILE%. If absolute, heading / will be discarded. should be unixified.
- * @member {String} cwd
- */
- exports.prototype['cwd'] = undefined;
- /**
- * input string for child process. if falsy in async execution, async input messages will be pasted into the child's stdin. since we don't use tty, it's recommended to use input string anyway.
- * @member {String} input
- */
- exports.prototype['input'] = undefined;
- /**
- * The value which In 'milliseconds' the maximum amount of time the child is allowed to run. (not idle time of stdout / stderr stream) if undefined, server will not kill the child process until receiving cancel request if it doesn't exit by self.
- * @member {Integer} timeout
- */
- exports.prototype['timeout'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
deleted file mode 100644
index 9811aab0..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/ExecResponse.js
+++ /dev/null
@@ -1,90 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.ExecResponse = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The ExecResponse model module.
- * @module model/ExecResponse
- * @version 0.1
- */
-
- /**
- * Constructs a new ExecResponse.
- * execution response
- * @alias module:model/ExecResponse
- * @class
- * @param exitCode
- * @param stdout
- * @param stderr
- */
- var exports = function(exitCode, stdout, stderr) {
- var _this = this;
-
- _this['exitCode'] = exitCode;
- _this['stdout'] = stdout;
- _this['stderr'] = stderr;
- };
-
- /**
- * Constructs a ExecResponse from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/ExecResponse} obj Optional instance to populate.
- * @return {module:model/ExecResponse} The populated ExecResponse instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('exitCode')) {
- obj['exitCode'] = ApiClient.convertToType(data['exitCode'], 'Integer');
- }
- if (data.hasOwnProperty('stdout')) {
- obj['stdout'] = ApiClient.convertToType(data['stdout'], 'String');
- }
- if (data.hasOwnProperty('stderr')) {
- obj['stderr'] = ApiClient.convertToType(data['stderr'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * exit code of child process. always 0 for async exec
- * @member {Integer} exitCode
- */
- exports.prototype['exitCode'] = undefined;
- /**
- * standard out of child process. empty for async exec
- * @member {String} stdout
- */
- exports.prototype['stdout'] = undefined;
- /**
- * standard error of child process. empty for async exec
- * @member {String} stderr
- */
- exports.prototype['stderr'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
deleted file mode 100644
index a499d4fd..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Match.js
+++ /dev/null
@@ -1,78 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Match = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The Match model module.
- * @module model/Match
- * @version 0.1
- */
-
- /**
- * Constructs a new Match.
- * search result for a file
- * @alias module:model/Match
- * @class
- * @param line
- * @param text
- */
- var exports = function(line, text) {
- var _this = this;
-
- _this['line'] = line;
- _this['text'] = text;
- };
-
- /**
- * Constructs a Match from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Match} obj Optional instance to populate.
- * @return {module:model/Match} The populated Match instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('line')) {
- obj['line'] = ApiClient.convertToType(data['line'], 'Integer');
- }
- if (data.hasOwnProperty('text')) {
- obj['text'] = ApiClient.convertToType(data['text'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * @member {Integer} line
- */
- exports.prototype['line'] = undefined;
- /**
- * @member {String} text
- */
- exports.prototype['text'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
deleted file mode 100644
index 30169a70..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestError.js
+++ /dev/null
@@ -1,77 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.RestError = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The RestError model module.
- * @module model/RestError
- * @version 0.1
- */
-
- /**
- * Constructs a new RestError.
- * Contains status text, not status code.
- * @alias module:model/RestError
- * @class
- * @param message
- */
- var exports = function(message) {
- var _this = this;
-
-
- _this['message'] = message;
- };
-
- /**
- * Constructs a RestError from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/RestError} obj Optional instance to populate.
- * @return {module:model/RestError} The populated RestError instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('code')) {
- obj['code'] = ApiClient.convertToType(data['code'], 'String');
- }
- if (data.hasOwnProperty('message')) {
- obj['message'] = ApiClient.convertToType(data['message'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * @member {String} code
- */
- exports.prototype['code'] = undefined;
- /**
- * @member {String} message
- */
- exports.prototype['message'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
deleted file mode 100644
index 4826532e..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/RestOK.js
+++ /dev/null
@@ -1,67 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.RestOK = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The RestOK model module.
- * @module model/RestOK
- * @version 0.1
- */
-
- /**
- * Constructs a new RestOK.
- * @alias module:model/RestOK
- * @class
- */
- var exports = function() {
- var _this = this;
-
-
- };
-
- /**
- * Constructs a RestOK from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/RestOK} obj Optional instance to populate.
- * @return {module:model/RestOK} The populated RestOK instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('message')) {
- obj['message'] = ApiClient.convertToType(data['message'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * @member {String} message
- */
- exports.prototype['message'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
deleted file mode 100644
index d00b802b..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Session.js
+++ /dev/null
@@ -1,169 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Session = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The Session model module.
- * @module model/Session
- * @version 0.1
- */
-
- /**
- * Constructs a new Session.
- * an application session per ide instance. bound to access token
- * @alias module:model/Session
- * @class
- * @param id
- * @param name
- * @param state
- * @param workspaceId
- * @param clientAddress
- * @param connectedAt
- * @param disconnectedAt
- */
- var exports = function(id, name, state, workspaceId, clientAddress, connectedAt, disconnectedAt) {
- var _this = this;
-
- _this['id'] = id;
- _this['name'] = name;
- _this['state'] = state;
- _this['workspaceId'] = workspaceId;
- _this['clientAddress'] = clientAddress;
- _this['connectedAt'] = connectedAt;
- _this['disconnectedAt'] = disconnectedAt;
-
-
- };
-
- /**
- * Constructs a Session from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Session} obj Optional instance to populate.
- * @return {module:model/Session} The populated Session instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('id')) {
- obj['id'] = ApiClient.convertToType(data['id'], 'String');
- }
- if (data.hasOwnProperty('name')) {
- obj['name'] = ApiClient.convertToType(data['name'], 'String');
- }
- if (data.hasOwnProperty('state')) {
- obj['state'] = ApiClient.convertToType(data['state'], 'String');
- }
- if (data.hasOwnProperty('workspaceId')) {
- obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
- }
- if (data.hasOwnProperty('clientAddress')) {
- obj['clientAddress'] = ApiClient.convertToType(data['clientAddress'], 'String');
- }
- if (data.hasOwnProperty('connectedAt')) {
- obj['connectedAt'] = ApiClient.convertToType(data['connectedAt'], 'Date');
- }
- if (data.hasOwnProperty('disconnectedAt')) {
- obj['disconnectedAt'] = ApiClient.convertToType(data['disconnectedAt'], 'Date');
- }
- if (data.hasOwnProperty('willCloseAt')) {
- obj['willCloseAt'] = ApiClient.convertToType(data['willCloseAt'], 'Date');
- }
- if (data.hasOwnProperty('willLoseAt')) {
- obj['willLoseAt'] = ApiClient.convertToType(data['willLoseAt'], 'Date');
- }
- }
- return obj;
- }
-
- /**
- * the id of a session. usually same to socket id.
- * @member {String} id
- */
- exports.prototype['id'] = undefined;
- /**
- * human readable name, usually derived from workspace name.
- * @member {String} name
- */
- exports.prototype['name'] = undefined;
- /**
- * state of this session NORMAL = connected, normally working LOSING = disconnected, waiting reconnection. still accessible with api CLOSING = socket connection will close connection by server (clinet will be notified) there's no 'CLOSED' / 'LOST' state, for server will remove session object in registry when the server closes connection or stops waiting for reconnection for timeout.
- * @member {module:model/Session.StateEnum} state
- */
- exports.prototype['state'] = undefined;
- /**
- * the id of workspace that this workspaces is working on.
- * @member {String} workspaceId
- */
- exports.prototype['workspaceId'] = undefined;
- /**
- * the peer address of session connection. not always
- * @member {String} clientAddress
- */
- exports.prototype['clientAddress'] = undefined;
- /**
- * the time when socket connection is established
- * @member {Date} connectedAt
- */
- exports.prototype['connectedAt'] = undefined;
- /**
- * the time when socket is closed.
- * @member {Date} disconnectedAt
- */
- exports.prototype['disconnectedAt'] = undefined;
- /**
- * when state becomes CLOSING, actual closing time will be updated by server.
- * @member {Date} willCloseAt
- */
- exports.prototype['willCloseAt'] = undefined;
- /**
- * when state becomes LOSING, server will not wait for reconnection after this time.
- * @member {Date} willLoseAt
- */
- exports.prototype['willLoseAt'] = undefined;
-
-
- /**
- * Allowed values for the state property.
- * @enum {String}
- * @readonly
- */
- exports.StateEnum = {
- /**
- * value: "NORMAL"
- * @const
- */
- "NORMAL": "NORMAL",
- /**
- * value: "LOSING"
- * @const
- */
- "LOSING": "LOSING",
- /**
- * value: "CLOSING"
- * @const
- */
- "CLOSING": "CLOSING" };
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
deleted file mode 100644
index 342c631e..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Stats.js
+++ /dev/null
@@ -1,163 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient', '../model/RestError'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'), require('./RestError'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Stats = factory(root.WebidaServiceApi.ApiClient, root.WebidaServiceApi.RestError);
- }
-}(this, function(ApiClient, RestError) {
- 'use strict';
-
-
-
-
- /**
- * The Stats model module.
- * @module model/Stats
- * @version 0.1
- */
-
- /**
- * Constructs a new Stats.
- * simplified/augmented fs.Stats class - see node.js doc for all properties
- * @alias module:model/Stats
- * @class
- * @param type
- */
- var exports = function(type) {
- var _this = this;
-
- _this['type'] = type;
-
-
-
-
-
-
- };
-
- /**
- * Constructs a Stats from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Stats} obj Optional instance to populate.
- * @return {module:model/Stats} The populated Stats instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('type')) {
- obj['type'] = ApiClient.convertToType(data['type'], 'String');
- }
- if (data.hasOwnProperty('birthtime')) {
- obj['birthtime'] = ApiClient.convertToType(data['birthtime'], 'Date');
- }
- if (data.hasOwnProperty('mtime')) {
- obj['mtime'] = ApiClient.convertToType(data['mtime'], 'Date');
- }
- if (data.hasOwnProperty('mode')) {
- obj['mode'] = ApiClient.convertToType(data['mode'], 'String');
- }
- if (data.hasOwnProperty('size')) {
- obj['size'] = ApiClient.convertToType(data['size'], 'Integer');
- }
- if (data.hasOwnProperty('nlink')) {
- obj['nlink'] = ApiClient.convertToType(data['nlink'], 'Integer');
- }
- if (data.hasOwnProperty('error')) {
- obj['error'] = RestError.constructFromObject(data['error']);
- }
- }
- return obj;
- }
-
- /**
- * @member {module:model/Stats.TypeEnum} type
- */
- exports.prototype['type'] = undefined;
- /**
- * @member {Date} birthtime
- */
- exports.prototype['birthtime'] = undefined;
- /**
- * @member {Date} mtime
- */
- exports.prototype['mtime'] = undefined;
- /**
- * @member {String} mode
- */
- exports.prototype['mode'] = undefined;
- /**
- * @member {Integer} size
- */
- exports.prototype['size'] = undefined;
- /**
- * @member {Integer} nlink
- */
- exports.prototype['nlink'] = undefined;
- /**
- * @member {module:model/RestError} error
- */
- exports.prototype['error'] = undefined;
-
-
- /**
- * Allowed values for the type property.
- * @enum {String}
- * @readonly
- */
- exports.TypeEnum = {
- /**
- * value: "DUMMY"
- * @const
- */
- "DUMMY": "DUMMY",
- /**
- * value: "FILE"
- * @const
- */
- "FILE": "FILE",
- /**
- * value: "DIRECTORY"
- * @const
- */
- "DIRECTORY": "DIRECTORY",
- /**
- * value: "BLOCK_DEVICE"
- * @const
- */
- "BLOCK_DEVICE": "BLOCK_DEVICE",
- /**
- * value: "CHARACTER_DEVICE"
- * @const
- */
- "CHARACTER_DEVICE": "CHARACTER_DEVICE",
- /**
- * value: "LINK"
- * @const
- */
- "LINK": "LINK",
- /**
- * value: "FIFO"
- * @const
- */
- "FIFO": "FIFO",
- /**
- * value: "SOCKET"
- * @const
- */
- "SOCKET": "SOCKET" };
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
deleted file mode 100644
index 82cc27ef..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Token.js
+++ /dev/null
@@ -1,137 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Token = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The Token model module.
- * @module model/Token
- * @version 0.1
- */
-
- /**
- * Constructs a new Token.
- * a json webtoken and accessible data
- * @alias module:model/Token
- * @class
- * @param text
- * @param tokenType
- * @param expiresAt
- * @param issuedAt
- */
- var exports = function(text, tokenType, expiresAt, issuedAt) {
- var _this = this;
-
- _this['text'] = text;
- _this['tokenType'] = tokenType;
- _this['expiresAt'] = expiresAt;
- _this['issuedAt'] = issuedAt;
-
-
- };
-
- /**
- * Constructs a Token from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Token} obj Optional instance to populate.
- * @return {module:model/Token} The populated Token instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('text')) {
- obj['text'] = ApiClient.convertToType(data['text'], 'String');
- }
- if (data.hasOwnProperty('tokenType')) {
- obj['tokenType'] = ApiClient.convertToType(data['tokenType'], 'String');
- }
- if (data.hasOwnProperty('expiresAt')) {
- obj['expiresAt'] = ApiClient.convertToType(data['expiresAt'], 'Date');
- }
- if (data.hasOwnProperty('issuedAt')) {
- obj['issuedAt'] = ApiClient.convertToType(data['issuedAt'], 'Date');
- }
- if (data.hasOwnProperty('sessionId')) {
- obj['sessionId'] = ApiClient.convertToType(data['sessionId'], 'String');
- }
- if (data.hasOwnProperty('workspaceId')) {
- obj['workspaceId'] = ApiClient.convertToType(data['workspaceId'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * actual token text that should be shipped in header or query
- * @member {String} text
- */
- exports.prototype['text'] = undefined;
- /**
- * MASTER : used to create an access token from clients, without login credential ACCESS : protects api access. should be unique for each ide session ADMIN : unrestriced access token for hub/admin service who controls server. there's no way to create admin token with API. Note that here's no REFRESH token, nor LOGIN token. The login api will create unrestricted access token & master token pair. Desktop app has a side-way to create an unrestricted master token before starting IDE instances.
- * @member {module:model/Token.TokenTypeEnum} tokenType
- */
- exports.prototype['tokenType'] = undefined;
- /**
- * @member {Date} expiresAt
- */
- exports.prototype['expiresAt'] = undefined;
- /**
- * @member {Date} issuedAt
- */
- exports.prototype['issuedAt'] = undefined;
- /**
- * mandatory for ACCESS token, identifying client instance
- * @member {String} sessionId
- */
- exports.prototype['sessionId'] = undefined;
- /**
- * If truthy, access rights are restricted to specified workspace only.
- * @member {String} workspaceId
- */
- exports.prototype['workspaceId'] = undefined;
-
-
- /**
- * Allowed values for the tokenType property.
- * @enum {String}
- * @readonly
- */
- exports.TokenTypeEnum = {
- /**
- * value: "MASTER"
- * @const
- */
- "MASTER": "MASTER",
- /**
- * value: "ACCESS"
- * @const
- */
- "ACCESS": "ACCESS",
- /**
- * value: "ADMIN"
- * @const
- */
- "ADMIN": "ADMIN" };
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
deleted file mode 100644
index 1bfb7164..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/User.js
+++ /dev/null
@@ -1,85 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.User = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The User model module.
- * @module model/User
- * @version 0.1
- */
-
- /**
- * Constructs a new User.
- * Any services/products should define some admin apis to manage users in the system and expose what should be exposed to client app. So, no properties are mandatory. Currently, properties are defined for compatiblity with legacy clients.
- * @alias module:model/User
- * @class
- */
- var exports = function() {
- var _this = this;
-
-
-
-
- };
-
- /**
- * Constructs a User from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/User} obj Optional instance to populate.
- * @return {module:model/User} The populated User instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('id')) {
- obj['id'] = ApiClient.convertToType(data['id'], 'String');
- }
- if (data.hasOwnProperty('email')) {
- obj['email'] = ApiClient.convertToType(data['email'], 'String');
- }
- if (data.hasOwnProperty('name')) {
- obj['name'] = ApiClient.convertToType(data['name'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * unique id per user (email is also unique)
- * @member {String} id
- */
- exports.prototype['id'] = undefined;
- /**
- * @member {String} email
- */
- exports.prototype['email'] = undefined;
- /**
- * @member {String} name
- */
- exports.prototype['name'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
deleted file mode 100644
index ef7a4aaa..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/model/Workspace.js
+++ /dev/null
@@ -1,119 +0,0 @@
-(function(root, factory) {
- if (typeof define === 'function' && define.amd) {
- // AMD. Register as an anonymous module.
- define(['../ApiClient'], factory);
- } else if (typeof module === 'object' && module.exports) {
- // CommonJS-like environments that support module.exports, like Node.
- module.exports = factory(require('../ApiClient'));
- } else {
- // Browser globals (root is window)
- if (!root.WebidaServiceApi) {
- root.WebidaServiceApi = {};
- }
- root.WebidaServiceApi.Workspace = factory(root.WebidaServiceApi.ApiClient);
- }
-}(this, function(ApiClient) {
- 'use strict';
-
-
-
-
- /**
- * The Workspace model module.
- * @module model/Workspace
- * @version 0.1
- */
-
- /**
- * Constructs a new Workspace.
- * A workspace in server
- * @alias module:model/Workspace
- * @class
- * @param id
- * @param name
- * @param description
- * @param createdAt
- * @param accessedAt
- */
- var exports = function(id, name, description, createdAt, accessedAt) {
- var _this = this;
-
- _this['id'] = id;
- _this['name'] = name;
- _this['description'] = description;
- _this['createdAt'] = createdAt;
- _this['accessedAt'] = accessedAt;
-
- };
-
- /**
- * Constructs a Workspace from a plain JavaScript object, optionally creating a new instance.
- * Copies all relevant properties from data to obj if supplied or a new instance if not.
- * @param {Object} data The plain JavaScript object bearing properties of interest.
- * @param {module:model/Workspace} obj Optional instance to populate.
- * @return {module:model/Workspace} The populated Workspace instance.
- */
- exports.constructFromObject = function(data, obj) {
- if (data) {
- obj = obj || new exports();
-
- if (data.hasOwnProperty('id')) {
- obj['id'] = ApiClient.convertToType(data['id'], 'String');
- }
- if (data.hasOwnProperty('name')) {
- obj['name'] = ApiClient.convertToType(data['name'], 'String');
- }
- if (data.hasOwnProperty('description')) {
- obj['description'] = ApiClient.convertToType(data['description'], 'String');
- }
- if (data.hasOwnProperty('createdAt')) {
- obj['createdAt'] = ApiClient.convertToType(data['createdAt'], 'Date');
- }
- if (data.hasOwnProperty('accessedAt')) {
- obj['accessedAt'] = ApiClient.convertToType(data['accessedAt'], 'Date');
- }
- if (data.hasOwnProperty('workspacePath')) {
- obj['workspacePath'] = ApiClient.convertToType(data['workspacePath'], 'String');
- }
- }
- return obj;
- }
-
- /**
- * the id of a workspace. usually same to file system id
- * @member {String} id
- */
- exports.prototype['id'] = undefined;
- /**
- * display text of this workspace for UI
- * @member {String} name
- */
- exports.prototype['name'] = undefined;
- /**
- * human readable description on this workspace
- * @member {String} description
- */
- exports.prototype['description'] = undefined;
- /**
- * the time when this workspace is created (registered from local file system)
- * @member {Date} createdAt
- */
- exports.prototype['createdAt'] = undefined;
- /**
- * the time when the last session on this workspace was made
- * @member {Date} accessedAt
- */
- exports.prototype['accessedAt'] = undefined;
- /**
- * absolute path of this workspace in server. not always available
- * @member {String} workspacePath
- */
- exports.prototype['workspacePath'] = undefined;
-
-
-
-
- return exports;
-}));
-
-
diff --git a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js b/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
deleted file mode 100644
index 8a81c1cd..00000000
--- a/common/src/webida/server-api-0.1-lib/webida-service-api-0.1/src/superagent.js
+++ /dev/null
@@ -1,1569 +0,0 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.superagent = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o= 200 && res.status < 300) {
- return self.callback(err, res);
- }
-
- var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
- new_err.original = err;
- new_err.response = res;
- new_err.status = res.status;
-
- self.callback(new_err, res);
- } catch(e) {
- self.callback(e); // #985 touching res may cause INVALID_STATE_ERR on old Android
- }
- });
-}
-
-/**
- * Mixin `Emitter` and `requestBase`.
- */
-
-Emitter(Request.prototype);
-for (var key in requestBase) {
- Request.prototype[key] = requestBase[key];
-}
-
-/**
- * Set Content-Type to `type`, mapping values from `request.types`.
- *
- * Examples:
- *
- * superagent.types.xml = 'application/xml';
- *
- * request.post('/')
- * .type('xml')
- * .send(xmlstring)
- * .end(callback);
- *
- * request.post('/')
- * .type('application/xml')
- * .send(xmlstring)
- * .end(callback);
- *
- * @param {String} type
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.type = function(type){
- this.set('Content-Type', request.types[type] || type);
- return this;
-};
-
-/**
- * Set responseType to `val`. Presently valid responseTypes are 'blob' and
- * 'arraybuffer'.
- *
- * Examples:
- *
- * req.get('/')
- * .responseType('blob')
- * .end(callback);
- *
- * @param {String} val
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.responseType = function(val){
- this._responseType = val;
- return this;
-};
-
-/**
- * Set Accept to `type`, mapping values from `request.types`.
- *
- * Examples:
- *
- * superagent.types.json = 'application/json';
- *
- * request.get('/agent')
- * .accept('json')
- * .end(callback);
- *
- * request.get('/agent')
- * .accept('application/json')
- * .end(callback);
- *
- * @param {String} accept
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.accept = function(type){
- this.set('Accept', request.types[type] || type);
- return this;
-};
-
-/**
- * Set Authorization field value with `user` and `pass`.
- *
- * @param {String} user
- * @param {String} pass
- * @param {Object} options with 'type' property 'auto' or 'basic' (default 'basic')
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.auth = function(user, pass, options){
- if (!options) {
- options = {
- type: 'basic'
- }
- }
-
- switch (options.type) {
- case 'basic':
- var str = btoa(user + ':' + pass);
- this.set('Authorization', 'Basic ' + str);
- break;
-
- case 'auto':
- this.username = user;
- this.password = pass;
- break;
- }
- return this;
-};
-
-/**
-* Add query-string `val`.
-*
-* Examples:
-*
-* request.get('/shoes')
-* .query('size=10')
-* .query({ color: 'blue' })
-*
-* @param {Object|String} val
-* @return {Request} for chaining
-* @api public
-*/
-
-Request.prototype.query = function(val){
- if ('string' != typeof val) val = serialize(val);
- if (val) this._query.push(val);
- return this;
-};
-
-/**
- * Queue the given `file` as an attachment to the specified `field`,
- * with optional `filename`.
- *
- * ``` js
- * request.post('/upload')
- * .attach('content', new Blob(['hey!'], { type: "text/html"}))
- * .end(callback);
- * ```
- *
- * @param {String} field
- * @param {Blob|File} file
- * @param {String} filename
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.attach = function(field, file, filename){
- this._getFormData().append(field, file, filename || file.name);
- return this;
-};
-
-Request.prototype._getFormData = function(){
- if (!this._formData) {
- this._formData = new root.FormData();
- }
- return this._formData;
-};
-
-/**
- * Invoke the callback with `err` and `res`
- * and handle arity check.
- *
- * @param {Error} err
- * @param {Response} res
- * @api private
- */
-
-Request.prototype.callback = function(err, res){
- var fn = this._callback;
- this.clearTimeout();
- fn(err, res);
-};
-
-/**
- * Invoke callback with x-domain error.
- *
- * @api private
- */
-
-Request.prototype.crossDomainError = function(){
- var err = new Error('Request has been terminated\nPossible causes: the network is offline, Origin is not allowed by Access-Control-Allow-Origin, the page is being unloaded, etc.');
- err.crossDomain = true;
-
- err.status = this.status;
- err.method = this.method;
- err.url = this.url;
-
- this.callback(err);
-};
-
-/**
- * Invoke callback with timeout error.
- *
- * @api private
- */
-
-Request.prototype._timeoutError = function(){
- var timeout = this._timeout;
- var err = new Error('timeout of ' + timeout + 'ms exceeded');
- err.timeout = timeout;
- this.callback(err);
-};
-
-/**
- * Compose querystring to append to req.url
- *
- * @api private
- */
-
-Request.prototype._appendQueryString = function(){
- var query = this._query.join('&');
- if (query) {
- this.url += ~this.url.indexOf('?')
- ? '&' + query
- : '?' + query;
- }
-};
-
-/**
- * Initiate request, invoking callback `fn(res)`
- * with an instanceof `Response`.
- *
- * @param {Function} fn
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.end = function(fn){
- var self = this;
- var xhr = this.xhr = request.getXHR();
- var timeout = this._timeout;
- var data = this._formData || this._data;
-
- // store callback
- this._callback = fn || noop;
-
- // state change
- xhr.onreadystatechange = function(){
- if (4 != xhr.readyState) return;
-
- // In IE9, reads to any property (e.g. status) off of an aborted XHR will
- // result in the error "Could not complete the operation due to error c00c023f"
- var status;
- try { status = xhr.status } catch(e) { status = 0; }
-
- if (0 == status) {
- if (self.timedout) return self._timeoutError();
- if (self._aborted) return;
- return self.crossDomainError();
- }
- self.emit('end');
- };
-
- // progress
- var handleProgress = function(e){
- if (e.total > 0) {
- e.percent = e.loaded / e.total * 100;
- }
- e.direction = 'download';
- self.emit('progress', e);
- };
- if (this.hasListeners('progress')) {
- xhr.onprogress = handleProgress;
- }
- try {
- if (xhr.upload && this.hasListeners('progress')) {
- xhr.upload.onprogress = handleProgress;
- }
- } catch(e) {
- // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
- // Reported here:
- // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
- }
-
- // timeout
- if (timeout && !this._timer) {
- this._timer = setTimeout(function(){
- self.timedout = true;
- self.abort();
- }, timeout);
- }
-
- // querystring
- this._appendQueryString();
-
- // initiate request
- if (this.username && this.password) {
- xhr.open(this.method, this.url, true, this.username, this.password);
- } else {
- xhr.open(this.method, this.url, true);
- }
-
- // CORS
- if (this._withCredentials) xhr.withCredentials = true;
-
- // body
- if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !this._isHost(data)) {
- // serialize stuff
- var contentType = this._header['content-type'];
- var serialize = this._serializer || request.serialize[contentType ? contentType.split(';')[0] : ''];
- if (!serialize && isJSON(contentType)) serialize = request.serialize['application/json'];
- if (serialize) data = serialize(data);
- }
-
- // set header fields
- for (var field in this.header) {
- if (null == this.header[field]) continue;
- xhr.setRequestHeader(field, this.header[field]);
- }
-
- if (this._responseType) {
- xhr.responseType = this._responseType;
- }
-
- // send stuff
- this.emit('request', this);
-
- // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
- // We need null here if data is undefined
- xhr.send(typeof data !== 'undefined' ? data : null);
- return this;
-};
-
-
-/**
- * Expose `Request`.
- */
-
-request.Request = Request;
-
-/**
- * GET `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.get = function(url, data, fn){
- var req = request('GET', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.query(data);
- if (fn) req.end(fn);
- return req;
-};
-
-/**
- * HEAD `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.head = function(url, data, fn){
- var req = request('HEAD', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.send(data);
- if (fn) req.end(fn);
- return req;
-};
-
-/**
- * OPTIONS query to `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.options = function(url, data, fn){
- var req = request('OPTIONS', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.send(data);
- if (fn) req.end(fn);
- return req;
-};
-
-/**
- * DELETE `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-function del(url, fn){
- var req = request('DELETE', url);
- if (fn) req.end(fn);
- return req;
-};
-
-request['del'] = del;
-request['delete'] = del;
-
-/**
- * PATCH `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed} data
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.patch = function(url, data, fn){
- var req = request('PATCH', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.send(data);
- if (fn) req.end(fn);
- return req;
-};
-
-/**
- * POST `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed} data
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.post = function(url, data, fn){
- var req = request('POST', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.send(data);
- if (fn) req.end(fn);
- return req;
-};
-
-/**
- * PUT `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.put = function(url, data, fn){
- var req = request('PUT', url);
- if ('function' == typeof data) fn = data, data = null;
- if (data) req.send(data);
- if (fn) req.end(fn);
- return req;
-};
-
-},{"./is-object":1,"./request":3,"./request-base":2,"emitter":4,"reduce":5}]},{},[6])(6)
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js b/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
new file mode 100644
index 00000000..7902cf7e
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsDirForest.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ '../common',
+ './WfsDirTree',
+ './WfsEntry',
+ './wfs-utils'
+], function(
+ common,
+ WfsDirTree,
+ WfsEntry,
+ wfsUtils
+) {
+ 'use strict';
+
+ var logger = common.logger;
+ var wfsApi = new common.api.WfsApi();
+
+ function WfsDirForest(wfsId, roots) {
+ this.dirs = {};
+ this.wfsId = wfsId;
+ var myself = this;
+
+ // TODO: reduce roots if one of them is a sub-tree of other tree.
+ roots.forEach(function(dir) {
+ myself.dirs[dir] = null;
+ });
+ }
+
+ WfsDirForest.prototype = {
+ build: function buildForest() {
+ var myself = this;
+ var promises = [];
+ this.dirs.forEach(function(dir) {
+ promises.push(myself.addTreeAsync(dir));
+ });
+ return Promise.all(promises);
+ },
+
+ getTree : function getTree(rootPath) {
+ return this.dirs[rootPath];
+ },
+
+ addTreeAsync : function addTree(rootPath) {
+ var myself = this;
+ return new Promise( function(resolve, reject) {
+ try {
+ if(!myself.dirs[rootPath]) {
+ var wfsPath = wfsUtils.normalizePath(rootPath);
+ wfsApi.dirTree(myself.wfsId, wfsPath, -1,
+ function (err, apiResult) {
+ if (err) {
+ logger.error('adding tree ' + rootPath + ' failed ', err);
+ reject(err);
+ } else {
+ var rootEntry = WfsEntry.fromJson(apiResult);
+ rootEntry.path = rootPath;
+ myself.dirs[rootPath] = new WfsDirTree(rootEntry);
+ resolve(myself.dirs[rootPath]);
+ }
+ }
+ );
+ } else {
+ resolve(this.dirs[rootPath]);
+ }
+ } catch(e) {
+ logger.error('adding tree ' + rootPath + ' failed ', e);
+ reject(e);
+ }
+ });
+ },
+
+ removeTree : function removeTree(rootPath) {
+ delete this.dirs[rootPath];
+ },
+
+ findTree : function findTree(wfsPath) {
+ var found = null;
+ var dirs = this.dirs;
+ Object.keys(dirs).some( function(rootPath) {
+ if (wfsPath.indexOf(rootPath) === 0) {
+ found = dirs[rootPath];
+ return true;
+ }
+ });
+ return found;
+ }
+ };
+
+ return WfsDirForest;
+});
+
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js b/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
new file mode 100644
index 00000000..baabab00
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsDirTree.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ './WfsEntry'
+], function(
+ WfsEntry
+) {
+ 'use strict';
+
+ // each root entry should have a path.
+ function WfsDirTree (entry, clone, detached) {
+ this.rootEntry = clone ? WfsEntry.clone(entry, null, detached) : entry;
+ }
+
+ WfsDirTree.prototype = {
+
+ getEntryByPath : function getEntryByPath(entryPath) {
+ if (typeof(entryPath) !== 'string') {
+ return null;
+ }
+ var absPath = (entryPath[0] !== '/') ? ('/' + entryPath) : entryPath;
+ var segments = absPath.split('/');
+
+ // if root entry has name, the first element of segments should be a dir name,
+ // not an empty string
+ if (this.rootEntry.name) {
+ segments = segments.slice(1);
+ }
+ var entry = this.rootEntry;
+ if (entry.name !== segments[0]) {
+ return null;
+ }
+ for (var i=0; i < segments.length; i++) {
+ if(!entry || i === segments.length-1) {
+ break;
+ } else {
+ entry = entry.getChildByName(segments[i+1]);
+ }
+ }
+ return entry;
+ },
+
+ // if some path are given in pathMap, then result will skip the entry
+ // so, to exclude some paths, put them in pathMap as truthy value (like true)
+ // this walk() method takes a little bit long time, if tree is very large.
+ // we may need to introdude worker, some kind of generator that yields entries.
+ // & we need event emitter to mimic generator in ES5.
+ // Introducing generator ill charge us another painful refactoring, however.
+
+ walk: function walk(pathMap, entry, predicate) {
+ var target = entry || this.rootEntry;
+ if (predicate(entry) && !pathMap[target.path]) {
+ pathMap[target.path] = entry;
+ }
+ entry.children.forEach( function(child) {
+ if (!pathMap[child.path]) {
+ walk(pathMap, child, predicate);
+ }
+ });
+ return pathMap;
+ }
+ };
+
+ return WfsDirTree;
+});
+
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
index 9a8d1796..c546fbb8 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
@@ -45,13 +45,15 @@ define([
}
WfsEntry.prototype = {
- // not implemented yet
- refreshStats : function() {
- throw new Error('do not use this abstract method');
- },
-
+
isRoot : function isRoot() { return !this.parent; },
+ isDetached: function isDetached() { return !this._path; },
+
+ detach : function detach() {
+ this._path = null;
+ },
+
// for compatiblity with webida 1.x client
// (will be replaced to function as node.js does, later )
get path() {
@@ -62,11 +64,19 @@ define([
}
},
+ // entry always have 'absolute path'
+ // so, root entry should have '/' or '/***/ as _path property
set path(value) {
if (this.isRoot()) {
+ if (!value || value === '/') {
+ return;
+ }
if (value.length > 1 && value[value.length-1] !== '/') {
value += '/';
}
+ if (value[0] !== '/') {
+ value = '/' + value;
+ }
this._path = value;
}
},
@@ -77,6 +87,16 @@ define([
hasChildren : function hasChildren() {
return this.children; // remember again, [] is falsy
+ },
+
+ getChildByName: function getChildByName(name) {
+ var found = null;
+ this.children.some( function(child) {
+ if (child.name === name) {
+ found = child;
+ return true;
+ }
+ });
}
};
@@ -89,9 +109,21 @@ define([
return entry;
};
+ WfsEntry.clone = function clone(entry, parent, withPath) {
+ // we don't have to clone name, for string is immutable
+ var cloned = new WfsEntry( new WfsStats(entry.stats), entry.name );
+ cloned.children = entry.children.map( function(child) {
+ return WfsEntry.clone(child, cloned);
+ });
+ cloned.parent = parent;
+ if (withPath) {
+ clone._path = entry._path;
+ }
+ return cloned;
+ };
+
// later, we should extend this class to WfsFile & WfsDirectory
// we also need WfsTree to handle WfsEntry trees and subtree
- //
return WfsEntry;
});
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
index 72093474..b7733a7a 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
@@ -15,7 +15,7 @@
*/
/**
- * @file WfsEntry.js
+ * @file WfsEventGate.js
* @since 1.7.0
* @author jh1977.kim@samsung.com
*/
@@ -77,9 +77,9 @@ define([
var holder = this.holders[path];
if (holder) {
if (holder.maskedBy) {
- throw new Error(path + 'is locked by other api call ' + holder.maskedBy);
+ throw new Error(path + ' is locked by other api call ' + holder.maskedBy);
} else {
- throw new Error(path + 'is locked by other processes in server');
+ throw new Error(path + ' is locked by other processes in server');
}
}
// If there's no holder but a mask exists - events are not arrived for the path.
@@ -93,7 +93,6 @@ define([
apiName : apiName,
holders: []
};
- logger.debug('added event mask for path ' + path);
}
},
@@ -119,8 +118,8 @@ define([
};
// if we have no holders in the mask object yet, that means
// api calls unmask too fast, while no events has been arrived yet.
- if (mask.holders.length === 0 ) {
- logger.debug('postponed unmasking for no events has arrived yet');
+ if (!this.holders[path]) {
+ logger.debug('postponed unmasking for final events has arrived yet');
setTimeout(unhold, POLLING_PERIOD);
} else {
unhold();
@@ -156,7 +155,6 @@ define([
if (wfsId !== this.wfsId) {
return;
}
- logger.debug('event gate got wfsRaw event', arguments);
var holder = this.holders[path];
if (!holder) {
holder = this._addNewHolder(path);
@@ -167,7 +165,6 @@ define([
if (!this.pollTimer) {
this.eventSequence = 0;
this.pollTimer = setInterval(this._pollEventsBound, POLLING_PERIOD);
- logger.debug('polling holded events - started');
}
},
@@ -175,7 +172,7 @@ define([
var myself = this;
events.forEach(function(event) {
var wstats = event.stats ? new WfsStats(event.stats) : undefined;
- logger.debug('fire wfs event', event);
+ //logger.debug('fire wfs event', event);
myself.session.emit('wfs', myself.wfsId, event.type, event.path, wstats);
});
var elapsedTime = new Date().getTime() - startedAt;
@@ -228,7 +225,6 @@ define([
if (allPaths.length <= 0) {
clearInterval(this.pollTimer);
this.pollTimer = null;
- logger.debug('no more pollable holders - stopped timer');
}
}
};
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
index d4e75bff..068d7ea3 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
@@ -15,7 +15,7 @@
*/
/**
- * @file MutatingEvent.js
+ * @file WfsEventHolder.js
* @since 1.7.0
* @author jh1977.kim@samsung.com
*/
@@ -38,7 +38,6 @@ define([
this.shouldFlipEventType = false;
this.maskedBy = maskedBy;
this.missingEventsBefore = 0;
- // when counter is negative, poll() should not increase counter
this.pollCounter = 0;
}
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js b/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
index 3f802243..096b4409 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
@@ -15,7 +15,7 @@
*/
/**
- * @file WfsEntry.js
+ * @file WfsMount.js
* @since 1.7.0
* @author jh1977.kim@samsung.com
*/
@@ -23,6 +23,7 @@
define([
'../common',
'../session',
+ '../workspace-service',
'./WfsStats',
'./WfsEntry',
'./WfsEventGate',
@@ -30,6 +31,7 @@ define([
], function (
common,
session,
+ workspaceService,
WfsStats,
WfsEntry,
WfsEventGate,
@@ -73,140 +75,122 @@ define([
}
WfsMount.prototype = {
- _fromLegacyPath: function _fromLegacyPath(legacyPath, allowUrl) {
+
+ // normalizer handles legacy path format with heading '/'
+ // and wfs:// url too.
+ _normalizePath: function _normalizePath(targetPath, allowUrl) {
try {
- return wfsUtils.fromLegacyPath(legacyPath, allowUrl ? this.wfsId : undefined);
+ return wfsUtils.normalizePath(targetPath, allowUrl ? this.wfsId : undefined);
} catch (e) {
- console.error('legacy path seems to be invalid : ' + legacyPath);
+ console.error('legacy path seems to be invalid : ' + targetPath);
}
},
- // result handler is (result, xhr) => desired (processed) result
- // usually, some json object will be transformed into a class instance
- _createApiCallback: function (apiName, resultHandler, callback, maskingPath) {
- var myself = this;
- function echo(x) { return x; }
- function invokeCallback(callback, err, result) {
- try {
- callback(err, result);
- } catch(e) {
- logger.warn('app layer callback for ' + apiName + '() threw error', e);
- }
+ _invokeCallback: function _invokeCallback(apiName, callback, err, result) {
+ try {
+ callback(err, result);
+ } catch(e) {
+ logger.warn('Callback of WfsMount#' + apiName + '() threw error', e);
}
- return function generatedCallback(err, result, response) {
- if (err) {
- logger.debug('wfsapi.' + apiName + '() error', err);
- if (maskingPath && myself.eventGate) {
- myself.eventGate.unmaskEvents(maskingPath, false);
- }
- invokeCallback(callback, err);
- } else {
- if (maskingPath && myself.eventGate) {
- myself.eventGate.unmaskEvents(maskingPath, true, false);
- }
- var handler = resultHandler || echo; // echo is default result hander
- try {
- var handled = handler(result, response.xhr);
- invokeCallback(callback, null, handled);
- } catch (err) {
- logger.warn('result handler for ' + apiName + '() error', err);
- invokeCallback(callback, err);
- }
- }
- };
},
- _callRestApi : function (apiName, path /*, .... , result handler, callback */ ) {
- var callable = wfsApi[apiName];
-
- var wfsPath = this._fromLegacyPath(path);
- var args = [ this.wfsId, wfsPath ];
- for (var i = 2; i < arguments.length; i++) {
- args.push(arguments[i]);
+ _maskEvents: function _maskEvents(wfsPath, apiName) {
+ if (this.eventGate) {
+ this.eventGate.maskEvents(wfsPath, apiName);
}
+ },
- var callback = args.pop();
- var resultHandler = args.pop();
- var apiCallback = null;
- if (callback.useEventMasking && this.eventGate) {
- this.eventGate.maskEvents(wfsPath, apiName);
- apiCallback = this._createApiCallback(apiName, resultHandler, callback, wfsPath);
- delete callback.useEventMasking;
- } else {
- apiCallback = this._createApiCallback(apiName, resultHandler, callback);
+ _unmaskEvents: function _unmaskEvents(wfsPath, succeeded, discard) {
+ if (this.eventGate) {
+ this.eventGate.unmaskEvents(wfsPath, succeeded, discard);
}
- args.push(apiCallback);
- return callable.apply(wfsApi, args);
},
- // do we need to set mask on path?
- // this simple operation may not cause any harmful effect, probably
- createDirectory: function wfsCreateDir(path, recursive, callback) {
- callback.useEventMasking = true;
- this._callRestApi('createDir', path, {ensure:recursive}, null, callback);
+ createDir: function wfsCreateDir(path, recursive, callback) {
+ var wfsPath = this._normalizePath(path);
+ var myself = this;
+ try {
+ this._maskEvents(wfsPath, 'createDir');
+ wfsApi.createDir(this.wfsId, wfsPath, { ensureParents: recursive },
+ function(err, result) {
+ var succeeded = err ? false : true;
+ myself._unmaskEvents(wfsPath, succeeded, false);
+ myself._invokeCallback('createDir', callback, err, result);
+ }
+ );
+ } catch (e) {
+ myself._invokeCallback('createDir', callback, e);
+ }
},
exists: function wfsExists(path, callback) {
- this._callRestApi('stat', path, {ignoreError: true},
- function(result) {
- return (result.type !== 'DUMMY');
- },
- callback
+ var wfsPath = this._normalizePath(path);
+ var myself = this;
+ wfsApi.stat(this.wfsId, wfsPath, { ignoreError: true },
+ function(err, apiResult) {
+ var result;
+ if (!err) {
+ result = (apiResult.type !== 'DUMMY');
+ }
+ myself._invokeCallback('exists', callback, err, result);
+ }
);
},
// legacy stat is renamed to mstat
- // TODO : change operation id of stats to stat, in swagger spec
stat: function wfsStat(path, callback) {
- this._callRestApi('stat', path, { /* no option */ },
- function (result) {
- return new WfsStats(result);
- },
- callback
+ var wfsPath = this._normalizePath(path);
+ var myself = this;
+ wfsApi.stat(this.wfsId, wfsPath,
+ function(err, apiResult) {
+ var result;
+ if (!err) {
+ result = new WfsStats(apiResult, wfsPath);
+ }
+ myself._invokeCallback('stat', callback, err, result);
+ }
);
},
- // prefer dirTree
- list : function wfsList(path, recursive, callback) {
- if (!callback) {
- callback = recursive;
- recursive = false;
- }
- this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
- callback(err, tree.children);
- });
- },
-
dirTree: function wfsDirTree(path, maxDepth, callback) {
// TODO: 'full recursive' seems to be dangerous
// server might suffer from stack overflow or starvation with disk i/o
// so, server may response with incomplete tree
// 1) add a 'response header' for incomplete message
// 2) add timeout parameter in spec
- // 3) in server, find a way to limit concurrency
-
- this._callRestApi('dirTree', path, maxDepth,
- function (result) {
- // re-constructing a very large tree in a single tick looks dangerous
- // we need a fromServerResultAsync, who injects some reasonable delays
- // while building tree from json
- var ret = WfsEntry.fromJson(result);
- ret.path = path;
- // logger.debug('wfsDirTree got dir tree on path ', result, ret);
- return ret;
- },
- callback
- );
- },
+ var wfsPath = this._normalizePath(path);
+ var myself = this;
+ wfsApi.dirTree(this.wfsId, wfsPath, maxDepth,
+ function(err, apiResult) {
+ var result;
+ if (!err) {
+ result = WfsEntry.fromJson(apiResult);
+ result.path = path;
+ }
+ myself._invokeCallback('dirTree', callback, err, result);
+ }
+ );
+ },
- remove : function wfsRemove(path, recursive, callback ) {
- callback.useEventMasking = true;
- this._callRestApi('remove', path, {recursive : recursive}, null, callback);
+ remove : function wfsRemove(path, noRecursive, callback ) {
+ var myself = this;
+ try {
+ var wfsPath = this._normalizePath(path);
+ this._maskEvents(wfsPath, 'remove');
+ wfsApi.remove(this.wfsId, wfsPath, { noRecursive: noRecursive },
+ function(err, apiResult) {
+ var succeeded = err ? false : true;
+ myself._unmaskEvents(wfsPath, succeeded, false);
+ myself._invokeCallback('remove', callback, err, apiResult);
+ }
+ );
+ } catch (e) {
+ myself.invokeCallback('remove', callback, e);
+ }
} ,
readFile : function wfsReadFile(path, responseType, callback) {
-
// TODO : we need 'as' parameter replacing response type in next client release
// as : enum of ['text', 'blob', 'json']
@@ -216,82 +200,202 @@ define([
responseType = 'text';
}
- this._callRestApi('readFile', path,
- function (noUseResult, xhr) {
- if (responseType === '' || responseType === 'text') {
- return xhr.responseText;
- } else {
- return xhr.response;
+ var wfsPath = this._normalizePath(path);
+ var myself = this;
+ wfsApi.readFile(this.wfsId, wfsPath,
+ function(err, apiResultNotUsed, apiResponse) {
+ var result;
+ if (!err) {
+ if (responseType === '' || responseType === 'text') {
+ result = apiResponse.xhr.responseText;
+ } else {
+ result = apiResponse.xhr.response;
+ }
}
- },
- callback
+ myself._invokeCallback('readFile', callback, err, result);
+ }
);
},
+ // TODO - add ensure parameter
writeFile : function wfsWriteFile(path, data, callback) {
- var dataType = typeof(data);
-
- // TODO : support plain object serialization, using AsyncApi class from swagger
- switch( dataType ) {
- case 'string':
- data = new Blob([data], {type:'text/plain'});
- break;
- case 'object':
- if (!(data instanceof Blob)) {
- throw new Error('invalid data - should be string or Blob');
+ var myself = this;
+ var err = null;
+ // TODO : support serialization of plain object
+ try {
+ switch( typeof(data)) {
+ case 'string':
+ data = new Blob([data], { type:'text/plain'});
+ break;
+ case 'object':
+ if (!(data instanceof Blob)) {
+ err = new Error('invalid data - should be string or Blob');
+ return myself.invokeCallback('writeFile', callback, err);
+ }
+ break;
+ default:
+ err = new Error('invalid data type - should be string or Blob');
+ return myself.invokeCallback('remove', callback, err);
+ }
+ var wfsPath = this._normalizePath(path);
+ this._maskEvents(wfsPath, 'writeFile');
+ wfsApi.writeFile(this.wfsId, wfsPath, data, { ensureParents: true },
+ function(err, apiResult) {
+ var succeeded = err ? false : true;
+ myself._unmaskEvents(wfsPath, succeeded, false);
+ myself._invokeCallback('writeFile', callback, err, apiResult);
}
- break;
- default:
- throw new Error('invalid data type - should be string or Blob');
+ );
+ } catch (e) {
+ myself.invokeCallback('writeFile', callback, e);
+ }
+ },
+
+ // TODO: supply more options & change signature to current api
+ copy : function wfsCopy(src, dst, recursive, callback) {
+ var myself = this;
+ // when recursive is omitted, webida 0.3 api doc says it's false
+ // but, actually, is handled to be true & there's no code that
+ // omits recursive flag nor set it false.
+ // So, new API does not have 'recursive' option.
+ try {
+ // when dst path is '/aaa/bbb', then actual dst is 'aaa
+ var wfsPath = this._normalizePath(dst);
+ var srcPath = this._normalizePath(src);
+ this._maskEvents(wfsPath, 'copy');
+ wfsApi.copy(this.wfsId, wfsPath, srcPath, {
+ noOverwrite: false,
+ followSymbolicLinks: false,
+ preserveTimestamps: false
+ }, function(err, apiResult) {
+ var succeeded = err ? false : true;
+ myself._unmaskEvents(wfsPath, succeeded, false);
+ myself._invokeCallback('copy', callback, err, apiResult);
+ }
+ );
+ } catch (e) {
+ myself._invokeCallback('copy', callback, e);
}
- // TODO: change 'ensure' default value to false, adding ensure parameter
- callback.useEventMasking = true;
- this._callRestApi('writeFile', path, data, { ensure: true }, null, callback);
+ },
+
+ // TODO: supply more options & change signature to current api
+ move : function wfsMove(src, dst, callback) {
+ var myself = this;
+ // when recursive is omitted, webida 0.3 api doc says it's false
+ // but, actually, is handled to be true & there's no code that
+ // omits recursive flag nor set it false.
+ // So, new API does not have 'recursive' option.
+ try {
+ // when dst path is '/aaa/bbb', then actual dst is 'aaa
+ var wfsPath = this._normalizePath(dst);
+ var srcPath = this._normalizePath(src);
+ this._maskEvents(wfsPath, 'move');
+ this._maskEvents(srcPath, 'move');
+
+ wfsApi.move(this.wfsId, wfsPath, srcPath, {
+ noOverwrite: false
+ }, function(err, apiResult) {
+ var succeeded = err ? false : true;
+ myself._unmaskEvents(wfsPath, succeeded, false);
+ myself._unmaskEvents(srcPath, succeeded, false);
+ myself._invokeCallback('move', callback, err, apiResult);
+ }
+ );
+ } catch (e) {
+ myself._invokeCallback('move', callback, e);
+ }
+ },
+
+ // deprecated. use dirTree
+ list : function wfsList(path, recursive, callback) {
+ if (!callback) {
+ callback = recursive;
+ recursive = false;
+ }
+ var myself = this;
+ this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
+ myself._invokeCallback('list', callback, err, tree.children);
+ });
},
// deprecated. use stat, instead
isDirectory: function wfsIsDirectory(path, callback) {
- this._callRestApi('stat', path, {/* no option */},
- function (result) {
- return result.type === 'DIRECTORY';
- },
- callback
- );
+ var myself = this;
+ this.stat(path, function (err, result) {
+ myself._invokeCallback('isDirectory', callback, err, result.isDirectory() );
+ });
},
// deprecated. use stat, instead
isFile: function wfsIsFile(path, callback) {
- this._callRestApi('stat', path, {/* no option */},
- function (result) {
- return result.type !== 'DIRECTORY';
- },
- callback
- );
+ var myself = this;
+ this.stat(path, function (err, result) {
+ myself._invokeCallback('isFile', callback, err, !result.isDirectory() );
+ });
},
// deprecated. use dirTree or never call this method
isEmpty: function wfsIsEmpty(path, callback) {
- this._callRestApi('dirTree', path, {recursive: true},
- function (result) {
- return result.children && result.children.length > 0;
- },
- callback
- );
+ var myself = this;
+ this.dirTree(path,1, function (err, tree) {
+ myself._invokeCallback('list', callback, err, tree.children.length === 0);
+ });
+ },
+
+ // deprecated. use 'createDir'
+ createDirectory: function wfsCreateDirectory(path, recursive, callback) {
+ this.createDir(path, recursive, callback);
},
// deprecated. use 'remove'
- 'delete' : function wfsDelete(path, recursive, callback ) {
- return this.remove(path, recursive, callback);
- } ,
-
- // not implemented yet
- copy: abstractify('copy'),
- move : abstractify('move'),
- exec : abstractify('exec'),
+ 'delete' : function wfsDelete(path, recursive, callback) {
+ if (typeof recursive === 'function') {
+ callback = recursive;
+ recursive = false;
+ }
+ return this.remove(path, !recursive, callback);
+ },
+
+ // deprecated. use workspaceService.exec, instead. (and do not use git.sh anymore)
+ exec : function wfsExec(path, info, callback) {
+ // info
+ // : cmd
+ // : args
+ var myself = this;
+
+ // replace 'git.sh' to 'git' for compatiblity
+ if (info.cmd === 'git.sh') {
+ info.cmd = 'git';
+ }
+ try {
+ workspaceService.exec({
+ command : info.cmd,
+ args: info.args,
+ cwd: this._normalizePath(path) // input, timeout will use default value
+ },
+ false, // no async exec by legacy wfsExec
+ function(err, result) {
+ var stdout, stderr, error;
+ if (typeof result === 'object') {
+ stdout = result.stdout;
+ stderr = result.stderr;
+ error = result.error;
+ }
+ // TODO : _invokeCallback should be able to handle multiple result arguments
+ try {
+ callback(err || error, stdout, stderr);
+ } catch (e) {
+ logger.warn('Callback of WfsMount#exec() threw error', e);
+ }
+ });
+ } catch(e) {
+ myself._invokeCallback('exec', callback, e);
+ }
+ },
+
searchFiles: abstractify('searchFiles'),
replaceFiles: abstractify('replaceFiles'),
addAlias : abstractify('addAlias'),
- mstat : abstractify('mstat') // we should GET :wfsid/op/mstats, not :wfsid/any/:wfsPath
};
return WfsMount;
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js b/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
new file mode 100644
index 00000000..692a7ff7
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
@@ -0,0 +1,356 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file WfsEntry.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+define([
+ '../common',
+ '../cache-db-manager',
+ '../workspace-service',
+ './WfsDirForest',
+ './WfsStats',
+ './wfs-utils'
+], function (
+ common,
+ cacheDbManager,
+ workspaceService,
+ WfsDirForest,
+ WfsStats,
+ wfsUtils
+) {
+ 'use strict';
+
+ // provides subset of legacy FileSystem object
+ // some methods are not supported, completely
+ // we should create better interface in next api 0.2 with cleaner spec and Promise
+
+ var logger = common.logger;
+ var wfsApi = new common.api.WfsApi();
+ var dbUtils = cacheDbManager.utils;
+ var CACHE_TTL = 86400*1000;
+
+ function WfsOfflineCache(wfsId, session) {
+ this.wfsId = wfsId;
+ this.session = session;
+ this.db = null;
+
+ this.dirForest = null; // become truthy after init
+ this._initPromise = null; // become truthy when init() is not complete yet.
+ this._shouldEmitWfsEvents = false; // writeToCache sends events
+
+ session.on('wfs', this._onWatcherEvent.bind(this));
+ // do we have to listen all wfs events?
+ // if an 'off-line cache dir' is removed then
+ // we should delete all cached info for the directory.
+ workspaceService.on('available', this._onWorkspaceAvailable.bind(this));
+ workspaceService.on('unavailable', this.this._onWorkspaceUnavailable.bind(this));
+ }
+
+ WfsOfflineCache.prototype = {
+
+ _onWatcherEvent: function onWatcherEvent(wfsId, type, path, stats) {
+ if (wfsId !== this.wfsId) {
+ return;
+ }
+ logger.debug('wfs event got', type, path, stats);
+ // is this one to be fetched?
+ },
+
+ // this method assumes workspace id is same to wfs id.
+ // if not, should check with ws.hasWfs() or something similar
+ _onWorkspaceAvailable: function _onWorkspaceAvailable() {
+ var ws = workspaceService.getWorkspace();
+ if (ws.id !== this.wfsId) {
+ return;
+ }
+ // if this cache is not initialized nor initializing,
+ if (this.dirForest) {
+ this._uploadLocalChanges();
+ } else {
+ if (!this._initPromise) {
+ this.init().then( function() {
+ logger.debug('initialized by workspace service event');
+ });
+ }
+ }
+ this._shouldEmitWfsEvents = false;
+ },
+
+ _onWorkspaceUnavailable: function _onWorkspaceUnavailable() {
+ var ws = workspaceService.getWorkspace();
+ if (ws.id !== this.wfsId) {
+ return;
+ }
+ this._shouldEmitWfsEvents = true;
+ },
+
+ init: function init() {
+ var myself = this;
+ if (!workspaceService.isAvailable()) {
+ return Promise.reject(new Error ('workspace is not available yet'));
+ }
+ var initPromise = cacheDbManager.openDB(this.wfsId)
+ .then( function(db) {
+ this.db = db;
+ return myself._buildForest();
+ })
+ .then( function() {
+ myself._initPromise = null;
+ this._prefetch();
+ this._uploadLocalChanges();
+ // resolves nothing
+ });
+ this._initPromise = initPromise;
+ return initPromise;
+ },
+
+ isAvailable : function isAvailable() {
+ return (this.db && this.dirForest);
+ },
+
+ // returns a promise that resolves data
+ readFromCache: function readFromCache(wfsPath) {
+ var myself = this;
+ return new Promise(function (resolve, reject) {
+ var tx = dbUtils.begin(myself.db, 'getItem');
+ var itemStore = tx.objectStore('items');
+ var req = itemStore.get(wfsPath);
+ dbUtils.swear(req, 'items', 'getSingleItem', resolve, reject);
+ // we don't have to care about tx events for now.
+ });
+ },
+
+ cleanOldItems: function cleanOldItems() {
+ var myself = this;
+ return new Promise(function (resolve, reject) {
+ var tx = dbUtils.begin(myself.db, 'getItem');
+ var itemStore = tx.objectStore('items');
+ var index = itemStore.index('timestamp');
+ var timestampUpperBound = new Date().getTime() - CACHE_TTL;
+ var keyRange = window.IDBKeyRange.upperBound(timestampUpperBound, true);
+ var req = index.openCursor(keyRange);
+ req.onsuccess = function(event) {
+ var cursor = event.target.result;
+ if (cursor) {
+ logger.debug('clean old item', cursor.value.wfsPath);
+ cursor.delete();
+ cursor.continue();
+ }
+ };
+ dbUtils.swear(tx, 'items', 'cleanOldItems', resolve, reject);
+ });
+ },
+
+ // returns a promise that resolves nothing
+ writeToCache: function writeToCache(wfsPath, data) {
+ var myself = this;
+ return new Promise(function (resolve, reject) {
+ var tx = dbUtils.begin(myself.db, 'writeChange', resolve, reject);
+ var itemStore = tx.objectStore('items');
+ var changeStore = tx.objectStore('changes');
+ var now = new Date();
+ this.readFromCache(wfsPath).then( function(item) {
+ if (item) {
+ item.stats.mtime = now;
+ item.stats.size = data.size || data.length;
+ } else {
+ item.stats = WfsStats.createFakeStats(now.getTime(), data);
+ }
+ item.data = data;
+ item.timestamp = now.getTime();
+ itemStore.put(item);
+ changeStore.put({
+ wfsPath: wfsPath,
+ data:data,
+ timestamp: now.getTime()
+ });
+ if (myself._shouldEmitWfsEvents) {
+ myself.session.emit('wfs', '_change', this.wfsId, item.stats);
+ }
+ }).catch( function(err) {
+ logger.error('writeToCacache failed while reading existing cache item', err);
+ reject(err);
+ });
+ });
+ },
+
+ _buildForest: function _buildForest() {
+ var workspace = workspaceService.getWorkspace();
+ var offlineCachePaths = workspace.offlineCachePaths;
+ var forest = new WfsDirForest(offlineCachePaths);
+ return forest.build().then( function() {
+ this.dirForest = forest;
+ });
+ },
+
+ _updateItem: function(wfsPath, entry) {
+ var myself = this;
+ return new Promise( function(resolve, reject) {
+ wfsApi.readFile(this.wfsId, this.wfsPath, function(err, apiResult) {
+ if(err) {
+ logger.error('update cache item failed', err);
+ return reject(err);
+ }
+ var tx = dbUtils.begin(myself.db, 'getItem');
+ var itemStore = tx.objectStore('items');
+ var req = itemStore.put(wfsPath, {
+ wfsPath : wfsPath,
+ timestamp : new Date().getTime(),
+ data:apiResult,
+ stats: entry.stats
+ });
+ dbUtils.swear(req, 'items', 'updateItem', resolve, reject);
+ });
+ });
+ // wfsApi should fix read file as blob
+ },
+
+ _prefetch: function _prefetch() {
+ var dirs = this.dirForest.dirs;
+ var myself = this;
+ Object.keys(dirs).forEach( function(dir) {
+ var tree = myself.dirForest.getTree(dir);
+ var files = tree.walk({}, null, function (entry) {
+ return entry.isFile;
+ });
+ myself._prefetchFiles(files);
+ });
+ },
+
+ _prefetchFiles: function _prefetchFiles(files) {
+ var myself = this;
+ var promises = [];
+ Object.keys(files).forEach( function(filePath) {
+ var fileEntry = files[filePath];
+ var wfsFilePath = wfsUtils.normalizePath(filePath);
+ // 1) check we have one or not
+ // 2) if we have one, then compare mtime
+ // 3) if fileEntry.stats.mtime is newer than cache, call updateItem.
+ var promise = myself.readFromCache(wfsFilePath)
+ .then( function(item) {
+ if(!item || item.stats.mtime < fileEntry.stats.mtime.getTime()) {
+ return myself._updateItem(wfsFilePath, fileEntry);
+ } else {
+ logger.debug('skip prefetching fresh one ' + wfsFilePath);
+ }
+ })
+ .catch( function (err) {
+ logger.error(wfsFilePath + ' prefetching failed', err);
+ // catch should not rethrow err, to make promise resolved, always.
+ return Promise.resolve();
+ });
+ promises.push(promise);
+ });
+ return Promise.all(promises);
+ },
+
+ _getChanges: function _getChanges() {
+ var myself = this;
+ var changes = [];
+ return new Promise(function (resolve, reject) {
+ var tx = dbUtils.begin(myself.db, 'getItem');
+ var changeStore = tx.objectStore('changes');
+ var index = changeStore.index('timestamp');
+ var req = index.openCursor(null);
+ req.onsuccess = function(event) {
+ var cursor = event.target.result;
+ if (!cursor) { // cursor reached to end of index
+ resolve(changes);
+ } else {
+ changes.push(cursor.value);
+ cursor.continue();
+ }
+ };
+ req.onerror = function (event) {
+ reject(event.target.error);
+ };
+ });
+ },
+
+ _removeChanges: function _removeChanges(removables) {
+ var myself = this;
+ return new Promise( function(resolve, reject) {
+ var tx = dbUtils.begin(myself.db, 'removeChanges', resolve, reject);
+ var changeStore = tx.objectStore('changes');
+ removables.forEach( function(rmPath) {
+ changeStore.delete(rmPath);
+ });
+ });
+ },
+
+ _uploadChangeIfNeeded: function _uploadChangeIfNeeded(change) {
+ var myself = this;
+ // this promise never rejects. if having error, resolves nothing, or, path to remove.
+ // 1) get server stat
+ // 2) if server's stat is older than change.timestamp, invoke writeFile()
+ // 3) resolve path or nothing
+ return new Promise( function (resolve) {
+ wfsApi.stat(myself.wfsId, change.wfsPath, {
+ ignoreError:true
+ }, function(err, apiResult) {
+ if (err) {
+ // this path should not removed
+ return resolve(null);
+ }
+ if (apiResult.type === 'FILE') {
+ // change.data should be blob!
+ wfsApi.writeFile(myself.wfsId, change.wfsPath, {
+ ensureParents : true
+ }, change.data, function(err) {
+ if(err) {
+ // hey, do we have to continue on error?
+ // should not reject here, to upload other changed files
+ logger.warn('uploading ' + change.wfsPath + 'failed', err);
+ resolve(null);
+ } else {
+ resolve(change.wfsPath);
+ }
+ });
+ } else {
+ resolve(change.wfsPath);
+ }
+ });
+ });
+ },
+
+ _uploadLocalChanges: function _uploadLocalChanges() {
+ var myself = this;
+ var removables = [];
+ return this._getChanges()
+ .then( function(changes) {
+ var promises = changes.map( function(change) {
+ return myself._uploadChangeIfNeeded(change);
+ });
+ return Promise.all(promises);
+ })
+ .then( function(removablePaths) {
+ removables = {};
+ removablePaths.forEach(function(rmPath) {
+ if (rmPath) {
+ removables[rmPath] = true;
+ }
+ });
+ return myself._removeChanges(Object.keys(removables));
+ });
+ }
+ };
+
+ return WfsOfflineCache;
+});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js b/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
index dbbc5d78..a5a52149 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
@@ -23,18 +23,21 @@
define([ ], function() {
'use strict';
- function WfsStats (serverStats) {
+ function WfsStats (apiModelStats, path) {
// all other properties are inherited from server stats object
- this.size = serverStats.size;
- this.mtime = serverStats.mtime;
- this.birthtime = serverStats.birthtime;
- this.mode = serverStats.mode;
- this.nlink = serverStats.nlink;
- this.type = serverStats.type;
+ this.size = apiModelStats.size;
+ this.mtime = apiModelStats.mtime;
+ this.birthtime = apiModelStats.birthtime;
+ this.mode = apiModelStats.mode;
+ this.nlink = apiModelStats.nlink;
+ this.type = apiModelStats.type;
+ if (path) {
+ this.setPath(path);
+ }
}
WfsStats.prorotype = {
- get isFile() { return (this.type !== 'DIRECTORY'); },
+ get isFile() { return (this.type === 'FILE'); },
get isDirectory() { return (this.type === 'DIRECTORY'); },
get isBlockDevice() { return (this.type === 'BLOCK_DEVICE'); },
get isCharacterDevice() { return (this.type === 'CHARACTER_DEVICE'); },
@@ -48,6 +51,17 @@ define([ ], function() {
}
};
+ WfsStats.createFakeStats = function createFakeStats(timestamp, data) {
+ var ret = new WfsStats({
+ size : data.size || data.length || -1,
+ mtime : timestamp,
+ birthtime : timestamp,
+ mode: '',
+ nlink : 0,
+ type: 'FILE'
+ });
+ return ret;
+ };
return WfsStats;
});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js b/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
index 4a71e31c..d4003f60 100644
--- a/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
+++ b/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
@@ -55,15 +55,15 @@ define([
}
};
- function fromLegacyPath(legacyPath, wfsId) {
+ function normalizePath(legacyPath, wfsId) {
if (typeof(legacyPath) !== 'string' || legacyPath.constructor.name !== 'String' || !legacyPath) {
throw new Error('wfs url must a truthy string');
}
- let ret = '';
+ var ret = '';
if (legacyPath.indexOf('wfs://') !== 0 ) {
// looks very heavy but normalizing path is not a simple job. believe me.
var tmpUri = new URI('file:///' + legacyPath);
- ret = tmpUri.normalize().path(true).slice(1); // should start with /, always
+ ret = tmpUri.normalize().path(true).slice(1);
} else {
var parsed = internals.parseLegacyUrl(legacyPath);
if (parsed.wfsId !== wfsId) {
@@ -123,7 +123,7 @@ define([
}
return {
- fromLegacyPath : fromLegacyPath,
+ normalizePath : normalizePath,
getAncestors : getAncestors
};
});
diff --git a/common/src/webida/server-api-0.1-lib/workspace-service.js b/common/src/webida/server-api-0.1-lib/workspace-service.js
new file mode 100644
index 00000000..e186f9d9
--- /dev/null
+++ b/common/src/webida/server-api-0.1-lib/workspace-service.js
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2012-2016 S-Core Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file workspace-service.js
+ * @since 1.7.0
+ * @author jh1977.kim@samsung.com
+ */
+
+// we don't want cyclic dependencies between common and TokenManager.
+// so, instead of requiring just ./common, we require all dependencies directly
+// the only instance of TokenManager is saved in common
+define([
+ 'external/eventEmitter/EventEmitter',
+ 'external/lodash/lodash.min',
+ 'webida-lib/util/genetic',
+ './common',
+ './session',
+], function (
+ EventEmitter,
+ _,
+ genetic,
+ common,
+ session
+) {
+ 'use strict';
+
+ var logger = common.logger;
+ var workspaceApi = new common.api.WorkspaceApi();
+
+ // workspace service can be 'management' service & 'exec' service
+ // exec service need 'connected session' & current workspace data (init)
+
+ // while mgmt service does not
+ function WorkspaceService() {
+ EventEmitter.call(this);
+ this._workspace = null;
+ }
+
+ genetic.inherits(WorkspaceService, EventEmitter, {
+
+ _update : function _update(model) {
+ var newWorkspace = _.assign({}, model);
+ this._workspace = newWorkspace;
+ },
+
+ isAvailable: function wsIsAvailable() {
+ return session.isConnected && this._workspace;
+ },
+
+ getWorkspace: function getWorkspace() {
+ return this._workspace;
+ },
+
+ // TODO : wrap some workspaceApi operations
+ // findProcs, cancel, update
+
+ // workspace-management service
+ // create, find, update, delete operations should be available when service is not available
+
+ exec : function wsExec(execution, async, callback) {
+ try {
+ if (!this.isAvailable()) {
+ throw new Error ('workspace service is not available- not initialized or lost session');
+ }
+ var myself = this;
+ var cws = this.getWorkspace();
+ workspaceApi.exec(cws.id, execution, { async: async }, function(err, result) {
+ myself._invokeCallback('exec', callback, err, result);
+ });
+ } catch(e) {
+ this._invokeCallback('exec', callback, e);
+ }
+ },
+
+ _invokeCallback: function _invokeCallback(apiName, callback, err, result) {
+ try {
+ callback(err, result);
+ } catch(e) {
+ logger.warn('Callback of WorkspaceService#' + apiName + '() threw error', e);
+ }
+ }
+ });
+
+ var workspaceService = new WorkspaceService();
+
+ // we can start working when session is connected
+ session.on('connect', function() {
+ workspaceApi.findWorkspaces(common.bootArgs.workspaceId, { },
+ function handleFoundWorkspace(err, result) {
+ if (err) {
+ logger.error('cannot find workspace from server', err);
+ workspaceService.emit('error');
+ return;
+ }
+ logger.debug('workspace service found current workspace', result[0]);
+ workspaceService._update(result[0]);
+ workspaceService.emit('available');
+ logger.debug('workspace service started', workspaceService);
+ }
+ );
+ });
+
+ session.on('disconnect', function() {
+ logger.debug('workspace service stops');
+ workspaceService.emit('unavailable');
+ });
+
+ return workspaceService;
+});
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
index c4b94654..b810b55c 100644
--- a/common/src/webida/server-api-0.1.js
+++ b/common/src/webida/server-api-0.1.js
@@ -28,13 +28,15 @@ define([
'./server-api-0.1-lib/auth',
'./server-api-0.1-lib/fs',
'./server-api-0.1-lib/messaging',
- './server-api-0.1-lib/session',
+ './server-api-0.1-lib/session',
+ './server-api-0.1-lib/workspace-service'
], function (
common,
auth,
fs,
messaging,
- session
+ session,
+ workspaceService
) {
'use strict';
@@ -58,7 +60,9 @@ define([
}
},
session : session,
-
+ // TODO: impl sessionService
+ workspaceService: workspaceService,
+
// for compatibility with plugin who are dependent to webida-0.3.js conf object
conf : {
fsServer : common.serverUrl,
@@ -70,8 +74,11 @@ define([
// - should be removed in next version (0.2 and later)
// - PM should should decide which plugin catalog to load by itself
// via window.__ELECTRON_BROWSER__ variable
- // - PM should not load .user_info/plugin-settings.json file directly while initializing
- // and may use local storage instead of using server api
+ // - PM should not load .user_info/plugin-settings.json file directly
+ // while initializing
+ // - PM should use not use per-user or per-workspace setting to know
+ // disabled plugins, for the plugin structure is fixed per apps.
+ // - there should be way to hook catalog data for ide & plugin developers
getPluginSettingsPath : function(callback) {
// plugin-settings-desktop.json : to use embedded server from desktop
From 67f440e2555239e9535a340e1f78f5359eb236c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Tue, 26 Jul 2016 19:20:14 +0900
Subject: [PATCH 13/15] replaced server-api to webida-service-client bower
component
- fixed bower.json
- upgraded lodash to 4.14.0
- fixed some codes that use _.contains(), deprecated long before and now removed
- renamed server-pubsub-0.x to server-pubsub-compat, for the code does nothing actually
---
apps/ide/src/dojoConfig.js | 24 +-
.../CodeEditorViewer.js | 30 +-
.../TextEditorViewer.js | 26 +-
bower.json | 10 +-
common/src/webida/app.js | 6 +-
.../session-event-dispatcher/plugin.js | 20 +-
.../AbstractSocketClient.js | 271 ------------
.../webida/server-api-0.1-lib/TokenManager.js | 159 -------
common/src/webida/server-api-0.1-lib/auth.js | 125 ------
.../server-api-0.1-lib/cache-db-manager.js | 233 ----------
.../src/webida/server-api-0.1-lib/common.js | 101 -----
common/src/webida/server-api-0.1-lib/fs.js | 59 ---
.../webida/server-api-0.1-lib/messaging.js | 46 --
.../src/webida/server-api-0.1-lib/session.js | 95 -----
.../server-api-0.1-lib/wfs/WfsDirForest.js | 112 -----
.../server-api-0.1-lib/wfs/WfsDirTree.js | 86 ----
.../webida/server-api-0.1-lib/wfs/WfsEntry.js | 129 ------
.../server-api-0.1-lib/wfs/WfsEventGate.js | 234 ----------
.../server-api-0.1-lib/wfs/WfsEventHolder.js | 263 ------------
.../webida/server-api-0.1-lib/wfs/WfsMount.js | 402 ------------------
.../server-api-0.1-lib/wfs/WfsOfflineCache.js | 356 ----------------
.../webida/server-api-0.1-lib/wfs/WfsStats.js | 67 ---
.../server-api-0.1-lib/wfs/wfs-utils.js | 129 ------
.../server-api-0.1-lib/workspace-service.js | 123 ------
common/src/webida/server-api-0.1.js | 109 -----
...-pubsub-0.1.js => server-pubsub-compat.js} | 0
common/src/webida/util/loadCSSList.js | 8 +-
27 files changed, 62 insertions(+), 3161 deletions(-)
delete mode 100644 common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
delete mode 100644 common/src/webida/server-api-0.1-lib/TokenManager.js
delete mode 100644 common/src/webida/server-api-0.1-lib/auth.js
delete mode 100644 common/src/webida/server-api-0.1-lib/cache-db-manager.js
delete mode 100644 common/src/webida/server-api-0.1-lib/common.js
delete mode 100644 common/src/webida/server-api-0.1-lib/fs.js
delete mode 100644 common/src/webida/server-api-0.1-lib/messaging.js
delete mode 100644 common/src/webida/server-api-0.1-lib/session.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
delete mode 100644 common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
delete mode 100644 common/src/webida/server-api-0.1-lib/workspace-service.js
delete mode 100644 common/src/webida/server-api-0.1.js
rename common/src/webida/{server-pubsub-0.1.js => server-pubsub-compat.js} (100%)
diff --git a/apps/ide/src/dojoConfig.js b/apps/ide/src/dojoConfig.js
index e3fcc189..407fa7fa 100644
--- a/apps/ide/src/dojoConfig.js
+++ b/apps/ide/src/dojoConfig.js
@@ -20,12 +20,12 @@
// in electron, we should remove global.require & global.module
// to make dojo & other amd module work
// how can we detect that we're working in electron?
- if (typeof(globalObject.process) === 'object' &&
- typeof(globalObject.require) === 'function' &&
- typeof(globalObject.module) === 'object') {
+ if (typeof(globalObject.process) === 'object' && typeof(globalObject.require) === 'function' &&
+ typeof(globalObject.module) === 'object') {
globalObject.nrequire = globalObject.require;
globalObject.nmodule = globalObject.module;
delete globalObject.require;
+ //noinspection JSAnnotator
delete globalObject.module;
globalObject.__ELECTRON_BROWSER__ = true;
}
@@ -44,7 +44,7 @@
{name: 'jquery', location: './jquery/dist', main: 'jquery.min'},
{name: 'put-selector', location: './put-selector'},
{name: 'showdown', location: './showdown/dist', main: 'showdown.min'},
- {name: 'URIjs', location:'./URIjs/src', main:'URI'},
+ {name: 'URIjs', location:'./URIjs/src', main:'URI.min'},
{name: 'xstyle', location: './xstyle'}
],
locale: ((webidaLocale === 'default') || (webidaLocale === '')) ?
@@ -59,6 +59,7 @@
},
aliases: [
['text', 'dojo/text'],
+ ['external/lodash/lodash.min', 'external/lodash/dist/lodash.min'], // new 4.x lodash changed bundle path.
['popup-dialog', 'webida-lib/widgets/dialogs/popup-dialog/PopupDialog'],
// TODO should use these below aliases for versioned resources
['FSCache', 'webida-lib/FSCache-0.1'],
@@ -77,16 +78,17 @@
// &, for new server api, additional package 'webida-restful-api' is required.
if (window.location.href.indexOf('legacy=') < 0 ) {
var dojoConfig = globalObject.dojoConfig;
+ dojoConfig.packages.push( {
+ name: 'webida-service-client',
+ location: './webida-service-client',
+ main: 'webida-service-client-bundle'
+ });
dojoConfig.aliases.pop();
dojoConfig.aliases.pop();
- dojoConfig.aliases.push(['webida-lib/server-api', 'webida-lib/server-api-0.1']);
- dojoConfig.aliases.push(['webida-lib/server-pubsub', 'webida-lib/server-pubsub-0.1']);
+ dojoConfig.aliases.push(['webida-lib/server-api', 'webida-service-client']);
+ dojoConfig.aliases.push(['webida-lib/server-pubsub', 'webida-lib/server-pubsub-compat']);
dojoConfig.aliases.push(['top/site-config.json', 'top/site-config-desktop.json']);
- dojoConfig.packages.push( {
- name: 'webida-restful-api',
- location: './webida-restful-api',
- main: 'api-bundle'
- });
+ dojoConfig.aliases.push(['urijs', 'URIjs']);
}
if (globalObject.__ELECTRON_BROWSER__) {
diff --git a/apps/ide/src/plugins/webida.editor.code-editor/CodeEditorViewer.js b/apps/ide/src/plugins/webida.editor.code-editor/CodeEditorViewer.js
index 0808b887..6cc300c5 100644
--- a/apps/ide/src/plugins/webida.editor.code-editor/CodeEditorViewer.js
+++ b/apps/ide/src/plugins/webida.editor.code-editor/CodeEditorViewer.js
@@ -24,7 +24,7 @@
* @see CodeEditorPart
* @since 1.3.0
* @author hw.shim@samsung.com
- * @author sewon326.kim@samsung.com
+ * @author sewon326.kim@samsung.com
* @author kyungmi.k@samsung.com
* @author cg25.woo@samsung.com
* @author h.m.kwon@samsung.com
@@ -226,13 +226,13 @@ define([
{
mode: ['html', 'xml'],
checkToken: function (token) {
- return _.contains(['tag', 'attribute', 'link'], token.type);
+ return _.includes(['tag', 'attribute', 'link'], token.type);
}
},
{
mode: ['css'],
checkToken: function (token) {
- return _.contains(['tag', 'builtin', 'qualifier', 'property error', 'property'], token.type);
+ return _.includes(['tag', 'builtin', 'qualifier', 'property error', 'property'], token.type);
}
}
];
@@ -291,14 +291,14 @@ define([
}
}
function isAvailable(type, name) {
- return _.contains(availables, type + '::' + name);
+ return _.includes(availables, type + '::' + name);
}
function cursorAtAutoHint(cm, modeName, cursor, rightToken) {
var token = cm.getTokenAt(cursor);
if (_.find(cursorAtAutoHintTokens, function (obj) {
- return _.contains(obj.mode, modeName) && obj.checkToken(token);
+ return _.includes(obj.mode, modeName) && obj.checkToken(token);
})) {
return true;
}
@@ -493,7 +493,7 @@ define([
onChangeForAutoHintDebounced = _.debounce(function (cm, changeObj, lastCursor) {
// TODO - limch - minimize addFile() call to WebWorker
var editor = cm.__instance;
-
+
if (editor._contentAssistDelegator) {
var options = {};
options.async = true;
@@ -635,7 +635,7 @@ define([
setMode : function (mode) {
var that = this;
- var assistDelegator = null;
+ var assistDelegator = null;
that.promiseForSetMode = new Promise(function (resolve, reject) {
if (mode === undefined || that.mode === mode) {
resolve('no change');
@@ -739,31 +739,31 @@ define([
this.linters = {};
}
this.linters[type] = option;
-
+
var that = this;
that.promiseForSetMode.then(function(){
var editor = that.editor;
- if (editor._contentAssistDelegator) {
+ if (editor._contentAssistDelegator) {
editor._contentAssistDelegator.execCommandForAll(
'setLinter',
that,
type,
option);
}
- });
+ });
},
__applyLinter : function () {
- if (this.editor && this.linters && _.contains(['js', 'json', 'css', 'html'], this.mode)) {
+ if (this.editor && this.linters && _.includes(['js', 'json', 'css', 'html'], this.mode)) {
if (this.linters[this.mode]) {
this._gutterOn('CodeMirror-lint-markers');
-
+
var that = this;
that.promiseForSetMode.then(function(){
var editor = that.editor;
- if (editor._contentAssistDelegator) {
+ if (editor._contentAssistDelegator) {
editor._contentAssistDelegator.execCommandForAll(
'applyLinter',
- that.editor,
+ that.editor,
that.mode);
}
});
@@ -905,7 +905,7 @@ define([
var editor = self.editor;
self.focus();
self.promiseForSetMode.then(function(){
- if (editor._contentAssistDelegator) {
+ if (editor._contentAssistDelegator) {
editor._contentAssistDelegator.execCommand('beautifyCode', editor);
}
});
diff --git a/apps/ide/src/plugins/webida.editor.text-editor/TextEditorViewer.js b/apps/ide/src/plugins/webida.editor.text-editor/TextEditorViewer.js
index 4b79ba37..8e0d95cd 100644
--- a/apps/ide/src/plugins/webida.editor.text-editor/TextEditorViewer.js
+++ b/apps/ide/src/plugins/webida.editor.text-editor/TextEditorViewer.js
@@ -115,7 +115,7 @@ define([
}
function isAvailable(type, name) {
- return _.contains(availables, type + '::' + name);
+ return _.includes(availables, type + '::' + name);
}
var eventTransformers = {
@@ -319,7 +319,7 @@ define([
cm.indentLine(e.from.line + i);
}
}
- });
+ });
},
synchronizeWidgetModel: function (recentViewer) {
@@ -471,7 +471,7 @@ define([
setSelection: function (anchor, head) {
this.cursor = head;
this.addDeferredAction(function (self) {
- self.editor.getDoc().setSelection(eventTransformers.wrapperLoc2cmLoc(anchor),
+ self.editor.getDoc().setSelection(eventTransformers.wrapperLoc2cmLoc(anchor),
eventTransformers.wrapperLoc2cmLoc(head));
});
if (!this.editor) {
@@ -526,7 +526,7 @@ define([
}
});
},
-
+
/**
* Highlights strings matching given query with query options
* Example: viewer.setHighlight('string',{caseSensitive: false, regexp: false, wholeWord: false});
@@ -552,7 +552,7 @@ define([
}
this.theme = theme;
if (theme === 'codemirror-default') {
- theme = this.theme = 'default';
+ theme = this.theme = 'default';
this.addDeferredAction(function (self) {
self.editor.setOption('theme', self.theme);
});
@@ -572,7 +572,7 @@ define([
break;
}
loadCSSList([require.toUrl(csspath)], function () {
- addAvailable('theme', theme);
+ addAvailable('theme', theme);
self.addDeferredAction(function (self) {
self.editor.setOption('theme', self.theme);
});
@@ -644,16 +644,16 @@ define([
_gutterOn: function (gutterName) {
if (this.editor) {
var gutters = this.editor.getOption('gutters');
- if (!_.contains(gutters, gutterName)) {
+ if (!_.includes(gutters, gutterName)) {
var i, newgutters = [];
var order = ['CodeMirror-linenumbers', 'CodeMirror-lint-markers', 'CodeMirror-foldgutter'];
for (i = 0; i < order.length; i++) {
- if (_.contains(gutters, order[i]) || order[i] === gutterName) {
+ if (_.includes(gutters, order[i]) || order[i] === gutterName) {
newgutters.push(order[i]);
}
}
for (i = 0; i < gutters.length; i++) {
- if (!_.contains(order, gutters[i])) {
+ if (!_.includes(order, gutters[i])) {
newgutters.push(gutters[i]);
}
}
@@ -806,7 +806,7 @@ define([
if (codeFolding) {
var self = this;
loadCSSList([require.toUrl('./css/codefolding.css')], function () {
- require(['external/codemirror/addon/fold/foldcode', 'external/codemirror/addon/fold/foldgutter',
+ require(['external/codemirror/addon/fold/foldcode', 'external/codemirror/addon/fold/foldgutter',
'external/codemirror/addon/fold/brace-fold'], function () {
self.addDeferredAction(function (self) {
self._gutterOn('CodeMirror-foldgutter');
@@ -1320,14 +1320,14 @@ define([
replace: function () {
this.addDeferredAction(function (self) {
- var editor = self.editor;
+ var editor = self.editor;
editor.execCommand('replace');
});
},
find: function () {
this.addDeferredAction(function (self) {
- var editor = self.editor;
+ var editor = self.editor;
editor.execCommand('find');
});
},
@@ -1428,7 +1428,7 @@ define([
var merge = function (current, processed, keymap) {
var curKeyMap = codemirror.keyMap[current];
keymap = _.extend(keymap, curKeyMap);
- if (curKeyMap.fallthrough && !_.contains(processed, curKeyMap.fallthrough)) {
+ if (curKeyMap.fallthrough && !_.includes(processed, curKeyMap.fallthrough)) {
processed.push(curKeyMap.fallthrough);
return merge(curKeyMap.fallthrough, processed, keymap);
} else {
diff --git a/bower.json b/bower.json
index d406913d..1cb46989 100644
--- a/bower.json
+++ b/bower.json
@@ -19,7 +19,7 @@
"jquery": "~2.1.4",
"jquery-cookie" : "carhartl/jquery-cookie#faa09dc38bd3c791212e8fca67ee661af55fa530",
"js-beautify": "~1.5.10",
- "lodash": "~3.10.0",
+ "lodash": "~4.14.0",
"moment": "~2.10.3",
"put-selector": "~0.3.6",
"qunit": "~1.18.0",
@@ -27,14 +27,12 @@
"requirejs": "~2.1.18",
"showdown": "~1.1.0",
"smalot-bootstrap-datetimepicker": "~2.3.4",
- "socket.io-client": "socket.io-client#~1.4.5",
- "superagent" : "~2.0.0",
"ladda": "hakimel/Ladda#ec575edabd0602ed303978148df7d5e731014010",
"term.js": "chjj/term.js#~v0.0.7",
"tern": "webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
"toastr": "~2.1.1",
- "URIjs": "~1.15.2",
- "webida-restful-api": "webida/webida-restful-api#~0.6.0",
+ "URIjs": "~1.18.1",
+ "webida-service-client": "webida/webida-service-client#~0.7.1",
"xstyle": "~0.3.1"
}
-}
+}
\ No newline at end of file
diff --git a/common/src/webida/app.js b/common/src/webida/app.js
index cd8055e0..d9cd3524 100644
--- a/common/src/webida/app.js
+++ b/common/src/webida/app.js
@@ -122,9 +122,9 @@ define([
}
function saveStatusSync() {
- if (webida.VERSION && webida.VERSION === '0.1') {
+ if (webida.VERSION) {
logger.info('current server api does not support synchronous file writing');
- return;
+ return null;
}
var statusString = getStatusStringToSave();
@@ -311,7 +311,7 @@ define([
mount.readFile(path + lastStatusFile, function (err, content) {
//logger.info('content = ', content);
if (err) {
- singleLogger.log('(C) not read last status file (' + err + ')');
+ singleLogger.error('(C) could not read last status file', err);
} else {
try {
appLastStatus = JSON.parse(content);
diff --git a/common/src/webida/plugins/session-event-dispatcher/plugin.js b/common/src/webida/plugins/session-event-dispatcher/plugin.js
index 0709271c..75f6dc2b 100644
--- a/common/src/webida/plugins/session-event-dispatcher/plugin.js
+++ b/common/src/webida/plugins/session-event-dispatcher/plugin.js
@@ -37,7 +37,7 @@ define([
var logger = Logger.getSingleton();
logger.debug = logger.log;
- var sessionClient = webida.session;
+ var sessionEventSource = webida.sessionService.getEventSource();
function dispatchTopic(topicName) {
return function __reflectingTopicDispatcher(eventName) {
@@ -51,16 +51,16 @@ define([
};
}
- sessionClient.on('announcement', dispatchTopic('server/session/announcement'));
- sessionClient.on('closing', dispatchTopic('server/session/closing'));
- sessionClient.on('connect', dispatchTopic('server/session/'));
- sessionClient.on('disconnect', dispatchTopic('server/session/disconnect'));
- sessionClient.on('reconnect', dispatchTopic('server/session/reconnect'));
- sessionClient.on('connect_error', dispatchTopic('server/session/connect/error'));
- sessionClient.on('connect_timeout', dispatchTopic('server/session/connect/timeout'));
- sessionClient.on('reconnect_failed', dispatchTopic('server/session/reconnect/failed'));
+ sessionEventSource.on('announcement', dispatchTopic('server/session/announcement'));
+ sessionEventSource.on('closing', dispatchTopic('server/session/closing'));
+ sessionEventSource.on('connect', dispatchTopic('server/session/'));
+ sessionEventSource.on('disconnect', dispatchTopic('server/session/disconnect'));
+ sessionEventSource.on('reconnect', dispatchTopic('server/session/reconnect'));
+ sessionEventSource.on('connect_error', dispatchTopic('server/session/connect/error'));
+ sessionEventSource.on('connect_timeout', dispatchTopic('server/session/connect/timeout'));
+ sessionEventSource.on('reconnect_failed', dispatchTopic('server/session/reconnect/failed'));
- sessionClient.on('wfs', dispatchLegacyResourceTopics);
+ sessionEventSource.on('wfs', dispatchLegacyResourceTopics);
// need some 'toasting' plugin for basic session events, but not here.
// for this plugins should work without toaster.
diff --git a/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js b/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
deleted file mode 100644
index 71ac33ba..00000000
--- a/common/src/webida/server-api-0.1-lib/AbstractSocketClient.js
+++ /dev/null
@@ -1,271 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file AbstractSocketClient.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-// we don't want cyclic dependencies between common and TokenManager.
-// so, instead of requiring just ./common, we require all dependencies directly
-// the only instance of TokenManager is saved in common
-define([
- 'URIjs',
- 'external/eventEmitter/EventEmitter',
- 'external/lodash/lodash.min',
- 'external/socket.io-client/socket.io',
- 'webida-lib/util/genetic',
- './common'
-], function (
- URI,
- EventEmitter,
- _,
- io,
- genetic,
- common
-) {
- 'use strict';
-
- var logger = common.logger;
-
- // to protect session token from outage,
- // token manager should care about 'maximum recovery time'
- // since we use socket.io's reconnection mechanism, calculation is quite complex.
-
- var CONNECT_OPTIONS = {
- multiplex: true, // each socket share web socket connection (need testing)
- timeout : 5000, // before connect_error and connect_timeout are emitted.
- transports : ['websocket'], // forces the transport to be only websocket.
- reconnection: true,
- reconnectionDelay: 500, // delay grows 0.5, 1.0, 1.5, to 3.0
- reconnectionDelayMax : 3000,
- reconnectionAttempts: 20,
- };
-
- // connectOptions.query is object, not string
- function AbstractSocketClient(namespace, connectOptions) {
- EventEmitter.call(this);
- this._connectOptions = _.defaults({}, CONNECT_OPTIONS, connectOptions);
- this._namespace = namespace;
- this.socket = null;
- this.isConnected = false;
- this.reconnectingCount = 0;
- this.disconnectedWhen = new Date().getTime();
- }
-
- genetic.inherits(AbstractSocketClient, EventEmitter, {
-
- connect: function connect() {
- // connect options cannot be changed after socket object is made
- // even if we put a getter for this._connectOptions.query,
- // socket.io will not read the query string again.
- this._connectOptions.query = this._buildConnectQueryString();
- var connectUrl = common.serverUrl + '/' + this._namespace;
- logger.debug(this.constructor.name + ' connecting to ' + connectUrl,
- this._connectOptions);
- this.socket = io(common.serverUrl + '/' + this._namespace, this._connectOptions);
- this._registerConnectionEventHandlers();
- this._registerEventHandlers();
- },
-
- disconnect: function disconnect() {
- this.socket.disconnect();
- },
-
- // OVERRIDE ME! don't call super._getEventHandlers!
- _getEventHandlers: function () {
- logger.warn(this.constructor.name + ' has no event handlers');
- return {};
- },
-
- _onConnect : function onConnect(error, isTimeout) {
- var info = {
- isTimeout : isTimeout,
- took : (new Date().getTime() - this.disconnectedWhen) + 'msec'
- };
- var shouldEmitEvent = false;
- if (error) {
- // ignores reconnecting error for it will be handled in onReconnect
- if (this.reconnectingCount === 0) {
- logger.error(this.constructor.name + ' connect error ', error, info);
- shouldEmitEvent = true;
- }
- } else {
- logger.debug(this.constructor.name + ' connected to server', info);
- shouldEmitEvent = true;
- }
- return shouldEmitEvent;
- },
-
- _onDisconnect : function onDisconnect() {
- logger.debug(this.constructor.name + ' disconnected from server');
- this.isConnected = false;
- return true;
- },
-
- // error, false => retrying error (will try again)
- // error, true => recovery failed. completely lost (will not try again)
- // null, false => retrying
- // null, true => recovery success
- _onReconnect : function onReconnect(error, done) {
- var reconnectingFor = new Date().getTime() - this.disconnectedWhen;
- var reconnectingInfo = {
- reconnectingCount : this.reconnectingCount,
- reconnectingFor : reconnectingFor + ' msec'
- };
- var shouldEmitEvent = false;
- var name = this.constructor.name;
- if (error) {
- if (done) {
- logger.error(name + ' LOST CONNECTION', error, reconnectingInfo);
- shouldEmitEvent = true;
- this.reconnectingCount = 0;
- } else {
- logger.warn(name + ' reconnecting attempt failed', error, reconnectingInfo);
- }
- } else {
- if (done) {
- logger.debug(name + ' recovered connection ', reconnectingInfo);
- shouldEmitEvent = true;
- } else {
- logger.debug(name + ' is trying to recover connection', reconnectingInfo);
- }
- }
- return shouldEmitEvent;
- },
-
- // calculating recovery time (without max delay)
- // - worst case : every reconnecting fails with timeout
- // - best case : every reconnecting fails immediately
- // = (n*t) + (d*n*(n-1)/2)
- // With maximum reconnecting delay time, calculation is a bit more complex
- // second term of f(n,d,t) becomes
- // d*m*(m+1)/2 + D*(n-m-1) where D = maximum delay time, m = D/d
- // = D*(m+1)/2 * D*(n-m-1) = D*(n-(m+1)/2)
- calculateRecoveryTime : function calculateRecoveryTime() {
- var opt = this._connectOptions;
-
- if (!opt.reconnect) {
- return {
- best : 0,
- worst: 0
- };
- }
-
- var n = opt.reconnectionAttempts;
- var t = opt.timeout;
- var d = opt.reconnectionDelay;
- var D = opt.reconnectionDealyMax;
- var m = D/d;
-
- var best = D * (n - (m + 1) / 2);
- var worst = best + (n * t);
-
- // if we set n = 20, t=5, d = 0.5, D=3 ,in default
- // best : 3* (20 - 7/2) = 3*16.5 = 49.5
- // worst : 149.5
- return {
- best : best,
- worst: worst
- };
- },
-
- _buildConnectQueryString: function _buildConnectQueryString() {
- var uri = new URI();
- var queryObject = _.defaults({}, CONNECT_OPTIONS.query, this._connectOptions.query);
-
- logger.debug('building query object', queryObject,
- CONNECT_OPTIONS.query, this._connectOptions.query);
-
- queryObject.token = common.tokenManager.accessToken.text;
- return uri.query(queryObject).query();
- },
-
- _registerConnectionEventHandlers: function _registerConnectionEventHandlers () {
- var myself = this;
- var socket = this.socket;
-
- socket.on('connect', function () {
- myself.isConnected = true;
- myself.reconnectingCount = 0;
-
- // we don't need to handle manager events
- var shouldEmit = myself._onConnect();
- if (shouldEmit) {
- myself.emit('connect');
- }
- });
-
- socket.on('connect_error', function (err) {
- var shouldEmit = myself._onConnect(err);
- if (shouldEmit) {
- myself.emit('connect_error', err);
- }
- });
-
- socket.on('connect_timeout', function (err) {
- var shouldEmit = myself._onConnect(err, true);
- if (shouldEmit) {
- myself.emit('connect_timeout', err);
- }
- });
-
- socket.on('reconnect_attempt', function (count) {
- myself.reconnectingCount = count;
- myself._onReconnect(null, false);
- });
-
- // seems not fired
- socket.on('reconnect_error', function (err) {
- myself._onReconnect(err, false);
- });
-
- socket.on('reconnect', function () {
- myself.isConnected = true;
- myself._onReconnect(null, true);
- myself.disconnectedWhen = 0;
- myself.reconnectingCount = 0;
- myself.emit('reconnect');
- });
-
- socket.on('reconnect_failed', function (err) {
- err = err || new Error('too much retry - reached to limit');
- myself._onReconnect(err, true);
- myself.emit('reconnect_failed', err);
- });
-
- socket.on('disconnect', function () {
- myself.disconnectedWhen = new Date().getTime();
- myself.isConnected = false;
- myself._onDisconnect();
- myself.emit('disconnect');
- });
- },
-
- _registerEventHandlers: function _registerEventHandlers() {
- var handlers = this._getEventHandlers();
- // handlers should map event name to handler function
- // handler function does not have to bind 'this'
- var myself = this;
- _.forEach(handlers, function(handler, eventName) {
- myself.socket.on(eventName, handler.bind(myself));
- });
- }
- });
-
- return AbstractSocketClient;
-});
diff --git a/common/src/webida/server-api-0.1-lib/TokenManager.js b/common/src/webida/server-api-0.1-lib/TokenManager.js
deleted file mode 100644
index ef3dfb4d..00000000
--- a/common/src/webida/server-api-0.1-lib/TokenManager.js
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file TokenManager.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-// we don't want cyclic dependencies between common and TokenManager.
-// so, instead of requiring just ./common, we require all dependencies directly
-// the only instance of TokenManager is saved in common
-define([
- 'webida-restful-api',
- 'external/eventEmitter/EventEmitter',
- 'webida-lib/util/genetic',
- 'webida-lib/util/logger/logger-client'
-], function (
- WebidaRestfulApi,
- EventEmitter,
- genetic,
- Logger
-) {
- 'use strict';
-
- var logger = new Logger();
- if (!logger.debug) {
- logger.debug = logger.log;
- }
-
- // issueToken() can take 'timeout' msec
- // so, we should begin calling issueToken(), at least 30 secs
-
- var MARGIN_TO_EXPIRE = WebidaRestfulApi.ApiClient.instance.timeout + (30 * 1000);
- var RETRY_AFTER = 5 * 1000;
- var authApi = new WebidaRestfulApi.AuthApi();
-
- // IDE does not use master token except login with master token
- // so, TokenManager handles access token only
-
- function TokenManager(accessToken) {
- EventEmitter.call(this);
- this._updateTimer = null;
- if (accessToken) {
- this.updateAccessToken(accessToken);
- }
- }
-
- genetic.inherits(TokenManager, EventEmitter, {
- updateAccessToken: function updateAccessToken(newAccessToken) {
- this.accessToken = newAccessToken;
- if (!this.accessToken) {
- return;
- }
-
- var ttl = this.getRemainingTTL();
- if(ttl < MARGIN_TO_EXPIRE) {
- // this error is very serious. if happens, fix server configuration
- // we recommend at least 2 min, usually 10 min.
- throw new Error('Token has too short expiration time ' + ttl);
- } else {
- this.emit('updated', this.accessToken);
- // ttl == expire - current
- // after == expire - current - margin == ttl - margin
- this._setUpdateTimer(ttl - MARGIN_TO_EXPIRE);
- }
- },
-
- _setUpdateTimer: function(after) {
- if (this._updateTimer !== null ) {
- window.clearTimeout(this._updateTimer);
- this._updateTimer = null;
- }
- var expiresAt = this.accessToken.expiresAt;
- var ttl = this.getRemainingTTL();
- logger.debug('token expires at ' + expiresAt + ' , ttl = ' + ttl);
- if (ttl < after) {
- var nextUpdateTime = new Date().getTime() + after;
- nextUpdateTime = new Date(nextUpdateTime);
- var updateError = new Error(
- 'cannot schedule next update time - time over :' +
- ' requested update time = ' + nextUpdateTime +
- ' , expiration time = ' + expiresAt
- );
- logger.log(updateError);
- this.emit('lost', updateError);
- return;
- }
- var willUpdateAt = new Date( new Date().getTime() + after );
- logger.debug('next update will start after ' + after + ' msec ', willUpdateAt);
- this._updateTimer = window.setTimeout(this._doUpdate.bind(this), after);
- },
-
- // events
- // updated : normally updated token via schedule
- // retry : could not update token, but will retry
- // lost : update failed and there's no chance to get token again.
- // app should login again.
-
- _doUpdate: function _doUpdate() {
- logger.log('start updating tokens');
- var self = this;
- authApi.issueToken( 'ACCESS', {}, function (error, result, response) {
- if(!error) {
- try {
- logger.log('new token arrived', result);
- self.updateAccessToken(result);
- } catch (updateError) {
- logger.log('new token has serious error', updateError);
- self.emit('lost', updateError);
- // should we have to retry?
- // no, this error is 'serious' configuration problem.
- }
- } else {
- // there can be serveral types of error
- // server refused - should not retry (status 4xx, usually)
- // server had error (5xx, 0)
- logger.log('could not get new token ', error);
- if (error.timeout || response.status === 503) {
- self.emit('retry', error);
- self._setUpdateTimer(RETRY_AFTER);
- } else {
- logger.log('server refused to issue new token', error);
- self.emit('lost', error);
- }
- }
- });
- },
-
- getRemainingTTL : function() {
- var expireTime = this.accessToken.expiresAt.getTime();
- var currentTime = new Date().getTime();
- return expireTime - currentTime;
- },
-
- dispose : function disposeTokenManager() {
- if (this._updateTimer) {
- window.clearTimeout(this._updateTimer);
- this.accessToken = null;
- }
- }
- });
-
- TokenManager.instance = new TokenManager();
- return TokenManager;
-});
diff --git a/common/src/webida/server-api-0.1-lib/auth.js b/common/src/webida/server-api-0.1-lib/auth.js
deleted file mode 100644
index 41b0f84d..00000000
--- a/common/src/webida/server-api-0.1-lib/auth.js
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file auth.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- './common',
- './session'
-], function (
- common,
- session
-) {
- 'use strict';
- var logger = common.logger;
- var AuthApi = common.api.AuthApi;
- var authApi = new AuthApi();
-
- // TODO : introduce webida.initializeAsync() that handles all init things,
- // with credential provider that interacts with UI,
- // and remove initAuth or make it a legacy-compatibility helper
- // - ALL webida.*** should be accessible during initialization, without NPE.
- // - SOME webida.***.****() functions may throw error during initialization,
- // - We should have no no 'pending' operation due to auth.
-
-
- // we may need to move this to common or somewhere else
- common.tokenManager.on('lost', function(error) {
- alert('TOKEN LOST. LOGIN AGAIN \n ' + error.toString() );
- });
-
- common.tokenManager.on('updated', function(token) {
- logger.debug('updated token', token);
- });
-
- // initAuth is called by app.js at first, before loading any other plugins
- function initAuth(clientId, redirectUrl, tokenGenerator, callback) {
- var masterToken = common.bootArgs.masterToken;
-
- logger.log('initAuth starts');
-
- if (!masterToken) {
- throw new Error('in-app login is not implemented yet');
- }
-
- authApi.login( {
- loginId:'bogus',
- loginPassword:'bogus',
- masterToken: masterToken
- }, function(err, data) {
- if (err) {
- // given callback is NOT a error-first-callback function
- logger.error('auth error', err);
- throw(err);
- }
- common.tokenManager.updateAccessToken(data);
- session.connect();
- // Oddly, there's no error-fist-callback for initAuth
- logger.log('initAuth registered access token', data);
- try {
- callback(data.sessionId);
- } catch (e) {
- logger.error('initAuth callback had error', e);
- }
- });
- }
-
- function getMyInfo(callback) {
- authApi.getInfo(function (error, data) {
- logger.debug('AuthApi.getInfo callback with ', error, data);
- if (!error) {
- callback(null, data);
- } else {
- logger.debug('getMyInfo failed', error);
- callback(error);
- }
- });
- }
-
- return {
- initAuth : initAuth,
- getMyInfo : getMyInfo,
-
- // for compatiblity with legacies
- getTokenObj : function getTokenObj() {
- var token = common.accessToken;
- if (token) {
- return {
- issueTime : token.issuedAt,
- data : token.text
- };
- }
- },
-
- getToken : function getToken() {
- var token = common.accessToken;
- if (token) {
- return token.text;
- }
- },
-
- getSessionID : function getSessionID() {
- var token = common.accessToken;
- if (token) {
- return token.sessionId;
- }
- }
- };
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/cache-db-manager.js b/common/src/webida/server-api-0.1-lib/cache-db-manager.js
deleted file mode 100644
index 0753c02a..00000000
--- a/common/src/webida/server-api-0.1-lib/cache-db-manager.js
+++ /dev/null
@@ -1,233 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file cache-db-manager.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-// we don't want cyclic dependencies between common and TokenManager.
-// so, instead of requiring just ./common, we require all dependencies directly
-// the only instance of TokenManager is saved in common
-define([
- './common'
-], function (
- common
-) {
- 'use strict';
-
- var logger = common.logger;
- var CACHE_DB_STORAGE_KEY = 'webida-offline-cache-db';
- var CACHE_DB_VERSION = 1;
- var CACHE_DB_NAME_PREFIX = 'webida-offline-cache-';
- var ITEM_STORE_NAME = 'items';
- var CHANGE_STORE_NAME = 'changes';
-
- function rejector() {
- return Promise.reject(new Error('local storage is not available'));
- }
-
- if (!window.localStorage) {
- return {
- catalog: {},
- open : rejector,
- remove : rejector,
- clean : rejector
- };
- }
-
- var privates = {
- catalog : null,
-
- loadCatalog: function loadCaches() {
- var loaded = window.localStorage.getItem(CACHE_DB_STORAGE_KEY);
- if (loaded) {
- privates.catalog = JSON.parse(loaded);
- } else {
- privates.catalog = {};
- privates.saveCatalog();
- }
- return privates.catalog;
- },
-
- saveCatalog: function saveCaches(data) {
- var toWrite = data || privates.catalog || {};
- window.localStorage.setItem(CACHE_DB_STORAGE_KEY, JSON.strintify(toWrite));
- },
-
- getCacheDBName : function (workspaceId) {
- return CACHE_DB_NAME_PREFIX + workspaceId;
- },
-
- // makes IDBRequest object to call given resolve/reject, in a promise constructor
- // basically works on IDBRequest, but also supports IDBOpenDBRequest type.
- // setting a transaction object as request will not work.
- // for transaction, use publics.util.begin() instead.
- swear: function (request, targetName, apiName, resolve, reject, isOpenDBRequest) {
- request.onerror = function (event) {
- if (isOpenDBRequest) {
- logger.error(targetName + ' ' + apiName + ' error', event);
- }
- if (typeof reject === 'function') {
- reject(request.error);
- }
- };
-
- request.onsuccess = function (event) {
- if (isOpenDBRequest) {
- logger.debug(targetName + ' ' + apiName + ' success', event);
- }
- if (typeof resolve === 'function') {
- resolve(request.result);
- }
- };
-
- if (isOpenDBRequest) {
- request.onblocked = function (event) {
- logger.debug(targetName + ' ' + apiName + ' blocked', event);
- if (typeof reject === 'function') {
- reject(new Error(apiName + ' request ' + targetName + ' is blocked'));
- }
- };
- }
- },
-
- createSchema: function createDBSchema(db, name) {
- // item { wfsPath,timestamp, data, stats }
- // timestamp is the time when data is updated, long int from Date.getTime() ;
- var itemStore = db.createObjectStore('items', { keyPath: 'wfsPath' });
- itemStore.createIndex('timestamp', 'timestamp', { unique:false });
-
- // change { wfsPath, timestamp, data }
- // We should separate data of change from item, to process upload/download in parallel.
- // If we don't, updating cache items can overwrite local change not uploaded yet.
- // That will be a really critical and hard-to-find bug.
- var changeStore = db.createObjectStore('changes', { keyPath: 'wfsPath' });
- changeStore.createIndex('timestamp', 'timestamp', { unique: false });
- logger.info('created cache db schema for ' + name);
- },
-
- // Usually, we need some 'serial' conversions, from 1 to version x.
- // Problem: if converting takes very long time, what should we do?
- // Since 'db' object will not wait for the tasks complete, and will fire success event
- // when it has no pending tx, we can't support any upgrade tasks that need any async
- // jobs other than db transaction. (for example, changing blob to string...)
- // SOLUTION : Do not upgrade if upgrading requires some external async tasks.
- // Rename db and let open()/clean() handle the rest of our works.
- // And, abandon data, sorry.
- upgradeSchema: function upgradeDBSchema(db, name, oldVersion, newVersion) {
- if (newVersion !== CACHE_DB_VERSION) {
- throw new Error('invalid db version ' + newVersion + ' to ' + name);
- }
- // no need to implement upgrade, yet.
- },
-
- openDB : function (workspaceId) {
- return new Promise(function (resolve, reject) {
- var name = privates.getCacheDBName(workspaceId);
- var openRequest = window.indexedDB.open(name, CACHE_DB_VERSION);
- openRequest.onupgradeneeded = function (event) {
- var db = event.target.result;
- // setting db.onsuccess, db.onerror does not work. request fires all events.
- if (event.oldVersion) {
- privates.upgradeSchema(db, name, event.oldVersion, event.newVersion);
- } else {
- privates.createSchema(db, name);
- }
- };
- privates.swear(openRequest, name, 'open', resolve, reject, true);
- });
- },
-
- removeDB : function(workspaceId) {
- var name = privates.getCacheDBName(workspaceId);
- return new Promise(function (resolve, reject) {
- var delRequest = window.indexedDB.deleteDatabase(name);
- privates.swear(delRequest, name, 'deleteDatabase', resolve, reject, true);
- });
- }
- };
-
- var publics = {
-
- // resolves to IDBDatabase object
- open : function openCacheDB(workspaceId) {
- return privates.openDB(workspaceId).then(function(db) {
- var name = privates.getCacheDBName(workspaceId);
- if (!privates.catalog[name]) {
- privates.catalog[name] = CACHE_DB_VERSION;
- privates.saveCatalog();
- }
- return db;
- });
- },
-
- clean: function cleanCacheDB(workspaceIds) {
- var promises = [];
- workspaceIds.forEach(function(id) {
- var name = privates.getCacheDBName(id);
- promises.push(privates.removeDB(id).then( function() {
- if (privates.catalog[name]) {
- delete privates.catalog[name];
- privates.saveCatalog();
- }
- }));
- });
- return Promise.all(promises);
- },
-
- utils: {
- swear: function setPinkyFingers() {
- return privates.swear.apply(null, arguments);
- },
-
- begin: function beginCacheTransaction(db, txName, resolve, reject) {
- var tx = db.transaction(db.objectStoreNames, 'readwrite');
- tx.__name = txName;
- tx.onerror = function (event) {
- logger.debug(txName + ' error', event);
- reject(tx.error);
- };
- tx.oncomplete = function (event) {
- logger.debug( txName + ' complete', event);
- resolve(); // resolves null, on alwyas.
- };
- return tx;
- },
- },
-
- constants: {
- ITEM_STORE_NAME: ITEM_STORE_NAME,
- CHANGE_STORE_NAME: CHANGE_STORE_NAME
- }
- };
-
- privates.loadCatalog();
-
- // if we don't listen storage event, clean() may hit dangling db.
- // There's no portable API like IDBFactory#getDatabaseNames(), we should avoid.
-
- window.addEventListener('storage', function(event) {
- if (event.storageArea === window.localStorage) {
- var value = event.newValue;
- logger.debug('DB catalog change', event);
- privates.catalog = value ? JSON.parse(value) : {};
- }
- });
-
- return publics;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/common.js b/common/src/webida/server-api-0.1-lib/common.js
deleted file mode 100644
index c4d925e8..00000000
--- a/common/src/webida/server-api-0.1-lib/common.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file common.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-define([
- 'URIjs',
- 'webida-restful-api',
- 'external/eventEmitter/EventEmitter',
- 'webida-lib/util/logger/logger-client',
- './TokenManager'
-], function (
- URI,
- WebidaRestfulApi,
- EventEmitter,
- Logger,
- TokenManager
-) {
- 'use strict';
-
- var logger = new Logger();
- if (!logger.debug) {
- logger.debug = logger.log;
- }
-
- var privates = {
- bootArgs : null,
- serverUri : null,
- serverUrl : null,
- session: null,
- tokenManager : TokenManager.instance,
- };
-
- var publics = {
- // accessors to privates. getters only, no setters
- get logger() { return logger; },
- get bootArgs() { return privates.bootArgs; },
- get serverUri() { return privates.serverUri; },
- get serverUrl() { return privates.serverUrl; },
- get tokenManager() { return privates.tokenManager;},
- get accessToken() { return privates.tokenManager.accessToken; },
- get api() {
- return WebidaRestfulApi;
- }
- };
-
- function initializeThisModule() {
- var locationUri = new URI(window.location.href);
- var bootArgs = locationUri.query(true);
-
- privates.bootArgs = bootArgs;
- Object.freeze(privates.bootArgs);
-
- privates.serverUri = new URI(bootArgs.serverUrl).normalize().resource('').path('');
- privates.serverUrl = privates.serverUri.toString().slice(0, -1);
-
- // by default, generated js client uses 'http://localhost/api' as base url
- // we should replace it to real server url
-
- var defaultClient = WebidaRestfulApi.ApiClient.instance;
- defaultClient.basePath = privates.serverUrl + '/api';
-
- // webidaSimpleAuth.apiKey is not a 'fixed' value.
- // so, we should define property getter (maybe proxy, later)
- var webidaSimpleAuth = defaultClient.authentications['webida-simple-auth'];
- Object.defineProperty(webidaSimpleAuth, 'apiKey', {
- enumerable: true,
- get : function getSimpleAuthApiKey() {
- if (privates.tokenManager.accessToken) {
- return privates.tokenManager.accessToken.text;
- } else {
- logger.log('has no access token yet');
- return 'not-a-token';
- }
- }
- });
- logger.debug('swagger api default client', defaultClient);
- }
-
- /* module main script */
- initializeThisModule();
-
- return publics;
-
-});
diff --git a/common/src/webida/server-api-0.1-lib/fs.js b/common/src/webida/server-api-0.1-lib/fs.js
deleted file mode 100644
index 5d1227c9..00000000
--- a/common/src/webida/server-api-0.1-lib/fs.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file fs.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- './common',
- './wfs/WfsMount'
-], function (
- common,
- WfsMount
-) {
- 'use strict';
-
- var privates = {
- mounts : {}
- };
-
- // To support multiple file systems in single workspace
- // 1) we need a way to set access token for each file system mounted
- // 2) server should provide a way to get an access token for each file system
- // But, don't make things too hard.
- // "1 ws == 1 fs" policy looks stupid but simple and clean for IDE application
-
- // In the view point of resource abstraction
- // every workspace items in workspace plugin may have some URI
- // and this API supports only wfs:// URI
- // If some application wants to implement its own workspace persistence,
- // then the application can decide to implement multiple data source provider or not.
- // IDE currently does not need more than 1 FS.
-
- function mountByFSID(fsid) {
- if (!privates.mounts[fsid]) {
- privates.mounts[fsid] = new WfsMount(fsid);
- }
- return privates.mounts[fsid];
- }
-
- return {
- mountByFSID : mountByFSID
- };
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/messaging.js b/common/src/webida/server-api-0.1-lib/messaging.js
deleted file mode 100644
index 878fe22a..00000000
--- a/common/src/webida/server-api-0.1-lib/messaging.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file messaging.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- 'external/eventEmitter/EventEmitter',
- 'webida-lib/util/genetic',
- './common',
- './AbstractSocketClient'
-], function (
- EventEmitter,
- io,
- common
-) {
- 'use strict';
- var logger = common.logger;
-
- // for some 'plugin specific socket client', we need
- // 1) generic name space, 'ide' or 'plugins', 'app', 'generic', ... etc
- // 2) a socket client (with space-specific protocol) that can
- // create/join/leave/remove room
- // broadcast to all, broadcast all but self
- // send direct message to someone
- // block/unblock message from someone
- // 3) an abstract class to use the socket client
-
- return {};
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/session.js b/common/src/webida/server-api-0.1-lib/session.js
deleted file mode 100644
index 9e594a2d..00000000
--- a/common/src/webida/server-api-0.1-lib/session.js
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file session.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-// we don't want cyclic dependencies between common and TokenManager.
-// so, instead of requiring just ./common, we require all dependencies directly
-// the only instance of TokenManager is saved in common
-define([
- 'webida-lib/util/genetic',
- './common',
- './AbstractSocketClient'
-], function (
- genetic,
- common,
- AbstractSocketClient
-) {
- 'use strict';
-
- var logger = common.logger;
- var SESSION_NAME_SPACE = 'session';
-
- // some api modules will listen events from session client
- // a plugin, called session-event-dispatcher, will listen for session client
- // and will 'translate' session events into dojo topic
-
- function SessionSocketClient() {
- AbstractSocketClient.call(this, SESSION_NAME_SPACE, {
- query : {
- workspaceId:common.bootArgs.workspaceId
- }
- });
- }
-
- genetic.inherits(SessionSocketClient, AbstractSocketClient, {
-
- // session events (should be handled by this class)
- // wfsWatcher(wfsId, start/stop)
- // wfsRaw(wfsId, fsEventName, path, stats)
- // announcement(msg)
- // closing(msg, after)
- // basic events on connection (handled in AbstractSocketClient class)
- // connect
- // connect_error(error)
- // connect_timeout(error)
- // disconnect
- // reconnect
- // reconnect_failed(err)
-
- _getEventHandlers: function () {
- return {
- // wfs-watch event is subscribed by fs module
- // stats object is not wfs/WfsStats instance.
- wfsWatcher: function(wfsId, event) {
- logger.debug('session got wfsWatcher event', arguments);
- this.emit('wfsWatcher', wfsId, event);
- },
-
- // wfs events will be fired through WFS Mount,
- wfsRaw: function(wfsId, event, path, stats) {
- logger.debug('session got wfsRaw event', arguments);
- this.emit('wfsRaw', wfsId, event, path, stats);
- },
-
- announcement: function(msg) {
- logger.debug('session got announcement event', arguments);
- this.emit('announcement', msg);
- },
- closing: function(msg, after) {
- logger.debug('session got closing event', arguments);
- this.emit('closing', msg, after);
- }
- };
- }
- });
-
- return new SessionSocketClient();
-});
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js b/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
deleted file mode 100644
index 7902cf7e..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsDirForest.js
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsDirForest.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- '../common',
- './WfsDirTree',
- './WfsEntry',
- './wfs-utils'
-], function(
- common,
- WfsDirTree,
- WfsEntry,
- wfsUtils
-) {
- 'use strict';
-
- var logger = common.logger;
- var wfsApi = new common.api.WfsApi();
-
- function WfsDirForest(wfsId, roots) {
- this.dirs = {};
- this.wfsId = wfsId;
- var myself = this;
-
- // TODO: reduce roots if one of them is a sub-tree of other tree.
- roots.forEach(function(dir) {
- myself.dirs[dir] = null;
- });
- }
-
- WfsDirForest.prototype = {
- build: function buildForest() {
- var myself = this;
- var promises = [];
- this.dirs.forEach(function(dir) {
- promises.push(myself.addTreeAsync(dir));
- });
- return Promise.all(promises);
- },
-
- getTree : function getTree(rootPath) {
- return this.dirs[rootPath];
- },
-
- addTreeAsync : function addTree(rootPath) {
- var myself = this;
- return new Promise( function(resolve, reject) {
- try {
- if(!myself.dirs[rootPath]) {
- var wfsPath = wfsUtils.normalizePath(rootPath);
- wfsApi.dirTree(myself.wfsId, wfsPath, -1,
- function (err, apiResult) {
- if (err) {
- logger.error('adding tree ' + rootPath + ' failed ', err);
- reject(err);
- } else {
- var rootEntry = WfsEntry.fromJson(apiResult);
- rootEntry.path = rootPath;
- myself.dirs[rootPath] = new WfsDirTree(rootEntry);
- resolve(myself.dirs[rootPath]);
- }
- }
- );
- } else {
- resolve(this.dirs[rootPath]);
- }
- } catch(e) {
- logger.error('adding tree ' + rootPath + ' failed ', e);
- reject(e);
- }
- });
- },
-
- removeTree : function removeTree(rootPath) {
- delete this.dirs[rootPath];
- },
-
- findTree : function findTree(wfsPath) {
- var found = null;
- var dirs = this.dirs;
- Object.keys(dirs).some( function(rootPath) {
- if (wfsPath.indexOf(rootPath) === 0) {
- found = dirs[rootPath];
- return true;
- }
- });
- return found;
- }
- };
-
- return WfsDirForest;
-});
-
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js b/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
deleted file mode 100644
index baabab00..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsDirTree.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsDirTree.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- './WfsEntry'
-], function(
- WfsEntry
-) {
- 'use strict';
-
- // each root entry should have a path.
- function WfsDirTree (entry, clone, detached) {
- this.rootEntry = clone ? WfsEntry.clone(entry, null, detached) : entry;
- }
-
- WfsDirTree.prototype = {
-
- getEntryByPath : function getEntryByPath(entryPath) {
- if (typeof(entryPath) !== 'string') {
- return null;
- }
- var absPath = (entryPath[0] !== '/') ? ('/' + entryPath) : entryPath;
- var segments = absPath.split('/');
-
- // if root entry has name, the first element of segments should be a dir name,
- // not an empty string
- if (this.rootEntry.name) {
- segments = segments.slice(1);
- }
- var entry = this.rootEntry;
- if (entry.name !== segments[0]) {
- return null;
- }
- for (var i=0; i < segments.length; i++) {
- if(!entry || i === segments.length-1) {
- break;
- } else {
- entry = entry.getChildByName(segments[i+1]);
- }
- }
- return entry;
- },
-
- // if some path are given in pathMap, then result will skip the entry
- // so, to exclude some paths, put them in pathMap as truthy value (like true)
- // this walk() method takes a little bit long time, if tree is very large.
- // we may need to introdude worker, some kind of generator that yields entries.
- // & we need event emitter to mimic generator in ES5.
- // Introducing generator ill charge us another painful refactoring, however.
-
- walk: function walk(pathMap, entry, predicate) {
- var target = entry || this.rootEntry;
- if (predicate(entry) && !pathMap[target.path]) {
- pathMap[target.path] = entry;
- }
- entry.children.forEach( function(child) {
- if (!pathMap[child.path]) {
- walk(pathMap, child, predicate);
- }
- });
- return pathMap;
- }
- };
-
- return WfsDirTree;
-});
-
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
deleted file mode 100644
index c546fbb8..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEntry.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsEntry.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
-], function(
-) {
- 'use strict';
-
- function WfsEntry (stats, name, parent) {
-
- // currently hidden stats property that controls everthing
- Object.defineProperty(this, 'stats', {
- value: stats,
- writable:true,
- enumerable : false,
- configurable : false
- });
- this.children = [];
- this.name = name;
- this._path = null; // will be filled later
-
- // when building tree with entries
- // parent property will be set later and initially undefined
- // root entry should have 'null' (not empty) parent
- this.parent = parent || null;
- }
-
- WfsEntry.prototype = {
-
- isRoot : function isRoot() { return !this.parent; },
-
- isDetached: function isDetached() { return !this._path; },
-
- detach : function detach() {
- this._path = null;
- },
-
- // for compatiblity with webida 1.x client
- // (will be replaced to function as node.js does, later )
- get path() {
- if (this.isRoot()) {
- return this._path || '/';
- } else {
- return this.parent._path + this.name;
- }
- },
-
- // entry always have 'absolute path'
- // so, root entry should have '/' or '/***/ as _path property
- set path(value) {
- if (this.isRoot()) {
- if (!value || value === '/') {
- return;
- }
- if (value.length > 1 && value[value.length-1] !== '/') {
- value += '/';
- }
- if (value[0] !== '/') {
- value = '/' + value;
- }
- this._path = value;
- }
- },
-
- get isFile() { return !this.isDirectory; },
-
- get isDirectory() { return (this.stats.type === 'DIRECTORY'); },
-
- hasChildren : function hasChildren() {
- return this.children; // remember again, [] is falsy
- },
-
- getChildByName: function getChildByName(name) {
- var found = null;
- this.children.some( function(child) {
- if (child.name === name) {
- found = child;
- return true;
- }
- });
- }
- };
-
- WfsEntry.fromJson = function fromJson(obj, parent) {
- var entry = new WfsEntry(obj.stats, obj.name, parent);
- entry.children = obj.children.map( function (child) {
- var childEntry = WfsEntry.fromJson(child, entry);
- return childEntry;
- });
- return entry;
- };
-
- WfsEntry.clone = function clone(entry, parent, withPath) {
- // we don't have to clone name, for string is immutable
- var cloned = new WfsEntry( new WfsStats(entry.stats), entry.name );
- cloned.children = entry.children.map( function(child) {
- return WfsEntry.clone(child, cloned);
- });
- cloned.parent = parent;
- if (withPath) {
- clone._path = entry._path;
- }
- return cloned;
- };
-
- // later, we should extend this class to WfsFile & WfsDirectory
- // we also need WfsTree to handle WfsEntry trees and subtree
- return WfsEntry;
-});
-
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
deleted file mode 100644
index b7733a7a..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEventGate.js
+++ /dev/null
@@ -1,234 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsEventGate.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- '../common',
- './WfsEventHolder',
- './WfsStats',
- './wfs-utils'
-], function (
- common,
- WfsEventHolder,
- WfsStats,
- wfsUtils
-) {
- 'use strict';
-
- // provides subset of legacy FileSystem object
- // some methods are not supported, completely
- // we should create better interface in next api 0.2 with cleaner spec and Promise
-
- var logger = common.logger;
- var POLLING_THRESHOLD = 2;
- var POLLING_PERIOD = 100;
-
- function WfsEventGate(session, wfsId) {
- this.wfsId = wfsId;
- this.session = session;
- this.masks = {}; // when masked /a/b, /a/b and /a/b/* will be masked
- this.holders = {}; // path -> mutating event
-
- this.pollTimer = null;
- this.eventSequence = 0;
- this._pollEventsBound = this._pollEvents.bind(this);
- this._onWatcherEventBound = this._onWatcherEvent.bind(this);
-
- session.on('wfsRaw', this._onWatcherEventBound);
- }
-
- WfsEventGate.prototype = {
-
- stopListening: function stopListening() {
- if (this.session) {
- this.session.off('wfsRaw', this._onWatcherEventBound);
- logger.debug('stopped listening event on wfs ' + this.wfsId);
- }
- },
-
- // When WfsMount calls some server api, it calls maskEvents() to hold events from server
- // on api target(src/dst) paths, masking events on the path and it's descendants.
- // (e.g. masking '/a/b' will mask events from /a/b and /a/b/**/*)
-
- // Masking will fais if given path is already holded by some holder. That means, some
- // API call is not completed on the path, or server has some command (build, git works...)
- // on the path. If masking failes, WfsMount should not proceed api call and invoke
- // failure callback with proper message.
-
- maskEvents: function maskEvents(path, apiName) {
- var holder = this.holders[path];
- if (holder) {
- if (holder.maskedBy) {
- throw new Error(path + ' is locked by other api call ' + holder.maskedBy);
- } else {
- throw new Error(path + ' is locked by other processes in server');
- }
- }
- // If there's no holder but a mask exists - events are not arrived for the path.
- // If we omit checking, api may call unmask() twice with 'different' policies,
- // and users will see somewhat weird things, maybe.
- var mask = this.masks[path];
- if (mask) {
- throw new Error(path + 'is locked by other api call ' + mask.apiName);
- } else {
- this.masks[path] = {
- apiName : apiName,
- holders: []
- };
- }
- },
-
- // when unmasking, wfs api should pass unmasking policy
- // 1) call was successful, discard held events and api wil emit a virtual event'
- // 2) call was successful, flip event types to make them 'local, known changes'
- // (flipping will prefix '_' at every normal held event)
- // 3) call was unsuccessful. emit all held events as 'remote, unknown changes'
- // (without flipping, every held event will be emitted as it is)
-
- unmaskEvents: function unmaskEvents(path, succeeded, discardEventsFromHolders) {
- var mask = this.masks[path];
- var myself = this;
- if (!succeeded) {
- discardEventsFromHolders = false;
- }
- if (mask) {
- var unhold = function unhold() {
- mask.holders.forEach(function(holder) {
- holder.unmask(succeeded, discardEventsFromHolders);
- });
- delete myself.masks[path];
- };
- // if we have no holders in the mask object yet, that means
- // api calls unmask too fast, while no events has been arrived yet.
- if (!this.holders[path]) {
- logger.debug('postponed unmasking for final events has arrived yet');
- setTimeout(unhold, POLLING_PERIOD);
- } else {
- unhold();
- }
- }
- },
-
- _findMask: function _isMasked(path) {
- var ancestors = wfsUtils.getAncestors(path, { includeSelf:true } );
- var myself = this;
- var mask = null;
- ancestors.some(function(ancestorPath) {
- mask = myself.masks[ancestorPath];
- return mask ? true : false;
- });
- return mask;
- },
-
- _addNewHolder : function _addNewHolder(path) {
- var mask = this._findMask(path);
- var holder = null;
- if (mask) {
- holder = new WfsEventHolder(this.wfsId, path, mask.apiName);
- mask.holders.push(holder);
- } else {
- holder = new WfsEventHolder(this.wfsId, path);
- }
- this.holders[path] = holder;
- return holder;
- },
-
- _onWatcherEvent : function _onWatcherEvent(wfsId, type, path, stats) {
- if (wfsId !== this.wfsId) {
- return;
- }
- var holder = this.holders[path];
- if (!holder) {
- holder = this._addNewHolder(path);
- }
- // all sequence numbers from getWfsEvents() has positive number, excluding 0.
- this.eventSequence++;
- holder.holdServerEvent(type, stats, this.eventSequence);
- if (!this.pollTimer) {
- this.eventSequence = 0;
- this.pollTimer = setInterval(this._pollEventsBound, POLLING_PERIOD);
- }
- },
-
- _fireEvents: function _fireEvents(events,startedAt) {
- var myself = this;
- events.forEach(function(event) {
- var wstats = event.stats ? new WfsStats(event.stats) : undefined;
- //logger.debug('fire wfs event', event);
- myself.session.emit('wfs', myself.wfsId, event.type, event.path, wstats);
- });
- var elapsedTime = new Date().getTime() - startedAt;
- if (elapsedTime >= POLLING_PERIOD) {
- // TODO: make polling interval & threshold adaptive, if possible
- logger.warn('polling takes too long time ', {
- polled: events.length,
- elapsedTime: elapsedTime
- });
- }
- },
-
- _pollEvents : function _pollEvents() {
- var startedAt = new Date().getTime();
- var events = [];
- var myself = this;
- var allPaths = Object.keys(this.holders);
-
- allPaths.forEach(function(path) {
- var holder = myself.holders[path];
- if (holder.poll(POLLING_THRESHOLD)) {
- // when a holder has some missing events, all events held by the holder
- // will not be emitted for app should reload stats of the path manually
- // refreshing can be done anytime, but sequence will be set to 0,
- // to refresh needed stats as soon as possible.
- // Currently, the value of missingEventsBefore is not used but if we
- // changes policy on missing events the number will be quite useful.
- if (holder.missingEventsBefore) {
- events.push({
- path: holder.path,
- type: '__refresh',
- sequence : 0
- });
- } else {
- holder.getWfsEvents().forEach(function (event) {
- events.push(event);
- });
- }
- delete myself.holders[holder.path];
- }
- });
-
- if (events.length > 0 ) {
- events.sort( function(ev1, ev2) {
- return ev1.sequence - ev2.sequence;
- });
- this._fireEvents(events, startedAt);
- }
-
- if (allPaths.length <= 0) {
- clearInterval(this.pollTimer);
- this.pollTimer = null;
- }
- }
- };
-
-
- return WfsEventGate;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js b/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
deleted file mode 100644
index 068d7ea3..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsEventHolder.js
+++ /dev/null
@@ -1,263 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsEventHolder.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- '../common'
-], function(
- common
-) {
- 'use strict';
-
- var logger = common.logger;
-
- function WfsEventHolder(wfsId, path, maskedBy) {
- this.events = [];
- this.path = path;
- this.wfsId = wfsId;
-
- this.discardEvents = false;
- this.shouldFlipEventType = false;
- this.maskedBy = maskedBy;
- this.missingEventsBefore = 0;
- this.pollCounter = 0;
- }
-
- // while stabilizing or masked
- WfsEventHolder.prototype = {
-
- get latest() {
- if (this.events.length > 0) {
- return this.events[this.events.length-1];
- } else {
- return null;
- }
- },
-
- // returns true when this holder is 'stable' enough to fire events
- // if poll returns true, gateway should fire events and remove holder
- // when holder works under mask, (this.maskedBy is truthy)
- // poll() will not work until this holder is freed by unmask() method.
- poll: function pollToFireEvent(threshold) {
- if (!this.maskedBy) {
- this.pollCounter++;
- if (this.pollCounter >= threshold) {
- this.pollCounter = -9999; // to make enough time before being polled again.
- return true;
- }
- }
- return false;
- },
-
- // when path is 'unmasked' then this holder should become 'pollable'
- unmask: function unmask(shouldFlipEventType, discardEvents) {
- if (this.maskedBy) {
- this.discardEvents = discardEvents;
- this.shouldFlipEventType = shouldFlipEventType;
- this.maskedBy = false;
- }
- },
-
- getWfsEvents : function getWfsEvents() {
- var myself = this;
- if (this.discardEvents) {
- return [];
- } else {
- return this.events.map( function(event) {
- return {
- path: myself.path,
- type: myself.shouldFlipEventType ? '_' + event.type : event.type,
- stats: event.stats,
- sequence : event.sequence
- };
- });
- }
- },
-
- holdServerEvent : function(newType, newStats, sequence) {
- var latest = this.latest;
- var current = {
- type : newType,
- stats : newStats,
- sequence : sequence
- };
-
- if (!latest) {
- this.events.push(current);
- return;
- }
-
- // If we miss some events from server (due to connection problem)
- // then events will be messed up (e.g. addDir->unlink->change->unlinkDir ..)
- // Guessing what happened in 'the blank of history' is NOT SAFE
- // and will make more complicated problems, probably.
- // So, in that case, holder produces final wfs events '_refresh' only
- // to force app to refresh the stats of path, manually.
-
- switch(latest.type) {
- case 'addDir':
- this._holdAfterAddDir(latest, current);
- break;
- case 'unlinkDir':
- this._holdAfterUnlinkDir(latest, current);
- break;
- case 'add':
- this._holdAfterAdd(latest, current);
- break;
- case 'change':
- this._holdAfterChange(latest, current);
- break;
- case 'unlink':
- this._holdAfterUnlink(latest, current);
- break;
- default:
- logger.error('unknown event type detected on ' + this.path, latest);
- break;
- }
- this.pollCounter = 0;
- },
-
- _holdAfterAddDir: function _holdAfterAddDir(latest, current) {
- switch(current.type) {
- case 'unlinkDir':
- // there has been a 'very short lived' directory
- this.events.pop();
- break;
- case 'addDir':
- case 'add':
- case 'change':
- case 'unlink':
- this._markMissingEvents(latest, current);
- this.events.push(current);
- break;
- default:
- logger.error('new event has invalid type', current);
- break; //
- }
- },
-
- _holdAfterUnlinkDir: function _holdAfterUnlinkDir(latest, current){
- switch(current.type) {
- case 'add': // a dir is removed and a file replaced that path. very normal.
- case 'addDir':
- // if we discard this event as we do in addDir event, new stats of addedDir
- // cannot be set to upper layer. Guess what happens if we have events,
- // addDir1 -> unlinkDir -> addDir2 : addDir2 remains with new stats
- // unlinkDir1 -> addDir -> unlinkDir2 : unlinkDir 1 remains, without stats. OK.
- this.events.push(current);
- break;
- case 'unlinkDir': // maybe missing addDir
- case 'change': // maybe missing add
- case 'unlink': // maybe missing add and some changes
- this._markMissingEvents(latest, current);
- this.events.push(current);
- break;
- default:
- logger.error('new event has invalid type', current);
- break; //
- }
- },
-
- _holdAfterAdd: function _holdAfterAdd(latest, current) {
- switch(current.type) {
- case 'change':
- // when a file is added and changed, then it means is still 'writing' contents.
- // in that case, we preserve previous add event, replacing stats only
- latest.stats = current.stats;
- break;
- case 'unlink': // file is added and removed. same as handling unlinkDir after addDir
- this.events.pop();
- break;
- case 'add': // maybe missing unlink
- case 'addDir': // maybe missing unlink
- case 'unlinkDir': // maybe missing unlink and addDir
- this._markMissingEvents(latest, current);
- this.events.push(current);
- break;
- default:
- logger.error('new event has invalid type', current);
- break; //
- }
- },
-
- _holdAfterChange: function _holdAfterChange(latest, current) {
- switch(current.type) {
- case 'change':
- // it's still writing.
- latest.stats = current.stats;
- break;
- case 'unlink':
- // no need to keep 'changing' history - we have 2 possible cases
- // 1) add -> change -> unlink ==> discard all
- // 2) change -> unlink ==> unlink remains.
- // case 1 does not happens for _holdAfterAdd merges 'change' event into add.
- this.events.pop();
- this.events.push(current);
- break;
- case 'add': // maybe missing unlink
- case 'addDir': // maybe missing unlink
- case 'unlinkDir': // maybe missing unlink and addDir
- this._markMissingEvents(latest, current);
- this.events.push(current);
- break;
- default:
- logger.error('new event has invalid type', current);
- break; //
- }
- },
-
- _holdAfterUnlink: function _holdAfterUnlink(latest, current) {
- switch(current.type) {
- case 'add':
- // it's usually 'atomic writing'
- latest.type = 'change';
- latest.stats = current.stats;
- // if server is creating a new directory and write a file atomically
- // then this 'chage' event should be fired after creating the directory.
- // if we don't change sequence number, such natural order might be broken.
- latest.sequence = current.sequence;
- break;
- case 'addDir': // very normal. just removed a file and replaced to a dir.
- this.events.push(current);
- break;
- case 'change': // maybe missing 'add'
- case 'unlink': // maybe missing 'add'
- case 'unlinkDir': // maybe missing 'addDir'
- this._markMissingEvents(latest, current);
- this.events.push(current);
- break;
- default:
- logger.error('new event has invalid type', current);
- break; //
- }
- },
-
- _markMissingEvents : function(latest, current) {
- logger.warn(this.path + ' has lost some events between latest and current event',
- latest, current );
- if (!this.missingEventsBefore) {
- this.missingEventsBefore = current.sequence;
- }
- }
- };
-
- return WfsEventHolder;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js b/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
deleted file mode 100644
index 096b4409..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsMount.js
+++ /dev/null
@@ -1,402 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsMount.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- '../common',
- '../session',
- '../workspace-service',
- './WfsStats',
- './WfsEntry',
- './WfsEventGate',
- './wfs-utils'
-], function (
- common,
- session,
- workspaceService,
- WfsStats,
- WfsEntry,
- WfsEventGate,
- wfsUtils
-) {
- 'use strict';
-
- // provides subset of legacy FileSystem object
- // some methods are not supported, completely
- // we should create better interface in next api 0.2 with cleaner spec and Promise
-
- var logger = common.logger;
- var wfsApi = new common.api.WfsApi();
-
- function abstractify(name) {
- return function abstractMethod() {
- var methodName = name || 'method';
- var callback = arguments[arguments.length-1];
- var err = new Error(methodName + ' is abstract');
- if (typeof(callback) === 'function') {
- return callback(err);
- } else {
- throw err;
- }
- };
- }
-
- function WfsMount(fsid) {
- this.wfsId = fsid;
- this.eventGate = new WfsEventGate(session, fsid);
- var myself = this;
-
- // if watcher has already started by other client
- // wfsWatcher#start event will never be delivered to session socket
- session.on('wfsWatcher', function(wfsId, event) {
- if (myself.eventGate && myself.wfsId === wfsId && event === 'stop') {
- myself.eventGate.stopListening();
- myself.eventGate = null;
- }
- });
- }
-
- WfsMount.prototype = {
-
- // normalizer handles legacy path format with heading '/'
- // and wfs:// url too.
- _normalizePath: function _normalizePath(targetPath, allowUrl) {
- try {
- return wfsUtils.normalizePath(targetPath, allowUrl ? this.wfsId : undefined);
- } catch (e) {
- console.error('legacy path seems to be invalid : ' + targetPath);
- }
- },
-
- _invokeCallback: function _invokeCallback(apiName, callback, err, result) {
- try {
- callback(err, result);
- } catch(e) {
- logger.warn('Callback of WfsMount#' + apiName + '() threw error', e);
- }
- },
-
- _maskEvents: function _maskEvents(wfsPath, apiName) {
- if (this.eventGate) {
- this.eventGate.maskEvents(wfsPath, apiName);
- }
- },
-
- _unmaskEvents: function _unmaskEvents(wfsPath, succeeded, discard) {
- if (this.eventGate) {
- this.eventGate.unmaskEvents(wfsPath, succeeded, discard);
- }
- },
-
- createDir: function wfsCreateDir(path, recursive, callback) {
- var wfsPath = this._normalizePath(path);
- var myself = this;
- try {
- this._maskEvents(wfsPath, 'createDir');
- wfsApi.createDir(this.wfsId, wfsPath, { ensureParents: recursive },
- function(err, result) {
- var succeeded = err ? false : true;
- myself._unmaskEvents(wfsPath, succeeded, false);
- myself._invokeCallback('createDir', callback, err, result);
- }
- );
- } catch (e) {
- myself._invokeCallback('createDir', callback, e);
- }
- },
-
- exists: function wfsExists(path, callback) {
- var wfsPath = this._normalizePath(path);
- var myself = this;
- wfsApi.stat(this.wfsId, wfsPath, { ignoreError: true },
- function(err, apiResult) {
- var result;
- if (!err) {
- result = (apiResult.type !== 'DUMMY');
- }
- myself._invokeCallback('exists', callback, err, result);
- }
- );
- },
-
- // legacy stat is renamed to mstat
- stat: function wfsStat(path, callback) {
- var wfsPath = this._normalizePath(path);
- var myself = this;
- wfsApi.stat(this.wfsId, wfsPath,
- function(err, apiResult) {
- var result;
- if (!err) {
- result = new WfsStats(apiResult, wfsPath);
- }
- myself._invokeCallback('stat', callback, err, result);
- }
- );
- },
-
- dirTree: function wfsDirTree(path, maxDepth, callback) {
- // TODO: 'full recursive' seems to be dangerous
- // server might suffer from stack overflow or starvation with disk i/o
- // so, server may response with incomplete tree
- // 1) add a 'response header' for incomplete message
- // 2) add timeout parameter in spec
-
- var wfsPath = this._normalizePath(path);
- var myself = this;
- wfsApi.dirTree(this.wfsId, wfsPath, maxDepth,
- function(err, apiResult) {
- var result;
- if (!err) {
- result = WfsEntry.fromJson(apiResult);
- result.path = path;
- }
- myself._invokeCallback('dirTree', callback, err, result);
- }
- );
- },
-
- remove : function wfsRemove(path, noRecursive, callback ) {
- var myself = this;
- try {
- var wfsPath = this._normalizePath(path);
- this._maskEvents(wfsPath, 'remove');
- wfsApi.remove(this.wfsId, wfsPath, { noRecursive: noRecursive },
- function(err, apiResult) {
- var succeeded = err ? false : true;
- myself._unmaskEvents(wfsPath, succeeded, false);
- myself._invokeCallback('remove', callback, err, apiResult);
- }
- );
- } catch (e) {
- myself.invokeCallback('remove', callback, e);
- }
- } ,
-
- readFile : function wfsReadFile(path, responseType, callback) {
- // TODO : we need 'as' parameter replacing response type in next client release
- // as : enum of ['text', 'blob', 'json']
-
- responseType = responseType || 'text';
- if (!callback) {
- callback = responseType;
- responseType = 'text';
- }
-
- var wfsPath = this._normalizePath(path);
- var myself = this;
- wfsApi.readFile(this.wfsId, wfsPath,
- function(err, apiResultNotUsed, apiResponse) {
- var result;
- if (!err) {
- if (responseType === '' || responseType === 'text') {
- result = apiResponse.xhr.responseText;
- } else {
- result = apiResponse.xhr.response;
- }
- }
- myself._invokeCallback('readFile', callback, err, result);
- }
- );
- },
-
- // TODO - add ensure parameter
- writeFile : function wfsWriteFile(path, data, callback) {
- var myself = this;
- var err = null;
- // TODO : support serialization of plain object
- try {
- switch( typeof(data)) {
- case 'string':
- data = new Blob([data], { type:'text/plain'});
- break;
- case 'object':
- if (!(data instanceof Blob)) {
- err = new Error('invalid data - should be string or Blob');
- return myself.invokeCallback('writeFile', callback, err);
- }
- break;
- default:
- err = new Error('invalid data type - should be string or Blob');
- return myself.invokeCallback('remove', callback, err);
- }
- var wfsPath = this._normalizePath(path);
- this._maskEvents(wfsPath, 'writeFile');
- wfsApi.writeFile(this.wfsId, wfsPath, data, { ensureParents: true },
- function(err, apiResult) {
- var succeeded = err ? false : true;
- myself._unmaskEvents(wfsPath, succeeded, false);
- myself._invokeCallback('writeFile', callback, err, apiResult);
- }
- );
- } catch (e) {
- myself.invokeCallback('writeFile', callback, e);
- }
- },
-
- // TODO: supply more options & change signature to current api
- copy : function wfsCopy(src, dst, recursive, callback) {
- var myself = this;
- // when recursive is omitted, webida 0.3 api doc says it's false
- // but, actually, is handled to be true & there's no code that
- // omits recursive flag nor set it false.
- // So, new API does not have 'recursive' option.
- try {
- // when dst path is '/aaa/bbb', then actual dst is 'aaa
- var wfsPath = this._normalizePath(dst);
- var srcPath = this._normalizePath(src);
- this._maskEvents(wfsPath, 'copy');
- wfsApi.copy(this.wfsId, wfsPath, srcPath, {
- noOverwrite: false,
- followSymbolicLinks: false,
- preserveTimestamps: false
- }, function(err, apiResult) {
- var succeeded = err ? false : true;
- myself._unmaskEvents(wfsPath, succeeded, false);
- myself._invokeCallback('copy', callback, err, apiResult);
- }
- );
- } catch (e) {
- myself._invokeCallback('copy', callback, e);
- }
- },
-
- // TODO: supply more options & change signature to current api
- move : function wfsMove(src, dst, callback) {
- var myself = this;
- // when recursive is omitted, webida 0.3 api doc says it's false
- // but, actually, is handled to be true & there's no code that
- // omits recursive flag nor set it false.
- // So, new API does not have 'recursive' option.
- try {
- // when dst path is '/aaa/bbb', then actual dst is 'aaa
- var wfsPath = this._normalizePath(dst);
- var srcPath = this._normalizePath(src);
- this._maskEvents(wfsPath, 'move');
- this._maskEvents(srcPath, 'move');
-
- wfsApi.move(this.wfsId, wfsPath, srcPath, {
- noOverwrite: false
- }, function(err, apiResult) {
- var succeeded = err ? false : true;
- myself._unmaskEvents(wfsPath, succeeded, false);
- myself._unmaskEvents(srcPath, succeeded, false);
- myself._invokeCallback('move', callback, err, apiResult);
- }
- );
- } catch (e) {
- myself._invokeCallback('move', callback, e);
- }
- },
-
- // deprecated. use dirTree
- list : function wfsList(path, recursive, callback) {
- if (!callback) {
- callback = recursive;
- recursive = false;
- }
- var myself = this;
- this.dirTree(path, (recursive ? -1 : 1) , function (err, tree) {
- myself._invokeCallback('list', callback, err, tree.children);
- });
- },
-
- // deprecated. use stat, instead
- isDirectory: function wfsIsDirectory(path, callback) {
- var myself = this;
- this.stat(path, function (err, result) {
- myself._invokeCallback('isDirectory', callback, err, result.isDirectory() );
- });
- },
-
- // deprecated. use stat, instead
- isFile: function wfsIsFile(path, callback) {
- var myself = this;
- this.stat(path, function (err, result) {
- myself._invokeCallback('isFile', callback, err, !result.isDirectory() );
- });
- },
-
- // deprecated. use dirTree or never call this method
- isEmpty: function wfsIsEmpty(path, callback) {
- var myself = this;
- this.dirTree(path,1, function (err, tree) {
- myself._invokeCallback('list', callback, err, tree.children.length === 0);
- });
- },
-
- // deprecated. use 'createDir'
- createDirectory: function wfsCreateDirectory(path, recursive, callback) {
- this.createDir(path, recursive, callback);
- },
-
- // deprecated. use 'remove'
- 'delete' : function wfsDelete(path, recursive, callback) {
- if (typeof recursive === 'function') {
- callback = recursive;
- recursive = false;
- }
- return this.remove(path, !recursive, callback);
- },
-
- // deprecated. use workspaceService.exec, instead. (and do not use git.sh anymore)
- exec : function wfsExec(path, info, callback) {
- // info
- // : cmd
- // : args
- var myself = this;
-
- // replace 'git.sh' to 'git' for compatiblity
- if (info.cmd === 'git.sh') {
- info.cmd = 'git';
- }
- try {
- workspaceService.exec({
- command : info.cmd,
- args: info.args,
- cwd: this._normalizePath(path) // input, timeout will use default value
- },
- false, // no async exec by legacy wfsExec
- function(err, result) {
- var stdout, stderr, error;
- if (typeof result === 'object') {
- stdout = result.stdout;
- stderr = result.stderr;
- error = result.error;
- }
- // TODO : _invokeCallback should be able to handle multiple result arguments
- try {
- callback(err || error, stdout, stderr);
- } catch (e) {
- logger.warn('Callback of WfsMount#exec() threw error', e);
- }
- });
- } catch(e) {
- myself._invokeCallback('exec', callback, e);
- }
- },
-
- searchFiles: abstractify('searchFiles'),
- replaceFiles: abstractify('replaceFiles'),
- addAlias : abstractify('addAlias'),
- };
-
- return WfsMount;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js b/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
deleted file mode 100644
index 692a7ff7..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsOfflineCache.js
+++ /dev/null
@@ -1,356 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsEntry.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- '../common',
- '../cache-db-manager',
- '../workspace-service',
- './WfsDirForest',
- './WfsStats',
- './wfs-utils'
-], function (
- common,
- cacheDbManager,
- workspaceService,
- WfsDirForest,
- WfsStats,
- wfsUtils
-) {
- 'use strict';
-
- // provides subset of legacy FileSystem object
- // some methods are not supported, completely
- // we should create better interface in next api 0.2 with cleaner spec and Promise
-
- var logger = common.logger;
- var wfsApi = new common.api.WfsApi();
- var dbUtils = cacheDbManager.utils;
- var CACHE_TTL = 86400*1000;
-
- function WfsOfflineCache(wfsId, session) {
- this.wfsId = wfsId;
- this.session = session;
- this.db = null;
-
- this.dirForest = null; // become truthy after init
- this._initPromise = null; // become truthy when init() is not complete yet.
- this._shouldEmitWfsEvents = false; // writeToCache sends events
-
- session.on('wfs', this._onWatcherEvent.bind(this));
- // do we have to listen all wfs events?
- // if an 'off-line cache dir' is removed then
- // we should delete all cached info for the directory.
- workspaceService.on('available', this._onWorkspaceAvailable.bind(this));
- workspaceService.on('unavailable', this.this._onWorkspaceUnavailable.bind(this));
- }
-
- WfsOfflineCache.prototype = {
-
- _onWatcherEvent: function onWatcherEvent(wfsId, type, path, stats) {
- if (wfsId !== this.wfsId) {
- return;
- }
- logger.debug('wfs event got', type, path, stats);
- // is this one to be fetched?
- },
-
- // this method assumes workspace id is same to wfs id.
- // if not, should check with ws.hasWfs() or something similar
- _onWorkspaceAvailable: function _onWorkspaceAvailable() {
- var ws = workspaceService.getWorkspace();
- if (ws.id !== this.wfsId) {
- return;
- }
- // if this cache is not initialized nor initializing,
- if (this.dirForest) {
- this._uploadLocalChanges();
- } else {
- if (!this._initPromise) {
- this.init().then( function() {
- logger.debug('initialized by workspace service event');
- });
- }
- }
- this._shouldEmitWfsEvents = false;
- },
-
- _onWorkspaceUnavailable: function _onWorkspaceUnavailable() {
- var ws = workspaceService.getWorkspace();
- if (ws.id !== this.wfsId) {
- return;
- }
- this._shouldEmitWfsEvents = true;
- },
-
- init: function init() {
- var myself = this;
- if (!workspaceService.isAvailable()) {
- return Promise.reject(new Error ('workspace is not available yet'));
- }
- var initPromise = cacheDbManager.openDB(this.wfsId)
- .then( function(db) {
- this.db = db;
- return myself._buildForest();
- })
- .then( function() {
- myself._initPromise = null;
- this._prefetch();
- this._uploadLocalChanges();
- // resolves nothing
- });
- this._initPromise = initPromise;
- return initPromise;
- },
-
- isAvailable : function isAvailable() {
- return (this.db && this.dirForest);
- },
-
- // returns a promise that resolves data
- readFromCache: function readFromCache(wfsPath) {
- var myself = this;
- return new Promise(function (resolve, reject) {
- var tx = dbUtils.begin(myself.db, 'getItem');
- var itemStore = tx.objectStore('items');
- var req = itemStore.get(wfsPath);
- dbUtils.swear(req, 'items', 'getSingleItem', resolve, reject);
- // we don't have to care about tx events for now.
- });
- },
-
- cleanOldItems: function cleanOldItems() {
- var myself = this;
- return new Promise(function (resolve, reject) {
- var tx = dbUtils.begin(myself.db, 'getItem');
- var itemStore = tx.objectStore('items');
- var index = itemStore.index('timestamp');
- var timestampUpperBound = new Date().getTime() - CACHE_TTL;
- var keyRange = window.IDBKeyRange.upperBound(timestampUpperBound, true);
- var req = index.openCursor(keyRange);
- req.onsuccess = function(event) {
- var cursor = event.target.result;
- if (cursor) {
- logger.debug('clean old item', cursor.value.wfsPath);
- cursor.delete();
- cursor.continue();
- }
- };
- dbUtils.swear(tx, 'items', 'cleanOldItems', resolve, reject);
- });
- },
-
- // returns a promise that resolves nothing
- writeToCache: function writeToCache(wfsPath, data) {
- var myself = this;
- return new Promise(function (resolve, reject) {
- var tx = dbUtils.begin(myself.db, 'writeChange', resolve, reject);
- var itemStore = tx.objectStore('items');
- var changeStore = tx.objectStore('changes');
- var now = new Date();
- this.readFromCache(wfsPath).then( function(item) {
- if (item) {
- item.stats.mtime = now;
- item.stats.size = data.size || data.length;
- } else {
- item.stats = WfsStats.createFakeStats(now.getTime(), data);
- }
- item.data = data;
- item.timestamp = now.getTime();
- itemStore.put(item);
- changeStore.put({
- wfsPath: wfsPath,
- data:data,
- timestamp: now.getTime()
- });
- if (myself._shouldEmitWfsEvents) {
- myself.session.emit('wfs', '_change', this.wfsId, item.stats);
- }
- }).catch( function(err) {
- logger.error('writeToCacache failed while reading existing cache item', err);
- reject(err);
- });
- });
- },
-
- _buildForest: function _buildForest() {
- var workspace = workspaceService.getWorkspace();
- var offlineCachePaths = workspace.offlineCachePaths;
- var forest = new WfsDirForest(offlineCachePaths);
- return forest.build().then( function() {
- this.dirForest = forest;
- });
- },
-
- _updateItem: function(wfsPath, entry) {
- var myself = this;
- return new Promise( function(resolve, reject) {
- wfsApi.readFile(this.wfsId, this.wfsPath, function(err, apiResult) {
- if(err) {
- logger.error('update cache item failed', err);
- return reject(err);
- }
- var tx = dbUtils.begin(myself.db, 'getItem');
- var itemStore = tx.objectStore('items');
- var req = itemStore.put(wfsPath, {
- wfsPath : wfsPath,
- timestamp : new Date().getTime(),
- data:apiResult,
- stats: entry.stats
- });
- dbUtils.swear(req, 'items', 'updateItem', resolve, reject);
- });
- });
- // wfsApi should fix read file as blob
- },
-
- _prefetch: function _prefetch() {
- var dirs = this.dirForest.dirs;
- var myself = this;
- Object.keys(dirs).forEach( function(dir) {
- var tree = myself.dirForest.getTree(dir);
- var files = tree.walk({}, null, function (entry) {
- return entry.isFile;
- });
- myself._prefetchFiles(files);
- });
- },
-
- _prefetchFiles: function _prefetchFiles(files) {
- var myself = this;
- var promises = [];
- Object.keys(files).forEach( function(filePath) {
- var fileEntry = files[filePath];
- var wfsFilePath = wfsUtils.normalizePath(filePath);
- // 1) check we have one or not
- // 2) if we have one, then compare mtime
- // 3) if fileEntry.stats.mtime is newer than cache, call updateItem.
- var promise = myself.readFromCache(wfsFilePath)
- .then( function(item) {
- if(!item || item.stats.mtime < fileEntry.stats.mtime.getTime()) {
- return myself._updateItem(wfsFilePath, fileEntry);
- } else {
- logger.debug('skip prefetching fresh one ' + wfsFilePath);
- }
- })
- .catch( function (err) {
- logger.error(wfsFilePath + ' prefetching failed', err);
- // catch should not rethrow err, to make promise resolved, always.
- return Promise.resolve();
- });
- promises.push(promise);
- });
- return Promise.all(promises);
- },
-
- _getChanges: function _getChanges() {
- var myself = this;
- var changes = [];
- return new Promise(function (resolve, reject) {
- var tx = dbUtils.begin(myself.db, 'getItem');
- var changeStore = tx.objectStore('changes');
- var index = changeStore.index('timestamp');
- var req = index.openCursor(null);
- req.onsuccess = function(event) {
- var cursor = event.target.result;
- if (!cursor) { // cursor reached to end of index
- resolve(changes);
- } else {
- changes.push(cursor.value);
- cursor.continue();
- }
- };
- req.onerror = function (event) {
- reject(event.target.error);
- };
- });
- },
-
- _removeChanges: function _removeChanges(removables) {
- var myself = this;
- return new Promise( function(resolve, reject) {
- var tx = dbUtils.begin(myself.db, 'removeChanges', resolve, reject);
- var changeStore = tx.objectStore('changes');
- removables.forEach( function(rmPath) {
- changeStore.delete(rmPath);
- });
- });
- },
-
- _uploadChangeIfNeeded: function _uploadChangeIfNeeded(change) {
- var myself = this;
- // this promise never rejects. if having error, resolves nothing, or, path to remove.
- // 1) get server stat
- // 2) if server's stat is older than change.timestamp, invoke writeFile()
- // 3) resolve path or nothing
- return new Promise( function (resolve) {
- wfsApi.stat(myself.wfsId, change.wfsPath, {
- ignoreError:true
- }, function(err, apiResult) {
- if (err) {
- // this path should not removed
- return resolve(null);
- }
- if (apiResult.type === 'FILE') {
- // change.data should be blob!
- wfsApi.writeFile(myself.wfsId, change.wfsPath, {
- ensureParents : true
- }, change.data, function(err) {
- if(err) {
- // hey, do we have to continue on error?
- // should not reject here, to upload other changed files
- logger.warn('uploading ' + change.wfsPath + 'failed', err);
- resolve(null);
- } else {
- resolve(change.wfsPath);
- }
- });
- } else {
- resolve(change.wfsPath);
- }
- });
- });
- },
-
- _uploadLocalChanges: function _uploadLocalChanges() {
- var myself = this;
- var removables = [];
- return this._getChanges()
- .then( function(changes) {
- var promises = changes.map( function(change) {
- return myself._uploadChangeIfNeeded(change);
- });
- return Promise.all(promises);
- })
- .then( function(removablePaths) {
- removables = {};
- removablePaths.forEach(function(rmPath) {
- if (rmPath) {
- removables[rmPath] = true;
- }
- });
- return myself._removeChanges(Object.keys(removables));
- });
- }
- };
-
- return WfsOfflineCache;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js b/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
deleted file mode 100644
index a5a52149..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/WfsStats.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file WfsStats.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([ ], function() {
- 'use strict';
-
- function WfsStats (apiModelStats, path) {
- // all other properties are inherited from server stats object
- this.size = apiModelStats.size;
- this.mtime = apiModelStats.mtime;
- this.birthtime = apiModelStats.birthtime;
- this.mode = apiModelStats.mode;
- this.nlink = apiModelStats.nlink;
- this.type = apiModelStats.type;
- if (path) {
- this.setPath(path);
- }
- }
-
- WfsStats.prorotype = {
- get isFile() { return (this.type === 'FILE'); },
- get isDirectory() { return (this.type === 'DIRECTORY'); },
- get isBlockDevice() { return (this.type === 'BLOCK_DEVICE'); },
- get isCharacterDevice() { return (this.type === 'CHARACTER_DEVICE'); },
- get isSymbolicLink() { return (this.type === 'LINK'); },
- get isFIFO() { return (this.type === 'FIFO'); },
- get isSocket() { return (this.type === 'SOCKET'); },
-
- setPath : function setPath(value) {
- this.path = value;
- this.name = value ? value.split('/').pop() : undefined;
- }
- };
-
- WfsStats.createFakeStats = function createFakeStats(timestamp, data) {
- var ret = new WfsStats({
- size : data.size || data.length || -1,
- mtime : timestamp,
- birthtime : timestamp,
- mode: '',
- nlink : 0,
- type: 'FILE'
- });
- return ret;
- };
-
- return WfsStats;
-});
\ No newline at end of file
diff --git a/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js b/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
deleted file mode 100644
index d4003f60..00000000
--- a/common/src/webida/server-api-0.1-lib/wfs/wfs-utils.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file wfs-utils.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-define([
- 'URIjs'
-], function (
- URI
-) {
- 'use strict';
-
- var internals = {
- createWfsUrl : function createWfsUrl(parsed) {
- var tmpUri = new URI('').protocol('wfs').path(parsed.wfsId + '/' + parsed.wfsPath);
- return tmpUri.toString();
- },
-
- parseLegacyUrl : function parseLegacyUrl(legacyUrl) {
- var uri = new URI(legacyUrl);
- var srcPathSegments = uri.normalize().path(true).split('/').slice(1); // drops heading '/' in path
-
- var wfsId = srcPathSegments[0];
- if (!wfsId) {
- throw new Error('no fsid part in wfs url' + legacyUrl);
- }
-
- var wfsPath = srcPathSegments.slice(1).join('/');
- if (!wfsPath || wfsPath === '/') {
- throw new Error('no path part in wfs url ' + legacyUrl);
- }
-
- // we can drop host of uri, for ide does not access to 'outside' of workspace
- return {
- wfsId: wfsId,
- wfsPath: wfsPath // wfsPath should not have heading '/'
- };
- }
- };
-
- function normalizePath(legacyPath, wfsId) {
- if (typeof(legacyPath) !== 'string' || legacyPath.constructor.name !== 'String' || !legacyPath) {
- throw new Error('wfs url must a truthy string');
- }
- var ret = '';
- if (legacyPath.indexOf('wfs://') !== 0 ) {
- // looks very heavy but normalizing path is not a simple job. believe me.
- var tmpUri = new URI('file:///' + legacyPath);
- ret = tmpUri.normalize().path(true).slice(1);
- } else {
- var parsed = internals.parseLegacyUrl(legacyPath);
- if (parsed.wfsId !== wfsId) {
- ret = internals.createWfsUrl(parsed);
- } else {
- ret = parsed.wfsPath;
- }
- }
- if (ret.length > 0 && ret[length-1] === '/') {
- ret = ret.slice(0,-1);
- }
- return ret;
- }
-
- // expected examples)
- // '/' || '' => [] (has no ancestors)
- // 'aaa' => [''] (has no ancestors in relative form)
- // 'aaa/bbb' => ['aaa']
- // 'aaa/bbb/ccc' || 'aaa/bbb/ccc/' => ['aaa/bbb', 'aaa']
- // '/aaa/bbb/ccc' || '/aaa/bbb/ccc/' => [ '/aaa/bbb', '/aaa', '/' ]
- // options {
- // includeSelf: true to include path itself
- // includeRoot: true to include '/' or '' in result
- function getAncestors(path, opts) {
- var options = opts || {includeSelf:true};
-
- if (path === '/' || path === '' ) {
- return options.includeSelf? [path] : [];
- }
-
- var isAbsolute = path[0] === '/';
- var ret = [];
- var segments = path.split('/');
- var p = '';
-
- // removes tailing / side effects
- if (segments.length > 1 && segments[segments.length-1] === '') {
- segments.pop();
- }
-
- while(segments.length >= 1) {
- if (options.includeSelf) {
- p = segments.join('/');
- segments.pop();
- } else {
- segments.pop();
- p = segments.join('/');
- }
- if (p) {
- ret.push(p);
- }
- }
- if (options.includeRoot) {
- ret.push(isAbsolute? '/' : '');
- }
- return ret;
- }
-
- return {
- normalizePath : normalizePath,
- getAncestors : getAncestors
- };
-});
diff --git a/common/src/webida/server-api-0.1-lib/workspace-service.js b/common/src/webida/server-api-0.1-lib/workspace-service.js
deleted file mode 100644
index e186f9d9..00000000
--- a/common/src/webida/server-api-0.1-lib/workspace-service.js
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @file workspace-service.js
- * @since 1.7.0
- * @author jh1977.kim@samsung.com
- */
-
-// we don't want cyclic dependencies between common and TokenManager.
-// so, instead of requiring just ./common, we require all dependencies directly
-// the only instance of TokenManager is saved in common
-define([
- 'external/eventEmitter/EventEmitter',
- 'external/lodash/lodash.min',
- 'webida-lib/util/genetic',
- './common',
- './session',
-], function (
- EventEmitter,
- _,
- genetic,
- common,
- session
-) {
- 'use strict';
-
- var logger = common.logger;
- var workspaceApi = new common.api.WorkspaceApi();
-
- // workspace service can be 'management' service & 'exec' service
- // exec service need 'connected session' & current workspace data (init)
-
- // while mgmt service does not
- function WorkspaceService() {
- EventEmitter.call(this);
- this._workspace = null;
- }
-
- genetic.inherits(WorkspaceService, EventEmitter, {
-
- _update : function _update(model) {
- var newWorkspace = _.assign({}, model);
- this._workspace = newWorkspace;
- },
-
- isAvailable: function wsIsAvailable() {
- return session.isConnected && this._workspace;
- },
-
- getWorkspace: function getWorkspace() {
- return this._workspace;
- },
-
- // TODO : wrap some workspaceApi operations
- // findProcs, cancel, update
-
- // workspace-management service
- // create, find, update, delete operations should be available when service is not available
-
- exec : function wsExec(execution, async, callback) {
- try {
- if (!this.isAvailable()) {
- throw new Error ('workspace service is not available- not initialized or lost session');
- }
- var myself = this;
- var cws = this.getWorkspace();
- workspaceApi.exec(cws.id, execution, { async: async }, function(err, result) {
- myself._invokeCallback('exec', callback, err, result);
- });
- } catch(e) {
- this._invokeCallback('exec', callback, e);
- }
- },
-
- _invokeCallback: function _invokeCallback(apiName, callback, err, result) {
- try {
- callback(err, result);
- } catch(e) {
- logger.warn('Callback of WorkspaceService#' + apiName + '() threw error', e);
- }
- }
- });
-
- var workspaceService = new WorkspaceService();
-
- // we can start working when session is connected
- session.on('connect', function() {
- workspaceApi.findWorkspaces(common.bootArgs.workspaceId, { },
- function handleFoundWorkspace(err, result) {
- if (err) {
- logger.error('cannot find workspace from server', err);
- workspaceService.emit('error');
- return;
- }
- logger.debug('workspace service found current workspace', result[0]);
- workspaceService._update(result[0]);
- workspaceService.emit('available');
- logger.debug('workspace service started', workspaceService);
- }
- );
- });
-
- session.on('disconnect', function() {
- logger.debug('workspace service stops');
- workspaceService.emit('unavailable');
- });
-
- return workspaceService;
-});
diff --git a/common/src/webida/server-api-0.1.js b/common/src/webida/server-api-0.1.js
deleted file mode 100644
index b810b55c..00000000
--- a/common/src/webida/server-api-0.1.js
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (c) 2012-2016 S-Core Co., Ltd.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-/**
-* @fileOverview Webida Server API binding library for Webida 1.x client
-*
-* This module implements some sub-set of webida-0.3.js with new webida service api spec.
-* @module server-api
-* @version 0.1
-*/
-
-define([
- './server-api-0.1-lib/common',
- './server-api-0.1-lib/auth',
- './server-api-0.1-lib/fs',
- './server-api-0.1-lib/messaging',
- './server-api-0.1-lib/session',
- './server-api-0.1-lib/workspace-service'
-], function (
- common,
- auth,
- fs,
- messaging,
- session,
- workspaceService
-) {
- 'use strict';
-
- var mod = {
- VERSION: '0.1',
- auth : auth,
- fs : fs,
-
- // incompatible properties, which webida-0.3.js does not have
- messaging: messaging,
- info : {
- serverUrl : common.serverUrl,
- serverUri : common.serverUri,
- get accessToken() {
- return common.tokenManager.accessToken;
- },
- get sessionId() {
- if (common.tokenManager.accessToken) {
- return common.tokenManager.accessToken.sessionId;
- }
- }
- },
- session : session,
- // TODO: impl sessionService
- workspaceService: workspaceService,
-
- // for compatibility with plugin who are dependent to webida-0.3.js conf object
- conf : {
- fsServer : common.serverUrl,
- connServer: common.serverUrl,
- fsApiBaseUrl: common.serverUrl + '/api/wfs'
- },
-
- // for compatibility with current plugin manager
- // - should be removed in next version (0.2 and later)
- // - PM should should decide which plugin catalog to load by itself
- // via window.__ELECTRON_BROWSER__ variable
- // - PM should not load .user_info/plugin-settings.json file directly
- // while initializing
- // - PM should use not use per-user or per-workspace setting to know
- // disabled plugins, for the plugin structure is fixed per apps.
- // - there should be way to hook catalog data for ide & plugin developers
-
- getPluginSettingsPath : function(callback) {
- // plugin-settings-desktop.json : to use embedded server from desktop
- // plugin-settings.json : to use legacy server from desktop/browser (0.1)
- // to connect remote server from desktop/browser (0.2~)
- // plugin-settings-legacy: to connect legacy server from desktop/browser (0.2~)
-
- if(common.bootArgs.legacy) {
- return callback('plugins/plugin-setting.json');
- } else {
- return callback('plugins/plugin-settings-desktop.json');
- }
- }
- };
-
- // for debugging purpose only, in debugger js console.
-
- // TODO : add bootArgs.debug
- // - debugging mode should be customizable in runtime, not build time.
- // - debugging mode will change Logger's singleton logger debugging level, too.
- // in production mode, log level of logger should adjusted to 'error' or 'off'
- // every new Logger() instance will respect global log level.
-
- window.__webida = mod;
- mod.common = common;
-
- return mod;
-});
diff --git a/common/src/webida/server-pubsub-0.1.js b/common/src/webida/server-pubsub-compat.js
similarity index 100%
rename from common/src/webida/server-pubsub-0.1.js
rename to common/src/webida/server-pubsub-compat.js
diff --git a/common/src/webida/util/loadCSSList.js b/common/src/webida/util/loadCSSList.js
index 86b4e781..e1010348 100644
--- a/common/src/webida/util/loadCSSList.js
+++ b/common/src/webida/util/loadCSSList.js
@@ -39,7 +39,7 @@ define([
function checkDone(doneItems) {
return function () {
_.each(doneItems, function (newDone) {
- if (_.contains(loadedItems, newDone)) {
+ if (_.includes(loadedItems, newDone)) {
notify.error('Not good ' + newDone + ' in ' + loadedItems);
} else {
loadedItems.push(newDone);
@@ -47,9 +47,9 @@ define([
});
_.each(doneItems, function (newDone) {
_.each(deferredDones[newDone], function (listener) {
- if (!_.contains(processedDones, listener.id)) {
+ if (!_.includes(processedDones, listener.id)) {
var containsAll = _.every(listener.neededs, function (x) {
- return _.contains(loadedItems, x);
+ return _.includes(loadedItems, x);
});
if (containsAll) {
processedDones.push(listener.id);
@@ -111,7 +111,7 @@ define([
});
var toLoad = _.filter(items, function (x) {
- return !_.contains(loadedItems, x) && !_.contains(loadingItems, x);
+ return !_.includes(loadedItems, x) && !_.includes(loadingItems, x);
});
if (toLoad.length > 0) {
loadingItems = loadingItems.concat(toLoad);
From 46b38ebebbfdea12deb58b0bf4f3236c71fcc03b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Thu, 28 Jul 2016 19:47:06 +0900
Subject: [PATCH 14/15] updated webida-service-client version
---
bower.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/bower.json b/bower.json
index 1cb46989..6037fbbb 100644
--- a/bower.json
+++ b/bower.json
@@ -32,7 +32,7 @@
"tern": "webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
"toastr": "~2.1.1",
"URIjs": "~1.18.1",
- "webida-service-client": "webida/webida-service-client#~0.7.1",
+ "webida-service-client": "webida/webida-service-client#~0.7.2",
"xstyle": "~0.3.1"
}
}
\ No newline at end of file
From 8fc0bb2e728eda9bce1d0ccb1899d428d191ae1e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=EA=B9=80=EC=A4=91=ED=9B=88?=
Date: Fri, 19 Aug 2016 19:36:04 +0900
Subject: [PATCH 15/15] applied new server event scheme
- fixed some lodash-related bugs on SimplePage
- updated service client to 0.8.1
---
.../plugins/webida.preference/pages/SimplePage.js | 4 ++--
bower.json | 4 ++--
.../plugins/session-event-dispatcher/plugin.js | 14 +++++++++-----
3 files changed, 13 insertions(+), 9 deletions(-)
diff --git a/apps/ide/src/plugins/webida.preference/pages/SimplePage.js b/apps/ide/src/plugins/webida.preference/pages/SimplePage.js
index 1bce5f95..0b8eada8 100644
--- a/apps/ide/src/plugins/webida.preference/pages/SimplePage.js
+++ b/apps/ide/src/plugins/webida.preference/pages/SimplePage.js
@@ -194,7 +194,7 @@ define([
});
var currentId = value;
- var currentValue = _.findWhere(dataSource, {id: currentId});
+ var currentValue = _.find(dataSource, {id: currentId});
if (currentValue) {
currentValue = currentValue.name;
} else {
@@ -210,7 +210,7 @@ define([
maxHeight: 300,
style: 'margin-top: 5px; margin-bottom: 5px; margin-left: 5px;',
onChange: function (value) {
- var item = _.findWhere(dataSource, {name: value});
+ var item = _.find(dataSource, {name: value});
if (item) {
self.store.setValue(key, item.id);
}
diff --git a/bower.json b/bower.json
index 6037fbbb..689b808d 100644
--- a/bower.json
+++ b/bower.json
@@ -32,7 +32,7 @@
"tern": "webida/tern#ab9f92a23d9f8d09071c3549b33ff40dcfb27ed3",
"toastr": "~2.1.1",
"URIjs": "~1.18.1",
- "webida-service-client": "webida/webida-service-client#~0.7.2",
+ "webida-service-client": "webida/webida-service-client#~0.8.1",
"xstyle": "~0.3.1"
}
-}
\ No newline at end of file
+}
diff --git a/common/src/webida/plugins/session-event-dispatcher/plugin.js b/common/src/webida/plugins/session-event-dispatcher/plugin.js
index 75f6dc2b..fd4f15a9 100644
--- a/common/src/webida/plugins/session-event-dispatcher/plugin.js
+++ b/common/src/webida/plugins/session-event-dispatcher/plugin.js
@@ -51,16 +51,20 @@ define([
};
}
- sessionEventSource.on('announcement', dispatchTopic('server/session/announcement'));
- sessionEventSource.on('closing', dispatchTopic('server/session/closing'));
- sessionEventSource.on('connect', dispatchTopic('server/session/'));
+ sessionEventSource.on('session.announcement', dispatchTopic('server/session/announcement'));
+ sessionEventSource.on('session.closing', dispatchTopic('server/session/closing'));
+
+ // following events are defined via socket.io & webida service client api does not change
+ // the event names for readability & simplicity.
+ sessionEventSource.on('connect', dispatchTopic('server/session/connect'));
sessionEventSource.on('disconnect', dispatchTopic('server/session/disconnect'));
sessionEventSource.on('reconnect', dispatchTopic('server/session/reconnect'));
sessionEventSource.on('connect_error', dispatchTopic('server/session/connect/error'));
sessionEventSource.on('connect_timeout', dispatchTopic('server/session/connect/timeout'));
sessionEventSource.on('reconnect_failed', dispatchTopic('server/session/reconnect/failed'));
-
- sessionEventSource.on('wfs', dispatchLegacyResourceTopics);
+
+ // workspace.wfs events come from WfsEventGate, not from server.
+ sessionEventSource.on('workspace.wfs', dispatchLegacyResourceTopics);
// need some 'toasting' plugin for basic session events, but not here.
// for this plugins should work without toaster.