diff --git a/biome.jsonc b/biome.jsonc
index 10e0514f21..51b6936f6e 100644
--- a/biome.jsonc
+++ b/biome.jsonc
@@ -3,11 +3,13 @@
"enabled": true,
"clientKind": "git",
"useIgnoreFile": true,
- "defaultBranch": "main",
+ "defaultBranch": "main"
},
"files": {
- "includes": ["**", "!**/pnpm-lock.yaml"],
- "ignoreUnknown": true,
+ // static/*.html are Go templates with {{ }} directives that
+ // Biome's HTML parser does not support.
+ "includes": ["**", "!**/pnpm-lock.yaml", "!**/static/*.html"],
+ "ignoreUnknown": true
},
"linter": {
"rules": {
@@ -15,7 +17,7 @@
"noSvgWithoutTitle": "off",
"useButtonType": "off",
"useSemanticElements": "off",
- "noStaticElementInteractions": "off",
+ "noStaticElementInteractions": "off"
},
"correctness": {
"noUnusedImports": "warn",
@@ -24,9 +26,9 @@
"noUnusedVariables": {
"level": "warn",
"options": {
- "ignoreRestSiblings": true,
- },
- },
+ "ignoreRestSiblings": true
+ }
+ }
},
"style": {
"noNonNullAssertion": "off",
@@ -47,7 +49,7 @@
"paths": {
"react": {
"message": "React 19 no longer requires forwardRef. Use ref as a prop instead.",
- "importNames": ["forwardRef"],
+ "importNames": ["forwardRef"]
},
// "@mui/material/Alert": "Use components/Alert/Alert instead.",
// "@mui/material/AlertTitle": "Use components/Alert/Alert instead.",
@@ -115,10 +117,10 @@
"@emotion/styled": "Use Tailwind CSS instead.",
// "@emotion/cache": "Use Tailwind CSS instead.",
// "components/Stack/Stack": "Use Tailwind flex utilities instead (e.g.,
).",
- "lodash": "Use lodash/
instead.",
- },
- },
- },
+ "lodash": "Use lodash/ instead."
+ }
+ }
+ }
},
"suspicious": {
"noArrayIndexKey": "off",
@@ -129,14 +131,21 @@
"noConsole": {
"level": "error",
"options": {
- "allow": ["error", "info", "warn"],
- },
- },
+ "allow": ["error", "info", "warn"]
+ }
+ }
},
"complexity": {
- "noImportantStyles": "off", // TODO: check and fix !important styles
- },
- },
+ "noImportantStyles": "off" // TODO: check and fix !important styles
+ }
+ }
},
- "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
+ "css": {
+ "parser": {
+ // Biome 2.3+ requires opt-in for @apply and other
+ // Tailwind directives.
+ "tailwindDirectives": true
+ }
+ },
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json"
}
diff --git a/package.json b/package.json
index b220803ad7..46c56d10e9 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,7 @@
"storybook": "pnpm run -C site/ storybook"
},
"devDependencies": {
- "@biomejs/biome": "2.2.0",
+ "@biomejs/biome": "2.4.10",
"markdown-table-formatter": "^1.6.1",
"markdownlint-cli2": "^0.16.0",
"quicktype": "^23.0.0"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1e2921375a..35d88ae183 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -12,8 +12,8 @@ importers:
.:
devDependencies:
'@biomejs/biome':
- specifier: 2.2.0
- version: 2.2.0
+ specifier: 2.4.10
+ version: 2.4.10
markdown-table-formatter:
specifier: ^1.6.1
version: 1.6.1
@@ -26,55 +26,55 @@ importers:
packages:
- '@biomejs/biome@2.2.0':
- resolution: {integrity: sha512-3On3RSYLsX+n9KnoSgfoYlckYBoU6VRM22cw1gB4Y0OuUVSYd/O/2saOJMrA4HFfA1Ff0eacOvMN1yAAvHtzIw==}
+ '@biomejs/biome@2.4.10':
+ resolution: {integrity: sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w==}
engines: {node: '>=14.21.3'}
hasBin: true
- '@biomejs/cli-darwin-arm64@2.2.0':
- resolution: {integrity: sha512-zKbwUUh+9uFmWfS8IFxmVD6XwqFcENjZvEyfOxHs1epjdH3wyyMQG80FGDsmauPwS2r5kXdEM0v/+dTIA9FXAg==}
+ '@biomejs/cli-darwin-arm64@2.4.10':
+ resolution: {integrity: sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
- '@biomejs/cli-darwin-x64@2.2.0':
- resolution: {integrity: sha512-+OmT4dsX2eTfhD5crUOPw3RPhaR+SKVspvGVmSdZ9y9O/AgL8pla6T4hOn1q+VAFBHuHhsdxDRJgFCSC7RaMOw==}
+ '@biomejs/cli-darwin-x64@2.4.10':
+ resolution: {integrity: sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
- '@biomejs/cli-linux-arm64-musl@2.2.0':
- resolution: {integrity: sha512-egKpOa+4FL9YO+SMUMLUvf543cprjevNc3CAgDNFLcjknuNMcZ0GLJYa3EGTCR2xIkIUJDVneBV3O9OcIlCEZQ==}
+ '@biomejs/cli-linux-arm64-musl@2.4.10':
+ resolution: {integrity: sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
- '@biomejs/cli-linux-arm64@2.2.0':
- resolution: {integrity: sha512-6eoRdF2yW5FnW9Lpeivh7Mayhq0KDdaDMYOJnH9aT02KuSIX5V1HmWJCQQPwIQbhDh68Zrcpl8inRlTEan0SXw==}
+ '@biomejs/cli-linux-arm64@2.4.10':
+ resolution: {integrity: sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
- '@biomejs/cli-linux-x64-musl@2.2.0':
- resolution: {integrity: sha512-I5J85yWwUWpgJyC1CcytNSGusu2p9HjDnOPAFG4Y515hwRD0jpR9sT9/T1cKHtuCvEQ/sBvx+6zhz9l9wEJGAg==}
+ '@biomejs/cli-linux-x64-musl@2.4.10':
+ resolution: {integrity: sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
- '@biomejs/cli-linux-x64@2.2.0':
- resolution: {integrity: sha512-5UmQx/OZAfJfi25zAnAGHUMuOd+LOsliIt119x2soA2gLggQYrVPA+2kMUxR6Mw5M1deUF/AWWP2qpxgH7Nyfw==}
+ '@biomejs/cli-linux-x64@2.4.10':
+ resolution: {integrity: sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
- '@biomejs/cli-win32-arm64@2.2.0':
- resolution: {integrity: sha512-n9a1/f2CwIDmNMNkFs+JI0ZjFnMO0jdOyGNtihgUNFnlmd84yIYY2KMTBmMV58ZlVHjgmY5Y6E1hVTnSRieggA==}
+ '@biomejs/cli-win32-arm64@2.4.10':
+ resolution: {integrity: sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ==}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
- '@biomejs/cli-win32-x64@2.2.0':
- resolution: {integrity: sha512-Nawu5nHjP/zPKTIryh2AavzTc/KEg4um/MxWdXW0A6P/RZOyIpa7+QSjeXwAwX/utJGaCoXRPWtF3m5U/bB3Ww==}
+ '@biomejs/cli-win32-x64@2.4.10':
+ resolution: {integrity: sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg==}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
@@ -778,39 +778,39 @@ packages:
snapshots:
- '@biomejs/biome@2.2.0':
+ '@biomejs/biome@2.4.10':
optionalDependencies:
- '@biomejs/cli-darwin-arm64': 2.2.0
- '@biomejs/cli-darwin-x64': 2.2.0
- '@biomejs/cli-linux-arm64': 2.2.0
- '@biomejs/cli-linux-arm64-musl': 2.2.0
- '@biomejs/cli-linux-x64': 2.2.0
- '@biomejs/cli-linux-x64-musl': 2.2.0
- '@biomejs/cli-win32-arm64': 2.2.0
- '@biomejs/cli-win32-x64': 2.2.0
+ '@biomejs/cli-darwin-arm64': 2.4.10
+ '@biomejs/cli-darwin-x64': 2.4.10
+ '@biomejs/cli-linux-arm64': 2.4.10
+ '@biomejs/cli-linux-arm64-musl': 2.4.10
+ '@biomejs/cli-linux-x64': 2.4.10
+ '@biomejs/cli-linux-x64-musl': 2.4.10
+ '@biomejs/cli-win32-arm64': 2.4.10
+ '@biomejs/cli-win32-x64': 2.4.10
- '@biomejs/cli-darwin-arm64@2.2.0':
+ '@biomejs/cli-darwin-arm64@2.4.10':
optional: true
- '@biomejs/cli-darwin-x64@2.2.0':
+ '@biomejs/cli-darwin-x64@2.4.10':
optional: true
- '@biomejs/cli-linux-arm64-musl@2.2.0':
+ '@biomejs/cli-linux-arm64-musl@2.4.10':
optional: true
- '@biomejs/cli-linux-arm64@2.2.0':
+ '@biomejs/cli-linux-arm64@2.4.10':
optional: true
- '@biomejs/cli-linux-x64-musl@2.2.0':
+ '@biomejs/cli-linux-x64-musl@2.4.10':
optional: true
- '@biomejs/cli-linux-x64@2.2.0':
+ '@biomejs/cli-linux-x64@2.4.10':
optional: true
- '@biomejs/cli-win32-arm64@2.2.0':
+ '@biomejs/cli-win32-arm64@2.4.10':
optional: true
- '@biomejs/cli-win32-x64@2.2.0':
+ '@biomejs/cli-win32-x64@2.4.10':
optional: true
'@cspotcode/source-map-support@0.8.1':
diff --git a/site/e2e/tests/externalAuth.spec.ts b/site/e2e/tests/externalAuth.spec.ts
index f5c429dd53..796dd0644e 100644
--- a/site/e2e/tests/externalAuth.spec.ts
+++ b/site/e2e/tests/externalAuth.spec.ts
@@ -12,162 +12,164 @@ import {
} from "../helpers";
import { beforeCoderTest, resetExternalAuthKey } from "../hooks";
-test.describe.skip("externalAuth", () => {
- test.beforeAll(async ({ baseURL }) => {
- const srv = await createServer(gitAuth.webPort);
+test.describe
+ .skip("externalAuth", () => {
+ test.beforeAll(async ({ baseURL }) => {
+ const srv = await createServer(gitAuth.webPort);
- // The GitHub validate endpoint returns the currently authenticated user!
- srv.use(gitAuth.validatePath, (_req, res) => {
- res.write(JSON.stringify(ghUser));
- res.end();
+ // The GitHub validate endpoint returns the currently authenticated user!
+ srv.use(gitAuth.validatePath, (_req, res) => {
+ res.write(JSON.stringify(ghUser));
+ res.end();
+ });
+ srv.use(gitAuth.tokenPath, (_req, res) => {
+ const r = (Math.random() + 1).toString(36).substring(7);
+ res.write(JSON.stringify({ access_token: r }));
+ res.end();
+ });
+ srv.use(gitAuth.authPath, (req, res) => {
+ res.redirect(
+ `${baseURL}/external-auth/${gitAuth.webProvider}/callback?code=1234&state=${req.query.state}`,
+ );
+ });
});
- srv.use(gitAuth.tokenPath, (_req, res) => {
- const r = (Math.random() + 1).toString(36).substring(7);
- res.write(JSON.stringify({ access_token: r }));
- res.end();
+
+ test.beforeEach(async ({ context, page }) => {
+ beforeCoderTest(page);
+ await login(page);
+ await resetExternalAuthKey(context);
});
- srv.use(gitAuth.authPath, (req, res) => {
- res.redirect(
- `${baseURL}/external-auth/${gitAuth.webProvider}/callback?code=1234&state=${req.query.state}`,
+
+ // Ensures that a Git auth provider with the device flow functions and completes!
+ test("external auth device", async ({ page }) => {
+ const device: ExternalAuthDevice = {
+ device_code: "1234",
+ user_code: "1234-5678",
+ expires_in: 900,
+ interval: 1,
+ verification_uri: "",
+ };
+
+ // Start a server to mock the GitHub API.
+ const srv = await createServer(gitAuth.devicePort);
+ srv.use(gitAuth.validatePath, (_req, res) => {
+ res.write(JSON.stringify(ghUser));
+ res.end();
+ });
+ srv.use(gitAuth.codePath, (_req, res) => {
+ res.write(JSON.stringify(device));
+ res.end();
+ });
+ srv.use(gitAuth.installationsPath, (_req, res) => {
+ res.write(JSON.stringify(ghInstall));
+ res.end();
+ });
+
+ const token = {
+ access_token: "",
+ error: "authorization_pending",
+ error_description: "",
+ };
+ // First we send a result from the API that the token hasn't been
+ // authorized yet to ensure the UI reacts properly.
+ const sentPending = new Awaiter();
+ srv.use(gitAuth.tokenPath, (_req, res) => {
+ res.write(JSON.stringify(token));
+ res.end();
+ sentPending.done();
+ });
+
+ await page.goto(`/external-auth/${gitAuth.deviceProvider}`, {
+ waitUntil: "domcontentloaded",
+ });
+ await page.getByText(device.user_code).isVisible();
+ await sentPending.wait();
+ // Update the token to be valid and ensure the UI updates!
+ token.error = "";
+ token.access_token = "hello-world";
+ await page.waitForSelector("text=1 organization authorized");
+ });
+
+ test("external auth web", async ({ page }) => {
+ await page.goto(`/external-auth/${gitAuth.webProvider}`, {
+ waitUntil: "domcontentloaded",
+ });
+ // This endpoint doesn't have the installations URL set intentionally!
+ await page.waitForSelector("text=You've authenticated with GitHub!");
+ });
+
+ test("successful external auth from workspace", async ({ page }) => {
+ const templateName = await createTemplate(
+ page,
+ echoResponsesWithExternalAuth([
+ { id: gitAuth.webProvider, optional: false },
+ ]),
);
+
+ await createWorkspace(page, templateName, { useExternalAuth: true });
});
- });
- test.beforeEach(async ({ context, page }) => {
- beforeCoderTest(page);
- await login(page);
- await resetExternalAuthKey(context);
- });
-
- // Ensures that a Git auth provider with the device flow functions and completes!
- test("external auth device", async ({ page }) => {
- const device: ExternalAuthDevice = {
- device_code: "1234",
- user_code: "1234-5678",
- expires_in: 900,
- interval: 1,
- verification_uri: "",
+ const ghUser: Endpoints["GET /user"]["response"]["data"] = {
+ login: "kylecarbs",
+ id: 7122116,
+ node_id: "MDQ6VXNlcjcxMjIxMTY=",
+ avatar_url: "https://avatars.githubusercontent.com/u/7122116?v=4",
+ gravatar_id: "",
+ url: "https://api.github.com/users/kylecarbs",
+ html_url: "https://github.com/kylecarbs",
+ followers_url: "https://api.github.com/users/kylecarbs/followers",
+ following_url:
+ "https://api.github.com/users/kylecarbs/following{/other_user}",
+ gists_url: "https://api.github.com/users/kylecarbs/gists{/gist_id}",
+ starred_url:
+ "https://api.github.com/users/kylecarbs/starred{/owner}{/repo}",
+ subscriptions_url: "https://api.github.com/users/kylecarbs/subscriptions",
+ organizations_url: "https://api.github.com/users/kylecarbs/orgs",
+ repos_url: "https://api.github.com/users/kylecarbs/repos",
+ events_url: "https://api.github.com/users/kylecarbs/events{/privacy}",
+ received_events_url:
+ "https://api.github.com/users/kylecarbs/received_events",
+ type: "User",
+ site_admin: false,
+ name: "Kyle Carberry",
+ company: "@coder",
+ blog: "https://carberry.com",
+ location: "Austin, TX",
+ email: "kyle@carberry.com",
+ hireable: null,
+ bio: "hey there",
+ twitter_username: "kylecarbs",
+ public_repos: 52,
+ public_gists: 9,
+ followers: 208,
+ following: 31,
+ created_at: "2014-04-01T02:24:41Z",
+ updated_at: "2023-06-26T13:03:09Z",
};
- // Start a server to mock the GitHub API.
- const srv = await createServer(gitAuth.devicePort);
- srv.use(gitAuth.validatePath, (_req, res) => {
- res.write(JSON.stringify(ghUser));
- res.end();
- });
- srv.use(gitAuth.codePath, (_req, res) => {
- res.write(JSON.stringify(device));
- res.end();
- });
- srv.use(gitAuth.installationsPath, (_req, res) => {
- res.write(JSON.stringify(ghInstall));
- res.end();
- });
-
- const token = {
- access_token: "",
- error: "authorization_pending",
- error_description: "",
- };
- // First we send a result from the API that the token hasn't been
- // authorized yet to ensure the UI reacts properly.
- const sentPending = new Awaiter();
- srv.use(gitAuth.tokenPath, (_req, res) => {
- res.write(JSON.stringify(token));
- res.end();
- sentPending.done();
- });
-
- await page.goto(`/external-auth/${gitAuth.deviceProvider}`, {
- waitUntil: "domcontentloaded",
- });
- await page.getByText(device.user_code).isVisible();
- await sentPending.wait();
- // Update the token to be valid and ensure the UI updates!
- token.error = "";
- token.access_token = "hello-world";
- await page.waitForSelector("text=1 organization authorized");
- });
-
- test("external auth web", async ({ page }) => {
- await page.goto(`/external-auth/${gitAuth.webProvider}`, {
- waitUntil: "domcontentloaded",
- });
- // This endpoint doesn't have the installations URL set intentionally!
- await page.waitForSelector("text=You've authenticated with GitHub!");
- });
-
- test("successful external auth from workspace", async ({ page }) => {
- const templateName = await createTemplate(
- page,
- echoResponsesWithExternalAuth([
- { id: gitAuth.webProvider, optional: false },
- ]),
- );
-
- await createWorkspace(page, templateName, { useExternalAuth: true });
- });
-
- const ghUser: Endpoints["GET /user"]["response"]["data"] = {
- login: "kylecarbs",
- id: 7122116,
- node_id: "MDQ6VXNlcjcxMjIxMTY=",
- avatar_url: "https://avatars.githubusercontent.com/u/7122116?v=4",
- gravatar_id: "",
- url: "https://api.github.com/users/kylecarbs",
- html_url: "https://github.com/kylecarbs",
- followers_url: "https://api.github.com/users/kylecarbs/followers",
- following_url:
- "https://api.github.com/users/kylecarbs/following{/other_user}",
- gists_url: "https://api.github.com/users/kylecarbs/gists{/gist_id}",
- starred_url:
- "https://api.github.com/users/kylecarbs/starred{/owner}{/repo}",
- subscriptions_url: "https://api.github.com/users/kylecarbs/subscriptions",
- organizations_url: "https://api.github.com/users/kylecarbs/orgs",
- repos_url: "https://api.github.com/users/kylecarbs/repos",
- events_url: "https://api.github.com/users/kylecarbs/events{/privacy}",
- received_events_url:
- "https://api.github.com/users/kylecarbs/received_events",
- type: "User",
- site_admin: false,
- name: "Kyle Carberry",
- company: "@coder",
- blog: "https://carberry.com",
- location: "Austin, TX",
- email: "kyle@carberry.com",
- hireable: null,
- bio: "hey there",
- twitter_username: "kylecarbs",
- public_repos: 52,
- public_gists: 9,
- followers: 208,
- following: 31,
- created_at: "2014-04-01T02:24:41Z",
- updated_at: "2023-06-26T13:03:09Z",
- };
-
- const ghInstall: Endpoints["GET /user/installations"]["response"]["data"] = {
- installations: [
+ const ghInstall: Endpoints["GET /user/installations"]["response"]["data"] =
{
- id: 1,
- access_tokens_url: "",
- account: ghUser,
- app_id: 1,
- app_slug: "coder",
- created_at: "2014-04-01T02:24:41Z",
- events: [],
- html_url: "",
- permissions: {},
- repositories_url: "",
- repository_selection: "all",
- single_file_name: "",
- suspended_at: null,
- suspended_by: null,
- target_id: 1,
- target_type: "",
- updated_at: "2023-06-26T13:03:09Z",
- },
- ],
- total_count: 1,
- };
-});
+ installations: [
+ {
+ id: 1,
+ access_tokens_url: "",
+ account: ghUser,
+ app_id: 1,
+ app_slug: "coder",
+ created_at: "2014-04-01T02:24:41Z",
+ events: [],
+ html_url: "",
+ permissions: {},
+ repositories_url: "",
+ repository_selection: "all",
+ single_file_name: "",
+ suspended_at: null,
+ suspended_by: null,
+ target_id: 1,
+ target_type: "",
+ updated_at: "2023-06-26T13:03:09Z",
+ },
+ ],
+ total_count: 1,
+ };
+ });
diff --git a/site/package.json b/site/package.json
index 03246dbfbd..2a93c29633 100644
--- a/site/package.json
+++ b/site/package.json
@@ -127,7 +127,7 @@
"devDependencies": {
"@babel/core": "7.29.0",
"@babel/plugin-syntax-typescript": "7.28.6",
- "@biomejs/biome": "2.2.4",
+ "@biomejs/biome": "2.4.10",
"@chromatic-com/storybook": "5.0.1",
"@octokit/types": "12.6.0",
"@playwright/test": "1.50.1",
diff --git a/site/pnpm-lock.yaml b/site/pnpm-lock.yaml
index 444e9db902..9a7c84a006 100644
--- a/site/pnpm-lock.yaml
+++ b/site/pnpm-lock.yaml
@@ -276,8 +276,8 @@ importers:
specifier: 7.28.6
version: 7.28.6(@babel/core@7.29.0)
'@biomejs/biome':
- specifier: 2.2.4
- version: 2.2.4
+ specifier: 2.4.10
+ version: 2.4.10
'@chromatic-com/storybook':
specifier: 5.0.1
version: 5.0.1(storybook@10.3.3(@testing-library/dom@10.4.0)(prettier@3.4.1)(react-dom@19.2.2(react@19.2.2))(react@19.2.2))
@@ -469,7 +469,7 @@ importers:
version: 8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0)
vite-plugin-checker:
specifier: 0.12.0
- version: 0.12.0(@biomejs/biome@2.2.4)(optionator@0.9.3)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0))
+ version: 0.12.0(@biomejs/biome@2.4.10)(optionator@0.9.3)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0))
vitest:
specifier: 4.1.1
version: 4.1.1(@types/node@20.19.25)(@vitest/browser-playwright@4.1.1)(jsdom@27.2.0)(msw@2.4.8(typescript@6.0.2))(vite@8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0))
@@ -708,55 +708,55 @@ packages:
'@bcoe/v8-coverage@0.2.3':
resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==, tarball: https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz}
- '@biomejs/biome@2.2.4':
- resolution: {integrity: sha512-TBHU5bUy/Ok6m8c0y3pZiuO/BZoY/OcGxoLlrfQof5s8ISVwbVBdFINPQZyFfKwil8XibYWb7JMwnT8wT4WVPg==, tarball: https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.4.tgz}
+ '@biomejs/biome@2.4.10':
+ resolution: {integrity: sha512-xxA3AphFQ1geij4JTHXv4EeSTda1IFn22ye9LdyVPoJU19fNVl0uzfEuhsfQ4Yue/0FaLs2/ccVi4UDiE7R30w==, tarball: https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.10.tgz}
engines: {node: '>=14.21.3'}
hasBin: true
- '@biomejs/cli-darwin-arm64@2.2.4':
- resolution: {integrity: sha512-RJe2uiyaloN4hne4d2+qVj3d3gFJFbmrr5PYtkkjei1O9c+BjGXgpUPVbi8Pl8syumhzJjFsSIYkcLt2VlVLMA==, tarball: https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.4.tgz}
+ '@biomejs/cli-darwin-arm64@2.4.10':
+ resolution: {integrity: sha512-vuzzI1cWqDVzOMIkYyHbKqp+AkQq4K7k+UCXWpkYcY/HDn1UxdsbsfgtVpa40shem8Kax4TLDLlx8kMAecgqiw==, tarball: https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [darwin]
- '@biomejs/cli-darwin-x64@2.2.4':
- resolution: {integrity: sha512-cFsdB4ePanVWfTnPVaUX+yr8qV8ifxjBKMkZwN7gKb20qXPxd/PmwqUH8mY5wnM9+U0QwM76CxFyBRJhC9tQwg==, tarball: https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.4.tgz}
+ '@biomejs/cli-darwin-x64@2.4.10':
+ resolution: {integrity: sha512-14fzASRo+BPotwp7nWULy2W5xeUyFnTaq1V13Etrrxkrih+ez/2QfgFm5Ehtf5vSjtgx/IJycMMpn5kPd5ZNaA==, tarball: https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [darwin]
- '@biomejs/cli-linux-arm64-musl@2.2.4':
- resolution: {integrity: sha512-7TNPkMQEWfjvJDaZRSkDCPT/2r5ESFPKx+TEev+I2BXDGIjfCZk2+b88FOhnJNHtksbOZv8ZWnxrA5gyTYhSsQ==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.4.tgz}
+ '@biomejs/cli-linux-arm64-musl@2.4.10':
+ resolution: {integrity: sha512-WrJY6UuiSD/Dh+nwK2qOTu8kdMDlLV3dLMmychIghHPAysWFq1/DGC1pVZx8POE3ZkzKR3PUUnVrtZfMfaJjyQ==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
- '@biomejs/cli-linux-arm64@2.2.4':
- resolution: {integrity: sha512-M/Iz48p4NAzMXOuH+tsn5BvG/Jb07KOMTdSVwJpicmhN309BeEyRyQX+n1XDF0JVSlu28+hiTQ2L4rZPvu7nMw==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.4.tgz}
+ '@biomejs/cli-linux-arm64@2.4.10':
+ resolution: {integrity: sha512-7MH1CMW5uuxQ/s7FLST63qF8B3Hgu2HRdZ7tA1X1+mk+St4JOuIrqdhIBnnyqeyWJNI+Bww7Es5QZ0wIc1Cmkw==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [linux]
- '@biomejs/cli-linux-x64-musl@2.2.4':
- resolution: {integrity: sha512-m41nFDS0ksXK2gwXL6W6yZTYPMH0LughqbsxInSKetoH6morVj43szqKx79Iudkp8WRT5SxSh7qVb8KCUiewGg==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.4.tgz}
+ '@biomejs/cli-linux-x64-musl@2.4.10':
+ resolution: {integrity: sha512-kDTi3pI6PBN6CiczsWYOyP2zk0IJI08EWEQyDMQWW221rPaaEz6FvjLhnU07KMzLv8q3qSuoB93ua6inSQ55Tw==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
- '@biomejs/cli-linux-x64@2.2.4':
- resolution: {integrity: sha512-orr3nnf2Dpb2ssl6aihQtvcKtLySLta4E2UcXdp7+RTa7mfJjBgIsbS0B9GC8gVu0hjOu021aU8b3/I1tn+pVQ==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.4.tgz}
+ '@biomejs/cli-linux-x64@2.4.10':
+ resolution: {integrity: sha512-tZLvEEi2u9Xu1zAqRjTcpIDGVtldigVvzug2fTuPG0ME/g8/mXpRPcNgLB22bGn6FvLJpHHnqLnwliOu8xjYrg==, tarball: https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [linux]
- '@biomejs/cli-win32-arm64@2.2.4':
- resolution: {integrity: sha512-NXnfTeKHDFUWfxAefa57DiGmu9VyKi0cDqFpdI+1hJWQjGJhJutHPX0b5m+eXvTKOaf+brU+P0JrQAZMb5yYaQ==, tarball: https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.4.tgz}
+ '@biomejs/cli-win32-arm64@2.4.10':
+ resolution: {integrity: sha512-umwQU6qPzH+ISTf/eHyJ/QoQnJs3V9Vpjz2OjZXe9MVBZ7prgGafMy7yYeRGnlmDAn87AKTF3Q6weLoMGpeqdQ==, tarball: https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [arm64]
os: [win32]
- '@biomejs/cli-win32-x64@2.2.4':
- resolution: {integrity: sha512-3Y4V4zVRarVh/B/eSHczR4LYoSVyv3Dfuvm3cWs5w/HScccS0+Wt/lHOcDTRYeHjQmMYVC3rIRWqyN2EI52+zg==, tarball: https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.4.tgz}
+ '@biomejs/cli-win32-x64@2.4.10':
+ resolution: {integrity: sha512-aW/JU5GuyH4uxMrNYpoC2kjaHlyJGLgIa3XkhPEZI0uKhZhJZU8BuEyJmvgzSPQNGozBwWjC972RaNdcJ9KyJg==, tarball: https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.10.tgz}
engines: {node: '>=14.21.3'}
cpu: [x64]
os: [win32]
@@ -7697,39 +7697,39 @@ snapshots:
'@bcoe/v8-coverage@0.2.3': {}
- '@biomejs/biome@2.2.4':
+ '@biomejs/biome@2.4.10':
optionalDependencies:
- '@biomejs/cli-darwin-arm64': 2.2.4
- '@biomejs/cli-darwin-x64': 2.2.4
- '@biomejs/cli-linux-arm64': 2.2.4
- '@biomejs/cli-linux-arm64-musl': 2.2.4
- '@biomejs/cli-linux-x64': 2.2.4
- '@biomejs/cli-linux-x64-musl': 2.2.4
- '@biomejs/cli-win32-arm64': 2.2.4
- '@biomejs/cli-win32-x64': 2.2.4
+ '@biomejs/cli-darwin-arm64': 2.4.10
+ '@biomejs/cli-darwin-x64': 2.4.10
+ '@biomejs/cli-linux-arm64': 2.4.10
+ '@biomejs/cli-linux-arm64-musl': 2.4.10
+ '@biomejs/cli-linux-x64': 2.4.10
+ '@biomejs/cli-linux-x64-musl': 2.4.10
+ '@biomejs/cli-win32-arm64': 2.4.10
+ '@biomejs/cli-win32-x64': 2.4.10
- '@biomejs/cli-darwin-arm64@2.2.4':
+ '@biomejs/cli-darwin-arm64@2.4.10':
optional: true
- '@biomejs/cli-darwin-x64@2.2.4':
+ '@biomejs/cli-darwin-x64@2.4.10':
optional: true
- '@biomejs/cli-linux-arm64-musl@2.2.4':
+ '@biomejs/cli-linux-arm64-musl@2.4.10':
optional: true
- '@biomejs/cli-linux-arm64@2.2.4':
+ '@biomejs/cli-linux-arm64@2.4.10':
optional: true
- '@biomejs/cli-linux-x64-musl@2.2.4':
+ '@biomejs/cli-linux-x64-musl@2.4.10':
optional: true
- '@biomejs/cli-linux-x64@2.2.4':
+ '@biomejs/cli-linux-x64@2.4.10':
optional: true
- '@biomejs/cli-win32-arm64@2.2.4':
+ '@biomejs/cli-win32-arm64@2.4.10':
optional: true
- '@biomejs/cli-win32-x64@2.2.4':
+ '@biomejs/cli-win32-x64@2.4.10':
optional: true
'@blazediff/core@1.9.1': {}
@@ -15034,7 +15034,7 @@ snapshots:
d3-time: 3.1.0
d3-timer: 3.0.1
- vite-plugin-checker@0.12.0(@biomejs/biome@2.2.4)(optionator@0.9.3)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0)):
+ vite-plugin-checker@0.12.0(@biomejs/biome@2.4.10)(optionator@0.9.3)(typescript@6.0.2)(vite@8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0)):
dependencies:
'@babel/code-frame': 7.29.0
chokidar: 4.0.3
@@ -15046,7 +15046,7 @@ snapshots:
vite: 8.0.2(@emnapi/core@1.7.1)(@emnapi/runtime@1.7.1)(@types/node@20.19.25)(esbuild@0.25.12)(jiti@1.21.7)(yaml@2.7.0)
vscode-uri: 3.1.0
optionalDependencies:
- '@biomejs/biome': 2.2.4
+ '@biomejs/biome': 2.4.10
optionator: 0.9.3
typescript: 6.0.2
diff --git a/site/src/api/api.test.ts b/site/src/api/api.test.ts
index e38e422c9f..a966f673e4 100644
--- a/site/src/api/api.test.ts
+++ b/site/src/api/api.test.ts
@@ -147,12 +147,9 @@ describe("api.ts", () => {
{ q: "owner:me" },
"/api/v2/workspaces?q=owner%3Ame",
],
- ])(
- "Workspaces - getURLWithSearchParams(%p, %p) returns %p",
- (basePath, filter, expected) => {
- expect(getURLWithSearchParams(basePath, filter)).toBe(expected);
- },
- );
+ ])("Workspaces - getURLWithSearchParams(%p, %p) returns %p", (basePath, filter, expected) => {
+ expect(getURLWithSearchParams(basePath, filter)).toBe(expected);
+ });
});
describe("getURLWithSearchParams - users", () => {
@@ -164,12 +161,9 @@ describe("api.ts", () => {
"/api/v2/users?q=status%3Aactive",
],
["/api/v2/users", { q: "" }, "/api/v2/users"],
- ])(
- "Users - getURLWithSearchParams(%p, %p) returns %p",
- (basePath, filter, expected) => {
- expect(getURLWithSearchParams(basePath, filter)).toBe(expected);
- },
- );
+ ])("Users - getURLWithSearchParams(%p, %p) returns %p", (basePath, filter, expected) => {
+ expect(getURLWithSearchParams(basePath, filter)).toBe(expected);
+ });
});
describe("update", () => {
diff --git a/site/src/components/Collapsible/Collapsible.tsx b/site/src/components/Collapsible/Collapsible.tsx
index 2ce8c12f63..40214f1b83 100644
--- a/site/src/components/Collapsible/Collapsible.tsx
+++ b/site/src/components/Collapsible/Collapsible.tsx
@@ -10,4 +10,4 @@ const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger;
const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent;
-export { Collapsible, CollapsibleTrigger, CollapsibleContent };
+export { Collapsible, CollapsibleContent, CollapsibleTrigger };
diff --git a/site/src/components/Dialogs/Dialog.tsx b/site/src/components/Dialogs/Dialog.tsx
index 40d08f4b3b..f8fd9adce9 100644
--- a/site/src/components/Dialogs/Dialog.tsx
+++ b/site/src/components/Dialogs/Dialog.tsx
@@ -67,4 +67,4 @@ export const DialogActionButtons: FC = ({
* Re-export of MUI's Dialog component, for convenience.
* @link See original documentation here: https://mui.com/material-ui/react-dialog/
*/
-export { MuiDialog as Dialog, type DialogProps };
+export { type DialogProps, MuiDialog as Dialog };
diff --git a/site/src/components/Filter/Filter.tsx b/site/src/components/Filter/Filter.tsx
index 1f0c1ba22a..f06f02b8f7 100644
--- a/site/src/components/Filter/Filter.tsx
+++ b/site/src/components/Filter/Filter.tsx
@@ -306,7 +306,7 @@ const PresetMenu: FC = ({
{(learnMoreLink || learnMoreLink2) && }
{learnMoreLink && (
-
+
View advanced filtering
@@ -314,7 +314,7 @@ const PresetMenu: FC = ({
)}
{learnMoreLink2 && learnMoreLabel2 && (
-
+
{learnMoreLabel2}
diff --git a/site/src/components/Kbd/Kbd.tsx b/site/src/components/Kbd/Kbd.tsx
index ead6055542..3e5e0d6f07 100644
--- a/site/src/components/Kbd/Kbd.tsx
+++ b/site/src/components/Kbd/Kbd.tsx
@@ -24,4 +24,5 @@ function KbdGroup({ className, ...props }: React.ComponentProps<"div">) {
/>
);
}
+
export { Kbd, KbdGroup };
diff --git a/site/src/components/Markdown/Markdown.tsx b/site/src/components/Markdown/Markdown.tsx
index 8c6637ec0a..1a197d7a0c 100644
--- a/site/src/components/Markdown/Markdown.tsx
+++ b/site/src/components/Markdown/Markdown.tsx
@@ -58,7 +58,7 @@ export const Markdown: FC = (props) => {
},
pre: ({ node, children }) => {
- if (!node || !node.children) {
+ if (!node?.children) {
return {children};
}
const firstChild = node.children[0];
diff --git a/site/src/contexts/ProxyContext.test.tsx b/site/src/contexts/ProxyContext.test.tsx
index beb8d27df0..10d1284765 100644
--- a/site/src/contexts/ProxyContext.test.tsx
+++ b/site/src/contexts/ProxyContext.test.tsx
@@ -108,23 +108,11 @@ describe("ProxyContextGetURLs", () => {
MockHealthyWildWorkspaceProxy.path_app_url,
MockHealthyWildWorkspaceProxy.wildcard_hostname,
],
- ])(
- "%p",
- (
- _,
- regions,
- latencies,
- selected,
- preferredPathAppURL,
- preferredWildcardHostname,
- ) => {
- const preferred = getPreferredProxy(regions, selected, latencies, true);
- expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL);
- expect(preferred.preferredWildcardHostname).toBe(
- preferredWildcardHostname,
- );
- },
- );
+ ])("%p", (_, regions, latencies, selected, preferredPathAppURL, preferredWildcardHostname) => {
+ const preferred = getPreferredProxy(regions, selected, latencies, true);
+ expect(preferred.preferredPathAppURL).toBe(preferredPathAppURL);
+ expect(preferred.preferredWildcardHostname).toBe(preferredWildcardHostname);
+ });
});
const TestingComponent = () => {
@@ -342,62 +330,56 @@ describe("ProxyContextSelection", () => {
},
},
],
- ] as [string, ProxyContextSelectionTest][])(
- "%s",
- async (
- _,
- {
- expUserProxyID,
- expProxyID: expSelectedProxyID,
- regions,
- storageProxy,
- latencies = {},
- afterLoad,
- },
- ) => {
- // Mock the latencies
- hardCodedLatencies = latencies;
+ ] as [string, ProxyContextSelectionTest][])("%s", async (_, {
+ expUserProxyID,
+ expProxyID: expSelectedProxyID,
+ regions,
+ storageProxy,
+ latencies = {},
+ afterLoad,
+ }) => {
+ // Mock the latencies
+ hardCodedLatencies = latencies;
- // Initial selection if present
- if (storageProxy) {
- saveUserSelectedProxy(storageProxy);
- }
+ // Initial selection if present
+ if (storageProxy) {
+ saveUserSelectedProxy(storageProxy);
+ }
- // Mock the API response
- server.use(
- http.get("/api/v2/regions", () =>
- HttpResponse.json({
- regions,
- }),
- ),
- http.get("/api/v2/workspaceproxies", () =>
- HttpResponse.json({ regions }),
- ),
- );
+ // Mock the API response
+ server.use(
+ http.get("/api/v2/regions", () =>
+ HttpResponse.json({
+ regions,
+ }),
+ ),
+ http.get("/api/v2/workspaceproxies", () =>
+ HttpResponse.json({ regions }),
+ ),
+ );
- TestingComponent();
- await waitForLoaderToBeRemoved();
+ TestingComponent();
+ await waitForLoaderToBeRemoved();
- await screen.findByTestId("latenciesLoaded").then((x) => {
- expect(x.title).toBe("true");
- });
+ await screen.findByTestId("latenciesLoaded").then((x) => {
+ expect(x.title).toBe("true");
+ });
- if (afterLoad) {
- await afterLoad();
- }
+ if (afterLoad) {
+ await afterLoad();
+ }
- await screen.findByTestId("isFetched").then((x) => {
- expect(x.title).toBe("true");
- });
- await screen.findByTestId("isLoading").then((x) => {
- expect(x.title).toBe("false");
- });
- await screen.findByTestId("preferredProxy").then((x) => {
- expect(x.title).toBe(expSelectedProxyID);
- });
- await screen.findByTestId("userProxy").then((x) => {
- expect(x.title).toBe(expUserProxyID || "");
- });
- },
- );
+ await screen.findByTestId("isFetched").then((x) => {
+ expect(x.title).toBe("true");
+ });
+ await screen.findByTestId("isLoading").then((x) => {
+ expect(x.title).toBe("false");
+ });
+ await screen.findByTestId("preferredProxy").then((x) => {
+ expect(x.title).toBe(expSelectedProxyID);
+ });
+ await screen.findByTestId("userProxy").then((x) => {
+ expect(x.title).toBe(expUserProxyID || "");
+ });
+ });
});
diff --git a/site/src/contexts/ProxyContext.tsx b/site/src/contexts/ProxyContext.tsx
index a019de6770..bfbdb43c09 100644
--- a/site/src/contexts/ProxyContext.tsx
+++ b/site/src/contexts/ProxyContext.tsx
@@ -228,7 +228,7 @@ export const getPreferredProxy = (
);
// If no proxy is selected, or the selected proxy is unhealthy default to the primary proxy.
- if (!selectedProxy || !selectedProxy.healthy) {
+ if (!selectedProxy?.healthy) {
// Default to the primary proxy
selectedProxy = proxies.find((proxy) => proxy.name === "primary");
diff --git a/site/src/hooks/useEmbeddedMetadata.ts b/site/src/hooks/useEmbeddedMetadata.ts
index 5679760f5b..c9fa5a7f89 100644
--- a/site/src/hooks/useEmbeddedMetadata.ts
+++ b/site/src/hooks/useEmbeddedMetadata.ts
@@ -241,7 +241,7 @@ export function makeUseEmbeddedMetadata(
metadata,
clearMetadataByKey: manager.clearMetadataByKey,
};
- }, [manager, metadata]);
+ }, [metadata]);
return stableMetadataResult;
};
diff --git a/site/src/modules/resources/AgentRowPreview.test.tsx b/site/src/modules/resources/AgentRowPreview.test.tsx
index a49801d416..5b4ed61a39 100644
--- a/site/src/modules/resources/AgentRowPreview.test.tsx
+++ b/site/src/modules/resources/AgentRowPreview.test.tsx
@@ -87,54 +87,51 @@ describe("AgentRowPreviewApps", () => {
workspaceAgent: EmptyAppPreview,
testName: "EmptyAppPreview",
},
- ])(
- " displays appropriately",
- ({ workspaceAgent }) => {
- renderComponent();
- for (const app of workspaceAgent.apps) {
- expect(
- screen.getByText(app.display_name as string),
- ).toBeInTheDocument();
- }
+ ])(" displays appropriately", ({
+ workspaceAgent,
+ }) => {
+ renderComponent();
+ for (const app of workspaceAgent.apps) {
+ expect(screen.getByText(app.display_name as string)).toBeInTheDocument();
+ }
- for (const app of workspaceAgent.display_apps) {
- // These get special treatment
- if (app === "vscode" || app === "vscode_insiders") {
- continue;
- }
- expect(screen.getByText(DisplayAppNameMap[app])).toBeInTheDocument();
+ for (const app of workspaceAgent.display_apps) {
+ // These get special treatment
+ if (app === "vscode" || app === "vscode_insiders") {
+ continue;
}
+ expect(screen.getByText(DisplayAppNameMap[app])).toBeInTheDocument();
+ }
- // test VS Code display
- if (workspaceAgent.display_apps.includes("vscode")) {
- expect(screen.getByText(DisplayAppNameMap.vscode)).toBeInTheDocument();
- } else if (workspaceAgent.display_apps.includes("vscode_insiders")) {
- expect(
- screen.getByText(DisplayAppNameMap.vscode_insiders),
- ).toBeInTheDocument();
- } else {
- expect(screen.queryByText("vscode")).not.toBeInTheDocument();
- expect(screen.queryByText("vscode_insiders")).not.toBeInTheDocument();
- }
+ // test VS Code display
+ if (workspaceAgent.display_apps.includes("vscode")) {
+ expect(screen.getByText(DisplayAppNameMap.vscode)).toBeInTheDocument();
+ } else if (workspaceAgent.display_apps.includes("vscode_insiders")) {
+ expect(
+ screen.getByText(DisplayAppNameMap.vscode_insiders),
+ ).toBeInTheDocument();
+ } else {
+ expect(screen.queryByText("vscode")).not.toBeInTheDocument();
+ expect(screen.queryByText("vscode_insiders")).not.toBeInTheDocument();
+ }
- // difference between all possible display apps and those displayed
- const excludedApps = DisplayApps.filter(
- (a) => !workspaceAgent.display_apps.includes(a),
- );
+ // difference between all possible display apps and those displayed
+ const excludedApps = DisplayApps.filter(
+ (a) => !workspaceAgent.display_apps.includes(a),
+ );
- for (const app of excludedApps) {
- expect(
- screen.queryByText(DisplayAppNameMap[app]),
- ).not.toBeInTheDocument();
- }
+ for (const app of excludedApps) {
+ expect(
+ screen.queryByText(DisplayAppNameMap[app]),
+ ).not.toBeInTheDocument();
+ }
- // test empty state
- if (
- workspaceAgent.display_apps.length === 0 &&
- workspaceAgent.apps.length === 0
- ) {
- expect(screen.getByText("None")).toBeInTheDocument();
- }
- },
- );
+ // test empty state
+ if (
+ workspaceAgent.display_apps.length === 0 &&
+ workspaceAgent.apps.length === 0
+ ) {
+ expect(screen.getByText("None")).toBeInTheDocument();
+ }
+ });
});
diff --git a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
index c31587cf4c..c415c536cc 100644
--- a/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
+++ b/site/src/modules/workspaces/DynamicParameter/DynamicParameter.tsx
@@ -859,7 +859,7 @@ export const useValidationSchemaForDynamicParameters = (
(v) =>
v.validation_regex !== null && v.validation_regex !== "",
);
- if (!regex || !regex.validation_regex) {
+ if (!regex?.validation_regex) {
return true;
}
diff --git a/site/src/pages/404Page/404Page.stories.tsx b/site/src/pages/404Page/404Page.stories.tsx
index 8f1b52ab7b..3253f3c4ac 100644
--- a/site/src/pages/404Page/404Page.stories.tsx
+++ b/site/src/pages/404Page/404Page.stories.tsx
@@ -10,4 +10,5 @@ export default meta;
type Story = StoryObj;
const Example: Story = {};
+
export { Example as NotFoundPage };
diff --git a/site/src/pages/AIBridgePage/JsonPrettyPrinter.tsx b/site/src/pages/AIBridgePage/JsonPrettyPrinter.tsx
index 63a72159cf..99620aa439 100644
--- a/site/src/pages/AIBridgePage/JsonPrettyPrinter.tsx
+++ b/site/src/pages/AIBridgePage/JsonPrettyPrinter.tsx
@@ -34,7 +34,6 @@ const formatJSONValue = (value: unknown, depth: number): ReactNode => {
if (entries.length === 0) return "{}";
return (
<>
- {/* biome-ignore lint/style/useConsistentCurlyBraces: \n requires a JS string literal */}
{"{\n"}
{entries.map(([k, v], i) => (
diff --git a/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.ts b/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.ts
index bbe980c49b..afece20da6 100644
--- a/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.ts
+++ b/site/src/pages/AgentsPage/components/ChatConversation/messageParsing.ts
@@ -298,7 +298,7 @@ export const parseMessagesWithMergedTools = (
if (tool.name !== "process_signal") continue;
const args = asRecord(tool.args);
const result = asRecord(tool.result);
- if (!args || !result || !result.success) continue;
+ if (!args || !result?.success) continue;
const pid = asString(args.process_id);
const sig = asString(args.signal);
if (pid && (sig === "kill" || sig === "terminate"))
diff --git a/site/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts b/site/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts
index 9e13e64c04..e45ac3bb95 100644
--- a/site/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts
+++ b/site/src/pages/AgentsPage/utils/agentWorkspaceUtils.test.ts
@@ -345,16 +345,18 @@ describe("shouldNavigateAfterArchive", () => {
activeRootChatId: undefined,
expected: false,
},
- ])(
- "$name → $expected",
- ({ activeChatId, archivedChatId, activeRootChatId, expected }) => {
- expect(
- shouldNavigateAfterArchive(
- activeChatId,
- archivedChatId,
- activeRootChatId,
- ),
- ).toBe(expected);
- },
- );
+ ])("$name → $expected", ({
+ activeChatId,
+ archivedChatId,
+ activeRootChatId,
+ expected,
+ }) => {
+ expect(
+ shouldNavigateAfterArchive(
+ activeChatId,
+ archivedChatId,
+ activeRootChatId,
+ ),
+ ).toBe(expected);
+ });
});
diff --git a/site/src/pages/CreateTokenPage/utils.test.tsx b/site/src/pages/CreateTokenPage/utils.test.tsx
index b09e72a812..c4532eb2fc 100644
--- a/site/src/pages/CreateTokenPage/utils.test.tsx
+++ b/site/src/pages/CreateTokenPage/utils.test.tsx
@@ -33,12 +33,12 @@ describe("unit/CreateTokenForm", () => {
maxTokenLifetime: 100 * 24 * NANO_HOUR,
expected: lifetimeDayPresets,
},
- ])(
- "filterByMaxTokenLifetime($maxTokenLifetime)",
- ({ maxTokenLifetime, expected }) => {
- expect(filterByMaxTokenLifetime(maxTokenLifetime)).toEqual(expected);
- },
- );
+ ])("filterByMaxTokenLifetime($maxTokenLifetime)", ({
+ maxTokenLifetime,
+ expected,
+ }) => {
+ expect(filterByMaxTokenLifetime(maxTokenLifetime)).toEqual(expected);
+ });
});
describe("determineDefaultLtValue", () => {
it.each<{
@@ -61,11 +61,11 @@ describe("unit/CreateTokenForm", () => {
maxTokenLifetime: 2 * 24 * NANO_HOUR,
expected: "custom",
},
- ])(
- "determineDefaultLtValue($maxTokenLifetime)",
- ({ maxTokenLifetime, expected }) => {
- expect(determineDefaultLtValue(maxTokenLifetime)).toEqual(expected);
- },
- );
+ ])("determineDefaultLtValue($maxTokenLifetime)", ({
+ maxTokenLifetime,
+ expected,
+ }) => {
+ expect(determineDefaultLtValue(maxTokenLifetime)).toEqual(expected);
+ });
});
});
diff --git a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
index 3477ca2518..a52d4c53db 100644
--- a/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
+++ b/site/src/pages/CreateWorkspacePage/CreateWorkspacePageView.tsx
@@ -266,7 +266,7 @@ export const CreateWorkspacePageView: FC = ({
}
}
- if (!selectedPreset || !selectedPreset.Parameters) {
+ if (!selectedPreset?.Parameters) {
setPresetParameterNames([]);
return;
}
diff --git a/site/src/pages/DeploymentSettingsPage/optionValue.test.ts b/site/src/pages/DeploymentSettingsPage/optionValue.test.ts
index 3b52bf1dad..fe34e605e6 100644
--- a/site/src/pages/DeploymentSettingsPage/optionValue.test.ts
+++ b/site/src/pages/DeploymentSettingsPage/optionValue.test.ts
@@ -166,10 +166,11 @@ describe("optionValue", () => {
},
expected: "",
},
- ])(
- "[$option.name]optionValue($option.value)",
- ({ option, expected, additionalValues }) => {
- expect(optionValue(option, additionalValues)).toEqual(expected);
- },
- );
+ ])("[$option.name]optionValue($option.value)", ({
+ option,
+ expected,
+ additionalValues,
+ }) => {
+ expect(optionValue(option, additionalValues)).toEqual(expected);
+ });
});
diff --git a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx
index abc5955319..e84b2d15de 100644
--- a/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx
+++ b/site/src/pages/TemplateVersionEditorPage/TemplateVersionEditorPage.test.tsx
@@ -330,52 +330,49 @@ describe.each([
],
askForVariables: true,
},
-])(
- "Missing template variables",
- ({
- testName,
- initialVariables,
- loadedVariables,
- templateVersion,
- askForVariables,
- }) => {
- it(testName, async () => {
- vi.resetAllMocks();
- const queryClient = new QueryClient();
- queryClient.setQueryData(
- templateVersionVariablesKey(MockTemplateVersion.id),
- initialVariables,
- );
+])("Missing template variables", ({
+ testName,
+ initialVariables,
+ loadedVariables,
+ templateVersion,
+ askForVariables,
+}) => {
+ it(testName, async () => {
+ vi.resetAllMocks();
+ const queryClient = new QueryClient();
+ queryClient.setQueryData(
+ templateVersionVariablesKey(MockTemplateVersion.id),
+ initialVariables,
+ );
+ server.use(
+ http.get(
+ "/api/v2/organizations/:org/templates/:template/versions/:version",
+ () => {
+ return HttpResponse.json(templateVersion);
+ },
+ ),
+ );
+
+ if (loadedVariables) {
server.use(
- http.get(
- "/api/v2/organizations/:org/templates/:template/versions/:version",
- () => {
- return HttpResponse.json(templateVersion);
- },
- ),
+ http.get("/api/v2/templateversions/:version/variables", () => {
+ return HttpResponse.json(loadedVariables);
+ }),
);
+ }
- if (loadedVariables) {
- server.use(
- http.get("/api/v2/templateversions/:version/variables", () => {
- return HttpResponse.json(loadedVariables);
- }),
- );
- }
+ renderEditorPage(queryClient);
+ await waitForLoaderToBeRemoved();
- renderEditorPage(queryClient);
- await waitForLoaderToBeRemoved();
-
- const dialogSelector = /template variables/i;
- if (askForVariables) {
- await screen.findByText(dialogSelector);
- } else {
- expect(screen.queryByText(dialogSelector)).not.toBeInTheDocument();
- }
- });
- },
-);
+ const dialogSelector = /template variables/i;
+ if (askForVariables) {
+ await screen.findByText(dialogSelector);
+ } else {
+ expect(screen.queryByText(dialogSelector)).not.toBeInTheDocument();
+ }
+ });
+});
test("display pending badge and update it to running when status changes", async () => {
const MockPendingTemplateVersion = {
diff --git a/site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.test.tsx b/site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.test.tsx
index eda3420f22..fd0873bb5d 100644
--- a/site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.test.tsx
+++ b/site/src/pages/UserSettingsPage/SchedulePage/SchedulePage.test.tsx
@@ -62,38 +62,36 @@ describe("SchedulePage", () => {
});
describe("cron tests", () => {
- it.each(cronTests)(
- "case %# has the correct expected time",
- async (test) => {
- server.use(
- http.put(
- `/api/v2/users/${MockUserOwner.id}/quiet-hours`,
- async ({ request }) => {
- const data =
- (await request.json()) as UpdateUserQuietHoursScheduleRequest;
- return HttpResponse.json({
- raw_schedule: data.schedule,
- user_set: true,
- time: `${test.hour.toString().padStart(2, "0")}:${test.minute
- .toString()
- .padStart(2, "0")}`,
- timezone: test.timezone,
- next: "", // This value isn't used in the UI, the UI generates it.
- });
- },
- ),
- );
+ it.each(
+ cronTests,
+ )("case %# has the correct expected time", async (test) => {
+ server.use(
+ http.put(
+ `/api/v2/users/${MockUserOwner.id}/quiet-hours`,
+ async ({ request }) => {
+ const data =
+ (await request.json()) as UpdateUserQuietHoursScheduleRequest;
+ return HttpResponse.json({
+ raw_schedule: data.schedule,
+ user_set: true,
+ time: `${test.hour.toString().padStart(2, "0")}:${test.minute
+ .toString()
+ .padStart(2, "0")}`,
+ timezone: test.timezone,
+ next: "", // This value isn't used in the UI, the UI generates it.
+ });
+ },
+ ),
+ );
- renderWithAuth();
- await fillForm(test);
- await submitForm();
- const successMessage = await screen.findByText(
- "Schedule updated successfully.",
- );
- expect(successMessage).toBeDefined();
- },
- 15_000,
- );
+ renderWithAuth();
+ await fillForm(test);
+ await submitForm();
+ const successMessage = await screen.findByText(
+ "Schedule updated successfully.",
+ );
+ expect(successMessage).toBeDefined();
+ }, 15_000);
});
describe("when it is an unknown error", () => {
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPageExperimental.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPageExperimental.tsx
index 3dbf2ca915..db765b9221 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPageExperimental.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceParametersPage/WorkspaceParametersPageExperimental.tsx
@@ -190,7 +190,7 @@ const WorkspaceParametersPageExperimental: FC = () => {
const handleSubmit = (values: {
rich_parameter_values: WorkspaceBuildParameter[];
}) => {
- if (!latestResponse || !latestResponse.parameters) {
+ if (!latestResponse?.parameters) {
return;
}
diff --git a/site/src/pages/WorkspaceSettingsPage/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx b/site/src/pages/WorkspaceSettingsPage/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx
index 22b14ebaea..0abfbcc092 100644
--- a/site/src/pages/WorkspaceSettingsPage/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx
+++ b/site/src/pages/WorkspaceSettingsPage/WorkspaceSchedulePage/WorkspaceSchedulePage.test.tsx
@@ -135,12 +135,9 @@ describe("WorkspaceSchedulePage", () => {
schedule: "20 16 * * 1,3,5",
},
],
- ] as const)(
- "formValuesToAutostartRequest(%p) return %p",
- (values, request) => {
- expect(formValuesToAutostartRequest(values)).toEqual(request);
- },
- );
+ ] as const)("formValuesToAutostartRequest(%p) return %p", (values, request) => {
+ expect(formValuesToAutostartRequest(values)).toEqual(request);
+ });
});
describe("formValuesToTTLRequest", () => {
diff --git a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx
index 3a4742c9b7..896f09742b 100644
--- a/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx
+++ b/site/src/pages/WorkspacesPage/WorkspacesPage.test.tsx
@@ -369,53 +369,50 @@ describe("WorkspaceApps filtering", () => {
["disabled", true],
["unhealthy", false],
["initializing", false],
- ])(
- "apps with '%s' health status should be shown: %s",
- async (health, shouldBeVisible) => {
- const app: WorkspaceApp = {
- ...MockWorkspaceApp,
- id: `${health}-app`,
- display_name: `${health} App`,
- health,
- hidden: false,
- };
- const workspace: Workspace = {
- ...MockWorkspace,
- latest_build: {
- ...MockWorkspace.latest_build,
- status: "running",
- resources: [
- {
- ...MockWorkspace.latest_build.resources[0],
- agents: [
- {
- ...MockWorkspaceAgent,
- apps: [app],
- },
- ],
- },
- ],
- },
- };
- vi.spyOn(API, "getWorkspaces").mockResolvedValue({
- workspaces: [workspace],
- count: 1,
- });
+ ])("apps with '%s' health status should be shown: %s", async (health, shouldBeVisible) => {
+ const app: WorkspaceApp = {
+ ...MockWorkspaceApp,
+ id: `${health}-app`,
+ display_name: `${health} App`,
+ health,
+ hidden: false,
+ };
+ const workspace: Workspace = {
+ ...MockWorkspace,
+ latest_build: {
+ ...MockWorkspace.latest_build,
+ status: "running",
+ resources: [
+ {
+ ...MockWorkspace.latest_build.resources[0],
+ agents: [
+ {
+ ...MockWorkspaceAgent,
+ apps: [app],
+ },
+ ],
+ },
+ ],
+ },
+ };
+ vi.spyOn(API, "getWorkspaces").mockResolvedValue({
+ workspaces: [workspace],
+ count: 1,
+ });
- renderWithAuth();
- await waitForLoaderToBeRemoved();
+ renderWithAuth();
+ await waitForLoaderToBeRemoved();
- const appLink = screen.queryByRole("link", {
- name: (name) =>
- name.toLowerCase().includes(app.display_name!.toLowerCase()),
- });
- if (shouldBeVisible) {
- expect(appLink).toBeInTheDocument();
- } else {
- expect(appLink).not.toBeInTheDocument();
- }
- },
- );
+ const appLink = screen.queryByRole("link", {
+ name: (name) =>
+ name.toLowerCase().includes(app.display_name!.toLowerCase()),
+ });
+ if (shouldBeVisible) {
+ expect(appLink).toBeInTheDocument();
+ } else {
+ expect(appLink).not.toBeInTheDocument();
+ }
+ });
it("does not show hidden apps regardless of health status", async () => {
const hiddenApp: WorkspaceApp = {
diff --git a/site/src/utils/dormant.test.ts b/site/src/utils/dormant.test.ts
index 2dc3a28196..286ed77c1b 100644
--- a/site/src/utils/dormant.test.ts
+++ b/site/src/utils/dormant.test.ts
@@ -27,16 +27,13 @@ describe("displayDormantDeletion", () => {
], // today + 1
[new Date().toISOString(), true, true], // today + 0
[new Date().toISOString(), false, false], // Advanced Scheduling off
- ])(
- "deleting_at=%p, allowAdvancedScheduling=%p, shouldDisplay=%p",
- (deleting_at, allowAdvancedScheduling, shouldDisplay) => {
- const workspace: TypesGen.Workspace = {
- ...Mocks.MockWorkspace,
- deleting_at,
- };
- expect(displayDormantDeletion(workspace, allowAdvancedScheduling)).toBe(
- shouldDisplay,
- );
- },
- );
+ ])("deleting_at=%p, allowAdvancedScheduling=%p, shouldDisplay=%p", (deleting_at, allowAdvancedScheduling, shouldDisplay) => {
+ const workspace: TypesGen.Workspace = {
+ ...Mocks.MockWorkspace,
+ deleting_at,
+ };
+ expect(displayDormantDeletion(workspace, allowAdvancedScheduling)).toBe(
+ shouldDisplay,
+ );
+ });
});
diff --git a/site/src/utils/workspace.test.ts b/site/src/utils/workspace.test.ts
index ee4c7c2b88..cb7480ed9e 100644
--- a/site/src/utils/workspace.test.ts
+++ b/site/src/utils/workspace.test.ts
@@ -35,23 +35,20 @@ describe("util > workspace", () => {
["start", "pending", false],
["start", "running", false],
["start", "succeeded", true],
- ])(
- "transition=%p, status=%p, isWorkspaceOn=%p",
- (transition, status, isOn) => {
- const workspace: TypesGen.Workspace = {
- ...Mocks.MockWorkspace,
- latest_build: {
- ...Mocks.MockWorkspaceBuild,
- job: {
- ...Mocks.MockProvisionerJob,
- status,
- },
- transition,
+ ])("transition=%p, status=%p, isWorkspaceOn=%p", (transition, status, isOn) => {
+ const workspace: TypesGen.Workspace = {
+ ...Mocks.MockWorkspace,
+ latest_build: {
+ ...Mocks.MockWorkspaceBuild,
+ job: {
+ ...Mocks.MockProvisionerJob,
+ status,
},
- };
- expect(isWorkspaceOn(workspace)).toBe(isOn);
- },
- );
+ transition,
+ },
+ };
+ expect(isWorkspaceOn(workspace)).toBe(isOn);
+ });
});
describe("defaultWorkspaceExtension", () => {
@@ -100,12 +97,9 @@ describe("util > workspace", () => {
},
"Coder",
],
- ])(
- "getDisplayWorkspaceBuildInitiatedBy(%p) returns %p",
- (build, initiatedBy) => {
- expect(getDisplayWorkspaceBuildInitiatedBy(build)).toEqual(initiatedBy);
- },
- );
+ ])("getDisplayWorkspaceBuildInitiatedBy(%p) returns %p", (build, initiatedBy) => {
+ expect(getDisplayWorkspaceBuildInitiatedBy(build)).toEqual(initiatedBy);
+ });
});
describe("getDisplayVersionStatus", () => {
@@ -125,26 +119,16 @@ describe("util > workspace", () => {
"v1.2.3",
agentVersionStatus.Deprecated,
],
- ])(
- "getDisplayVersionStatus(theme, %p, %p, %p, %p) returns (%p, %p)",
- (
+ ])("getDisplayVersionStatus(theme, %p, %p, %p, %p) returns (%p, %p)", (agentVersion, serverVersion, agentAPIVersion, serverAPIVersion, expectedVersion, expectedStatus) => {
+ const { displayVersion, status } = getDisplayVersionStatus(
agentVersion,
serverVersion,
agentAPIVersion,
serverAPIVersion,
- expectedVersion,
- expectedStatus,
- ) => {
- const { displayVersion, status } = getDisplayVersionStatus(
- agentVersion,
- serverVersion,
- agentAPIVersion,
- serverAPIVersion,
- );
- expect(displayVersion).toEqual(expectedVersion);
- expect(status).toEqual(expectedStatus);
- },
- );
+ );
+ expect(displayVersion).toEqual(expectedVersion);
+ expect(status).toEqual(expectedStatus);
+ });
});
describe("getDisplayWorkspaceTemplateName", () => {