pinokiod 3.9.0 → 3.9.3
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/:w +1247 -0
- package/kernel/api/filepicker/index.js +59 -0
- package/kernel/api/fs/index.js +6 -4
- package/kernel/api/index.js +123 -37
- package/kernel/api/input/index.js +2 -0
- package/kernel/api/web/index.js +6 -0
- package/kernel/bin/caddy.js +127 -0
- package/kernel/bin/cloudflared.js +1 -0
- package/kernel/bin/conda.js +10 -2
- package/kernel/bin/cuda.js +0 -16
- package/kernel/bin/ffmpeg.js +4 -6
- package/kernel/bin/git.js +55 -29
- package/kernel/bin/gxx.js +8 -6
- package/kernel/bin/huggingface.js +4 -5
- package/kernel/bin/index.js +347 -88
- package/kernel/bin/node.js +13 -6
- package/kernel/bin/py.js +1 -1
- package/kernel/bin/setup.js +146 -0
- package/kernel/bin/uv.js +4 -5
- package/kernel/bin/zip.js +7 -8
- package/kernel/connect/index.js +25 -0
- package/kernel/connect/providers/github/README.md +11 -0
- package/kernel/connect/providers/x/README.md +96 -0
- package/kernel/connect/providers/x/index.js +152 -0
- package/kernel/environment.js +50 -1
- package/kernel/index.js +152 -32
- package/kernel/info.js +4 -2
- package/kernel/kv.js +38 -0
- package/kernel/loader.js +13 -3
- package/kernel/peer.js +161 -0
- package/kernel/procs.js +116 -0
- package/kernel/prototype.js +62 -0
- package/kernel/router/common.js +42 -0
- package/kernel/router/connector.js +81 -0
- package/kernel/router/index.js +235 -0
- package/kernel/router/localhost_home_router.js +84 -0
- package/kernel/router/localhost_port_router.js +15 -0
- package/kernel/router/localhost_variable_router.js +37 -0
- package/kernel/router/peer_home_router.js +15 -0
- package/kernel/router/peer_peer_router.js +26 -0
- package/kernel/router/peer_port_router.js +45 -0
- package/kernel/router/peer_variable_router.js +46 -0
- package/kernel/router/processor.js +31 -0
- package/kernel/shell.js +141 -60
- package/kernel/shells.js +32 -17
- package/kernel/store.js +58 -0
- package/kernel/sysinfo.js +0 -1
- package/kernel/util.js +143 -36
- package/package.json +4 -1
- package/pipe/index.js +0 -2
- package/script/index.js +12 -0
- package/server/index.js +1473 -553
- package/server/public/Socket.js +5 -1
- package/server/public/SourceCodePro-Regular.ttf +0 -0
- package/server/public/SpaceMono-Bold.ttf +0 -0
- package/server/public/SpaceMono-BoldItalic.ttf +0 -0
- package/server/public/SpaceMono-Italic.ttf +0 -0
- package/server/public/SpaceMono-Regular.ttf +0 -0
- package/server/public/commander.js +40 -0
- package/server/public/common.js +60 -0
- package/server/public/dropzone-min.js +2 -0
- package/server/public/dropzone.css +1 -0
- package/server/public/filepond-plugin-file-validate-type.min.js +9 -0
- package/server/public/filepond-plugin-image-crop.min.js +9 -0
- package/server/public/filepond-plugin-image-edit.min.css +8 -0
- package/server/public/filepond-plugin-image-edit.min.js +9 -0
- package/server/public/filepond-plugin-image-exif-orientation.min.js +9 -0
- package/server/public/filepond-plugin-image-preview.min.css +8 -0
- package/server/public/filepond-plugin-image-preview.min.js +9 -0
- package/server/public/filepond-plugin-image-resize.min.js +9 -0
- package/server/public/filepond-plugin-image-transform.min.js +9 -0
- package/server/public/filepond.min.css +8 -0
- package/server/public/filepond.min.js +9 -0
- package/server/public/fscreator.js +174 -0
- package/server/public/fseditor.js +212 -0
- package/server/public/github.png +0 -0
- package/server/public/highlight-js.js +81 -0
- package/server/public/highlight.css +9 -0
- package/server/public/highlight.js +1244 -0
- package/server/public/install.js +17 -20
- package/server/public/modalinput.js +105 -9
- package/server/public/opener.js +3 -1
- package/server/public/pinokio-black.png +0 -0
- package/server/public/pinokio-black2.png +0 -0
- package/server/public/redoc.standalone.js +1832 -0
- package/server/public/style.css +215 -17
- package/server/public/swagger-ui-bundle.js +2 -0
- package/server/public/swagger-ui.css +3 -0
- package/server/public/x.js +63 -0
- package/server/socket.js +136 -39
- package/server/views/404.ejs +0 -1
- package/server/views/app.ejs +368 -98
- package/server/views/bootstrap.ejs +22 -19
- package/server/views/connect/x.ejs +324 -0
- package/server/views/connect.ejs +197 -0
- package/server/views/download.ejs +7 -1
- package/server/views/editor.ejs +68 -9
- package/server/views/explore.ejs +13 -10
- package/server/views/file_explorer.ejs +10 -37
- package/server/views/github.ejs +218 -0
- package/server/views/help.ejs +4 -3
- package/server/views/index.ejs +275 -121
- package/server/views/install.ejs +56 -29
- package/server/views/keys.ejs +276 -0
- package/server/views/network.ejs +889 -0
- package/server/views/partials/dynamic.ejs +9 -0
- package/server/views/partials/menu.ejs +7 -1
- package/server/views/prototype/index.ejs +311 -0
- package/server/views/prototype/show.ejs +383 -0
- package/server/views/redoc.ejs +18 -0
- package/server/views/required_env_editor.ejs +11 -2
- package/server/views/settings.ejs +38 -10
- package/server/views/setup.ejs +254 -0
- package/server/views/setup_home.ejs +192 -0
- package/server/views/shell.ejs +781 -0
- package/server/views/swaggerui.ejs +19 -0
- package/server/views/terminal.ejs +174 -42
- package/LICENSE +0 -7
- package/server/views/proxy.ejs +0 -405
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
const os = require('os')
|
|
2
|
+
let platform = os.platform()
|
|
3
|
+
module.exports = {
|
|
4
|
+
ai: (kernel) => {
|
|
5
|
+
let conda_requirements = [
|
|
6
|
+
"uv",
|
|
7
|
+
"node",
|
|
8
|
+
"huggingface",
|
|
9
|
+
"git",
|
|
10
|
+
"ffmpeg",
|
|
11
|
+
// "caddy"
|
|
12
|
+
]
|
|
13
|
+
let requirements = [
|
|
14
|
+
{ name: "conda", },
|
|
15
|
+
{ name: "git", },
|
|
16
|
+
// { name: "zip", },
|
|
17
|
+
{ name: "node", },
|
|
18
|
+
{ name: "ffmpeg", },
|
|
19
|
+
// { name: "caddy", }
|
|
20
|
+
]
|
|
21
|
+
if (platform === "win32") {
|
|
22
|
+
requirements.push({ name: "registry" })
|
|
23
|
+
requirements.push({ name: "vs" })
|
|
24
|
+
}
|
|
25
|
+
if (platform === "darwin") {
|
|
26
|
+
requirements.push({ name: "brew" })
|
|
27
|
+
}
|
|
28
|
+
if (platform === "linux") {
|
|
29
|
+
requirements.push({ name: "gxx" })
|
|
30
|
+
conda_requirements.push("gxx")
|
|
31
|
+
}
|
|
32
|
+
if (kernel.gpu === "nvidia") {
|
|
33
|
+
requirements.push({ name: "cuda", })
|
|
34
|
+
conda_requirements.push("cuda")
|
|
35
|
+
}
|
|
36
|
+
requirements = requirements.concat([
|
|
37
|
+
{ name: "cloudflared" },
|
|
38
|
+
// { name: "playwright" },
|
|
39
|
+
{ name: "huggingface" },
|
|
40
|
+
{ name: "uv" },
|
|
41
|
+
{ name: "py" },
|
|
42
|
+
])
|
|
43
|
+
return {
|
|
44
|
+
icon: "fa-solid fa-brain",
|
|
45
|
+
title: "AI",
|
|
46
|
+
description: "Install common modules required for running AI locally",
|
|
47
|
+
requirements,
|
|
48
|
+
conda_requirements
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
javascript: (kernel) => {
|
|
52
|
+
return {
|
|
53
|
+
icon: "fa-brands fa-js",
|
|
54
|
+
title: "Node.js",
|
|
55
|
+
description: "Set up self-contained node.js development environment",
|
|
56
|
+
requirements: [
|
|
57
|
+
{ name: "conda", },
|
|
58
|
+
{ name: "git", },
|
|
59
|
+
{ name: "node", },
|
|
60
|
+
],
|
|
61
|
+
conda_requirements: [
|
|
62
|
+
"node",
|
|
63
|
+
"git",
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
python: (kernel) => {
|
|
68
|
+
return {
|
|
69
|
+
icon: "fa-brands fa-python",
|
|
70
|
+
title: "Python",
|
|
71
|
+
description: "Set up self-contained python development environment",
|
|
72
|
+
requirements: [
|
|
73
|
+
{ name: "conda", },
|
|
74
|
+
{ name: "git", },
|
|
75
|
+
{ name: "uv", },
|
|
76
|
+
],
|
|
77
|
+
conda_requirements: [
|
|
78
|
+
"uv",
|
|
79
|
+
"git",
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
dev: (kernel) => {
|
|
84
|
+
let requirements = [
|
|
85
|
+
{ name: "conda", },
|
|
86
|
+
{ name: "git", },
|
|
87
|
+
{ name: "node", },
|
|
88
|
+
{ name: "uv", },
|
|
89
|
+
]
|
|
90
|
+
let conda_requirements = [
|
|
91
|
+
"uv",
|
|
92
|
+
"node",
|
|
93
|
+
"git",
|
|
94
|
+
]
|
|
95
|
+
if (platform === "win32") {
|
|
96
|
+
requirements.push({ name: "registry" })
|
|
97
|
+
requirements.push({ name: "vs" })
|
|
98
|
+
}
|
|
99
|
+
if (platform === "darwin") {
|
|
100
|
+
requirements.push({ name: "brew" })
|
|
101
|
+
}
|
|
102
|
+
if (platform === "linux") {
|
|
103
|
+
requirements.push({ name: "gxx" })
|
|
104
|
+
conda_requirements.push("gxx")
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
icon: "fa-solid fa-laptop-code",
|
|
108
|
+
title: "Coding",
|
|
109
|
+
description: "Install common modules required for development (Node.js, python, Visual Studio Developer Tools (Windows), Xcode build tools (Mac)",
|
|
110
|
+
requirements,
|
|
111
|
+
conda_requirements,
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
network: (kernel) => {
|
|
115
|
+
return {
|
|
116
|
+
icon: "fa-solid fa-wifi",
|
|
117
|
+
title: "Network",
|
|
118
|
+
description: "Automatic HTTPS and local network sharing for ALL local apps",
|
|
119
|
+
requirements: [
|
|
120
|
+
{ name: "conda", },
|
|
121
|
+
{ name: "git", },
|
|
122
|
+
{ name: "caddy", },
|
|
123
|
+
],
|
|
124
|
+
conda_requirements: [
|
|
125
|
+
"git",
|
|
126
|
+
"caddy"
|
|
127
|
+
]
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
connect: (kernel) => {
|
|
131
|
+
return {
|
|
132
|
+
icon: "fa-solid fa-wifi",
|
|
133
|
+
title: "API Connect",
|
|
134
|
+
description: "Connect with 3rd party APIs",
|
|
135
|
+
requirements: [
|
|
136
|
+
{ name: "conda", },
|
|
137
|
+
{ name: "git", },
|
|
138
|
+
{ name: "caddy", },
|
|
139
|
+
],
|
|
140
|
+
conda_requirements: [
|
|
141
|
+
"git",
|
|
142
|
+
"caddy"
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
package/kernel/bin/uv.js
CHANGED
|
@@ -3,16 +3,15 @@ const fetch = require('cross-fetch')
|
|
|
3
3
|
const { rimraf } = require('rimraf')
|
|
4
4
|
const decompress = require('decompress');
|
|
5
5
|
class UV {
|
|
6
|
+
cmd() {
|
|
7
|
+
return "uv"
|
|
8
|
+
}
|
|
6
9
|
async install(req, ondata) {
|
|
7
10
|
await this.kernel.bin.exec({
|
|
8
11
|
message: [
|
|
9
12
|
"conda clean -y --all",
|
|
10
|
-
|
|
13
|
+
`conda install -y -c conda-forge ${this.cmd()}`
|
|
11
14
|
]
|
|
12
|
-
// conda: {
|
|
13
|
-
// name: "base",
|
|
14
|
-
// activate: "minimal"
|
|
15
|
-
// }
|
|
16
15
|
}, ondata)
|
|
17
16
|
}
|
|
18
17
|
async installed() {
|
package/kernel/bin/zip.js
CHANGED
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
class Zip {
|
|
2
|
-
|
|
2
|
+
cmd() {
|
|
3
3
|
let cmd
|
|
4
4
|
if (this.kernel.platform === 'win32') {
|
|
5
|
-
cmd = "
|
|
5
|
+
cmd = "7zip"
|
|
6
6
|
} else {
|
|
7
|
-
cmd = "
|
|
7
|
+
cmd = "p7zip"
|
|
8
8
|
}
|
|
9
|
+
return cmd
|
|
10
|
+
}
|
|
11
|
+
async install(req, ondata) {
|
|
9
12
|
await this.kernel.bin.exec({
|
|
10
13
|
message: [
|
|
11
14
|
"conda clean -y --all",
|
|
12
|
-
cmd
|
|
15
|
+
`conda install -y -c conda-forge ${this.cmd()}`
|
|
13
16
|
]
|
|
14
|
-
// conda: {
|
|
15
|
-
// name: "base",
|
|
16
|
-
// activate: "minimal"
|
|
17
|
-
// }
|
|
18
17
|
}, ondata)
|
|
19
18
|
}
|
|
20
19
|
async installed() {
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
const fetch = require('cross-fetch')
|
|
2
|
+
const X = require('./providers/x')
|
|
3
|
+
class Connect {
|
|
4
|
+
constructor(kernel) {
|
|
5
|
+
this.kernel = kernel
|
|
6
|
+
this.x = new X(kernel)
|
|
7
|
+
}
|
|
8
|
+
async request(provider, method, req) {
|
|
9
|
+
let res = await this[provider].request(method, req)
|
|
10
|
+
return res
|
|
11
|
+
}
|
|
12
|
+
async login(provider, req) {
|
|
13
|
+
let res = await this[provider].login(req)
|
|
14
|
+
return res
|
|
15
|
+
}
|
|
16
|
+
async logout(provider, req) {
|
|
17
|
+
let res = await this[provider].logout(req)
|
|
18
|
+
return res
|
|
19
|
+
}
|
|
20
|
+
async keys(provider) {
|
|
21
|
+
let res = await this[provider].keys()
|
|
22
|
+
return res
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
module.exports = Connect
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
# Usage
|
|
4
|
+
|
|
5
|
+
When you log into Github here, the login will be used for the git installed within Pinokio.
|
|
6
|
+
|
|
7
|
+
Logging into Github lets you do things like:
|
|
8
|
+
|
|
9
|
+
1. Cloning from Private Repositories
|
|
10
|
+
2. Publishing to Github
|
|
11
|
+
3. Use all `gh` CLI commands in all Pinokio shells ([Learn more](https://cli.github.com/))
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
# Usage
|
|
4
|
+
|
|
5
|
+
## 1. Iniitialize
|
|
6
|
+
|
|
7
|
+
First include the script
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<script src="https://pinokio.localhost/x.js"></script>
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Then initialize the X object
|
|
14
|
+
|
|
15
|
+
```javascript
|
|
16
|
+
const x = new X()
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 2. Make API Calls
|
|
20
|
+
|
|
21
|
+
Now you can make API calls to X v2 API (Without worrying about authentication). For example:
|
|
22
|
+
|
|
23
|
+
```javascript
|
|
24
|
+
await x.tweet({ text: text })
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The instantiated object `x` is equivalent to the `client.v2` object from [node-twitter-api-v2](https://github.com/PLhery/node-twitter-api-v2)
|
|
28
|
+
|
|
29
|
+
Read the full API documentation here: https://github.com/PLhery/node-twitter-api-v2/blob/master/doc/v2.md
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
# Examples
|
|
34
|
+
|
|
35
|
+
## 1. Minimal Post App
|
|
36
|
+
|
|
37
|
+
The authentication is automatically taken care of. You just need to make a POST request to the `/connect/x/api` endpoint, using ANY x.com API.
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<html>
|
|
41
|
+
<body>
|
|
42
|
+
<form>
|
|
43
|
+
<input type='text' id='post'/>
|
|
44
|
+
<input type='submit'>
|
|
45
|
+
</form>
|
|
46
|
+
<script src="https://pinokio.localhost/x.js"></script>
|
|
47
|
+
<script>
|
|
48
|
+
const x = new X()
|
|
49
|
+
document.querySelector("form").addEventListener('submit', async (e) => {
|
|
50
|
+
e.preventDefault()
|
|
51
|
+
let text = document.querySelector("#post").value
|
|
52
|
+
await x.tweet({ text: text })
|
|
53
|
+
})
|
|
54
|
+
</script>
|
|
55
|
+
</body>
|
|
56
|
+
</html>
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## 2. Upload Media App
|
|
62
|
+
|
|
63
|
+
```html
|
|
64
|
+
<html>
|
|
65
|
+
<body>
|
|
66
|
+
<form>
|
|
67
|
+
<input type='file' id='media' name='media'>
|
|
68
|
+
<input type='submit'>
|
|
69
|
+
</form>
|
|
70
|
+
<script src="https://pinokio.localhost/x.js"></script>
|
|
71
|
+
<script>
|
|
72
|
+
const x = new X()
|
|
73
|
+
document.querySelector("form").addEventListener('submit', async (e) => {
|
|
74
|
+
e.preventDefault()
|
|
75
|
+
// 1. get the uploaded file
|
|
76
|
+
let media = document.querySelector("#media").files[0]
|
|
77
|
+
// 2. determine the media_type ("tweet_gif", "tweet_image", or "tweet_video")
|
|
78
|
+
let type = media.type; // e.g., "image/png", "video/mp4", "image/gif"
|
|
79
|
+
let media_category
|
|
80
|
+
if (type.startsWith("image/")) {
|
|
81
|
+
media_category = (type === "image/gif" ? "tweet_gif" : "tweet_image");
|
|
82
|
+
} else if (type.startsWith("video/")) {
|
|
83
|
+
media_category = "tweet_video"
|
|
84
|
+
}
|
|
85
|
+
// 3. upload media
|
|
86
|
+
let media_id = await x.uploadMedia(media, { media_category })
|
|
87
|
+
// 4. post the uploaded media
|
|
88
|
+
let res = await x.tweet({ media: { media_ids: [media_id] }})
|
|
89
|
+
console.log(res)
|
|
90
|
+
})
|
|
91
|
+
</script>
|
|
92
|
+
</body>
|
|
93
|
+
</html>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
const fs = require('fs')
|
|
2
|
+
const path = require('path')
|
|
3
|
+
const fetch = require('cross-fetch')
|
|
4
|
+
const FormData = require('form-data');
|
|
5
|
+
const marked = require('marked')
|
|
6
|
+
const { TwitterApi } = require('twitter-api-v2')
|
|
7
|
+
class X {
|
|
8
|
+
id = 'd2FQZ0U4NXpzYnRyS1hZeHBvbUc6MTpjaQ'
|
|
9
|
+
constructor(kernel) {
|
|
10
|
+
this.kernel = kernel
|
|
11
|
+
}
|
|
12
|
+
async readme() {
|
|
13
|
+
let md = await fs.promises.readFile(path.resolve(__dirname, "README.md"), "utf8")
|
|
14
|
+
return marked.parse(md, {
|
|
15
|
+
//baseUrl: req._parsedUrl.pathname.replace(/^\/_api/, "/raw/") + "/"
|
|
16
|
+
//baseUrl: req.originalUrl + "/"
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
async persist(auth) {
|
|
20
|
+
this.auth = auth
|
|
21
|
+
this.auth.expires_at = Date.now() + this.auth.expires_in * 1000
|
|
22
|
+
let authPath = this.kernel.path('connect/x.json')
|
|
23
|
+
await fs.promises.mkdir(this.kernel.path("connect"), { recursive: true }).catch((e) => { })
|
|
24
|
+
await fs.promises.writeFile(authPath, JSON.stringify(this.auth, null, 2))
|
|
25
|
+
}
|
|
26
|
+
async destroy() {
|
|
27
|
+
await fs.promises.rm(this.kernel.path("connect/x.json"))
|
|
28
|
+
this.auth = null
|
|
29
|
+
}
|
|
30
|
+
async sync() {
|
|
31
|
+
// check if auth exists
|
|
32
|
+
// if not, throw error
|
|
33
|
+
let authPath = this.kernel.path('connect/x.json')
|
|
34
|
+
this.auth = (await this.kernel.loader.load(authPath)).resolved
|
|
35
|
+
if (!this.auth) {
|
|
36
|
+
throw new Error("not authenticated")
|
|
37
|
+
return
|
|
38
|
+
}
|
|
39
|
+
if (!this.auth.refresh_token) {
|
|
40
|
+
throw new Error("no refresh token")
|
|
41
|
+
return
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// check if auth has expired
|
|
45
|
+
// if expired, refresh and return
|
|
46
|
+
if (Date.now() < this.auth.expires_at) {
|
|
47
|
+
console.log("authentication valid")
|
|
48
|
+
return
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
console.log("auth expired. refresh....", JSON.stringify({ auth: this.auth, id: this.id }, null, 2))
|
|
53
|
+
// expired — refresh
|
|
54
|
+
const response = await fetch('https://api.twitter.com/2/oauth2/token', {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: { 'Content-Type': 'application/json' },
|
|
57
|
+
body: JSON.stringify({
|
|
58
|
+
grant_type: 'refresh_token',
|
|
59
|
+
refresh_token: this.auth.refresh_token,
|
|
60
|
+
client_id: this.id
|
|
61
|
+
})
|
|
62
|
+
}).then((res) => {
|
|
63
|
+
return res.json()
|
|
64
|
+
});
|
|
65
|
+
await this.persist(response)
|
|
66
|
+
return this.auth
|
|
67
|
+
}
|
|
68
|
+
async keys() {
|
|
69
|
+
await this.sync()
|
|
70
|
+
return this.auth
|
|
71
|
+
}
|
|
72
|
+
async request(method, req) {
|
|
73
|
+
/*
|
|
74
|
+
method := "uploadMedia"
|
|
75
|
+
params := {
|
|
76
|
+
"value.0", val1,
|
|
77
|
+
"type.0": "String",
|
|
78
|
+
"value.1": val2,
|
|
79
|
+
"type.1": "Blob"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
uploadMedia(
|
|
83
|
+
val1,
|
|
84
|
+
{
|
|
85
|
+
key2: val2,
|
|
86
|
+
key3: val3
|
|
87
|
+
}
|
|
88
|
+
)
|
|
89
|
+
*/
|
|
90
|
+
await this.sync()
|
|
91
|
+
const contentType = req.headers['content-type'];
|
|
92
|
+
let args
|
|
93
|
+
if (contentType.toLowerCase() === "application/json") {
|
|
94
|
+
// don't transform
|
|
95
|
+
args = req.body
|
|
96
|
+
let response = await this.client.v2[method](...args)
|
|
97
|
+
return response
|
|
98
|
+
} else {
|
|
99
|
+
args = []
|
|
100
|
+
let body = Object.assign({}, req.body)
|
|
101
|
+
if (req.files) {
|
|
102
|
+
for (const file of req.files) {
|
|
103
|
+
body[file.fieldname] = file.buffer
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
let types = []
|
|
107
|
+
for(let key in body) {
|
|
108
|
+
let chunks = key.split(".")
|
|
109
|
+
let index = parseInt(chunks[1])
|
|
110
|
+
if (chunks[0] === "type") {
|
|
111
|
+
types[index] = body[key]
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
for(let key in body) {
|
|
115
|
+
let chunks = key.split(".")
|
|
116
|
+
let index = parseInt(chunks[1])
|
|
117
|
+
if (chunks[0] === "value") {
|
|
118
|
+
let type = types[index]
|
|
119
|
+
if (type === "Object") {
|
|
120
|
+
args[index] = JSON.parse(body[key])
|
|
121
|
+
} else {
|
|
122
|
+
args[index] = body[key]
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
console.log({ args, method })
|
|
127
|
+
|
|
128
|
+
this.client = new TwitterApi(this.auth.access_token);
|
|
129
|
+
let response = await this.client.v2[method](...args)
|
|
130
|
+
return response
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
async login (req) {
|
|
134
|
+
const authHeader = 'Basic ' + Buffer.from(`${this.id}:`).toString('base64');
|
|
135
|
+
const response = await fetch('https://api.x.com/2/oauth2/token', {
|
|
136
|
+
method: 'POST',
|
|
137
|
+
headers: {
|
|
138
|
+
'Content-Type': 'application/json',
|
|
139
|
+
// 'Authorization': authHeader
|
|
140
|
+
},
|
|
141
|
+
body: JSON.stringify(req.payload)
|
|
142
|
+
}).then((res) => {
|
|
143
|
+
return res.json()
|
|
144
|
+
});
|
|
145
|
+
await this.persist(response)
|
|
146
|
+
return this.auth
|
|
147
|
+
}
|
|
148
|
+
async logout (req) {
|
|
149
|
+
await this.destroy()
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
module.exports = X
|
package/kernel/environment.js
CHANGED
|
@@ -439,4 +439,53 @@ const get_raw = async (homedir) => {
|
|
|
439
439
|
}
|
|
440
440
|
return current_env
|
|
441
441
|
}
|
|
442
|
-
|
|
442
|
+
|
|
443
|
+
const requirements = async (script, filepath, kernel) => {
|
|
444
|
+
let pre_items = []
|
|
445
|
+
let requires_instantiation = false
|
|
446
|
+
if (script && script.pre) {
|
|
447
|
+
let env = await get2(filepath, kernel)
|
|
448
|
+
for(let item of script.pre) {
|
|
449
|
+
if (item.env) {
|
|
450
|
+
// if index is not set, use 0 as default (for key)
|
|
451
|
+
if (!item.index) {
|
|
452
|
+
item.index = 0
|
|
453
|
+
}
|
|
454
|
+
if (item.key) {
|
|
455
|
+
const hasProtocol = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(item.key);
|
|
456
|
+
const url = new URL(hasProtocol ? item.key : `https://${item.key}`);
|
|
457
|
+
item.host = url.host
|
|
458
|
+
item.val = await kernel.kv.get(item.host, item.index)
|
|
459
|
+
} else {
|
|
460
|
+
item.host = ""
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (env[item.env]) {
|
|
464
|
+
item.val = env[item.env]
|
|
465
|
+
} else {
|
|
466
|
+
if (item.default) {
|
|
467
|
+
if (typeof item.default === 'object') {
|
|
468
|
+
if (item.default.key) {
|
|
469
|
+
const hasProtocol = /^[a-zA-Z][a-zA-Z\d+\-.]*:\/\//.test(item.default.key);
|
|
470
|
+
const url = new URL(hasProtocol ? item.default.key : `https://${item.default.key}`);
|
|
471
|
+
item.host = url.host
|
|
472
|
+
|
|
473
|
+
let index = item.default.index || 0
|
|
474
|
+
item.index = index
|
|
475
|
+
item.val = await kernel.kv.get(item.host, index)
|
|
476
|
+
} else {
|
|
477
|
+
item.host = ""
|
|
478
|
+
}
|
|
479
|
+
} else {
|
|
480
|
+
item.val = item.default
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
requires_instantiation = true
|
|
484
|
+
}
|
|
485
|
+
pre_items.push(item)
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
return { items: pre_items, requires_instantiation }
|
|
490
|
+
}
|
|
491
|
+
module.exports = { ENV, get, get2, init_folders, requirements }
|