share command
This commit is contained in:
parent
5797ff9ebc
commit
cfa8f2795e
14
app/nose/bin/share.ts
Normal file
14
app/nose/bin/share.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { apps } from "app/src/webapp"
|
||||||
|
import { connectSneaker } from "app/src/sneaker"
|
||||||
|
|
||||||
|
export default async function (app: string) {
|
||||||
|
if (!app) {
|
||||||
|
return `usage: share <app>`
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!apps().includes(app)) {
|
||||||
|
return { error: `${app} not found` }
|
||||||
|
}
|
||||||
|
|
||||||
|
return await connectSneaker(app)
|
||||||
|
}
|
||||||
|
|
@ -1,38 +1,67 @@
|
||||||
import app from "./server"
|
import nose from "./server"
|
||||||
|
|
||||||
|
// const SNEAKER_URL = "sneaker-ep2i.onrender.com"
|
||||||
|
// const SNEAKER_TLS = true
|
||||||
const SNEAKER_URL = "localhost:3100"
|
const SNEAKER_URL = "localhost:3100"
|
||||||
|
const SNEAKER_TLS = false
|
||||||
|
|
||||||
const ws = new WebSocket(`ws://${SNEAKER_URL}/tunnel`)
|
type Connection = {
|
||||||
|
subdomain: string
|
||||||
ws.onerror = e => console.log("sneaker error", e)
|
ws: any
|
||||||
|
|
||||||
ws.onmessage = async event => {
|
|
||||||
const msg = JSON.parse(event.data.toString())
|
|
||||||
try {
|
|
||||||
const req = new Request("http://localhost" + msg.path, {
|
|
||||||
method: msg.method,
|
|
||||||
headers: msg.headers,
|
|
||||||
body: msg.body || undefined,
|
|
||||||
})
|
|
||||||
|
|
||||||
const res = await app.fetch(req)
|
|
||||||
|
|
||||||
const body = await res.text()
|
|
||||||
const headers: Record<string, string> = {}
|
|
||||||
res.headers.forEach((v, k) => (headers[k] = v))
|
|
||||||
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
id: msg.id,
|
|
||||||
status: res.status,
|
|
||||||
headers,
|
|
||||||
body,
|
|
||||||
}))
|
|
||||||
} catch (err: any) {
|
|
||||||
ws.send(JSON.stringify({
|
|
||||||
id: msg.id,
|
|
||||||
status: 500,
|
|
||||||
headers: { "content-type": "text/plain" },
|
|
||||||
body: "error: " + err.message,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const connections: Record<string, Connection> = {}
|
||||||
|
|
||||||
|
// returns the sneaker subdomain if successful
|
||||||
|
export async function connectSneaker(app: string): Promise<string> {
|
||||||
|
if (connections[app]) {
|
||||||
|
return connections[app].subdomain
|
||||||
|
}
|
||||||
|
|
||||||
|
const ws = new WebSocket(`ws${SNEAKER_TLS ? "s" : ""}://${SNEAKER_URL}/tunnel?app=${app}`)
|
||||||
|
let resolve: (v: string) => void
|
||||||
|
let promise = new Promise<string>(res => resolve = res)
|
||||||
|
|
||||||
|
ws.onclose = (e) => delete connections[app]
|
||||||
|
|
||||||
|
ws.onerror = e => console.error("sneaker error", e)
|
||||||
|
|
||||||
|
ws.onmessage = async event => {
|
||||||
|
const msg = JSON.parse(event.data.toString())
|
||||||
|
|
||||||
|
if (msg.subdomain) {
|
||||||
|
connections[app] = { subdomain: "", ws }
|
||||||
|
resolve(msg.subdomain)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const req = new Request(`http://${msg.app}.localhost` + msg.path, {
|
||||||
|
method: msg.method,
|
||||||
|
headers: msg.headers,
|
||||||
|
body: msg.body || undefined,
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = await nose.fetch(req)
|
||||||
|
|
||||||
|
const body = await res.text()
|
||||||
|
const headers: Record<string, string> = {}
|
||||||
|
res.headers.forEach((v, k) => (headers[k] = v))
|
||||||
|
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
id: msg.id,
|
||||||
|
status: res.status,
|
||||||
|
headers,
|
||||||
|
body,
|
||||||
|
}))
|
||||||
|
} catch (err: any) {
|
||||||
|
ws.send(JSON.stringify({
|
||||||
|
id: msg.id,
|
||||||
|
status: 500,
|
||||||
|
headers: { "content-type": "text/plain" },
|
||||||
|
body: "error: " + err.message,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user