pinokiod 1.3.62 → 1.3.64
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/cloudflare/index.js +8 -0
- package/kernel/api/proxy/index.js +8 -0
- package/kernel/environment.js +5 -0
- package/kernel/index.js +3 -0
- package/kernel/info.js +62 -0
- package/package.json +1 -1
- package/server/index.js +57 -14
- package/server/views/browser-experimental.ejs +1 -0
- package/server/views/index.ejs +1 -7
- package/server/views/share_editor.ejs +42 -4
|
@@ -52,6 +52,14 @@ class C {
|
|
|
52
52
|
});
|
|
53
53
|
})
|
|
54
54
|
|
|
55
|
+
if (!kernel.memory.local[req.parent.path].$share) {
|
|
56
|
+
kernel.memory.local[req.parent.path].$share = {}
|
|
57
|
+
}
|
|
58
|
+
if (!kernel.memory.local[req.parent.path].$share.cloudflare) {
|
|
59
|
+
kernel.memory.local[req.parent.path].$share.cloudflare = {}
|
|
60
|
+
}
|
|
61
|
+
kernel.memory.local[req.parent.path].$share.cloudflare[req.params.uri] = cloudflare_url
|
|
62
|
+
|
|
55
63
|
return { uri: cloudflare_url }
|
|
56
64
|
}
|
|
57
65
|
async stop (req, ondata, kernel) {
|
|
@@ -40,6 +40,14 @@ class P {
|
|
|
40
40
|
});
|
|
41
41
|
})
|
|
42
42
|
|
|
43
|
+
if (!kernel.memory.local[req.parent.path].$share) {
|
|
44
|
+
kernel.memory.local[req.parent.path].$share = {}
|
|
45
|
+
}
|
|
46
|
+
if (!kernel.memory.local[req.parent.path].$share.local) {
|
|
47
|
+
kernel.memory.local[req.parent.path].$share.local = {}
|
|
48
|
+
}
|
|
49
|
+
kernel.memory.local[req.parent.path].$share.local[req.params.uri] = response.proxy
|
|
50
|
+
|
|
43
51
|
return response
|
|
44
52
|
}
|
|
45
53
|
}
|
package/kernel/environment.js
CHANGED
package/kernel/index.js
CHANGED
|
@@ -21,6 +21,7 @@ const Script = require('./script')
|
|
|
21
21
|
const Environment = require("./environment")
|
|
22
22
|
const Util = require('./util')
|
|
23
23
|
const Config = require("./pinokio.json")
|
|
24
|
+
const Info = require('./info')
|
|
24
25
|
const VARS = {
|
|
25
26
|
pip: {
|
|
26
27
|
install: {
|
|
@@ -28,6 +29,7 @@ const VARS = {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
}
|
|
32
|
+
|
|
31
33
|
//const memwatch = require('@airbnb/node-memwatch');
|
|
32
34
|
class Kernel {
|
|
33
35
|
//schema = ">=1.0.0"
|
|
@@ -42,6 +44,7 @@ class Kernel {
|
|
|
42
44
|
this.jsdom = jsdom
|
|
43
45
|
this.exposed = {}
|
|
44
46
|
this.envs = {}
|
|
47
|
+
this.info = new Info(this)
|
|
45
48
|
}
|
|
46
49
|
/*
|
|
47
50
|
kernel.env() => return the system environment
|
package/kernel/info.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/*
|
|
2
|
+
info.local(...args)
|
|
3
|
+
info.running(...args)
|
|
4
|
+
info.exists(...args)
|
|
5
|
+
info.path(...args)
|
|
6
|
+
*/
|
|
7
|
+
const path = require('path')
|
|
8
|
+
const fs = require("fs")
|
|
9
|
+
class Info {
|
|
10
|
+
constructor(kernel) {
|
|
11
|
+
this.kernel = kernel
|
|
12
|
+
}
|
|
13
|
+
callsites () {
|
|
14
|
+
const _prepareStackTrace = Error.prepareStackTrace;
|
|
15
|
+
try {
|
|
16
|
+
let result = [];
|
|
17
|
+
Error.prepareStackTrace = (_, callSites) => {
|
|
18
|
+
const callSitesWithoutCurrent = callSites.slice(1);
|
|
19
|
+
result = callSitesWithoutCurrent;
|
|
20
|
+
return callSitesWithoutCurrent;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
new Error().stack; // eslint-disable-line unicorn/error-message, no-unused-expressions
|
|
24
|
+
return result;
|
|
25
|
+
} finally {
|
|
26
|
+
Error.prepareStackTrace = _prepareStackTrace;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
caller () {
|
|
30
|
+
return this.callsites()[2].getFileName()
|
|
31
|
+
}
|
|
32
|
+
// get the app path
|
|
33
|
+
app_path(...args) {
|
|
34
|
+
}
|
|
35
|
+
// get full path of the relative path
|
|
36
|
+
path(...args) {
|
|
37
|
+
let cwd = path.dirname(this.caller())
|
|
38
|
+
return path.resolve(cwd, ...args)
|
|
39
|
+
}
|
|
40
|
+
running(...args) {
|
|
41
|
+
let cwd = path.dirname(this.caller())
|
|
42
|
+
let resolved_path = path.resolve(cwd, ...args)
|
|
43
|
+
return this.kernel.api.running[resolved_path]
|
|
44
|
+
}
|
|
45
|
+
exists(...args) {
|
|
46
|
+
let cwd = path.dirname(this.caller())
|
|
47
|
+
let resolved_path = path.resolve(cwd, ...args)
|
|
48
|
+
return fs.existsSync(resolved_path)
|
|
49
|
+
}
|
|
50
|
+
local(...args) {
|
|
51
|
+
let cwd = path.dirname(this.caller())
|
|
52
|
+
let resolved_path = path.resolve(cwd, ...args)
|
|
53
|
+
return this.kernel.memory.local[resolved_path] || {}
|
|
54
|
+
}
|
|
55
|
+
global(...args) {
|
|
56
|
+
let cwd = path.dirname(this.caller())
|
|
57
|
+
let resolved_path = path.resolve(cwd, ...args)
|
|
58
|
+
return this.kernel.memory.global[resolved_path] || {}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = Info
|
package/package.json
CHANGED
package/server/index.js
CHANGED
|
@@ -180,9 +180,9 @@ class Server {
|
|
|
180
180
|
if (config && config.menu) {
|
|
181
181
|
if (typeof config.menu === "function") {
|
|
182
182
|
if (config.menu.constructor.name === "AsyncFunction") {
|
|
183
|
-
config.menu = await config.menu(this.kernel)
|
|
183
|
+
config.menu = await config.menu(this.kernel, this.kernel.info)
|
|
184
184
|
} else {
|
|
185
|
-
config.menu = config.menu(this.kernel)
|
|
185
|
+
config.menu = config.menu(this.kernel, this.kernel.info)
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
188
|
|
|
@@ -636,9 +636,9 @@ class Server {
|
|
|
636
636
|
let resolved
|
|
637
637
|
if (typeof runner === "function") {
|
|
638
638
|
if (runner.constructor.name === "AsyncFunction") {
|
|
639
|
-
resolved = await runner(this.kernel)
|
|
639
|
+
resolved = await runner(this.kernel, this.kernel.info)
|
|
640
640
|
} else {
|
|
641
|
-
resolved = runner(this.kernel)
|
|
641
|
+
resolved = runner(this.kernel, this.kernel.info)
|
|
642
642
|
}
|
|
643
643
|
runnable = resolved && resolved.run ? true : false
|
|
644
644
|
} else {
|
|
@@ -969,9 +969,9 @@ class Server {
|
|
|
969
969
|
if (config && config.menu) {
|
|
970
970
|
if (typeof config.menu === "function") {
|
|
971
971
|
if (config.menu.constructor.name === "AsyncFunction") {
|
|
972
|
-
config.menu = await config.menu(this.kernel)
|
|
972
|
+
config.menu = await config.menu(this.kernel, this.kernel.info)
|
|
973
973
|
} else {
|
|
974
|
-
config.menu = config.menu(this.kernel)
|
|
974
|
+
config.menu = config.menu(this.kernel, this.kernel.info)
|
|
975
975
|
}
|
|
976
976
|
}
|
|
977
977
|
|
|
@@ -991,9 +991,9 @@ class Server {
|
|
|
991
991
|
if (config && config.update) {
|
|
992
992
|
if (typeof config.update === "function") {
|
|
993
993
|
if (config.update.constructor.name === "AsyncFunction") {
|
|
994
|
-
config.update = await config.update(this.kernel)
|
|
994
|
+
config.update = await config.update(this.kernel, this.kernel.info)
|
|
995
995
|
} else {
|
|
996
|
-
config.update = config.update(this.kernel)
|
|
996
|
+
config.update = config.update(this.kernel, this.kernel.info)
|
|
997
997
|
}
|
|
998
998
|
}
|
|
999
999
|
let absolute = path.resolve(__dirname, ...pathComponents, config.update)
|
|
@@ -1082,9 +1082,9 @@ class Server {
|
|
|
1082
1082
|
if (config.menu) {
|
|
1083
1083
|
if (typeof config.menu === "function") {
|
|
1084
1084
|
if (config.menu.constructor.name === "AsyncFunction") {
|
|
1085
|
-
config.menu = await config.menu(this.kernel)
|
|
1085
|
+
config.menu = await config.menu(this.kernel, this.kernel.info)
|
|
1086
1086
|
} else {
|
|
1087
|
-
config.menu = config.menu(this.kernel)
|
|
1087
|
+
config.menu = config.menu(this.kernel, this.kernel.info)
|
|
1088
1088
|
}
|
|
1089
1089
|
}
|
|
1090
1090
|
|
|
@@ -1096,9 +1096,9 @@ class Server {
|
|
|
1096
1096
|
if (config.shortcuts) {
|
|
1097
1097
|
if (typeof config.shortcuts === "function") {
|
|
1098
1098
|
if (config.shortcuts.constructor.name === "AsyncFunction") {
|
|
1099
|
-
config.shortcuts = await config.shortcuts(this.kernel)
|
|
1099
|
+
config.shortcuts = await config.shortcuts(this.kernel, this.kernel.info)
|
|
1100
1100
|
} else {
|
|
1101
|
-
config.shortcuts = config.shortcuts(this.kernel)
|
|
1101
|
+
config.shortcuts = config.shortcuts(this.kernel, this.kernel.info)
|
|
1102
1102
|
}
|
|
1103
1103
|
}
|
|
1104
1104
|
await this.renderShortcuts(uri, item.name, config, pathComponents)
|
|
@@ -1894,6 +1894,12 @@ class Server {
|
|
|
1894
1894
|
// initialize kernel
|
|
1895
1895
|
await this.kernel.init({ port: this.port})
|
|
1896
1896
|
|
|
1897
|
+
let env = await Environment.get(this.kernel.homedir)
|
|
1898
|
+
if (env && env.PINOKIO_PORT) {
|
|
1899
|
+
this.port = env.PINOKIO_PORT
|
|
1900
|
+
}
|
|
1901
|
+
|
|
1902
|
+
|
|
1897
1903
|
// start proxy for Pinokio itself
|
|
1898
1904
|
// await this.kernel.api.startProxy("/", `http://127.0.0.1:${this.port}`, "/")
|
|
1899
1905
|
|
|
@@ -2183,7 +2189,44 @@ class Server {
|
|
|
2183
2189
|
config[key] = ""
|
|
2184
2190
|
}
|
|
2185
2191
|
}
|
|
2192
|
+
// find urls in the current app
|
|
2193
|
+
let app_path = path.resolve(this.kernel.homedir, "api", req.params.name)
|
|
2194
|
+
let scripts = Object.keys(this.kernel.memory.local).filter((x) => {
|
|
2195
|
+
return x.startsWith(app_path)
|
|
2196
|
+
})
|
|
2197
|
+
let cloudflare_links = []
|
|
2198
|
+
let local_links = []
|
|
2199
|
+
console.log({ app_path, scripts })
|
|
2200
|
+
for(let script in this.kernel.memory.local) {
|
|
2201
|
+
let mem = this.kernel.memory.local[script]
|
|
2202
|
+
console.log({ script, mem })
|
|
2203
|
+
if (mem.$share) {
|
|
2204
|
+
if (mem.$share.cloudflare) {
|
|
2205
|
+
for(let key in mem.$share.cloudflare) {
|
|
2206
|
+
let val = mem.$share.cloudflare[key]
|
|
2207
|
+
let qr = await QRCode.toDataURL(val)
|
|
2208
|
+
cloudflare_links.push({
|
|
2209
|
+
url: val,
|
|
2210
|
+
qr
|
|
2211
|
+
})
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
if (mem.$share.local) {
|
|
2215
|
+
for(let key in mem.$share.local) {
|
|
2216
|
+
let val = mem.$share.local[key]
|
|
2217
|
+
let qr = await QRCode.toDataURL(val)
|
|
2218
|
+
local_links.push({
|
|
2219
|
+
url: val,
|
|
2220
|
+
qr
|
|
2221
|
+
})
|
|
2222
|
+
}
|
|
2223
|
+
}
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
console.log({ cloudflare_links, local_links })
|
|
2186
2227
|
res.render("share_editor", {
|
|
2228
|
+
cloudflare_links,
|
|
2229
|
+
local_links,
|
|
2187
2230
|
keys,
|
|
2188
2231
|
config,
|
|
2189
2232
|
theme: this.theme,
|
|
@@ -2247,9 +2290,9 @@ class Server {
|
|
|
2247
2290
|
if (config && config.menu) {
|
|
2248
2291
|
if (typeof config.menu === "function") {
|
|
2249
2292
|
if (config.menu.constructor.name === "AsyncFunction") {
|
|
2250
|
-
config.menu = await config.menu(this.kernel)
|
|
2293
|
+
config.menu = await config.menu(this.kernel, this.kernel.info)
|
|
2251
2294
|
} else {
|
|
2252
|
-
config.menu = config.menu(this.kernel)
|
|
2295
|
+
config.menu = config.menu(this.kernel, this.kernel.info)
|
|
2253
2296
|
}
|
|
2254
2297
|
}
|
|
2255
2298
|
|
|
@@ -1272,6 +1272,7 @@ document.querySelector("aside").addEventListener("click", async (e) => {
|
|
|
1272
1272
|
e.stopPropagation()
|
|
1273
1273
|
let link = target.closest("[href]")
|
|
1274
1274
|
let src = new URL(link.href).pathname
|
|
1275
|
+
target.querySelector("i.fa-square").className = "fa-solid fa-check"
|
|
1275
1276
|
n.Noty({
|
|
1276
1277
|
text: `stopping ${src}`,
|
|
1277
1278
|
silent: true
|
package/server/views/index.ejs
CHANGED
|
@@ -223,7 +223,7 @@ body.dark .browser-options-row {
|
|
|
223
223
|
<a href="/" target="_blank" class='btn' features="browser"><div><i class="fa-solid fa-square-up-right"></i> Open</div></a>
|
|
224
224
|
<div class='flexible'>
|
|
225
225
|
<h3><i class="fa-solid fa-bolt"></i> Instant Launch</h3>
|
|
226
|
-
<div>(Experimental) Directly open pinokio apps from your favorite browser address bar at
|
|
226
|
+
<div>(Experimental) Directly open pinokio apps from your favorite browser address bar at localhost. If an app you're trying to use is already running, it will instantly load. If it's not, the app will first launch and then load the website.</div>
|
|
227
227
|
</div>
|
|
228
228
|
</div>
|
|
229
229
|
<% } %>
|
|
@@ -283,9 +283,6 @@ body.dark .browser-options-row {
|
|
|
283
283
|
<div class='title'><%=item.name%></div>
|
|
284
284
|
<div class='description'><%=item.description%></div>
|
|
285
285
|
<div>
|
|
286
|
-
<button class='btn browse' data-src="<%=item.browser_url%>/browse">
|
|
287
|
-
<i class="fa-regular fa-folder-open"></i>
|
|
288
|
-
</button>
|
|
289
286
|
<% if (item.running_scripts) { %>
|
|
290
287
|
<% item.running_scripts.forEach((s) => { %>
|
|
291
288
|
<button class='btn shutdown' data-src="<%=s.path%>">
|
|
@@ -333,9 +330,6 @@ body.dark .browser-options-row {
|
|
|
333
330
|
<div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
|
|
334
331
|
<div class='title'><%=item.name%></div>
|
|
335
332
|
<div class='description'><%=item.description%></div>
|
|
336
|
-
<button class='btn browse' data-src="<%=item.browser_url%>/browse">
|
|
337
|
-
<i class="fa-regular fa-folder-open"></i>
|
|
338
|
-
</button>
|
|
339
333
|
<% if (item.shortcuts && item.shortcuts.length > 0) { %>
|
|
340
334
|
<div class='btns'>
|
|
341
335
|
<% item.shortcuts.forEach((btn) => { %>
|
|
@@ -109,6 +109,11 @@ body.dark .env-item label {
|
|
|
109
109
|
display: inline-block;
|
|
110
110
|
margin-bottom: 5px;
|
|
111
111
|
font-weight: bold;
|
|
112
|
+
font-size: 20px;
|
|
113
|
+
letter-spacing: -1px;
|
|
114
|
+
}
|
|
115
|
+
.env-item ul {
|
|
116
|
+
margin: 5px 0;
|
|
112
117
|
}
|
|
113
118
|
.env-item {
|
|
114
119
|
padding-top: 10px;
|
|
@@ -131,6 +136,17 @@ hr {
|
|
|
131
136
|
border: none;
|
|
132
137
|
height: 1px;
|
|
133
138
|
}
|
|
139
|
+
.shared {
|
|
140
|
+
margin-left: 30px;
|
|
141
|
+
}
|
|
142
|
+
.shared a {
|
|
143
|
+
display: block;
|
|
144
|
+
margin-bottom: 5px;
|
|
145
|
+
}
|
|
146
|
+
.shared img {
|
|
147
|
+
width: 200px;
|
|
148
|
+
}
|
|
149
|
+
|
|
134
150
|
</style>
|
|
135
151
|
<script>
|
|
136
152
|
document.addEventListener("DOMContentLoaded", async () => {
|
|
@@ -173,8 +189,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
173
189
|
<% } else { %>
|
|
174
190
|
<input type="checkbox" id="PINOKIO_SHARE_CLOUDFLARE" name="cloudflare" />
|
|
175
191
|
<% } %>
|
|
176
|
-
<label for="cloudflare">
|
|
177
|
-
<
|
|
192
|
+
<label for="cloudflare"><i class="fa-brands fa-cloudflare"></i> Run a Public Node</label>
|
|
193
|
+
<ul>
|
|
194
|
+
<li>This will turn this local app into a public node.</li>
|
|
195
|
+
<li>Anyone with a URL can access a public node.</li>
|
|
196
|
+
<li>Users can't access Pinokio itself, only can access each app's UI.</li>
|
|
197
|
+
<li>Powered by <a href="https://www.cloudflare.com/products/tunnel/" target="_blank" features="browser">Cloudflare Tunnel</a></li>
|
|
198
|
+
<li>You can manually configure this in through the Configure menu (set PINOKIO_SHARE_CLOUDFLARE to true)</li>
|
|
199
|
+
</ul>
|
|
200
|
+
<% cloudflare_links.forEach((link) => { %>
|
|
201
|
+
<div class='shared'>
|
|
202
|
+
<a href="<%=link.url%>" target="_blank" features="browser"><%=link.url%></a>
|
|
203
|
+
<img src="<%=link.qr%>">
|
|
204
|
+
</div>
|
|
205
|
+
<% }) %>
|
|
178
206
|
</div>
|
|
179
207
|
<div class='env-item'>
|
|
180
208
|
<% if (config.PINOKIO_SHARE_LOCAL.toString() === "true") { %>
|
|
@@ -182,8 +210,18 @@ document.addEventListener("DOMContentLoaded", async () => {
|
|
|
182
210
|
<% } else { %>
|
|
183
211
|
<input type="checkbox" id="PINOKIO_SHARE_LOCAL" name="local" />
|
|
184
212
|
<% } %>
|
|
185
|
-
<label for="local">Share with Local Network
|
|
186
|
-
<
|
|
213
|
+
<label for="local"><i class="fa-solid fa-network-wired"></i> Share with Local Network</label>
|
|
214
|
+
<ul>
|
|
215
|
+
<li>This will allow any device on the same local network to access the app.</li>
|
|
216
|
+
<li>A new IP will be provided when local sharing is on, which can be used to access from any device on the same network.</li>
|
|
217
|
+
<li>You can manually configure this through the Configure menu (set PINOKIO_SHARE_LOCAL to true)</li>
|
|
218
|
+
</ul>
|
|
219
|
+
<% local_links.forEach((link) => { %>
|
|
220
|
+
<div class='shared'>
|
|
221
|
+
<a href="<%=link.url%>" target="_blank" features="browser"><%=link.url%></a>
|
|
222
|
+
<img src="<%=link.qr%>">
|
|
223
|
+
</div>
|
|
224
|
+
<% }) %>
|
|
187
225
|
</div>
|
|
188
226
|
<div class='runner'>
|
|
189
227
|
<div id='save' class='btn'>
|