@wxn0brp/db 0.0.5 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/cjs/CollectionManager.d.ts +43 -0
- package/dist/cjs/CollectionManager.js +59 -0
- package/dist/cjs/action.d.ts +71 -0
- package/dist/cjs/action.js +199 -0
- package/dist/cjs/database.d.ts +77 -0
- package/dist/cjs/database.js +118 -0
- package/dist/cjs/executor.d.ts +28 -0
- package/{executor.js → dist/cjs/executor.js} +47 -54
- package/dist/cjs/file/find.d.ts +11 -0
- package/dist/cjs/file/find.js +80 -0
- package/dist/cjs/file/index.d.ts +3 -0
- package/dist/cjs/file/index.js +25 -0
- package/dist/cjs/file/remove.d.ts +7 -0
- package/dist/cjs/file/remove.js +61 -0
- package/dist/cjs/file/update.d.ts +7 -0
- package/dist/cjs/file/update.js +68 -0
- package/dist/cjs/file/utils.d.ts +8 -0
- package/dist/cjs/file/utils.js +23 -0
- package/dist/cjs/format.d.ts +18 -0
- package/dist/cjs/format.js +36 -0
- package/dist/cjs/gen.d.ts +5 -0
- package/dist/cjs/gen.js +78 -0
- package/dist/cjs/graph.d.ts +47 -0
- package/dist/cjs/graph.js +90 -0
- package/{index.d.ts → dist/cjs/index.d.ts} +2 -2
- package/dist/cjs/index.js +18 -0
- package/dist/cjs/relation.d.ts +64 -0
- package/{relation.js → dist/cjs/relation.js} +26 -45
- package/dist/cjs/remote/client/database.d.ts +71 -0
- package/dist/cjs/remote/client/database.js +145 -0
- package/dist/cjs/remote/client/function.d.ts +5 -0
- package/dist/cjs/remote/client/function.js +32 -0
- package/dist/cjs/remote/client/graph.d.ts +54 -0
- package/dist/cjs/remote/client/graph.js +93 -0
- package/dist/cjs/remote/client/remote.d.ts +16 -0
- package/dist/cjs/remote/client/remote.js +2 -0
- package/dist/cjs/remote/server/auth.d.ts +31 -0
- package/dist/cjs/remote/server/auth.js +99 -0
- package/dist/cjs/remote/server/db.d.ts +2 -0
- package/dist/cjs/remote/server/db.js +223 -0
- package/dist/cjs/remote/server/function.d.ts +2 -0
- package/dist/cjs/remote/server/function.js +89 -0
- package/dist/cjs/remote/server/graph.d.ts +2 -0
- package/dist/cjs/remote/server/graph.js +145 -0
- package/dist/cjs/remote/server/index.d.ts +1 -0
- package/dist/cjs/remote/server/index.js +66 -0
- package/dist/cjs/remote/server/initDataBases.d.ts +1 -0
- package/dist/cjs/remote/server/initDataBases.js +25 -0
- package/dist/cjs/remote/server/pathUtils.d.ts +1 -0
- package/dist/cjs/remote/server/pathUtils.js +12 -0
- package/dist/cjs/remote/server/secret.d.ts +1 -0
- package/dist/cjs/remote/server/secret.js +25 -0
- package/dist/cjs/remote/serverMgmt/index.d.ts +1 -0
- package/dist/cjs/remote/serverMgmt/index.js +87 -0
- package/dist/cjs/types/Id.d.ts +3 -0
- package/dist/cjs/types/Id.js +2 -0
- package/dist/cjs/types/arg.d.ts +6 -0
- package/dist/cjs/types/arg.js +2 -0
- package/dist/cjs/types/data.d.ts +4 -0
- package/dist/cjs/types/data.js +2 -0
- package/dist/cjs/types/options.d.ts +12 -0
- package/dist/cjs/types/options.js +2 -0
- package/dist/cjs/types/searchOpts.d.ts +61 -0
- package/dist/cjs/types/searchOpts.js +8 -0
- package/dist/cjs/types/types.d.ts +6 -0
- package/dist/cjs/types/types.js +2 -0
- package/dist/cjs/utils/hasFields.d.ts +8 -0
- package/dist/cjs/utils/hasFields.js +22 -0
- package/dist/cjs/utils/hasFieldsAdvanced.d.ts +5 -0
- package/dist/cjs/utils/hasFieldsAdvanced.js +182 -0
- package/dist/cjs/utils/updateFindObject.d.ts +11 -0
- package/dist/cjs/utils/updateFindObject.js +32 -0
- package/dist/cjs/utils/updateObject.d.ts +8 -0
- package/dist/cjs/utils/updateObject.js +18 -0
- package/dist/esm/CollectionManager.d.ts +43 -0
- package/dist/esm/CollectionManager.js +57 -0
- package/dist/esm/action.d.ts +71 -0
- package/dist/esm/action.js +194 -0
- package/dist/esm/database.d.ts +77 -0
- package/dist/esm/database.js +113 -0
- package/dist/esm/executor.d.ts +28 -0
- package/dist/esm/executor.js +45 -0
- package/dist/esm/file/find.d.ts +11 -0
- package/dist/esm/file/find.js +73 -0
- package/dist/esm/file/index.d.ts +3 -0
- package/{file → dist/esm/file}/index.js +1 -1
- package/dist/esm/file/remove.d.ts +7 -0
- package/dist/esm/file/remove.js +56 -0
- package/dist/esm/file/update.d.ts +7 -0
- package/dist/esm/file/update.js +63 -0
- package/dist/esm/file/utils.d.ts +8 -0
- package/{file → dist/esm/file}/utils.js +3 -11
- package/dist/esm/format.d.ts +18 -0
- package/{format.js → dist/esm/format.js} +29 -29
- package/dist/esm/gen.d.ts +5 -0
- package/dist/esm/gen.js +75 -0
- package/dist/esm/graph.d.ts +47 -0
- package/dist/esm/graph.js +85 -0
- package/dist/esm/index.d.ts +7 -0
- package/{index.js → dist/esm/index.js} +1 -9
- package/dist/esm/relation.d.ts +64 -0
- package/dist/esm/relation.js +65 -0
- package/dist/esm/remote/client/database.d.ts +71 -0
- package/dist/esm/remote/client/database.js +140 -0
- package/dist/esm/remote/client/function.d.ts +5 -0
- package/dist/esm/remote/client/function.js +30 -0
- package/dist/esm/remote/client/graph.d.ts +54 -0
- package/dist/esm/remote/client/graph.js +88 -0
- package/dist/esm/remote/client/remote.d.ts +16 -0
- package/dist/esm/remote/client/remote.js +1 -0
- package/dist/esm/remote/server/auth.d.ts +31 -0
- package/{remote → dist/esm/remote}/server/auth.js +31 -44
- package/dist/esm/remote/server/db.d.ts +2 -0
- package/dist/esm/remote/server/db.js +218 -0
- package/dist/esm/remote/server/function.d.ts +2 -0
- package/dist/esm/remote/server/function.js +87 -0
- package/dist/esm/remote/server/graph.d.ts +2 -0
- package/{remote → dist/esm/remote}/server/graph.js +62 -55
- package/dist/esm/remote/server/gui/css/main.css +130 -0
- package/dist/esm/remote/server/gui/css/scrool.css +81 -0
- package/dist/esm/remote/server/gui/css/style.css +61 -0
- package/dist/esm/remote/server/gui/favicon.svg +12 -0
- package/dist/esm/remote/server/gui/html/data.html +15 -0
- package/dist/esm/remote/server/gui/html/main.html +46 -0
- package/dist/esm/remote/server/gui/html/nav.html +25 -0
- package/dist/esm/remote/server/gui/html/popup.html +51 -0
- package/dist/esm/remote/server/gui/index.html +49 -0
- package/dist/esm/remote/server/gui/js/api.js +166 -0
- package/dist/esm/remote/server/gui/js/index.js +17 -0
- package/dist/esm/remote/server/gui/js/loadHTML.js +16 -0
- package/dist/esm/remote/server/gui/js/popUp.js +72 -0
- package/dist/esm/remote/server/gui/js/queryApi.js +51 -0
- package/dist/esm/remote/server/gui/js/queryDb.js +79 -0
- package/dist/esm/remote/server/gui/js/queryGraph.js +144 -0
- package/dist/esm/remote/server/gui/js/render.js +64 -0
- package/dist/esm/remote/server/gui/js/templates.js +31 -0
- package/dist/esm/remote/server/gui/js/utils.js +36 -0
- package/dist/esm/remote/server/gui/js/vars.js +9 -0
- package/dist/esm/remote/server/gui/libs/core.js +176 -0
- package/dist/esm/remote/server/gui/libs/d3.v7.min.js +2 -0
- package/dist/esm/remote/server/gui/libs/handlebars.min.js +29 -0
- package/dist/esm/remote/server/gui/libs/json5.min.js +1 -0
- package/dist/esm/remote/server/index.d.ts +1 -0
- package/dist/esm/remote/server/index.js +61 -0
- package/dist/esm/remote/server/initDataBases.d.ts +1 -0
- package/dist/esm/remote/server/initDataBases.js +20 -0
- package/dist/esm/remote/server/pathUtils.d.ts +1 -0
- package/{remote → dist/esm/remote}/server/pathUtils.js +2 -3
- package/dist/esm/remote/server/secret.d.ts +1 -0
- package/{remote → dist/esm/remote}/server/secret.js +3 -7
- package/dist/esm/remote/serverMgmt/index.d.ts +1 -0
- package/{remote → dist/esm/remote}/serverMgmt/index.js +27 -31
- package/dist/esm/types/Id.d.ts +3 -0
- package/dist/esm/types/Id.js +1 -0
- package/dist/esm/types/arg.d.ts +6 -0
- package/dist/esm/types/arg.js +1 -0
- package/dist/esm/types/data.d.ts +4 -0
- package/dist/esm/types/data.js +1 -0
- package/dist/esm/types/options.d.ts +12 -0
- package/dist/esm/types/options.js +1 -0
- package/dist/esm/types/searchOpts.d.ts +61 -0
- package/dist/esm/types/searchOpts.js +7 -0
- package/dist/esm/types/types.d.ts +6 -0
- package/dist/esm/types/types.js +1 -0
- package/dist/esm/utils/hasFields.d.ts +8 -0
- package/{utils → dist/esm/utils}/hasFields.js +4 -4
- package/dist/esm/utils/hasFieldsAdvanced.d.ts +5 -0
- package/dist/esm/utils/hasFieldsAdvanced.js +176 -0
- package/dist/esm/utils/updateFindObject.d.ts +11 -0
- package/{utils → dist/esm/utils}/updateFindObject.js +11 -16
- package/dist/esm/utils/updateObject.d.ts +8 -0
- package/{utils → dist/esm/utils}/updateObject.js +4 -4
- package/package.json +55 -36
- package/CollectionManager.js +0 -119
- package/action.js +0 -258
- package/database.d.ts +0 -44
- package/database.js +0 -203
- package/docs/database.md +0 -140
- package/docs/graph.md +0 -86
- package/docs/relation.md +0 -51
- package/docs/remote.md +0 -30
- package/docs/remote_server.md +0 -35
- package/docs/search_opts.md +0 -227
- package/file/find.js +0 -89
- package/file/remove.js +0 -74
- package/file/update.js +0 -83
- package/gen.d.ts +0 -1
- package/gen.js +0 -97
- package/graph.d.ts +0 -27
- package/graph.js +0 -140
- package/relation.d.ts +0 -23
- package/remote/client/database.d.ts +0 -41
- package/remote/client/database.js +0 -228
- package/remote/client/graph.d.ts +0 -31
- package/remote/client/graph.js +0 -148
- package/remote/server/db.js +0 -197
- package/remote/server/function.js +0 -43
- package/remote/server/index.js +0 -63
- package/remote/server/initDataBases.js +0 -20
- package/test/hasFieldsAdvanced.test.js +0 -70
- package/utils/hasFieldsAdvanced.js +0 -184
- /package/{remote → dist/cjs/remote}/server/gui/css/main.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/css/scrool.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/css/style.css +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/favicon.svg +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/data.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/main.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/nav.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/html/popup.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/index.html +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/api.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/index.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/loadHTML.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/popUp.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryApi.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryDb.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/queryGraph.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/render.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/templates.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/utils.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/js/vars.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/core.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/d3.v7.min.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/handlebars.min.js +0 -0
- /package/{remote → dist/cjs/remote}/server/gui/libs/json5.min.js +0 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script type="text/x-handlebars-template" id="databases-list-template">
|
|
2
|
+
{{#each serversList}}
|
|
3
|
+
<li>
|
|
4
|
+
<h2>{{this.name}}</h2>
|
|
5
|
+
<ul id="database-nav-{{this.id}}" class="database-nav"></ul>
|
|
6
|
+
</li>
|
|
7
|
+
{{/each}}
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<script type="text/x-handlebars-template" id="database-nav-template">
|
|
11
|
+
{{#each dbs}}
|
|
12
|
+
<li onclick="renderFunc.renderTables('{{this.serverId}}', '{{this.name}}')">
|
|
13
|
+
<details>
|
|
14
|
+
<summary class="selectMeta">{{this.name}}</summary>
|
|
15
|
+
<ul id="database-nav-{{this.serverId}}-{{this.name}}" class="database-nav-meta"></ul>
|
|
16
|
+
</details>
|
|
17
|
+
</li>
|
|
18
|
+
{{/each}}
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<script type="text/x-handlebars-template" id="databases-tables-template">
|
|
22
|
+
{{#each tables}}
|
|
23
|
+
<li class="selectMeta" onclick="event.stopPropagation();selectTable('{{../server}}','{{../db}}','{{this}}')">{{this}}</li>
|
|
24
|
+
{{/each}}
|
|
25
|
+
</script>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script id="addServer-template" type="text/x-handlebars-template">
|
|
2
|
+
<h2>Add Server</h2>
|
|
3
|
+
<label>
|
|
4
|
+
<span>Name:</span>
|
|
5
|
+
<input type="text" id="name">
|
|
6
|
+
</label>
|
|
7
|
+
{{br 10}}
|
|
8
|
+
<label>
|
|
9
|
+
<span>Url:</span>
|
|
10
|
+
<input type="text" id="url">
|
|
11
|
+
</label>
|
|
12
|
+
{{br 10}}
|
|
13
|
+
<label>
|
|
14
|
+
<span>Login:</span>
|
|
15
|
+
<input type="text" id="login">
|
|
16
|
+
</label>
|
|
17
|
+
{{br 10}}
|
|
18
|
+
<label>
|
|
19
|
+
<span>Password:</span>
|
|
20
|
+
<input type="password" id="pass">
|
|
21
|
+
</label>
|
|
22
|
+
{{br 10}}
|
|
23
|
+
<div style="display: flex; justify-content: space-around; width: 50%; min-width: 200px; margin: auto;">
|
|
24
|
+
<button id="login-btn">Login</button>
|
|
25
|
+
<button id="cancel-btn">Cancel</button>
|
|
26
|
+
</div>
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<script id="menageServers-template" type="text/x-handlebars-template">
|
|
30
|
+
<h2>Manage Servers</h2>
|
|
31
|
+
<button onclick="popupFunc.showAddServer()">Add Server</button>
|
|
32
|
+
{{br 10}}
|
|
33
|
+
{{#each serversList}}
|
|
34
|
+
<div>
|
|
35
|
+
<div>Name: {{this.name}}</div>
|
|
36
|
+
<div>URL: {{this.url}}</div>
|
|
37
|
+
<div>Login: {{this.login}}</div>
|
|
38
|
+
{{br 3}}
|
|
39
|
+
<button id="menageServers__{{this.id}}" onclick="menageServers.toggleServer('{{this.id}}', '{{this.name}}', '{{this.url}}')">
|
|
40
|
+
{{#if this.saved}}Remove from saved
|
|
41
|
+
{{else}}Add to saved
|
|
42
|
+
{{/if}}
|
|
43
|
+
</button>
|
|
44
|
+
</div>
|
|
45
|
+
{{br 10}}
|
|
46
|
+
<hr>
|
|
47
|
+
{{br 10}}
|
|
48
|
+
{{/each}}
|
|
49
|
+
{{br 10}}
|
|
50
|
+
<button id="cancel-btn">Close</button>
|
|
51
|
+
</script>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>wxn0brP database gui</title>
|
|
7
|
+
<link rel="stylesheet" href="css/style.css">
|
|
8
|
+
<link rel="stylesheet" href="css/main.css">
|
|
9
|
+
<link rel="shortcut icon" href="favicon.svg" type="image/x-icon">
|
|
10
|
+
</head>
|
|
11
|
+
<body>
|
|
12
|
+
<noscript>This page require JS to work</noscript>
|
|
13
|
+
<div id="app">
|
|
14
|
+
<span id="nav__toggle">☰</span>
|
|
15
|
+
<div id="popUpContainer"></div>
|
|
16
|
+
<nav style="left: 0px">
|
|
17
|
+
Selected:
|
|
18
|
+
<br />
|
|
19
|
+
<span id="selected-server"></span>
|
|
20
|
+
<br />
|
|
21
|
+
<span id="selected-database"></span>
|
|
22
|
+
<br />
|
|
23
|
+
<span id="selected-table"></span>
|
|
24
|
+
<br />
|
|
25
|
+
<br />
|
|
26
|
+
<button onclick="popupFunc.showMgmtServers()">Mengage Server</button>
|
|
27
|
+
<ul id="database-server-list"></ul>
|
|
28
|
+
</nav>
|
|
29
|
+
</div>
|
|
30
|
+
<div id="templates" style="display: none;"></div>
|
|
31
|
+
|
|
32
|
+
<script src="libs/core.js"></script>
|
|
33
|
+
<script src="libs/handlebars.min.js"></script>
|
|
34
|
+
<script src="libs/json5.min.js"></script>
|
|
35
|
+
<script src="libs/d3.v7.min.js"></script>
|
|
36
|
+
|
|
37
|
+
<script src="js/loadHTML.js"></script>
|
|
38
|
+
<script src="js/vars.js"></script>
|
|
39
|
+
<script src="js/utils.js"></script>
|
|
40
|
+
<script src="js/templates.js"></script>
|
|
41
|
+
<script src="js/api.js"></script>
|
|
42
|
+
<script src="js/popUp.js"></script>
|
|
43
|
+
<script src="js/render.js"></script>
|
|
44
|
+
<script src="js/queryApi.js"></script>
|
|
45
|
+
<script src="js/queryDb.js"></script>
|
|
46
|
+
<script src="js/queryGraph.js"></script>
|
|
47
|
+
<script src="js/index.js"></script>
|
|
48
|
+
</body>
|
|
49
|
+
</html>
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const databaseGetMetaFunc = {
|
|
2
|
+
async loadDbList(serverId){
|
|
3
|
+
const server = serversMeta[serverId];
|
|
4
|
+
if(!server) return;
|
|
5
|
+
const res = await fetch(server.url + "getDbList", {
|
|
6
|
+
method: "POST",
|
|
7
|
+
headers: {
|
|
8
|
+
"Content-Type": "application/json",
|
|
9
|
+
"Authorization": server.token
|
|
10
|
+
},
|
|
11
|
+
}).then(res => res.json());
|
|
12
|
+
|
|
13
|
+
if(res.err){
|
|
14
|
+
alert(res.msg);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
serversData[serverId] = {};
|
|
18
|
+
const dbObj = serversData[serverId];
|
|
19
|
+
res.result.forEach(db => {
|
|
20
|
+
dbObj[db.name] = {
|
|
21
|
+
collections: [],
|
|
22
|
+
type: db.type
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
return dbObj;
|
|
26
|
+
},
|
|
27
|
+
|
|
28
|
+
async loginToDb(serverUrl, serverName, login, password){
|
|
29
|
+
if(!serverUrl.endsWith("/")) serverUrl += "/";
|
|
30
|
+
const res = await fetch(serverUrl + "login", {
|
|
31
|
+
method: "POST",
|
|
32
|
+
headers: {
|
|
33
|
+
"Content-Type": "application/json"
|
|
34
|
+
},
|
|
35
|
+
body: JSON.stringify({ login, password })
|
|
36
|
+
}).then(res => res.json());
|
|
37
|
+
if(res.err){
|
|
38
|
+
alert(res.msg);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const id = Object.keys(serversMeta).length + 1;
|
|
43
|
+
serversMeta[id] = {
|
|
44
|
+
url: serverUrl,
|
|
45
|
+
token: res.token,
|
|
46
|
+
name: serverName,
|
|
47
|
+
login
|
|
48
|
+
}
|
|
49
|
+
return id;
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
async getDbTables(serverId, dbName){
|
|
53
|
+
const server = serversMeta[serverId];
|
|
54
|
+
if(!server) return;
|
|
55
|
+
|
|
56
|
+
const res = await fetch(server.url + "db/" + getSelectedDatabase().type + "/getCollections", {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
"Authorization": server.token
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({ db: dbName })
|
|
63
|
+
}).then(res => res.json());
|
|
64
|
+
if(res.err){
|
|
65
|
+
alert(res.msg);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
serversData[serverId][dbName].collections = res.result;
|
|
70
|
+
return res.result;
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
getAll(){
|
|
74
|
+
const out = [];
|
|
75
|
+
Object.keys(serversMeta).forEach(id => {
|
|
76
|
+
const server = serversMeta[id];
|
|
77
|
+
out.push({
|
|
78
|
+
id,
|
|
79
|
+
name: server.name,
|
|
80
|
+
saved: server.saved,
|
|
81
|
+
url: server.url,
|
|
82
|
+
login: server.login,
|
|
83
|
+
})
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
const savedServers = JSON.parse(localStorage.getItem("servers") || "[]");
|
|
87
|
+
savedServers.forEach(server => {
|
|
88
|
+
if(out.find(s => s.name == server.name)) return;
|
|
89
|
+
out.push({
|
|
90
|
+
id: -1,
|
|
91
|
+
name: server.name,
|
|
92
|
+
url: server.url,
|
|
93
|
+
saved: true,
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const storageControler = {
|
|
102
|
+
addServerStorage(id){
|
|
103
|
+
let servers = JSON.parse(localStorage.getItem("servers") || "[]");
|
|
104
|
+
const server = serversMeta[id];
|
|
105
|
+
if(!server.url.endsWith("/")) server.url += "/";
|
|
106
|
+
servers.push({
|
|
107
|
+
name: server.name,
|
|
108
|
+
url: server.url,
|
|
109
|
+
});
|
|
110
|
+
servers.sort((a, b) => a.name.localeCompare(b.name));
|
|
111
|
+
localStorage.setItem("servers", JSON.stringify(servers));
|
|
112
|
+
},
|
|
113
|
+
|
|
114
|
+
removeServerStorage(serverId, serverData=null){
|
|
115
|
+
let servers = JSON.parse(localStorage.getItem("servers"));
|
|
116
|
+
if(!servers) servers = [];
|
|
117
|
+
const server = serverData || serversMeta[serverId];
|
|
118
|
+
server.saved = false;
|
|
119
|
+
|
|
120
|
+
const index = servers.findIndex(({ name, url }) => name == server.name && url == server.url);
|
|
121
|
+
if(index > -1) servers.splice(index, 1);
|
|
122
|
+
|
|
123
|
+
localStorage.setItem("servers", JSON.stringify(servers));
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
async getServersFromStorage(){
|
|
127
|
+
let servers = JSON.parse(localStorage.getItem("servers"));
|
|
128
|
+
if(!servers) return;
|
|
129
|
+
|
|
130
|
+
for(let server of servers){
|
|
131
|
+
const serverId = await popupFunc.addServer(server);
|
|
132
|
+
if(serverId){
|
|
133
|
+
serversMeta[serverId].saved = true;
|
|
134
|
+
}
|
|
135
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
136
|
+
}
|
|
137
|
+
renderFunc.renderServerList();
|
|
138
|
+
},
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const menageServers = {
|
|
142
|
+
toggleServer(id, name="", url=""){
|
|
143
|
+
let server = serversMeta[id];
|
|
144
|
+
if(!server){
|
|
145
|
+
if(id != -1) return;
|
|
146
|
+
const servers = JSON.parse(localStorage.getItem("servers") || "[]");
|
|
147
|
+
if(!servers) return;
|
|
148
|
+
storageControler.removeServerStorage(-1, { name, url });
|
|
149
|
+
document.querySelector("#popUpContainer #menageServers #cancel-btn").click();
|
|
150
|
+
setTimeout(() => {
|
|
151
|
+
popupFunc.showMgmtServers();
|
|
152
|
+
}, 1000);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
if(server.saved){
|
|
157
|
+
storageControler.removeServerStorage(id);
|
|
158
|
+
server.saved = false;
|
|
159
|
+
document.querySelector("#menageServers__" + id).innerHTML = "Add to saved";
|
|
160
|
+
}else{
|
|
161
|
+
storageControler.addServerStorage(id);
|
|
162
|
+
server.saved = true;
|
|
163
|
+
document.querySelector("#menageServers__" + id).innerHTML = "Remove from saved";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const navPos = document.querySelector("nav");
|
|
2
|
+
|
|
3
|
+
function selectTable(server, db, table){
|
|
4
|
+
vars.selectedServer = server;
|
|
5
|
+
vars.selectedDb = db;
|
|
6
|
+
vars.selectedTable = table;
|
|
7
|
+
renderFunc.updateQueryStyle();
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
new AutoUpdater(vars, "selectedServer", "#selected-server", data => data ? serversMeta[data]?.name + " >" : "-");
|
|
11
|
+
new AutoUpdater(vars, "selectedDb", "#selected-database", data => data ? data + " >" : "-");
|
|
12
|
+
new AutoUpdater(vars, "selectedTable", "#selected-table", data => data ? data : "-");
|
|
13
|
+
|
|
14
|
+
document.querySelector("#nav__toggle").addEventListener("click", () => {
|
|
15
|
+
navPos.style.left = navPos.style.left == "0px" ? "-" +navPos.clientWidth + "px" : "0px";
|
|
16
|
+
});
|
|
17
|
+
storageControler.getServersFromStorage().then(renderFunc.renderServerList);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
function loadHTML(){
|
|
2
|
+
const templateDiv = document.querySelector("#templates");
|
|
3
|
+
const appDiv = document.querySelector("#app");
|
|
4
|
+
[
|
|
5
|
+
"data",
|
|
6
|
+
"nav",
|
|
7
|
+
"popup",
|
|
8
|
+
].forEach(file => {
|
|
9
|
+
const html = cw.get(`html/${file}.html`);
|
|
10
|
+
templateDiv.innerHTML += html;
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
appDiv.innerHTML += cw.get("html/main.html");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
loadHTML();
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
const popupDiv = document.querySelector("#popUpContainer");
|
|
2
|
+
|
|
3
|
+
const popupFunc = {
|
|
4
|
+
async addServer(data={}){
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
let { url, name, login, pass } = data;
|
|
7
|
+
const popup = document.createElement("div");
|
|
8
|
+
popup.id = "addServer";
|
|
9
|
+
popup.innerHTML = templates.addServer(data);
|
|
10
|
+
|
|
11
|
+
const urlInput = popup.querySelector("#url");
|
|
12
|
+
const nameInput = popup.querySelector("#name");
|
|
13
|
+
const loginInput = popup.querySelector("#login");
|
|
14
|
+
const passInput = popup.querySelector("#pass");
|
|
15
|
+
urlInput.value = url || "";
|
|
16
|
+
nameInput.value = name || "";
|
|
17
|
+
loginInput.value = login || "";
|
|
18
|
+
passInput.value = pass || "";
|
|
19
|
+
|
|
20
|
+
async function loginFunc(){
|
|
21
|
+
url = urlInput.value;
|
|
22
|
+
name = nameInput.value;
|
|
23
|
+
login = loginInput.value;
|
|
24
|
+
pass = passInput.value;
|
|
25
|
+
if(!url || !name || !login || !pass){
|
|
26
|
+
alert("All fields are required");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
const serverId = await databaseGetMetaFunc.loginToDb(url, name, login, pass);
|
|
30
|
+
if(!serverId) return;
|
|
31
|
+
|
|
32
|
+
resolve(serverId);
|
|
33
|
+
popup.fadeOut(() => popup.remove());
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
popup.querySelector("#login-btn").addEventListener("click", loginFunc);
|
|
37
|
+
passInput.addEventListener("keydown", (e) => {
|
|
38
|
+
if(e.key == "Enter") loginFunc();
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
popup.querySelector("#cancel-btn").addEventListener("click", () => {
|
|
42
|
+
resolve(false);
|
|
43
|
+
popup.fadeOut(() => popup.remove());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
popupDiv.appendChild(popup);
|
|
47
|
+
popup.fadeIn();
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
async showAddServer(){
|
|
52
|
+
const res = await popupFunc.addServer();
|
|
53
|
+
if(!res) return;
|
|
54
|
+
renderFunc.renderServerList();
|
|
55
|
+
document.querySelector("#popUpContainer #menageServers #cancel-btn").click();
|
|
56
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
57
|
+
popupFunc.showMgmtServers();
|
|
58
|
+
},
|
|
59
|
+
|
|
60
|
+
showMgmtServers(){
|
|
61
|
+
const div = document.createElement("div");
|
|
62
|
+
div.id = "menageServers";
|
|
63
|
+
const servers = databaseGetMetaFunc.getAll();
|
|
64
|
+
div.innerHTML = templates.menageServers({ serversList: servers });
|
|
65
|
+
popupDiv.appendChild(div);
|
|
66
|
+
div.fadeIn();
|
|
67
|
+
|
|
68
|
+
div.querySelector("#cancel-btn").addEventListener("click", () => {
|
|
69
|
+
div.fadeOut(() => div.remove());
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const dbActionUtils = {
|
|
2
|
+
async query(data, path){
|
|
3
|
+
if(!vars.selectedServer) return false;
|
|
4
|
+
if(!vars.selectedDb) return false;
|
|
5
|
+
if(!vars.selectedTable) return false;
|
|
6
|
+
|
|
7
|
+
const body = {
|
|
8
|
+
db: vars.selectedDb,
|
|
9
|
+
collection: vars.selectedTable,
|
|
10
|
+
...data
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const server = serversMeta[vars.selectedServer];
|
|
14
|
+
const res = await fetch(server.url + "db/" + path, {
|
|
15
|
+
method: "POST",
|
|
16
|
+
headers: {
|
|
17
|
+
"Content-Type": "application/json",
|
|
18
|
+
"Authorization": server.token
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify(body)
|
|
21
|
+
}).then(res => res.json());
|
|
22
|
+
if(res.err){
|
|
23
|
+
alert(res.msg);
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return res.result;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const dbActions = {
|
|
32
|
+
async find(query, context=undefined, opts=undefined){
|
|
33
|
+
const body = {
|
|
34
|
+
search: query,
|
|
35
|
+
context,
|
|
36
|
+
opts
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return await dbActionUtils.query(body, "database/find");
|
|
40
|
+
},
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const graphActions = {
|
|
44
|
+
async find(node){
|
|
45
|
+
return await dbActionUtils.query({ node }, "graph/find");
|
|
46
|
+
},
|
|
47
|
+
|
|
48
|
+
async getAll(){
|
|
49
|
+
return await dbActionUtils.query({}, "graph/getAll");
|
|
50
|
+
},
|
|
51
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
const queryDbFunc = {
|
|
2
|
+
queryInput: document.querySelector("#query"),
|
|
3
|
+
queryTypeSelect: document.querySelector("#query-type"),
|
|
4
|
+
queryContextInput: document.querySelector("#query-context"),
|
|
5
|
+
queryContextLabel: document.querySelector("#query-context-label"),
|
|
6
|
+
queryOptsInput: document.querySelector("#query-opts"),
|
|
7
|
+
|
|
8
|
+
renderData(){
|
|
9
|
+
if(!db_data || db_data.length == 0){
|
|
10
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
data_output.innerHTML = templates.tableData({ data: db_data });
|
|
14
|
+
},
|
|
15
|
+
|
|
16
|
+
init(){
|
|
17
|
+
document.querySelector("#query-db-btn").addEventListener("click", async () => {
|
|
18
|
+
let query = queryDbFunc.queryInput.value.trim();
|
|
19
|
+
let type = queryDbFunc.queryTypeSelect.value.trim();
|
|
20
|
+
let context = queryDbFunc.queryContextInput.value.trim();
|
|
21
|
+
let opts = queryDbFunc.queryOptsInput.value.trim();
|
|
22
|
+
|
|
23
|
+
if(!query) query = "{}";
|
|
24
|
+
if(!type) type = "json";
|
|
25
|
+
if(!context) context = "{}";
|
|
26
|
+
if(!opts) opts = "{}";
|
|
27
|
+
|
|
28
|
+
switch(type){
|
|
29
|
+
case "js-function":
|
|
30
|
+
try{
|
|
31
|
+
(new Function("return " + query))();
|
|
32
|
+
}catch{
|
|
33
|
+
return alert("Invalid query context");
|
|
34
|
+
}
|
|
35
|
+
break;
|
|
36
|
+
case "json5":
|
|
37
|
+
if(!query.startsWith("{")) query = "{" + query + "}";
|
|
38
|
+
query = JSON5.parse(query);
|
|
39
|
+
break;
|
|
40
|
+
case "json":
|
|
41
|
+
query = JSON.parse(query);
|
|
42
|
+
break;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
context = JSON5.parse(context);
|
|
46
|
+
opts = JSON5.parse(opts);
|
|
47
|
+
if(!context) context = {};
|
|
48
|
+
if(!opts) opts = {};
|
|
49
|
+
|
|
50
|
+
const data = await dbActions.find(query, context, opts);
|
|
51
|
+
if(!data) return;
|
|
52
|
+
db_data = data;
|
|
53
|
+
queryDbFunc.renderData();
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
queryDbFunc.queryTypeSelect.addEventListener("change", () => {
|
|
57
|
+
queryDbFunc.queryContextLabel.style.display = queryTypeSelect.value == "js-function" ? "block" : "none";
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
document.querySelector("#sortData").addEventListener("click", () => {
|
|
61
|
+
const sortKey = prompt("Enter key to sort by:");
|
|
62
|
+
if(!sortKey) return;
|
|
63
|
+
queryDbFunc.sortData(sortKey);
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
sortData(key){
|
|
68
|
+
db_data.sort((a, b) => {
|
|
69
|
+
const aValue = a[key] !== undefined ? a[key] : "";
|
|
70
|
+
const bValue = b[key] !== undefined ? b[key] : "";
|
|
71
|
+
if(aValue > bValue) return 1;
|
|
72
|
+
if(aValue < bValue) return -1;
|
|
73
|
+
return 0;
|
|
74
|
+
});
|
|
75
|
+
this.renderData();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
queryDbFunc.init();
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
const queryGraphFunc = {
|
|
2
|
+
queryInput: document.querySelector("#query-graph-node"),
|
|
3
|
+
outputMethodSelect: document.querySelector("#query-graph-output-method"),
|
|
4
|
+
|
|
5
|
+
init(){
|
|
6
|
+
document.querySelector("#query-graph-btn").addEventListener("click", async () => {
|
|
7
|
+
const node = queryGraphFunc.queryInput.value.trim();
|
|
8
|
+
const edges = await graphActions.find(node);
|
|
9
|
+
db_data = edges;
|
|
10
|
+
queryGraphFunc.displayEdges();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
document.querySelector("#query-graph-all-btn").addEventListener("click", async () => {
|
|
14
|
+
const edges = await graphActions.getAll();
|
|
15
|
+
db_data = edges;
|
|
16
|
+
queryGraphFunc.displayEdges();
|
|
17
|
+
});
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
displayEdges(){
|
|
21
|
+
const method = queryGraphFunc.outputMethodSelect.value;
|
|
22
|
+
|
|
23
|
+
switch(method){
|
|
24
|
+
case "table":
|
|
25
|
+
if(!db_data || db_data.length == 0){
|
|
26
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
data_output.innerHTML = templates.tableData({ data: db_data });
|
|
30
|
+
break;
|
|
31
|
+
case "graph":
|
|
32
|
+
queryGraphFunc.displayEdgesGraph();
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
displayEdgesGraph(){
|
|
38
|
+
if(!db_data || db_data.length == 0){
|
|
39
|
+
data_output.innerHTML = "<p>No data</p>";
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
data_output.innerHTML = "";
|
|
43
|
+
const { nodes, links } = queryGraphFunc.transformData(db_data);
|
|
44
|
+
|
|
45
|
+
const div = document.createElement("div");
|
|
46
|
+
div.style.height = "500px";
|
|
47
|
+
div.style.width = "99%";
|
|
48
|
+
data_output.appendChild(div);
|
|
49
|
+
|
|
50
|
+
const width = div.clientWidth;
|
|
51
|
+
const height = div.clientHeight;
|
|
52
|
+
|
|
53
|
+
const zoom = d3.zoom()
|
|
54
|
+
.scaleExtent([0.1, 4])
|
|
55
|
+
.on("zoom", (event) => {
|
|
56
|
+
g.attr("transform", event.transform);
|
|
57
|
+
})
|
|
58
|
+
|
|
59
|
+
const svg = d3.create("svg")
|
|
60
|
+
.attr("width", width)
|
|
61
|
+
.attr("height", height)
|
|
62
|
+
.call(zoom);
|
|
63
|
+
|
|
64
|
+
const g = svg.append("g");
|
|
65
|
+
|
|
66
|
+
const simulation = d3.forceSimulation(nodes)
|
|
67
|
+
.force("link", d3.forceLink().id(d => d.id).distance(90))
|
|
68
|
+
.force("charge", d3.forceManyBody().strength(-90))
|
|
69
|
+
.force("center", d3.forceCenter(width / 2, height / 2))
|
|
70
|
+
.force("collision", d3.forceCollide().radius(50))
|
|
71
|
+
.force("gravity", d3.forceManyBody().strength(20));
|
|
72
|
+
|
|
73
|
+
const link = g.append("g")
|
|
74
|
+
.attr("class", "links")
|
|
75
|
+
.selectAll("line")
|
|
76
|
+
.data(links)
|
|
77
|
+
.enter().append("line")
|
|
78
|
+
.attr("stroke-width", 2)
|
|
79
|
+
.style("stroke", "var(--accent)");
|
|
80
|
+
|
|
81
|
+
const node = g.append("g")
|
|
82
|
+
.attr("class", "nodes")
|
|
83
|
+
.selectAll("g")
|
|
84
|
+
.data(nodes)
|
|
85
|
+
.enter().append("g");
|
|
86
|
+
|
|
87
|
+
node.append("circle")
|
|
88
|
+
.attr("r", 8)
|
|
89
|
+
.attr("fill", "var(--accent)");
|
|
90
|
+
|
|
91
|
+
node.append("text")
|
|
92
|
+
.attr("dx", 12)
|
|
93
|
+
.attr("dy", ".35em")
|
|
94
|
+
.attr("fill", "var(--txt)")
|
|
95
|
+
.text(d => d.id)
|
|
96
|
+
.style("cursor", "pointer")
|
|
97
|
+
.on("click", function(event, d) {
|
|
98
|
+
queryGraphFunc.copyToClipboard(d.id);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
simulation
|
|
102
|
+
.nodes(nodes)
|
|
103
|
+
.on("tick", () => {
|
|
104
|
+
link.attr("x1", d => d.source.x)
|
|
105
|
+
.attr("y1", d => d.source.y)
|
|
106
|
+
.attr("x2", d => d.target.x)
|
|
107
|
+
.attr("y2", d => d.target.y);
|
|
108
|
+
|
|
109
|
+
node.attr("transform", d => `translate(${d.x},${d.y})`);
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
simulation.force("link").links(links);
|
|
113
|
+
div.appendChild(svg.node());
|
|
114
|
+
|
|
115
|
+
const resetView = document.createElement("button");
|
|
116
|
+
resetView.innerText = "Reset view";
|
|
117
|
+
resetView.addEventListener("click", () => {
|
|
118
|
+
svg.transition().duration(750)
|
|
119
|
+
.call(zoom.transform, d3.zoomIdentity);
|
|
120
|
+
});
|
|
121
|
+
data_output.appendChild(resetView);
|
|
122
|
+
},
|
|
123
|
+
|
|
124
|
+
transformData(inputData){
|
|
125
|
+
const nodesSet = new Set();
|
|
126
|
+
|
|
127
|
+
const links = inputData.map(({ a, b }) => {
|
|
128
|
+
nodesSet.add(a);
|
|
129
|
+
nodesSet.add(b);
|
|
130
|
+
return { source: a, target: b };
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const nodes = Array.from(nodesSet).map(id => ({ id }));
|
|
134
|
+
return { nodes, links };
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
copyToClipboard(text){
|
|
138
|
+
navigator.clipboard.writeText(text).then(() => alert("Copied in clipboard!")).catch(() => {
|
|
139
|
+
alert("Failed to copy in clipboard. Manually select and copy it:\n" + text);
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
queryGraphFunc.init();
|