Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Use Axios client for EventSource#440

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
bcpeinhardt merged 3 commits intocoder:mainfromaaronlehmann:event-source-axios-3
Mar 3, 2025
Merged
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletionsCHANGELOG.md
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,29 +2,43 @@

## Unreleased

- Remove agent singleton so that client TLS certificates are reloaded on every API request.

### Fixed

- Remove agent singleton so that client TLS certificates are reloaded on every API request.
- Use Axios client to receive event stream so TLS settings are properly applied.

## [v1.4.1](https://github.com/coder/vscode-coder/releases/tag/v1.4.1) (2025-02-19)

### Fixed

- Recreate REST client in spots where confirmStart may have waited indefinitely.

## [v1.4.0](https://github.com/coder/vscode-coder/releases/tag/v1.4.0) (2025-02-04)

### Fixed

- Recreate REST client after starting a workspace to ensure fresh TLS certificates.

### Changed

- Use `coder ssh` subcommand in place of `coder vscodessh`.

## [v1.3.10](https://github.com/coder/vscode-coder/releases/tag/v1.3.10) (2025-01-17)

### Fixed

- Fix bug where checking for overridden properties incorrectly converted host name pattern to regular expression.

## [v1.3.9](https://github.com/coder/vscode-coder/releases/tag/v1.3.9) (2024-12-12)

### Fixed

- Only show a login failure dialog for explicit logins (and not autologins).

## [v1.3.8](https://github.com/coder/vscode-coder/releases/tag/v1.3.8) (2024-12-06)

### Changed

