pinokiod 0.1.31 → 0.1.33
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/kernel/api/index.js +5 -0
- package/kernel/api/key/index.js +26 -0
- package/kernel/index.js +5 -1
- package/kernel/key.js +43 -0
- package/package.json +2 -1
- package/server/index.js +84 -39
- package/server/public/modalinput.js +9 -0
- package/server/public/style.css +48 -3
- package/server/views/browser.ejs +205 -53
- package/server/views/editor.ejs +143 -26
- package/server/views/fullscreen_editor.ejs +41 -1
- package/server/views/index.ejs +46 -66
package/kernel/api/index.js
CHANGED
|
@@ -381,6 +381,8 @@ class Api {
|
|
|
381
381
|
}
|
|
382
382
|
async step (request, rawrpc, input, i, total) {
|
|
383
383
|
|
|
384
|
+
console.log("STEP", { request, rawrpc, input, i, total })
|
|
385
|
+
|
|
384
386
|
// clear global regular expression object RegExp.lastMatch (memory leak prevention)
|
|
385
387
|
let r = /\s*/g.exec("");
|
|
386
388
|
|
|
@@ -795,6 +797,7 @@ class Api {
|
|
|
795
797
|
// API Call
|
|
796
798
|
|
|
797
799
|
request.path = this.resolvePath(this.userdir, request.uri)
|
|
800
|
+
console.log("#PROCESS", { request, userdir: this.userdir })
|
|
798
801
|
let { cwd, script } = await this.resolveScript(request.path)
|
|
799
802
|
request.cwd = cwd
|
|
800
803
|
|
|
@@ -880,8 +883,10 @@ class Api {
|
|
|
880
883
|
filename = path.parse(scriptpath).base
|
|
881
884
|
}
|
|
882
885
|
|
|
886
|
+
|
|
883
887
|
// get the core script
|
|
884
888
|
let script = (await this.loader.load(scriptpath)).resolved
|
|
889
|
+
console.log("##### ", { scriptpath, script })
|
|
885
890
|
|
|
886
891
|
// if the sccript is a function, instantiate first
|
|
887
892
|
if (typeof script === "function") {
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
# 1. key.set => pops up key + password input
|
|
3
|
+
{
|
|
4
|
+
"method": "key.set"
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
# 2. key.get => pops up key + password input
|
|
8
|
+
# 2.1. Publick key/val
|
|
9
|
+
{
|
|
10
|
+
"method": "key.get"
|
|
11
|
+
}
|
|
12
|
+
*/
|
|
13
|
+
const fs = require('fs')
|
|
14
|
+
const { createStore } = require('key-store')
|
|
15
|
+
class Key {
|
|
16
|
+
async set(req, ondata, kernel) {
|
|
17
|
+
ondata(req.params, "key.set")
|
|
18
|
+
let { key, password } = await kernel.api.wait(req.parent.path)
|
|
19
|
+
}
|
|
20
|
+
async get(req, ondata, kernel) {
|
|
21
|
+
ondata(req.params, "key.get")
|
|
22
|
+
let { key, password } = await kernel.api.wait(req.parent.path)
|
|
23
|
+
return response
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
module.exports = Key
|
package/kernel/index.js
CHANGED
|
@@ -11,6 +11,7 @@ const Bin = require('./bin')
|
|
|
11
11
|
const Api = require("./api")
|
|
12
12
|
const Template = require('./template')
|
|
13
13
|
const Shells = require("./shells")
|
|
14
|
+
const Key = require("./key")
|
|
14
15
|
const Config = require("./pinokio.json")
|
|
15
16
|
const VARS = {
|
|
16
17
|
pip: {
|
|
@@ -26,7 +27,7 @@ class Kernel {
|
|
|
26
27
|
this.store = store
|
|
27
28
|
this.arch = os.arch()
|
|
28
29
|
this.platform = os.platform()
|
|
29
|
-
|
|
30
|
+
this.key = new Key()
|
|
30
31
|
}
|
|
31
32
|
resumeprocess(uri) {
|
|
32
33
|
let proc = this.procs[uri]
|
|
@@ -174,6 +175,9 @@ class Kernel {
|
|
|
174
175
|
}
|
|
175
176
|
console.log("this.vars", this.vars)
|
|
176
177
|
|
|
178
|
+
// let keyfile = path.resolve(this.homedir, "keys.json")
|
|
179
|
+
// await this.key.init(keyfile)
|
|
180
|
+
|
|
177
181
|
// let home = this.store.get("home")
|
|
178
182
|
// if (home) {
|
|
179
183
|
// this.homedir = home
|
package/kernel/key.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
const { createStore } = require('key-store')
|
|
2
|
+
class Key {
|
|
3
|
+
async init(filePath) {
|
|
4
|
+
const saveKeys = (data) => {
|
|
5
|
+
return fs.promises.writeFile(filePath, JSON.stringify(data, null, 2), 'utf8')
|
|
6
|
+
}
|
|
7
|
+
const readKeys = async () => {
|
|
8
|
+
try {
|
|
9
|
+
let s = await fs.promises.readFile(filePath, "utf8")
|
|
10
|
+
return JSON.parse(s)
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return {}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
let keys = await readKeys()
|
|
16
|
+
|
|
17
|
+
this.store = await createStore(saveKeys, keys)
|
|
18
|
+
}
|
|
19
|
+
keys() {
|
|
20
|
+
return this.store.getKeyIDs()
|
|
21
|
+
}
|
|
22
|
+
get(key, password) {
|
|
23
|
+
if (password) {
|
|
24
|
+
return this.store.getPrivateKeyData(key, password)
|
|
25
|
+
} else {
|
|
26
|
+
return this.store.getPublicKeyData(key)
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
set(key, val, password) {
|
|
30
|
+
if (password) {
|
|
31
|
+
console.log({ key, val, password})
|
|
32
|
+
return this.store.saveKey(key, password, String(val))
|
|
33
|
+
} else {
|
|
34
|
+
console.log({ key, val})
|
|
35
|
+
//return this.store.savePublicKeyData(key, String(val))
|
|
36
|
+
return this.store.saveKey(key, "", "", String(val))
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
del(key) {
|
|
40
|
+
this.store.removeKey(key)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
module.exports = Key
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pinokiod",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.33",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
"http-terminator": "^3.2.0",
|
|
33
33
|
"isomorphic-git": "^1.23.0",
|
|
34
34
|
"jsonpath-plus": "^7.2.0",
|
|
35
|
+
"key-store": "^1.2.0",
|
|
35
36
|
"localtunnel": "^2.0.2",
|
|
36
37
|
"lodash": "^4.17.21",
|
|
37
38
|
"marked": "^5.0.1",
|
package/server/index.js
CHANGED
|
@@ -23,11 +23,13 @@ const multer = require('multer');
|
|
|
23
23
|
const localtunnel = require('localtunnel');
|
|
24
24
|
|
|
25
25
|
|
|
26
|
+
|
|
26
27
|
const Socket = require('./socket')
|
|
27
28
|
const Kernel = require("../kernel")
|
|
28
29
|
const packagejson = require("../package.json")
|
|
29
30
|
class Server {
|
|
30
31
|
constructor(config) {
|
|
32
|
+
this.tabs = {}
|
|
31
33
|
this.agent = config.agent
|
|
32
34
|
this.port = config.port
|
|
33
35
|
this.kernel = new Kernel(config.store)
|
|
@@ -169,7 +171,8 @@ class Server {
|
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
// check if it's a folder or a file
|
|
172
|
-
let p = "/api"
|
|
174
|
+
let p = "/api" // run mode
|
|
175
|
+
let _p = "/_api" // edit mode
|
|
173
176
|
let paths = [{
|
|
174
177
|
name: '<i class="fa-solid fa-house"></i>',
|
|
175
178
|
path: "/",
|
|
@@ -337,6 +340,7 @@ class Server {
|
|
|
337
340
|
val: this.theme,
|
|
338
341
|
options: ["light", "dark"]
|
|
339
342
|
}]
|
|
343
|
+
console.log("agent", this.agent)
|
|
340
344
|
res.render("settings", {
|
|
341
345
|
version: this.version,
|
|
342
346
|
logo: this.logo,
|
|
@@ -480,6 +484,11 @@ class Server {
|
|
|
480
484
|
let template
|
|
481
485
|
template = "fullscreen_editor"
|
|
482
486
|
|
|
487
|
+
if (req.query && req.query.mode === "source") {
|
|
488
|
+
template = "editor"
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
|
|
483
492
|
// Deprecate source view and form view => Everything is full screen by default
|
|
484
493
|
// if (req.query && req.query.mode === "source") {
|
|
485
494
|
// if (req.query && req.query.fullscreen) {
|
|
@@ -681,6 +690,16 @@ class Server {
|
|
|
681
690
|
// })
|
|
682
691
|
// }
|
|
683
692
|
console.log("mem", mem)
|
|
693
|
+
console.log("originalUrl", req.originalUrl)
|
|
694
|
+
let edu = new URL("http://localhost" + req.originalUrl)
|
|
695
|
+
edu.searchParams.set("mode", "source")
|
|
696
|
+
let editorUrl = edu.pathname + edu.search
|
|
697
|
+
console.log("editorUrl", editorUrl)
|
|
698
|
+
console.log("req.query", req.query)
|
|
699
|
+
|
|
700
|
+
|
|
701
|
+
|
|
702
|
+
|
|
684
703
|
const result = {
|
|
685
704
|
error,
|
|
686
705
|
memory: mem,
|
|
@@ -688,7 +707,8 @@ class Server {
|
|
|
688
707
|
logo: this.logo,
|
|
689
708
|
theme: this.theme,
|
|
690
709
|
//run: (req.query && req.query.run ? true : false),
|
|
691
|
-
run: true, // run mode by default
|
|
710
|
+
//run: true, // run mode by default
|
|
711
|
+
run: (req.query && req.query.mode === "source" ? false : true),
|
|
692
712
|
stop: (req.query && req.query.stop ? true : false),
|
|
693
713
|
pinokioPath,
|
|
694
714
|
runnable,
|
|
@@ -709,6 +729,8 @@ class Server {
|
|
|
709
729
|
install_required,
|
|
710
730
|
//current: encodeURIComponent(req.originalUrl),
|
|
711
731
|
current: req.originalUrl,
|
|
732
|
+
editorUrl,
|
|
733
|
+
execUrl: "~" + req.originalUrl.replace(/^\/_api/, "\/api")
|
|
712
734
|
}
|
|
713
735
|
console.log("RESULT", result)
|
|
714
736
|
|
|
@@ -936,6 +958,12 @@ class Server {
|
|
|
936
958
|
// items
|
|
937
959
|
|
|
938
960
|
|
|
961
|
+
console.log("ITEMS", items)
|
|
962
|
+
|
|
963
|
+
|
|
964
|
+
let U = `${_p}/${pathComponents.join("/")}`
|
|
965
|
+
console.log("*******", { filepath, pathComponents, U })
|
|
966
|
+
|
|
939
967
|
|
|
940
968
|
res.render("index", {
|
|
941
969
|
error: error,
|
|
@@ -956,43 +984,45 @@ class Server {
|
|
|
956
984
|
notRunning,
|
|
957
985
|
readme,
|
|
958
986
|
filepath,
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
//
|
|
993
|
-
//
|
|
994
|
-
|
|
995
|
-
|
|
987
|
+
items: items.map((x) => {
|
|
988
|
+
//let name = (x.name.startsWith("0x") ? Buffer.from(x.name.slice(2), "hex").toString() : x.name)
|
|
989
|
+
let name
|
|
990
|
+
let description
|
|
991
|
+
let icon
|
|
992
|
+
let uri
|
|
993
|
+
if (meta) {
|
|
994
|
+
let m = meta[x.name]
|
|
995
|
+
name = (m && m.title ? m.title : x.name)
|
|
996
|
+
description = (m && m.description ? m.description : "")
|
|
997
|
+
if (m && m.icon) {
|
|
998
|
+
icon = m.icon
|
|
999
|
+
} else {
|
|
1000
|
+
icon = null
|
|
1001
|
+
}
|
|
1002
|
+
uri = x.name
|
|
1003
|
+
} else {
|
|
1004
|
+
if (x.isDirectory()) {
|
|
1005
|
+
icon = "fa-solid fa-folder"
|
|
1006
|
+
} else {
|
|
1007
|
+
icon = "fa-regular fa-file"
|
|
1008
|
+
}
|
|
1009
|
+
name = x.name
|
|
1010
|
+
description = ""
|
|
1011
|
+
}
|
|
1012
|
+
return {
|
|
1013
|
+
icon,
|
|
1014
|
+
menu: x.menu,
|
|
1015
|
+
//icon: (x.isDirectory() ? "fa-solid fa-folder" : "fa-regular fa-file"),
|
|
1016
|
+
name,
|
|
1017
|
+
uri,
|
|
1018
|
+
//description: x.path,
|
|
1019
|
+
description,
|
|
1020
|
+
//url: p + "/" + x.name,
|
|
1021
|
+
// url: _p + "/" + x.name,
|
|
1022
|
+
url: `${U}/${x.name}`,
|
|
1023
|
+
browser_url: "/pinokio/browser/" + x.name
|
|
1024
|
+
}
|
|
1025
|
+
}),
|
|
996
1026
|
})
|
|
997
1027
|
}
|
|
998
1028
|
}
|
|
@@ -1585,6 +1615,15 @@ class Server {
|
|
|
1585
1615
|
res.status(404).send(e.message);
|
|
1586
1616
|
}
|
|
1587
1617
|
})
|
|
1618
|
+
this.app.get("/_api/*", async (req, res) => {
|
|
1619
|
+
let pathComponents = req.params[0].split("/")
|
|
1620
|
+
req.query.mode = "source"
|
|
1621
|
+
try {
|
|
1622
|
+
await this.render(req, res, pathComponents)
|
|
1623
|
+
} catch (e) {
|
|
1624
|
+
res.status(404).send(e.message)
|
|
1625
|
+
}
|
|
1626
|
+
})
|
|
1588
1627
|
this.app.get("/api/*", async (req, res) => {
|
|
1589
1628
|
let pathComponents = req.params[0].split("/")
|
|
1590
1629
|
try {
|
|
@@ -1660,6 +1699,10 @@ class Server {
|
|
|
1660
1699
|
res.json({ error: e.message })
|
|
1661
1700
|
}
|
|
1662
1701
|
})
|
|
1702
|
+
this.app.post("/pinokio/tabs", async (req, res) => {
|
|
1703
|
+
this.tabs[req.body.name] = req.body.tabs
|
|
1704
|
+
res.json({ success: true })
|
|
1705
|
+
})
|
|
1663
1706
|
this.app.get("/pinokio/browser/:name", async (req, res) => {
|
|
1664
1707
|
let name = req.params.name
|
|
1665
1708
|
let app_path = this.kernel.path("api", name, "pinokio.js")
|
|
@@ -1689,12 +1732,14 @@ class Server {
|
|
|
1689
1732
|
memory: this.kernel.memory,
|
|
1690
1733
|
sidebar: "/pinokio/sidebar/" + name,
|
|
1691
1734
|
name,
|
|
1735
|
+
tabs: (this.tabs[name] || []),
|
|
1692
1736
|
config,
|
|
1693
1737
|
// sidebar_url: "/pinokio/sidebar/" + name,
|
|
1694
1738
|
home: req.originalUrl,
|
|
1695
1739
|
// paths,
|
|
1696
1740
|
theme: this.theme,
|
|
1697
1741
|
agent: this.agent,
|
|
1742
|
+
src: "/_api/" + name,
|
|
1698
1743
|
rawpath
|
|
1699
1744
|
})
|
|
1700
1745
|
})
|
|
@@ -4,6 +4,8 @@ const ModalInput = async (params) => {
|
|
|
4
4
|
title,
|
|
5
5
|
type: "modal" (default) |"notify"
|
|
6
6
|
form: [{
|
|
7
|
+
type,
|
|
8
|
+
items,
|
|
7
9
|
key,
|
|
8
10
|
title,
|
|
9
11
|
description,
|
|
@@ -21,6 +23,13 @@ const ModalInput = async (params) => {
|
|
|
21
23
|
let input
|
|
22
24
|
if (type === 'textarea') {
|
|
23
25
|
input = `<textarea oninput="autoExpand(this)" data-id="${field.key}" class="swal2-input" placeholder="${field.placeholder ? field.placeholder : ''}"></textarea>`
|
|
26
|
+
} else if (type === 'select') {
|
|
27
|
+
if (field.items && Array.isArray(field.items)) {
|
|
28
|
+
let items = field.items.map((item) => {
|
|
29
|
+
return `<option value="${item}">${item}</option>`
|
|
30
|
+
}).join("")
|
|
31
|
+
input = `<select>${items}</select>`
|
|
32
|
+
}
|
|
24
33
|
} else {
|
|
25
34
|
input = `<input type='${type}' data-id="${field.key}" class="swal2-input" placeholder="${field.placeholder ? field.placeholder : ''}">`
|
|
26
35
|
}
|
package/server/public/style.css
CHANGED
|
@@ -784,6 +784,9 @@ body.dark .line {
|
|
|
784
784
|
}
|
|
785
785
|
body.dark .line.selected {
|
|
786
786
|
background: rgba(0,0,0, 0.2);
|
|
787
|
+
/*
|
|
788
|
+
border-left: 6px solid white;
|
|
789
|
+
*/
|
|
787
790
|
}
|
|
788
791
|
body.dark .line:hover {
|
|
789
792
|
background: rgba(0,0,0, 0.2);
|
|
@@ -792,8 +795,10 @@ body.dark .line:hover {
|
|
|
792
795
|
background: rgba(200,0,0, 0.04);
|
|
793
796
|
}
|
|
794
797
|
.line.selected {
|
|
795
|
-
|
|
796
|
-
|
|
798
|
+
background: rgba(0,0,100, 0.03);
|
|
799
|
+
/*
|
|
800
|
+
border-left: 6px solid black;
|
|
801
|
+
*/
|
|
797
802
|
}
|
|
798
803
|
.line {
|
|
799
804
|
text-decoration: none;
|
|
@@ -824,9 +829,11 @@ body.dark a.line {
|
|
|
824
829
|
a.line {
|
|
825
830
|
color: var(--light-color);
|
|
826
831
|
}
|
|
832
|
+
/*
|
|
827
833
|
body.dark .line i {
|
|
828
834
|
color: var(--dark-link-color);
|
|
829
835
|
}
|
|
836
|
+
*/
|
|
830
837
|
.line .title i {
|
|
831
838
|
/*
|
|
832
839
|
color: #54aeff;
|
|
@@ -959,7 +966,10 @@ button {
|
|
|
959
966
|
cursor: pointer;
|
|
960
967
|
}
|
|
961
968
|
body.dark .btn {
|
|
969
|
+
/*
|
|
962
970
|
color: var(--dark-btn-color);
|
|
971
|
+
*/
|
|
972
|
+
color: white;
|
|
963
973
|
background: var(--dark-btn-bg);
|
|
964
974
|
}
|
|
965
975
|
.btn {
|
|
@@ -1279,7 +1289,10 @@ b {
|
|
|
1279
1289
|
background: royalblue;
|
|
1280
1290
|
}
|
|
1281
1291
|
body.dark #new-window {
|
|
1292
|
+
/*
|
|
1282
1293
|
color: var(--dark-btn-color);
|
|
1294
|
+
*/
|
|
1295
|
+
color: white;
|
|
1283
1296
|
}
|
|
1284
1297
|
#new-window {
|
|
1285
1298
|
padding: 10px;
|
|
@@ -1289,7 +1302,10 @@ body.dark #new-window {
|
|
|
1289
1302
|
color: var(--light-color);
|
|
1290
1303
|
}
|
|
1291
1304
|
body.dark .btn2 {
|
|
1305
|
+
/*
|
|
1292
1306
|
color: var(--dark-btn-color);
|
|
1307
|
+
*/
|
|
1308
|
+
color: white;
|
|
1293
1309
|
}
|
|
1294
1310
|
.btn2:hover {
|
|
1295
1311
|
background: rgba(0,0,0,0.06);
|
|
@@ -1357,7 +1373,7 @@ body.dark .header-label {
|
|
|
1357
1373
|
top: 0;
|
|
1358
1374
|
padding: 10px;
|
|
1359
1375
|
/*
|
|
1360
|
-
border-top:
|
|
1376
|
+
border-top: 2px solid rgba(0,0,0,0.04);
|
|
1361
1377
|
*/
|
|
1362
1378
|
}
|
|
1363
1379
|
|
|
@@ -1367,17 +1383,46 @@ nav.error-message {
|
|
|
1367
1383
|
color: rgba(0,0,0,0.7);
|
|
1368
1384
|
font-weight: bold;
|
|
1369
1385
|
}
|
|
1386
|
+
.not-running-apps {
|
|
1387
|
+
}
|
|
1370
1388
|
/*
|
|
1371
1389
|
.running-apps {
|
|
1390
|
+
background: rgba(0,0,100, 0.03);
|
|
1372
1391
|
background: rgba(255,215, 0, 0.2);
|
|
1373
1392
|
}
|
|
1374
1393
|
*/
|
|
1394
|
+
/*
|
|
1395
|
+
body.dark .running-apps {
|
|
1396
|
+
border-left: 6px solid gold;
|
|
1397
|
+
}
|
|
1398
|
+
*/
|
|
1399
|
+
.running-apps {
|
|
1400
|
+
border-left: 10px solid gold;
|
|
1401
|
+
/*
|
|
1402
|
+
background: rgba(255,215,0,0.03);
|
|
1403
|
+
*/
|
|
1404
|
+
}
|
|
1405
|
+
/*
|
|
1406
|
+
.running-apps .description {
|
|
1407
|
+
color: yellowgreen;
|
|
1408
|
+
}
|
|
1409
|
+
.running-apps .title {
|
|
1410
|
+
color: yellowgreen;
|
|
1411
|
+
}
|
|
1412
|
+
*/
|
|
1375
1413
|
.running-apps .spinner {
|
|
1376
1414
|
width: 50px;
|
|
1377
1415
|
text-align: center;
|
|
1416
|
+
font-size: 20px;
|
|
1417
|
+
/*
|
|
1418
|
+
color: yellowgreen;
|
|
1419
|
+
*/
|
|
1378
1420
|
}
|
|
1379
1421
|
body.dark header .home {
|
|
1422
|
+
/*
|
|
1380
1423
|
color: var(--dark-btn-color);
|
|
1424
|
+
*/
|
|
1425
|
+
color: white;
|
|
1381
1426
|
}
|
|
1382
1427
|
header .home {
|
|
1383
1428
|
color: var(--light-color);
|