mirror of https://github.com/coder/coder.git
fix: update API code to use Axios instances (#13029)
* fix: update API code to use Axios instance * docs: fix typo * fix: update all global axios imports to use Coder instance * fix: remove needless import * fix: update import order * refactor: rename coderAxiosInstance to axiosInstance * docs: update variable reference in FE contributing docs
This commit is contained in:
parent
dd27a8a634
commit
3f21cb8a2f
|
@ -152,7 +152,7 @@ example below:
|
||||||
export const getAgentListeningPorts = async (
|
export const getAgentListeningPorts = async (
|
||||||
agentID: string,
|
agentID: string,
|
||||||
): Promise<TypesGen.ListeningPortsResponse> => {
|
): Promise<TypesGen.ListeningPortsResponse> => {
|
||||||
const response = await axios.get(
|
const response = await axiosInstance.get(
|
||||||
`/api/v2/workspaceagents/${agentID}/listening-ports`,
|
`/api/v2/workspaceagents/${agentID}/listening-ports`,
|
||||||
);
|
);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { type BrowserContext, expect, type Page, test } from "@playwright/test";
|
import { type BrowserContext, expect, type Page, test } from "@playwright/test";
|
||||||
import axios from "axios";
|
|
||||||
import { type ChildProcess, exec, spawn } from "child_process";
|
import { type ChildProcess, exec, spawn } from "child_process";
|
||||||
import { randomUUID } from "crypto";
|
import { randomUUID } from "crypto";
|
||||||
import express from "express";
|
import express from "express";
|
||||||
|
@ -7,6 +6,7 @@ import capitalize from "lodash/capitalize";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import * as ssh from "ssh2";
|
import * as ssh from "ssh2";
|
||||||
import { Duplex } from "stream";
|
import { Duplex } from "stream";
|
||||||
|
import { axiosInstance } from "api/api";
|
||||||
import type {
|
import type {
|
||||||
WorkspaceBuildParameter,
|
WorkspaceBuildParameter,
|
||||||
UpdateTemplateMeta,
|
UpdateTemplateMeta,
|
||||||
|
@ -398,7 +398,7 @@ export const waitUntilUrlIsNotResponding = async (url: string) => {
|
||||||
|
|
||||||
while (retries < maxRetries) {
|
while (retries < maxRetries) {
|
||||||
try {
|
try {
|
||||||
await axios.get(url);
|
await axiosInstance.get(url);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,9 @@ import type {
|
||||||
Reporter,
|
Reporter,
|
||||||
TestError,
|
TestError,
|
||||||
} from "@playwright/test/reporter";
|
} from "@playwright/test/reporter";
|
||||||
import axios from "axios";
|
|
||||||
import * as fs from "fs/promises";
|
import * as fs from "fs/promises";
|
||||||
import type { Writable } from "stream";
|
import type { Writable } from "stream";
|
||||||
|
import { axiosInstance } from "api/api";
|
||||||
import { coderdPProfPort, enterpriseLicense } from "./constants";
|
import { coderdPProfPort, enterpriseLicense } from "./constants";
|
||||||
|
|
||||||
class CoderReporter implements Reporter {
|
class CoderReporter implements Reporter {
|
||||||
|
@ -136,9 +136,10 @@ class CoderReporter implements Reporter {
|
||||||
const logLines = (chunk: string): string[] => chunk.trimEnd().split("\n");
|
const logLines = (chunk: string): string[] => chunk.trimEnd().split("\n");
|
||||||
|
|
||||||
const exportDebugPprof = async (outputFile: string) => {
|
const exportDebugPprof = async (outputFile: string) => {
|
||||||
const response = await axios.get(
|
const response = await axiosInstance.get(
|
||||||
`http://127.0.0.1:${coderdPProfPort}/debug/pprof/goroutine?debug=1`,
|
`http://127.0.0.1:${coderdPProfPort}/debug/pprof/goroutine?debug=1`,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
throw new Error(`Error: Received status code ${response.status}`);
|
throw new Error(`Error: Received status code ${response.status}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
import axios from "axios";
|
|
||||||
import {
|
import {
|
||||||
MockTemplate,
|
MockTemplate,
|
||||||
MockTemplateVersionParameter1,
|
MockTemplateVersionParameter1,
|
||||||
|
@ -8,6 +7,7 @@ import {
|
||||||
MockWorkspaceBuildParameter1,
|
MockWorkspaceBuildParameter1,
|
||||||
} from "testHelpers/entities";
|
} from "testHelpers/entities";
|
||||||
import * as api from "./api";
|
import * as api from "./api";
|
||||||
|
import { axiosInstance } from "./api";
|
||||||
import type * as TypesGen from "./typesGenerated";
|
import type * as TypesGen from "./typesGenerated";
|
||||||
|
|
||||||
describe("api.ts", () => {
|
describe("api.ts", () => {
|
||||||
|
@ -17,13 +17,16 @@ describe("api.ts", () => {
|
||||||
const loginResponse: TypesGen.LoginWithPasswordResponse = {
|
const loginResponse: TypesGen.LoginWithPasswordResponse = {
|
||||||
session_token: "abc_123_test",
|
session_token: "abc_123_test",
|
||||||
};
|
};
|
||||||
jest.spyOn(axios, "post").mockResolvedValueOnce({ data: loginResponse });
|
|
||||||
|
jest
|
||||||
|
.spyOn(axiosInstance, "post")
|
||||||
|
.mockResolvedValueOnce({ data: loginResponse });
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await api.login("test", "123");
|
const result = await api.login("test", "123");
|
||||||
|
|
||||||
// then
|
// then
|
||||||
expect(axios.post).toHaveBeenCalled();
|
expect(axiosInstance.post).toHaveBeenCalled();
|
||||||
expect(result).toStrictEqual(loginResponse);
|
expect(result).toStrictEqual(loginResponse);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -38,7 +41,7 @@ describe("api.ts", () => {
|
||||||
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
||||||
return Promise.reject(expectedError);
|
return Promise.reject(expectedError);
|
||||||
});
|
});
|
||||||
axios.post = axiosMockPost;
|
axiosInstance.post = axiosMockPost;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.login("test", "123");
|
await api.login("test", "123");
|
||||||
|
@ -54,7 +57,7 @@ describe("api.ts", () => {
|
||||||
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
});
|
});
|
||||||
axios.post = axiosMockPost;
|
axiosInstance.post = axiosMockPost;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
await api.logout();
|
await api.logout();
|
||||||
|
@ -73,7 +76,8 @@ describe("api.ts", () => {
|
||||||
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
||||||
return Promise.reject(expectedError);
|
return Promise.reject(expectedError);
|
||||||
});
|
});
|
||||||
axios.post = axiosMockPost;
|
|
||||||
|
axiosInstance.post = axiosMockPost;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.logout();
|
await api.logout();
|
||||||
|
@ -92,7 +96,8 @@ describe("api.ts", () => {
|
||||||
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
||||||
return Promise.resolve({ data: apiKeyResponse });
|
return Promise.resolve({ data: apiKeyResponse });
|
||||||
});
|
});
|
||||||
axios.post = axiosMockPost;
|
|
||||||
|
axiosInstance.post = axiosMockPost;
|
||||||
|
|
||||||
// when
|
// when
|
||||||
const result = await api.getApiKey();
|
const result = await api.getApiKey();
|
||||||
|
@ -112,7 +117,8 @@ describe("api.ts", () => {
|
||||||
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
const axiosMockPost = jest.fn().mockImplementationOnce(() => {
|
||||||
return Promise.reject(expectedError);
|
return Promise.reject(expectedError);
|
||||||
});
|
});
|
||||||
axios.post = axiosMockPost;
|
|
||||||
|
axiosInstance.post = axiosMockPost;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.getApiKey();
|
await api.getApiKey();
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
||||||
import axios, { type AxiosError, type AxiosResponse } from "axios";
|
import { type AxiosError, type AxiosResponse, isAxiosError } from "axios";
|
||||||
|
|
||||||
const Language = {
|
const Language = {
|
||||||
errorsByCode: {
|
errorsByCode: {
|
||||||
|
@ -25,7 +25,7 @@ export type ApiError = AxiosError<ApiErrorResponse> & {
|
||||||
|
|
||||||
export const isApiError = (err: unknown): err is ApiError => {
|
export const isApiError = (err: unknown): err is ApiError => {
|
||||||
return (
|
return (
|
||||||
axios.isAxiosError(err) &&
|
isAxiosError(err) &&
|
||||||
err.response !== undefined &&
|
err.response !== undefined &&
|
||||||
isApiErrorResponse(err.response.data)
|
isApiErrorResponse(err.response.data)
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import axios from "axios";
|
|
||||||
import { type FC, useEffect } from "react";
|
import { type FC, useEffect } from "react";
|
||||||
import { Outlet, Navigate, useLocation } from "react-router-dom";
|
import { Outlet, Navigate, useLocation } from "react-router-dom";
|
||||||
|
import { axiosInstance } from "api/api";
|
||||||
import { isApiError } from "api/errors";
|
import { isApiError } from "api/errors";
|
||||||
import { Loader } from "components/Loader/Loader";
|
import { Loader } from "components/Loader/Loader";
|
||||||
import { ProxyProvider } from "contexts/ProxyContext";
|
import { ProxyProvider } from "contexts/ProxyContext";
|
||||||
|
@ -22,7 +22,7 @@ export const RequireAuth: FC = () => {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const interceptorHandle = axios.interceptors.response.use(
|
const interceptorHandle = axiosInstance.interceptors.response.use(
|
||||||
(okResponse) => okResponse,
|
(okResponse) => okResponse,
|
||||||
(error: unknown) => {
|
(error: unknown) => {
|
||||||
// 401 Unauthorized
|
// 401 Unauthorized
|
||||||
|
@ -32,13 +32,14 @@ export const RequireAuth: FC = () => {
|
||||||
signOut();
|
signOut();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, pass the response through so that it can be displayed in the UI
|
// Otherwise, pass the response through so that it can be displayed in
|
||||||
|
// the UI
|
||||||
return Promise.reject(error);
|
return Promise.reject(error);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
axios.interceptors.response.eject(interceptorHandle);
|
axiosInstance.interceptors.response.eject(interceptorHandle);
|
||||||
};
|
};
|
||||||
}, [isLoading, isSigningOut, isSignedIn, signOut]);
|
}, [isLoading, isSigningOut, isSignedIn, signOut]);
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import PerformanceObserver from "@fastly/performance-observer-polyfill";
|
import PerformanceObserver from "@fastly/performance-observer-polyfill";
|
||||||
import axios from "axios";
|
|
||||||
import { useEffect, useReducer, useState } from "react";
|
import { useEffect, useReducer, useState } from "react";
|
||||||
|
import { axiosInstance } from "api/api";
|
||||||
import type { Region } from "api/typesGenerated";
|
import type { Region } from "api/typesGenerated";
|
||||||
import { generateRandomString } from "utils/random";
|
import { generateRandomString } from "utils/random";
|
||||||
|
|
||||||
|
@ -198,7 +198,7 @@ export const useProxyLatency = (
|
||||||
observer.observe({ entryTypes: ["resource"] });
|
observer.observe({ entryTypes: ["resource"] });
|
||||||
|
|
||||||
const proxyRequests = Object.keys(proxyChecks).map((latencyURL) => {
|
const proxyRequests = Object.keys(proxyChecks).map((latencyURL) => {
|
||||||
return axios.get(latencyURL, {
|
return axiosInstance.get(latencyURL, {
|
||||||
withCredentials: false,
|
withCredentials: false,
|
||||||
// Must add a custom header to make the request not a "simple request".
|
// Must add a custom header to make the request not a "simple request".
|
||||||
// We want to force a preflight request.
|
// We want to force a preflight request.
|
||||||
|
|
Loading…
Reference in New Issue