- When starting a workspace, shell out to the Coder binary instead of making an
API call. This reduces drift between what the plugin does and the CLI does. As
part of this, the `session_token` file was renamed to `session` since that is
Expand Down
12 changes: 6 additions & 6 deletionspackage.json
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -208,10 +208,10 @@
],
"menus": {
"commandPalette": [
{
"command": "coder.openFromSidebar",
"when": "false"
}
{
"command": "coder.openFromSidebar",
"when": "false"
}
],
"view/title": [
{
Expand DownExpand Up@@ -275,7 +275,7 @@
"test:ci": "CI=true yarn test"
},
"devDependencies": {
"@types/eventsource": "^1.1.15",
"@types/eventsource": "^3.0.0",
"@types/glob": "^7.1.3",
"@types/node": "^18.0.0",
"@types/node-forge": "^1.3.11",
Expand DownExpand Up@@ -309,7 +309,7 @@
"dependencies": {
"axios": "1.7.7",
"date-fns": "^3.6.0",
"eventsource": "^2.0.2",
"eventsource": "^3.0.5",
"find-process": "^1.4.7",
"jsonc-parser": "^3.3.1",
"memfs": "^4.9.3",
Expand Down
3 changes: 3 additions & 0 deletionssrc/api-helper.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
import { isApiError, isApiErrorResponse } from "coder/site/src/api/errors"
import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
import { ErrorEvent } from "eventsource"
import { z } from "zod"

export function errToStr(error: unknown, def: string) {
Expand All@@ -9,6 +10,8 @@ export function errToStr(error: unknown, def: string) {
return error.response.data.message
} else if (isApiErrorResponse(error)) {
return error.message
} else if (error instanceof ErrorEvent) {
return error.code ? `${error.code}: ${error.message || def}` : error.message || def
} else if (typeof error === "string" && error.trim().length > 0) {
return error
}
Expand Down
56 changes: 56 additions & 0 deletionssrc/api.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
import { AxiosInstance } from "axios"
import { spawn } from "child_process"
import { Api } from "coder/site/src/api/api"
import { ProvisionerJobLog, Workspace } from "coder/site/src/api/typesGenerated"
import { FetchLikeInit } from "eventsource"
import fs from "fs/promises"
import { ProxyAgent } from "proxy-agent"
import * as vscode from "vscode"
Expand DownExpand Up@@ -90,6 +92,58 @@ export async function makeCoderSdk(baseUrl: string, token: string | undefined, s
return restClient
}

/**
* Creates a fetch adapter using an Axios instance that returns streaming responses.
* This can be used with APIs that accept fetch-like interfaces.
*/
export function createStreamingFetchAdapter(axiosInstance: AxiosInstance) {
return async (url: string | URL, init?: FetchLikeInit) => {
const urlStr = url.toString()

const response = await axiosInstance.request({
url: urlStr,
headers: init?.headers as Record<string, string>,
responseType: "stream",
validateStatus: () => true, // Don't throw on any status code
})
const stream = new ReadableStream({
start(controller) {
response.data.on("data", (chunk: Buffer) => {
controller.enqueue(chunk)
})

response.data.on("end", () => {
controller.close()
})

response.data.on("error", (err: Error) => {
controller.error(err)
})
},

cancel() {
response.data.destroy()
return Promise.resolve()
},
})

return {
body: {
getReader: () => stream.getReader(),
},
url: urlStr,
status: response.status,
redirected: response.request.res.responseUrl !== urlStr,
headers: {
get: (name: string) => {
const value = response.headers[name.toLowerCase()]
return value === undefined ? null : String(value)
},
},
}
}
}

/**
* Start or update a workspace and return the updated workspace.
*/
Expand DownExpand Up@@ -182,6 +236,7 @@ export async function waitForBuild(
path += `&after=${logs[logs.length - 1].id}`
}

const agent = await createHttpAgent()
await new Promise<void>((resolve, reject) => {
try {
const baseUrl = new URL(baseUrlRaw)
Expand All@@ -194,6 +249,7 @@ export async function waitForBuild(
| undefined,
},
followRedirects: true,
agent: agent,
})
socket.binaryType = "nodebuffer"
socket.on("message", (data) => {
Expand Down
12 changes: 4 additions & 8 deletionssrc/workspaceMonitor.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
import { Api } from "coder/site/src/api/api"
import { Workspace } from "coder/site/src/api/typesGenerated"
import { formatDistanceToNowStrict } from "date-fns"
import EventSource from "eventsource"
import{EventSource } from "eventsource"
import * as vscode from "vscode"
import { createStreamingFetchAdapter } from "./api"
import { errToStr } from "./api-helper"
import { Storage } from "./storage"

Expand DownExpand Up@@ -40,16 +41,11 @@ export class WorkspaceMonitor implements vscode.Disposable {
) {
this.name = `${workspace.owner_name}/${workspace.name}`
const url = this.restClient.getAxiosInstance().defaults.baseURL
const token = this.restClient.getAxiosInstance().defaults.headers.common["Coder-Session-Token"] as
| string
| undefined
const watchUrl = new URL(`${url}/api/v2/workspaces/${workspace.id}/watch`)
this.storage.writeToCoderOutputChannel(`Monitoring ${this.name}...`)

const eventSource = new EventSource(watchUrl.toString(), {
headers: {
"Coder-Session-Token": token,
},
fetch: createStreamingFetchAdapter(this.restClient.getAxiosInstance()),
})

eventSource.addEventListener("data", (event) => {
Expand All@@ -64,7 +60,7 @@ export class WorkspaceMonitor implements vscode.Disposable {
})

eventSource.addEventListener("error", (event) => {
this.notifyError(event.data)
this.notifyError(event)
})

// Store so we can close in dispose().
Expand Down
8 changes: 3 additions & 5 deletionssrc/workspacesProvider.ts
View file
Open in desktop
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
import { Api } from "coder/site/src/api/api"
import { Workspace, WorkspaceAgent } from "coder/site/src/api/typesGenerated"
import EventSource from "eventsource"
import{EventSource } from "eventsource"
import * as path from "path"
import * as vscode from "vscode"
import { createStreamingFetchAdapter } from "./api"
import {
AgentMetadataEvent,
AgentMetadataEventSchemaArray,
Expand DownExpand Up@@ -228,12 +229,9 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
function monitorMetadata(agentId: WorkspaceAgent["id"], restClient: Api): AgentWatcher {
// TODO: Is there a better way to grab the url and token?
const url = restClient.getAxiosInstance().defaults.baseURL
const token = restClient.getAxiosInstance().defaults.headers.common["Coder-Session-Token"] as string | undefined
const metadataUrl = new URL(`${url}/api/v2/workspaceagents/${agentId}/watch-metadata`)
const eventSource = new EventSource(metadataUrl.toString(), {
headers: {
"Coder-Session-Token": token,
},
fetch: createStreamingFetchAdapter(restClient.getAxiosInstance()),
})

let disposed = false
Expand Down
25 changes: 17 additions & 8 deletionsyarn.lock
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -537,10 +537,12 @@
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4"
integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==

"@types/eventsource@^1.1.15":
version "1.1.15"
resolved "https://registry.yarnpkg.com/@types/eventsource/-/eventsource-1.1.15.tgz#949383d3482e20557cbecbf3b038368d94b6be27"
integrity sha512-XQmGcbnxUNa06HR3VBVkc9+A2Vpi9ZyLJcdS5dwaQQ/4ZMWFO+5c90FnMUpbtMZwB/FChoYHwuVg8TvkECacTA==
"@types/eventsource@^3.0.0":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/eventsource/-/eventsource-3.0.0.tgz#6b1b50c677032fd3be0b5c322e8ae819b3df62eb"
integrity sha512-yEhFj31FTD29DtNeqePu+A+lD6loRef6YOM5XfN1kUwBHyy2DySGlA3jJU+FbQSkrfmlBVluf2Dub/OyReFGKA==
dependencies:
eventsource "*"

"@types/glob@^7.1.3":
version "7.2.0"
Expand DownExpand Up@@ -2529,10 +2531,17 @@ events@^3.2.0:
resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400"
integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==

eventsource@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-2.0.2.tgz#76dfcc02930fb2ff339520b6d290da573a9e8508"
integrity sha512-IzUmBGPR3+oUG9dUeXynyNmf91/3zUSJg1lCktzKw47OXuhco54U3r9B7O4XX+Rb1Itm9OZ2b0RkTs10bICOxA==
eventsource-parser@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.0.tgz#9303e303ef807d279ee210a17ce80f16300d9f57"
integrity sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==

eventsource@*, eventsource@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.5.tgz#0cae1eee2d2c75894de8b02a91d84e5c57f0cc5a"
integrity sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==
dependencies:
eventsource-parser "^3.0.0"

exec@^0.2.1:
version "0.2.1"
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp