mirror of https://github.com/coder/code-server.git
Implement endpoint for getting recent directories
This commit is contained in:
parent
16bcf59cb0
commit
8793110941
|
@ -10,8 +10,17 @@ body {
|
|||
background: #272727;
|
||||
color: #f4f4f4;
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji",
|
||||
"Segoe UI Emoji", "Segoe UI Symbol";
|
||||
font-family:
|
||||
-apple-system,
|
||||
BlinkMacSystemFont,
|
||||
"Segoe UI",
|
||||
Roboto,
|
||||
Helvetica,
|
||||
Arial,
|
||||
sans-serif,
|
||||
"Apple Color Emoji",
|
||||
"Segoe UI Emoji",
|
||||
"Segoe UI Symbol";
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
|
|
|
@ -33,8 +33,11 @@ export interface SessionResponse {
|
|||
}
|
||||
|
||||
export interface RecentResponse {
|
||||
readonly recent: ReadonlyArray<Application>
|
||||
readonly running: ReadonlyArray<Application>
|
||||
readonly paths: string[]
|
||||
}
|
||||
|
||||
export interface RunningResponse {
|
||||
readonly applications: ReadonlyArray<Application>
|
||||
}
|
||||
|
||||
export interface HealthRequest {
|
||||
|
|
|
@ -19,6 +19,7 @@ export enum ApiEndpoint {
|
|||
applications = "/applications",
|
||||
recent = "/recent",
|
||||
run = "/run",
|
||||
running = "/running",
|
||||
session = "/session",
|
||||
status = "/status",
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
import { field, logger } from "@coder/logger"
|
||||
import * as cp from "child_process"
|
||||
import * as fs from "fs-extra"
|
||||
import * as http from "http"
|
||||
import * as net from "net"
|
||||
import * as path from "path"
|
||||
import * as url from "url"
|
||||
import * as WebSocket from "ws"
|
||||
import {
|
||||
Application,
|
||||
ApplicationsResponse,
|
||||
ClientMessage,
|
||||
RecentResponse,
|
||||
RunningResponse,
|
||||
ServerMessage,
|
||||
SessionError,
|
||||
SessionResponse,
|
||||
|
@ -22,6 +26,12 @@ interface ServerSession {
|
|||
readonly app: Application
|
||||
}
|
||||
|
||||
interface VsRecents {
|
||||
[key: string]: (string | object)[]
|
||||
}
|
||||
|
||||
type VsSettings = [string, string][]
|
||||
|
||||
/**
|
||||
* API HTTP provider.
|
||||
*/
|
||||
|
@ -29,7 +39,11 @@ export class ApiHttpProvider extends HttpProvider {
|
|||
private readonly ws = new WebSocket.Server({ noServer: true })
|
||||
private readonly sessions = new Map<string, ServerSession>()
|
||||
|
||||
public constructor(options: HttpProviderOptions, private readonly server: HttpServer) {
|
||||
public constructor(
|
||||
options: HttpProviderOptions,
|
||||
private readonly server: HttpServer,
|
||||
private readonly dataDir?: string,
|
||||
) {
|
||||
super(options)
|
||||
}
|
||||
|
||||
|
@ -60,6 +74,11 @@ export class ApiHttpProvider extends HttpProvider {
|
|||
return {
|
||||
content: await this.recent(),
|
||||
} as HttpResponse<RecentResponse>
|
||||
case ApiEndpoint.running:
|
||||
this.ensureMethod(request)
|
||||
return {
|
||||
content: await this.running(),
|
||||
} as HttpResponse<RunningResponse>
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
@ -280,12 +299,58 @@ export class ApiHttpProvider extends HttpProvider {
|
|||
}
|
||||
|
||||
/**
|
||||
* Return recent sessions.
|
||||
* Return VS Code's recent paths.
|
||||
*/
|
||||
public async recent(): Promise<RecentResponse> {
|
||||
try {
|
||||
if (!this.dataDir) {
|
||||
throw new Error("data directory is not set")
|
||||
}
|
||||
|
||||
const state: VsSettings = JSON.parse(await fs.readFile(path.join(this.dataDir, "User/state/global.json"), "utf8"))
|
||||
const setting = Array.isArray(state) && state.find((item) => item[0] === "recently.opened")
|
||||
if (!setting) {
|
||||
throw new Error("settings appear malformed")
|
||||
}
|
||||
|
||||
const paths: { [key: string]: Promise<string> } = {}
|
||||
Object.values(JSON.parse(setting[1]) as VsRecents).forEach((recents) => {
|
||||
recents
|
||||
.filter((recent) => typeof recent === "string")
|
||||
.forEach((recent) => {
|
||||
try {
|
||||
const pathname = url.parse(recent as string).pathname
|
||||
if (pathname && !paths[pathname]) {
|
||||
paths[pathname] = new Promise<string>((resolve) => {
|
||||
fs.stat(pathname)
|
||||
.then(() => resolve(pathname))
|
||||
.catch(() => resolve())
|
||||
})
|
||||
}
|
||||
} catch (error) {
|
||||
logger.debug("invalid path", field("path", recent))
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
recent: [], // TODO
|
||||
running: Array.from(this.sessions).map(([sessionId, session]) => ({
|
||||
paths: await Promise.all(Object.values(paths)),
|
||||
}
|
||||
} catch (error) {
|
||||
if (error.code !== "ENOENT") {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
return { paths: [] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Return running sessions.
|
||||
*/
|
||||
public async running(): Promise<RunningResponse> {
|
||||
return {
|
||||
applications: Array.from(this.sessions).map(([sessionId, session]) => ({
|
||||
...session.app,
|
||||
sessionId,
|
||||
})),
|
||||
|
|
|
@ -90,14 +90,14 @@ export class MainHttpProvider extends HttpProvider {
|
|||
}
|
||||
|
||||
public async getRoot(route: Route): Promise<HttpResponse> {
|
||||
const recent = await this.api.recent()
|
||||
const running = await this.api.running()
|
||||
const apps = await this.api.installedApplications()
|
||||
const response = await this.getUtf8Resource(this.rootPath, "src/browser/pages/home.html")
|
||||
response.content = response.content
|
||||
.replace(/{{COMMIT}}/g, this.options.commit)
|
||||
.replace(/{{BASE}}/g, this.base(route))
|
||||
.replace(/{{UPDATE:NAME}}/, await this.getUpdate())
|
||||
.replace(/{{APP_LIST:RUNNING}}/, this.getAppRows(recent.running))
|
||||
.replace(/{{APP_LIST:RUNNING}}/, this.getAppRows(running.applications))
|
||||
.replace(
|
||||
/{{APP_LIST:EDITORS}}/,
|
||||
this.getAppRows(apps.filter((app) => app.categories && app.categories.includes("Editor"))),
|
||||
|
|
|
@ -44,7 +44,7 @@ const main = async (args: Args): Promise<void> => {
|
|||
}
|
||||
|
||||
const httpServer = new HttpServer(options)
|
||||
const api = httpServer.registerHttpProvider("/api", ApiHttpProvider, httpServer)
|
||||
const api = httpServer.registerHttpProvider("/api", ApiHttpProvider, httpServer, args["user-data-dir"])
|
||||
const update = httpServer.registerHttpProvider("/update", UpdateHttpProvider, !args["disable-updates"])
|
||||
httpServer.registerHttpProvider("/vscode", VscodeHttpProvider, args)
|
||||
httpServer.registerHttpProvider("/login", LoginHttpProvider)
|
||||
|
|
Loading…
Reference in New Issue