Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
9c1b704
Consolidated changes and features that were developed during xmas time
Oksamies Dec 22, 2025
ea8d8dc
chore: migrate build system to Vite and update TS config
Oksamies Dec 22, 2025
0dc2cd2
Run pre-commit on all files
Oksamies Dec 22, 2025
897e6ab
Update README and configuration for thunderstore.localhost integration
Oksamies Dec 20, 2025
468f44a
Enhance testing setup with Docker integration and Vitest configuration
Oksamies Dec 19, 2025
5eebd4b
Add centralized invalid session cleanup and wire Dapper to it
Oksamies Dec 19, 2025
68ed09f
Improve StrongForm validation UX and text input styling
Oksamies Dec 9, 2025
f827827
Disable team profile form for non-owner members
anttimaki Dec 8, 2025
50c65d2
Disable hover highlight styles from disabled text inputs
anttimaki Dec 8, 2025
a4f75be
Disable hover highlight styles from disabled buttons
anttimaki Dec 8, 2025
2547e81
Add RequiredIndicator component and update forms to use it for requir…
Oksamies Dec 20, 2025
e144cf7
feat: Enhance StrongForm validation and add tests
Oksamies Dec 22, 2025
2cdada4
Refactor tests to enable package version dependencies and source chec…
Oksamies Dec 19, 2025
bc69ac6
Merge pull request #1677 from thunderstore-io/12-20-update_readme_and…
Oksamies Dec 22, 2025
360a8a3
Merge pull request #1675 from thunderstore-io/testing_setup
Oksamies Dec 22, 2025
4e40255
Merge pull request #1660 from thunderstore-io/12-09-add_centralized_i…
Oksamies Dec 22, 2025
f05203b
Merge pull request #1661 from thunderstore-io/12-09-improve_strongfor…
Oksamies Dec 22, 2025
a0e0c3c
Merge pull request #1676 from thunderstore-io/12-19-refactor_tests_to…
Oksamies Dec 22, 2025
ce1b390
refactor: update imports to use type-only imports in thunderstore-api…
Oksamies Dec 22, 2025
2ab2d80
Merge pull request #1680 from thunderstore-io/12-22-refactor_update_i…
Oksamies Dec 22, 2025
d38461e
Fix issue with root.tsx import sorting making styles break
Oksamies Dec 22, 2025
10e0a7f
Merge pull request #1681 from thunderstore-io/12-22-fix_issue_with_ro…
Oksamies Dec 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .github/actions/get-node-version/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { setOutput, setFailed, getInput } from "@actions/core";
import semver from "semver";
import { getInput, setFailed, setOutput } from "@actions/core";
import { readFileSync } from "fs";
import semver from "semver";

