pinokiod 2.15.20 → 2.15.22

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.
@@ -38,6 +38,23 @@ class FS {
38
38
  let data = await fs.promises.readFile(filepath, req.params.encoding)
39
39
  return data
40
40
  }
41
+ async cat(req, ondata, kernel) {
42
+ /*
43
+ params := {
44
+ path: <filepath>,
45
+ }
46
+ */
47
+ let cwd = (req.cwd ? req.cwd : kernel.api.userdir)
48
+ let filepath = kernel.api.filePath(req.params.path, cwd)
49
+ //let filepath = path.resolve(cwd, req.params.path)
50
+ let data = await fs.promises.readFile(filepath, "utf8")
51
+ ondata({
52
+ raw: data.replace(/\n/g, "\r\n")
53
+ })
54
+ ondata({
55
+ raw: "\r\n"
56
+ })
57
+ }
41
58
  // async unzip(req, ondata, kernel) {
42
59
  // /*
43
60
  // params := {
@@ -520,7 +520,6 @@ class Api {
520
520
 
521
521
  }
522
522
  async step (request, rawrpc, input, i, total, args) {
523
- console.log("STEP")
524
523
 
525
524
  await this.init()
526
525
 
@@ -531,8 +530,6 @@ class Api {
531
530
 
532
531
  let { cwd, script } = await this.resolveScript(request.path)
533
532
 
534
- console.log("RESOLVED SCRIPT", script)
535
-
536
533
  let memory = {
537
534
  script: this.kernel.script,
538
535
  input,
@@ -558,25 +555,17 @@ class Api {
558
555
  // get fully resolved env
559
556
  let env = await Environment.get2(request.path, this.kernel)
560
557
  // set template
561
- this.kernel.template.update({ env })
558
+ this.kernel.template.update({ envs: env, env })
562
559
 
563
560
  // render until `{{ }}` pattern does not exist
564
561
  // 1. render once
565
562
  let rpc = rawrpc
566
563
  let pass = 0;
567
- console.log("PARSE START")
568
564
  while(true) {
569
- console.log("rpc", rpc)
570
- console.log("memory", memory)
571
565
  rpc = this.kernel.template.render(rpc, memory)
572
- console.log("parsed rpc", rpc)
573
- console.log(this.kernel.template.istemplate.toString())
574
- console.log("isteamplate = ", this.kernel.template.istemplate(rpc))
575
566
  let test = this.kernel.template.istemplate(rpc)
576
- console.log({ test })
577
567
  if (this.kernel.template.istemplate(rpc)) {
578
568
  pass++;
579
- console.log("PASS", pass)
580
569
  if (pass >= 4) {
581
570
  // only try 4 times
582
571
  break;
@@ -587,13 +576,10 @@ class Api {
587
576
  break;
588
577
  }
589
578
  }
590
- console.log("rpc before", { rpc })
591
579
 
592
580
  // replace {{{ }}} with {{ }}
593
581
  rpc = this.kernel.template.flatten(rpc)
594
582
 
595
- console.log("rpc after", { rpc })
596
-
597
583
  // 6. rpc must have method names
598
584
  if (rpc.method) {
599
585
 
@@ -1226,7 +1212,6 @@ class Api {
1226
1212
  // }
1227
1213
  // }
1228
1214
  // script = Object.assign(script, merge)
1229
- console.log("SCRIPT", script)
1230
1215
 
1231
1216
  return { cwd, script }
1232
1217
  }
@@ -3,8 +3,31 @@ const fs = require('fs')
3
3
  const rm = (old, keys) => {
4
4
  for (let key of keys) {
5
5
  try {
6
- let fun = new Function('old', 'key', `delete old.${key}; return old;`);
7
- old = fun(old, key);
6
+ // let fun = new Function('old', 'key', `delete old.${key}; return old;`);
7
+ // old = fun(old, key);
8
+ let keypath = String(key).split(".")
9
+ // multiple keys. check if that path exists.
10
+ // if not, create the path
11
+ let next = old
12
+ for(let i=0; i<keypath.length; i++) {
13
+ if (i === keypath.length-1) {
14
+ // last
15
+ let path_key = keypath[i]
16
+ if (/^[0-9]+$/.test(path_key)) {
17
+ if (Array.isArray(next)) {
18
+ // array index
19
+ let index = Number(path_key)
20
+ next.splice(index, 1)
21
+ }
22
+ } else {
23
+ // key
24
+ delete next[path_key]
25
+ }
26
+ } else {
27
+ const key = keypath[i];
28
+ next = next[key];
29
+ }
30
+ }
8
31
  } catch (e) {
9
32
  }
10
33
  }
@@ -1,62 +1,64 @@
1
1
  const path = require('path')
2
2
  const fs = require('fs')
3
3
  const set = async (old, kv, kernel, req, ondata) => {
4
- console.log("SET", { old, kv })
5
- for (let key in kv) {
6
- try {
7
- if (key.startsWith('[')) {
8
- // array
9
- let fun = new Function(
10
- 'old',
11
- 'key',
12
- 'val',
13
- `old${key} = val; return old;`
14
- );
15
- old = fun(old, key, kv[key]);
16
- } else {
17
-
18
- let keypath = key.split(".")
19
- // multiple keys. check if that path exists.
20
- // if not, create the path
21
- let next = old
22
- for(let i=0; i<keypath.length; i++) {
23
- console.log("turn", { i, path: keypath[i], next })
24
- if (i === keypath.length-1) {
25
- // last
26
- next[keypath[i]] = kv[key]
27
- } else {
28
- const key = keypath[i];
29
- if (!(key in next)) {
30
- next[key] = {}
4
+ if (Array.isArray(kv)) {
5
+ old = kv
6
+ } else {
7
+ for (let key in kv) {
8
+ try {
9
+ if (key.startsWith('[')) {
10
+ // array
11
+ let fun = new Function(
12
+ 'old',
13
+ 'key',
14
+ 'val',
15
+ `old${key} = val; return old;`
16
+ );
17
+ old = fun(old, key, kv[key]);
18
+ } else {
19
+
20
+ let keypath = key.split(".")
21
+ // multiple keys. check if that path exists.
22
+ // if not, create the path
23
+ let next = old
24
+ for(let i=0; i<keypath.length; i++) {
25
+ if (i === keypath.length-1) {
26
+ // last
27
+ next[keypath[i]] = kv[key]
28
+ } else {
29
+ const key = keypath[i];
30
+ if (!(key in next)) {
31
+ next[key] = {}
32
+ }
33
+ next = next[key];
31
34
  }
32
- next = next[key];
33
35
  }
34
- }
35
36
 
36
- // let fun = new Function(
37
- // 'old',
38
- // 'key',
39
- // 'val',
40
- // //`old.${key} = val; return old;`
41
- // `old["${key}"] = val; return old;`
42
- // );
43
- // old = fun(old, key, kv[key]);
44
- }
37
+ // let fun = new Function(
38
+ // 'old',
39
+ // 'key',
40
+ // 'val',
41
+ // //`old.${key} = val; return old;`
42
+ // `old["${key}"] = val; return old;`
43
+ // );
44
+ // old = fun(old, key, kv[key]);
45
+ }
45
46
 
46
47
 
47
- // // reserved variable: "url"
48
- // if (key === "url") {
49
- // // start proxy
50
- // ondata({
51
- // raw: `\r\n[Start proxy] ${kv[key]}\r\n`
52
- // })
53
- // let response = await kernel.api.startProxy(req.parent.path, kv[key], "Shared")
54
- // console.log("Response", response)
55
- // ondata({
56
- // raw: `Proxy Started ${JSON.stringify(response)}\r\n`
57
- // })
58
- // }
59
- } catch (e) {
48
+ // // reserved variable: "url"
49
+ // if (key === "url") {
50
+ // // start proxy
51
+ // ondata({
52
+ // raw: `\r\n[Start proxy] ${kv[key]}\r\n`
53
+ // })
54
+ // let response = await kernel.api.startProxy(req.parent.path, kv[key], "Shared")
55
+ // console.log("Response", response)
56
+ // ondata({
57
+ // raw: `Proxy Started ${JSON.stringify(response)}\r\n`
58
+ // })
59
+ // }
60
+ } catch (e) {
61
+ }
60
62
  }
61
63
  }
62
64
  return old
@@ -109,8 +111,6 @@ module.exports = async (req, ondata, kernel) => {
109
111
  // }
110
112
  }
111
113
  }
112
- console.log("kernel.memory", kernel.memory)
113
-
114
114
  // set self => save to the file
115
115
 
116
116
  /*
package/kernel/index.js CHANGED
@@ -359,6 +359,7 @@ class Kernel {
359
359
  platform: this.platform,
360
360
  arch: this.arch,
361
361
  env: this.envs,
362
+ envs: this.envs,
362
363
  proxy: (port) => {
363
364
  return this.api.get_proxy_url("/proxy", port)
364
365
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinokiod",
3
- "version": "2.15.20",
3
+ "version": "2.15.22",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "scripts": {
package/server/index.js CHANGED
@@ -215,6 +215,34 @@ class Server {
215
215
  let app_path = this.kernel.path("api", name, "pinokio.js")
216
216
  let rawpath = "/api/" + name
217
217
  let config = (await this.kernel.loader.load(app_path)).resolved
218
+
219
+
220
+
221
+ // let requires_instantiation = false
222
+ // console.log("## CONFIG", config)
223
+ // if (config && config.pre) {
224
+ // let env = await Environment.get2(app_path, this.kernel)
225
+ // for(let item of config.pre) {
226
+ // console.log("ITEM" , item)
227
+ // if (item.env) {
228
+ // if (env[item.env]) {
229
+ //
230
+ // } else {
231
+ // requires_instantiation = true
232
+ // break;
233
+ // }
234
+ // }
235
+ // }
236
+ // }
237
+ // console.log({ requires_instantiation })
238
+ // if (requires_instantiation) {
239
+ // // redirect to pre
240
+ // res.redirect("/required_env/api/" + name)
241
+ // return
242
+ // }
243
+
244
+
245
+
218
246
  if (config && config.menu) {
219
247
  if (typeof config.menu === "function") {
220
248
  if (config.menu.constructor.name === "AsyncFunction") {
@@ -865,52 +893,82 @@ class Server {
865
893
  let editorUrl = edu.pathname + edu.search
866
894
 
867
895
  let referer = req.get("Referer")
868
- console.log({ referer })
869
896
 
870
897
  let prev = null
871
898
  if (/\/env\/api\/.+/.test(new URL(referer).pathname)) {
872
899
  prev = referer
873
900
  }
874
901
 
875
- const result = {
876
- prev,
877
- error,
878
- memory: mem,
879
- // memory: mem,
880
- logo: this.logo,
881
- theme: this.theme,
882
- //run: (req.query && req.query.run ? true : false),
883
- //run: true, // run mode by default
884
- run: (req.query && req.query.mode === "source" ? false : true),
885
- stop: (req.query && req.query.stop ? true : false),
886
- pinokioPath,
887
- runnable,
888
- agent: this.agent,
889
- rawpath,
890
- gitRemote,
891
- filename,
892
- filepath,
893
- encodedFilePath: encodeURIComponent(filepath),
894
- schemaPath,
895
- uri,
896
- mod,
897
- json,
898
- js,
899
- content,
900
- paths,
901
- requirements,
902
- requirements_pending,
903
- install_required,
904
- //current: encodeURIComponent(req.originalUrl),
905
- current: req.originalUrl,
906
- editorUrl,
907
- execUrl: "~" + req.originalUrl.replace(/^\/_api/, "\/api"),
908
- proxies: this.kernel.api.proxies[filepath],
902
+
903
+ let requires_instantiation = false
904
+ let pre_items = []
905
+ if (resolved && resolved.pre) {
906
+ let env = await Environment.get2(filepath, this.kernel)
907
+ for(let item of resolved.pre) {
908
+ if (item.env) {
909
+ if (env[item.env]) {
910
+ item.val = env[item.env]
911
+ } else {
912
+ requires_instantiation = true
913
+ }
914
+ pre_items.push(item)
915
+ }
916
+ }
917
+ }
918
+ if (requires_instantiation) {
919
+ let p = Util.api_path(filepath, this.kernel)
920
+ res.render("required_env_editor", {
921
+ agent: this.agent,
922
+ theme: this.theme,
923
+ filename,
924
+ filepath: p,
925
+ items: pre_items
926
+ })
927
+ } else {
928
+ const result = {
929
+ prev,
930
+ error,
931
+ memory: mem,
932
+ // memory: mem,
933
+ logo: this.logo,
934
+ theme: this.theme,
935
+ //run: (req.query && req.query.run ? true : false),
936
+ //run: true, // run mode by default
937
+ run: (req.query && req.query.mode === "source" ? false : true),
938
+ stop: (req.query && req.query.stop ? true : false),
939
+ pinokioPath,
940
+ runnable,
941
+ agent: this.agent,
942
+ rawpath,
943
+ gitRemote,
944
+ filename,
945
+ filepath,
946
+ encodedFilePath: encodeURIComponent(filepath),
947
+ schemaPath,
948
+ uri,
949
+ mod,
950
+ json,
951
+ js,
952
+ content,
953
+ paths,
954
+ requirements,
955
+ requirements_pending,
956
+ install_required,
957
+ //current: encodeURIComponent(req.originalUrl),
958
+ current: req.originalUrl,
959
+ editorUrl,
960
+ execUrl: "~" + req.originalUrl.replace(/^\/_api/, "\/api"),
961
+ proxies: this.kernel.api.proxies[filepath],
962
+ }
963
+
964
+ res.render(template, result)
909
965
  }
910
966
 
911
- console.log({ result })
912
967
 
913
- res.render(template, result)
968
+
969
+
970
+
971
+
914
972
  } else {
915
973
  res.render("frame", {
916
974
  logo: this.logo,
@@ -2405,6 +2463,23 @@ class Server {
2405
2463
  str: configStr
2406
2464
  })
2407
2465
  } else {
2466
+
2467
+ let requires_instantiation = false
2468
+ let pre_items = {}
2469
+ if (config && config.pre) {
2470
+ let env = await Environment.get2(filepath, this.kernel)
2471
+ for(let item of config.pre) {
2472
+ if (item.env) {
2473
+ if (env[item.env]) {
2474
+
2475
+ } else {
2476
+ requires_instantiation = true
2477
+ }
2478
+ }
2479
+ }
2480
+ }
2481
+ console.log({ requires_instantiation })
2482
+
2408
2483
  res.render("env_editor", {
2409
2484
  home: null,
2410
2485
  config,
@@ -2415,6 +2490,8 @@ class Server {
2415
2490
  theme: this.theme,
2416
2491
  filepath,
2417
2492
  agent: this.agent,
2493
+ pre_items,
2494
+ requires_instantiation,
2418
2495
  })
2419
2496
  }
2420
2497
  //res.render("env_editor", {
@@ -2431,17 +2508,22 @@ class Server {
2431
2508
  }))
2432
2509
  this.app.get("/pre/api/:name", ex(async (req, res) => {
2433
2510
  let p = path.resolve(this.kernel.homedir, "api", req.params.name, "pinokio.js")
2511
+ let p2 = path.resolve(this.kernel.homedir, "api", req.params.name)
2434
2512
  let config = (await this.kernel.loader.load(p)).resolved
2435
2513
  if (config && config.pre) {
2436
2514
  config.pre.forEach((item) => {
2437
- item.icon = `/api/${req.params.name}/${item.icon}?raw=true`
2515
+ if (item.icon) {
2516
+ item.icon = `/api/${req.params.name}/${item.icon}?raw=true`
2517
+ }
2438
2518
  })
2519
+ let env = await Environment.get2(p2, this.kernel)
2439
2520
  res.render("pre", {
2440
2521
  name: req.params.name,
2441
2522
  theme: this.theme,
2442
2523
  agent: this.agent,
2443
2524
  name: req.params.name,
2444
- items: config.pre
2525
+ items: config.pre,
2526
+ env
2445
2527
  })
2446
2528
  } else {
2447
2529
  res.redirect("/env/" + req.params.name + "?init=true")
@@ -954,7 +954,10 @@ body.dark .line:hover {
954
954
  .line {
955
955
  text-decoration: none;
956
956
  display: block;
957
+ /*
957
958
  padding: 15px 15px;
959
+ */
960
+ padding: 10px;
958
961
  border-bottom: 1px solid var(--light-thin);
959
962
  }
960
963
  .thick.line {
@@ -1002,8 +1005,12 @@ body.dark .line i {
1002
1005
  text-align: center;
1003
1006
  }
1004
1007
  .line img {
1008
+ /*
1005
1009
  width: 60px;
1006
1010
  height: 60px;
1011
+ */
1012
+ width: 40px;
1013
+ height: 40px;
1007
1014
  border-radius: 10px;
1008
1015
  }
1009
1016
  body.dark .line .btn {
@@ -123,9 +123,16 @@ body.dark .env-item label {
123
123
  font-weight: bold;
124
124
  font-size: 18px;
125
125
  }
126
+ .env-item.highlighted {
127
+ border: 5px solid red;
128
+ }
126
129
  .env-item {
130
+ /*
127
131
  padding-top: 10px;
128
132
  padding-bottom: 30px;
133
+ */
134
+ padding: 10px;
135
+ margin-bottom: 20px;
129
136
  }
130
137
  body.dark .comment {
131
138
  border-left: 2px solid white;
@@ -206,6 +213,12 @@ footer .btn.go-home {
206
213
  #editor {
207
214
  height: auto;
208
215
  }
216
+ .env-title {
217
+ font-weight: bold;
218
+ }
219
+ .env-description {
220
+ margin-bottom: 10px;
221
+ }
209
222
  </style>
210
223
  <script>
211
224
  document.addEventListener("DOMContentLoaded", async () => {
@@ -292,7 +305,7 @@ document.addEventListener("DOMContentLoaded", async () => {
292
305
  </h1>
293
306
  </header>
294
307
  <% } %>
295
- <div id='editor' class='<%=init ? "hidden" : ''%>'>
308
+ <div id='editor' class='<%=init && !requires_instantiation ? "hidden" : ''%>'>
296
309
  <!--
297
310
  <h1>Configure</h1>
298
311
  -->
@@ -300,10 +313,23 @@ document.addEventListener("DOMContentLoaded", async () => {
300
313
  <% if (item.type === "comment") { %>
301
314
  <div class='comment'><%=item.val.replaceAll(/^[ #]+/g, "")%></div>
302
315
  <% } else { %>
303
- <div class='env-item'>
304
- <label for="<%=item.key%>"><%=item.key%></label>
305
- <input id="<%=item.key%>" type="text" value="<%=item.val%>">
306
- </div>
316
+ <% if(pre_items[item.key]) { %>
317
+ <div class='env-item highlighted'>
318
+ <label for="<%=item.key%>"><%=item.key%></label>
319
+ <% if (pre_items[item.key].title) { %>
320
+ <div class='env-title'><%=pre_items[item.key].title%></div>
321
+ <% } %>
322
+ <% if (pre_items[item.key].description) { %>
323
+ <div class='env-description'><%=pre_items[item.key].description%></div>
324
+ <% } %>
325
+ <input id="<%=item.key%>" type="text" value="<%=item.val%>">
326
+ </div>
327
+ <% } else { %>
328
+ <div class='env-item'>
329
+ <label for="<%=item.key%>"><%=item.key%></label>
330
+ <input id="<%=item.key%>" type="text" value="<%=item.val%>">
331
+ </div>
332
+ <% } %>
307
333
  <% } %>
308
334
  <% }) %>
309
335
  </div>
@@ -312,9 +312,16 @@ body.dark .browser-options-row {
312
312
  <% if (item.icon) { %>
313
313
  <img src="<%=item.icon%>">
314
314
  <% } else { %>
315
+ <% if (theme === 'dark') { %>
316
+ <img src="/pinokio-white.png">
317
+ <% } else { %>
318
+ <img src="/pinokio-black.png">
319
+ <% } %>
320
+ <!--
315
321
  <div class='avatar'>
316
322
  <i class="fa-regular fa-circle-dot"></i>
317
323
  </div>
324
+ -->
318
325
  <% } %>
319
326
  <div class='col'>
320
327
  <div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
@@ -366,9 +373,16 @@ body.dark .browser-options-row {
366
373
  <% if (item.icon) { %>
367
374
  <img src="<%=item.icon%>">
368
375
  <% } else { %>
376
+ <!--
369
377
  <div class='avatar'>
370
378
  <i class="fa-regular fa-circle-dot"></i>
371
379
  </div>
380
+ -->
381
+ <% if (theme === 'dark') { %>
382
+ <img src="/pinokio-white.png">
383
+ <% } else { %>
384
+ <img src="/pinokio-black.png">
385
+ <% } %>
372
386
  <% } %>
373
387
  <div class='col'>
374
388
  <div class='uri'><i class="fa-regular fa-folder"></i><%=item.url%></div>
@@ -55,6 +55,9 @@ h1 {
55
55
  margin: 10px 0;
56
56
 
57
57
  }
58
+ .item .title {
59
+ font-weight: bold;
60
+ }
58
61
  .item .btn {
59
62
  width: 50px;
60
63
  text-align: center;
@@ -78,6 +81,22 @@ footer a.btn {
78
81
  .e {
79
82
  padding: 5px 0;
80
83
  }
84
+ .env {
85
+ padding: 10px;
86
+ border-left: 2px solid black;
87
+ margin-top: 10px;
88
+ }
89
+ .env label {
90
+ font-weight: bold;
91
+ font-size: 12px;
92
+ display: block;
93
+ margin-bottom: 5px;
94
+ }
95
+ .env input[type=text] {
96
+ padding: 5px;
97
+ box-sizing: border-box;
98
+ width: 100%;
99
+ }
81
100
  </style>
82
101
  </head>
83
102
  <body class='columns <%=theme%>'>
@@ -91,14 +110,29 @@ footer a.btn {
91
110
  </div>
92
111
  <div class='items'>
93
112
  <% items.forEach((item) => { %>
94
- <div class='item'>
95
- <img src="<%=item.icon%>">
113
+ <% if (item.href) { %>
114
+ <div class='item'>
115
+ <% if (item.icon) { %>
116
+ <img src="<%=item.icon%>">
117
+ <% } %>
118
+ <div class='col'>
119
+ <div class='title'><%=item.title%></div>
120
+ <div class='description'><%=item.description%></div>
121
+ </div>
122
+ <a target="_blank" features="browser" href='<%=item.href%>' class='btn'>Get</a>
123
+ </div>
124
+ <% } else if (item.env) { %>
125
+ <!--
96
126
  <div class='col'>
97
127
  <div class='title'><%=item.title%></div>
98
128
  <div class='description'><%=item.description%></div>
129
+ <div class='env'>
130
+ <label><%=item.env%></label>
131
+ <input type='text' value="<%=env[item.env] ? env[item.env] : ''%>" />
132
+ </div>
99
133
  </div>
100
- <a target="_blank" features="browser" href='<%=item.href%>' class='btn'>Get</a>
101
- </div>
134
+ -->
135
+ <% } %>
102
136
  <% }) %>
103
137
  </div>
104
138
  <footer>
@@ -0,0 +1,275 @@
1
+ <html class='columns'>
2
+ <head>
3
+ <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
4
+ <script src="/hotkeys.min.js"></script>
5
+ <script src="/ace/ace.js"></script>
6
+ <script src="/noty.js"></script>
7
+ <script src="/notyq.js"></script>
8
+ <script src="/xterm.js"></script>
9
+ <script src="/xterm-addon-fit.js"></script>
10
+ <script src="/xterm-addon-web-links.js"></script>
11
+ <script src="/xterm-theme.js"></script>
12
+ <script src="/xterm-addon-search.js"></script>
13
+ <script src="/xterm-addon-search-bar.js"></script>
14
+ <script src="/sweetalert2.js"></script>
15
+ <script src="/Socket.js"></script>
16
+ <script src="/common.js"></script>
17
+ <script src="/he.js"></script>
18
+ <script src="/opener.js"></script>
19
+ <script src="/nav.js"></script>
20
+ <script src="/autoexpand.js"></script>
21
+ <script src="/modalinput.js"></script>
22
+ <script src="/simplemodal.js"></script>
23
+ <script src="/waitmodal.js"></script>
24
+ <script src="/notifyinput.js"></script>
25
+ <script src="/report.js"></script>
26
+ <link href="/xterm.min.css" rel="stylesheet" />
27
+ <link href="/css/fontawesome.min.css" rel="stylesheet">
28
+ <link href="/css/solid.min.css" rel="stylesheet">
29
+ <link href="/css/regular.min.css" rel="stylesheet">
30
+ <link href="/css/brands.min.css" rel="stylesheet">
31
+ <link href="/style.css" rel="stylesheet"/>
32
+ <link href="/noty.css" rel="stylesheet"/>
33
+ <% if (agent === "electron") { %>
34
+ <link href="/electron.css" rel="stylesheet"/>
35
+ <% } %>
36
+ <style>
37
+ body.frozen {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100%;
41
+ }
42
+ #table > table {
43
+ border-left: 2px solid black;
44
+ padding-left: 5px;
45
+ margin: 10px 0;
46
+ }
47
+ .highlight {
48
+ background: yellow;
49
+ width: 100px;
50
+ }
51
+ th {
52
+ background: rgba(0,0,0,0.1);
53
+ padding: 10px;
54
+ font-size: 12px;
55
+ }
56
+ td {
57
+ font-size: 12px;
58
+ padding: 10px;
59
+ }
60
+ td.val {
61
+ background: rgba(0,0,0,0.06);
62
+ }
63
+ td.key {
64
+ background: rgba(0,0,0,0.1);
65
+ }
66
+ .button {
67
+ cursor: pointer;
68
+ background: rgba(0,0,0,0.8);
69
+ color: white;
70
+ padding: 5px 10px;
71
+ border-radius: 4px;
72
+ }
73
+ .button:hover {
74
+
75
+ }
76
+ main {
77
+ width: 100%;
78
+ box-sizing: border-box;
79
+ max-width: 600px;
80
+ padding: 20px;
81
+ margin: 0 auto;
82
+ }
83
+
84
+ header .btn {
85
+ font-family: Sans-serif;
86
+ display: block;
87
+ margin-left: 10px;
88
+ font-style: normal;
89
+ font-size: 12px;
90
+ font-weight: normal;
91
+ padding: 5px 10px;
92
+ }
93
+ .disabled {
94
+ opacity: 0.7;
95
+ }
96
+ body.dark .env-item input[type=text] {
97
+ background: white;
98
+ }
99
+ .env-item input[type=text] {
100
+ width: 100%;
101
+ padding: 10px;
102
+ box-sizing: border-box;
103
+ border: none;
104
+ background: rgba(0,0,100, 0.1);
105
+ }
106
+ body.dark .env-item label {
107
+ color: cornflowerblue;
108
+ }
109
+ .env-item label {
110
+ color: royalblue;
111
+ display: block;
112
+ margin-bottom: 5px;
113
+ font-weight: bold;
114
+ font-size: 18px;
115
+ }
116
+ .env-item.highlighted {
117
+ border: 5px solid red;
118
+ }
119
+ .env-item {
120
+ /*
121
+ padding-top: 10px;
122
+ padding-bottom: 30px;
123
+ */
124
+ padding: 10px;
125
+ margin-bottom: 20px;
126
+ }
127
+ body.dark .comment {
128
+ border-left: 2px solid white;
129
+ }
130
+ .comment {
131
+ opacity: 0.8;
132
+ border-left: 2px solid black;
133
+ padding-left: 10px;
134
+ }
135
+ #save {
136
+ background: royalblue;
137
+ width: 100%;
138
+ box-sizing: border-box;
139
+ text-align: center;
140
+ }
141
+ a#customize {
142
+ text-decoration: underline;
143
+ cursor: pointer;
144
+ }
145
+ .e {
146
+ padding: 10px 0;
147
+ }
148
+ #editor {
149
+ padding: 20px 0;
150
+ }
151
+ .center {
152
+ display: flex;
153
+ align-items: center;
154
+ justify-content: center;
155
+ }
156
+ body {
157
+ display: block;
158
+ }
159
+ .card {
160
+ display: flex;
161
+ padding: 10px 0;
162
+ box-sizing: border-box;
163
+ }
164
+ .card img {
165
+ width: 100px;
166
+ border-radius: 10px;
167
+ }
168
+ .card .description {
169
+ opacity: 0.8;
170
+ }
171
+ .card .title {
172
+ font-weight: bold;
173
+ font-size: 30px;
174
+ letter-spacing: -1px;
175
+ }
176
+ .card .col {
177
+ padding-left: 10px;
178
+ }
179
+ h1 {
180
+ text-align: center;
181
+ font-size: 50px;
182
+ padding-bottom: 20px;
183
+ }
184
+ footer {
185
+ background: none;
186
+ padding: 0;
187
+ text-align: right;
188
+ display: flex;
189
+ margin: 10px 0 20px 0;
190
+ }
191
+ footer .btn {
192
+ margin-left: 10px;
193
+ display: inline-block;
194
+ -webkit-appearance: button;
195
+ -moz-appearance: button;
196
+ appearance: button;
197
+
198
+ }
199
+ footer .btn.go-home {
200
+ margin-left: 0px;
201
+ }
202
+ .btn.home-button {
203
+ background: none !important;
204
+ margin: 0 !important;
205
+ font-size: 16px !important;
206
+ }
207
+ #editor {
208
+ height: auto;
209
+ }
210
+ .env-title {
211
+ font-weight: bold;
212
+ }
213
+ .env-description {
214
+ margin-bottom: 10px;
215
+ }
216
+ .subtitle {
217
+ text-align: center;
218
+ }
219
+ </style>
220
+ <script>
221
+ document.addEventListener("DOMContentLoaded", async () => {
222
+ const n = new N()
223
+ document.querySelector("#save").addEventListener("click", async (e) => {
224
+ // save
225
+ const vals = {}
226
+ const els = document.querySelectorAll(".env-item")
227
+ for(let el of els) {
228
+ let input = el.querySelector("input[type=text]")
229
+ vals[input.id] = input.value
230
+ }
231
+ console.log("vals", vals)
232
+ let res = await fetch("/env", {
233
+ method: "POST",
234
+ headers: {
235
+ "Content-Type": "application/json"
236
+ },
237
+ body: JSON.stringify({
238
+ filepath: "<%=filepath%>",
239
+ vals
240
+ })
241
+ }).then((res) => {
242
+ return res.json()
243
+ })
244
+ console.log("res" ,res)
245
+ location.href = location.href
246
+ })
247
+ })
248
+ </script>
249
+ </head>
250
+ <body class='<%=theme%> center'>
251
+ <main>
252
+ <div>
253
+ <h1><%=filename%></h1>
254
+ <div class='subtitle'>Please enter the required values to continue.</div>
255
+ </div>
256
+ <div id='editor'>
257
+ <% items.forEach((item) => { %>
258
+ <div class='env-item'>
259
+ <label for="<%=item.env%>"><%=item.env%></label>
260
+ <% if (item.title) { %>
261
+ <div class='env-title'><%=item.title%></div>
262
+ <% } %>
263
+ <% if (item.description) { %>
264
+ <div class='env-description'><%=item.description%></div>
265
+ <% } %>
266
+ <input id="<%=item.env%>" type="text" value="<%=item.val%>">
267
+ </div>
268
+ <% }) %>
269
+ <div id='save' class='btn'>
270
+ <span class='save'><i class="fa-solid fa-check"></i> Done</span>
271
+ </div>
272
+ </div>
273
+ </main>
274
+ </body>
275
+ </html>