(() => {
const inputPath = getInput("package-json");
Expand Down
3 changes: 3 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ repos:
hooks:
- id: prettier
exclude_types: [markdown, yaml]
additional_dependencies:
- prettier@3.1.0
- "@trivago/prettier-plugin-sort-imports@6.0.0"
- repo: https://github.com/thibaudcolas/pre-commit-stylelint
rev: v16.9.0
hooks:
Expand Down
11 changes: 10 additions & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,14 @@
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"vueIndentScriptAndStyle": false
"vueIndentScriptAndStyle": false,
"plugins": ["@trivago/prettier-plugin-sort-imports"],
"importOrder": [
"^\\./styles/index\\.css$",
"<THIRD_PARTY_MODULES>",
"^@thunderstore/(.*)$",
"^[./]"
],
"importOrderSeparation": true,
"importOrderSortSpecifiers": true
}
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,25 @@ running:
docker compose -f docker-compose.build.yml build
```

## Testing (Docker)

Frontend tests run in Vitest browser mode (Playwright). To keep the environment consistent, use the dedicated test runner compose file instead of the dev container.

Prereqs:
- Ensure `./build-secrets/.npmrc` exists (same requirement as Docker builds).

Run tests:

```bash
yarn test:container
```

Run coverage:

```bash
yarn coverage:container
```

## pre-commit

[Pre-commit](https://pre-commit.com/) enforces code style practices in this
Expand Down
4 changes: 2 additions & 2 deletions apps/cyberstorm-remix/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ The easiest way to run the full stack (Backend + Frontend) is using Docker.
(If you have some pre-existing containers, please do `docker compose -f docker-compose.remix.development.yml down -v` and `docker compose -f docker-compose.remix.development.yml up -d --build`)

4. **Open Browser**
- **Frontend**: [http://new.localhost](http://new.localhost)
- **Backend**: [http://localhost](http://localhost)
- **Frontend**: [http://new.thunderstore.localhost](http://new.thunderstore.localhost)
- **Backend**: [http://thunderstore.localhost](http://thunderstore.localhost)

## Manual Setup

Expand Down
24 changes: 13 additions & 11 deletions apps/cyberstorm-remix/app/c/community.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
import { faDiscord } from "@fortawesome/free-brands-svg-icons";
import { faBook, faDownload } from "@fortawesome/free-solid-svg-icons";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
getPublicEnvVariables,
getSessionTools,
} from "cyberstorm/security/publicEnvVariables";
import { Suspense } from "react";
import type {
LoaderFunctionArgs,
ShouldRevalidateFunctionArgs,
Expand All @@ -9,26 +18,19 @@ import {
useLocation,
useOutletContext,
} from "react-router";

import {
Heading,
NewButton,
NewIcon,
NewLink,
SkeletonBox,
} from "@thunderstore/cyberstorm";
import "./Community.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faBook, faDownload } from "@fortawesome/free-solid-svg-icons";
import { faDiscord } from "@fortawesome/free-brands-svg-icons";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";
import { classnames } from "@thunderstore/cyberstorm";
import { DapperTs } from "@thunderstore/dapper-ts";

import { type OutletContextShape } from "../root";
import {
getPublicEnvVariables,
getSessionTools,
} from "cyberstorm/security/publicEnvVariables";
import { Suspense } from "react";
import { classnames } from "@thunderstore/cyberstorm/src/utils/utils";
import "./Community.css";

export async function loader({ params }: LoaderFunctionArgs) {
if (params.communityId) {
Expand Down
10 changes: 6 additions & 4 deletions apps/cyberstorm-remix/app/c/tabs/PackageSearch/PackageSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { useLoaderData, useOutletContext } from "react-router";
import { PackageSearch } from "~/commonComponents/PackageSearch/PackageSearch";
import { PackageOrderOptions } from "~/commonComponents/PackageSearch/components/PackageOrder";
import { DapperTs } from "@thunderstore/dapper-ts";
import {
getPublicEnvVariables,
getSessionTools,
} from "cyberstorm/security/publicEnvVariables";
import { useLoaderData, useOutletContext } from "react-router";
import { PackageSearch } from "~/commonComponents/PackageSearch/PackageSearch";
import { PackageOrderOptions } from "~/commonComponents/PackageSearch/components/PackageOrder";
import { type OutletContextShape } from "~/root";

import { DapperTs } from "@thunderstore/dapper-ts";

import type { Route } from "./+types/PackageSearch";

export async function loader({ params, request }: Route.LoaderArgs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,13 @@ import {
faSquareCheck,
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { memo } from "react";
import { type TRISTATE } from "~/commonComponents/types";

import "./CheckboxList.css";
import { Actionable, NewIcon } from "@thunderstore/cyberstorm";
import { classnames } from "@thunderstore/cyberstorm/src/utils/utils";
import { type TRISTATE } from "~/commonComponents/types";
import { memo } from "react";
import { classnames } from "@thunderstore/cyberstorm";

import "./CheckboxList.css";

type typeA<B> = (v: B) => void;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { CodeBox, NewAlert } from "@thunderstore/cyberstorm";
import { memo, useMemo } from "react";
import { stripHtmlTags } from "cyberstorm/utils/HTMLParsing";
import { memo, useMemo } from "react";

import { CodeBox, NewAlert } from "@thunderstore/cyberstorm";

import "./CodeBoxHTML.css";

export interface CodeBoxHTMLProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { memo, type PropsWithChildren } from "react";
import { faCaretDown } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import "./Collapsible.css";
import { type PropsWithChildren, memo } from "react";

import { NewIcon } from "@thunderstore/cyberstorm";
import { classnames } from "@thunderstore/cyberstorm/src/utils/utils";
import { classnames } from "@thunderstore/cyberstorm";

import "./Collapsible.css";

interface Props extends PropsWithChildren {
headerTitle: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { classnames } from "@thunderstore/cyberstorm/src/utils/utils";
import { type ReactElement, useState } from "react";

import { classnames } from "@thunderstore/cyberstorm";

import "./CollapsibleText.css";
import { useState, type ReactElement } from "react";

export interface CollapsibleTextProps {
text?: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import "./Connection.css";
import { type ReactElement } from "react";

import { NewIcon, NewSwitch } from "@thunderstore/cyberstorm";
import { type OAuthConnection } from "@thunderstore/dapper/types";
import { type ReactElement } from "react";
import { type userLinkedAccountDisconnectProviders } from "../../../../../packages/thunderstore-api/src";
import type { userLinkedAccountDisconnectProviders } from "@thunderstore/thunderstore-api";

import "./Connection.css";

interface ConnectionProps {
name: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { faCheck, faClone } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faClone, faCheck } from "@fortawesome/free-solid-svg-icons";
import { type Dispatch, type SetStateAction, useState } from "react";
import "./CopyButton.css";
import { NewIcon, Tooltip } from "@thunderstore/cyberstorm/src";
import React from "react";

import { NewIcon, Tooltip } from "@thunderstore/cyberstorm";

import "./CopyButton.css";

interface CopyButtonProps {
text: string;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { useEffect, type JSX } from "react";
import { isRouteErrorResponse, useRouteError } from "react-router";
import { captureRemixErrorBoundaryError } from "@sentry/remix";
import { type JSX, useEffect } from "react";
import { isRouteErrorResponse, useRouteError } from "react-router";

import { ApiError } from "@thunderstore/thunderstore-api";

Expand Down
10 changes: 6 additions & 4 deletions apps/cyberstorm-remix/app/commonComponents/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import "./Footer.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons";
import { faBoltLightning } from "@fortawesome/free-solid-svg-icons";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

import {
Heading,
NewButton,
NewIcon,
NewLink,
ThunderstoreLogoHorizontal,
} from "@thunderstore/cyberstorm";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";

import "./Footer.css";

const AD_IMAGE_SRC = "/cyberstorm-static/images/tsmm_screenshot.png";
const DISCORD_URL = "https://discord.thunderstore.io/";
Expand Down Expand Up @@ -200,7 +202,7 @@ export function Footer() {
</NewLink>
</div>
<p className="footer__copyright">
© 2025 Thunderstore and contributors.{" "}
© 2026 Thunderstore and contributors.{" "}
<span>
This page is{" "}
<NewLink
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Image, NewLink, formatToDisplayName } from "@thunderstore/cyberstorm";
import { type PackageVersionDependency } from "@thunderstore/thunderstore-api";

import "./ListingDependency.css";
import { formatToDisplayName, Image, NewLink } from "@thunderstore/cyberstorm";

export interface ListingDependencyProps {
dependency: PackageVersionDependency;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { MarkdownHooks } from "react-markdown";
import gfm from "remark-gfm";

import { nimbusSanitize } from "./Sanitize";

interface MarkdownProps {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type Schema, sanitize } from "hast-util-sanitize";
import type { Nodes } from "hast";
import { type Schema, sanitize } from "hast-util-sanitize";

/**
* Based on:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons";
import {
faBars,
faGamepad,
faLongArrowLeft,
faCaretRight,
faCaretDown,
faCaretRight,
faCog,
faUsers,
faGamepad,
faLongArrowLeft,
faUpload,
faUsers,
} from "@fortawesome/free-solid-svg-icons";
import {
faArrowRightToBracket,
faSignOut,
} from "@fortawesome/free-solid-svg-icons";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { getPublicEnvVariables } from "cyberstorm/security/publicEnvVariables";
import {
buildAuthLoginUrl,
buildLogoutUrl,
} from "cyberstorm/utils/ThunderstoreAuth";

import "./MobileNavigation.css";
import "./Navigation.css";
import {
Heading,
Menu,
Modal,
NewAvatar,
NewButton,
NewDropDown,
NewDropDownDivider,
NewDropDownItem,
NewAvatar,
NewIcon,
NewLink,
OverwolfLogo,
ThunderstoreLogo,
} from "@thunderstore/cyberstorm";
import { classnames } from "@thunderstore/cyberstorm";
import { type CurrentUser } from "@thunderstore/dapper/types";

import {
faSignOut,
faArrowRightToBracket,
} from "@fortawesome/free-solid-svg-icons";
import { faDiscord, faGithub } from "@fortawesome/free-brands-svg-icons";

import { classnames } from "@thunderstore/cyberstorm/src/utils/utils";
import {
buildAuthLoginUrl,
buildLogoutUrl,
} from "cyberstorm/utils/ThunderstoreAuth";
import { faArrowUpRight } from "@fortawesome/pro-solid-svg-icons";
import { getPublicEnvVariables } from "cyberstorm/security/publicEnvVariables";
import "./MobileNavigation.css";
import "./Navigation.css";

export function Navigation(props: {
// hydrationCheck: boolean;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
// import { useSession } from "@thunderstore/ts-api-react";
// import { useHydrated } from "remix-utils/use-hydrated";
// import { useEffect, useRef, useState } from "react";

import { type CurrentUser } from "@thunderstore/dapper/types";

import {
MobileNavigationMenu,
MobileUserPopoverContent,
Expand Down
Loading
Loading