Skip to content

Commit 70015b9

Browse files
authored
Merge branch 'master' into feat/tunnel-vision
2 parents 3f9cdc7 + 0ba7f62 commit 70015b9

489 files changed

Lines changed: 20712 additions & 10030 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/fix-formatting.yml

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
version: ${{ env.PNPM_VERSION }}
3535

3636
- name: Install formatter
37-
run: pnpm install -D -w oxfmt
37+
run: pnpm install -D -w oxfmt --ignore-scripts
3838

3939
- name: Get changed files
4040
id: get-changed-files
@@ -52,10 +52,11 @@ jobs:
5252
return changedFiles.filter(file=> file.status !== "removed").map(file => file.filename).join(' ');
5353
5454
- name: Fix formatting
55+
env:
56+
CHANGED_FILES: ${{ steps.get-changed-files.outputs.result }}
5557
run: |
56-
CHANGED_FILES=$(echo ${{ steps.get-changed-files.outputs.result }})
5758
if [ -n "$CHANGED_FILES" ]; then
58-
pnpm oxfmt $CHANGED_FILES --no-error-on-unmatched-pattern
59+
echo "$CHANGED_FILES" | tr ' ' '\n' | xargs pnpm oxfmt --no-error-on-unmatched-pattern
5960
fi
6061
6162
- name: Commit changes

.github/workflows/monkey-ci.yml

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ jobs:
2828
should-build-be: ${{ steps.export-changes.outputs.should-build-be }}
2929
should-build-fe: ${{ steps.export-changes.outputs.should-build-fe }}
3030
should-build-pkg: ${{ steps.export-changes.outputs.should-build-pkg }}
31-
assets-json: ${{ steps.export-changes.outputs.assets-json }}
31+
assets-or-styles: ${{ steps.export-changes.outputs.assets-or-styles }}
3232

3333
steps:
3434
- name: Full checkout
@@ -41,8 +41,9 @@ jobs:
4141
id: filter
4242
with:
4343
filters: |
44-
json:
44+
assets-or-styles:
4545
- 'frontend/static/**/*'
46+
- '**/*.{scss,css}'
4647
be-src:
4748
- 'backend/**/*.{ts,js,json,lua,css,html}'
4849
- 'backend/package.json'
@@ -64,13 +65,13 @@ jobs:
6465
echo "should-build-pkg=${{ steps.filter.outputs.pkg-src }}" >> $GITHUB_OUTPUT
6566
echo "should-build-be=${{ steps.filter.outputs.be-src }}" >> $GITHUB_OUTPUT
6667
echo "should-build-fe=${{ steps.filter.outputs.fe-src }}" >> $GITHUB_OUTPUT
67-
echo "assets-json=${{ steps.filter.outputs.json }}" >> $GITHUB_OUTPUT
68+
echo "assets-or-styles=${{ steps.filter.outputs.assets-or-styles }}" >> $GITHUB_OUTPUT
6869
6970
prime-cache:
7071
name: prime-cache
7172
runs-on: ubuntu-latest
7273
needs: [pre-ci]
73-
if: needs.pre-ci.outputs.should-build-be == 'true' || needs.pre-ci.outputs.should-build-fe == 'true' || needs.pre-ci.outputs.should-build-pkg == 'true' || needs.pre-ci.outputs.assets-json == 'true' || contains(github.event.pull_request.labels.*.name, 'force-full-ci')
74+
if: needs.pre-ci.outputs.should-build-be == 'true' || needs.pre-ci.outputs.should-build-fe == 'true' || needs.pre-ci.outputs.should-build-pkg == 'true' || needs.pre-ci.outputs.assets-or-styles == 'true' || contains(github.event.pull_request.labels.*.name, 'force-full-ci')
7475
steps:
7576
- name: Checkout pnpm-lock
7677
uses: actions/checkout@v4
@@ -216,7 +217,7 @@ jobs:
216217
name: ci-assets
217218
needs: [pre-ci, prime-cache]
218219
runs-on: ubuntu-latest
219-
if: needs.pre-ci.outputs.assets-json == 'true' || contains(github.event.pull_request.labels.*.name, 'force-full-ci')
220+
if: needs.pre-ci.outputs.assets-or-styles == 'true' || contains(github.event.pull_request.labels.*.name, 'force-full-ci')
220221
steps:
221222
- uses: actions/checkout@v4
222223
with:
@@ -228,6 +229,10 @@ jobs:
228229
id: filter
229230
with:
230231
filters: |
232+
styles:
233+
- '**/*.{scss,css}'
234+
json:
235+
- 'frontend/static/**/*.json'
231236
languages:
232237
- 'frontend/static/languages/**'
233238
quotes:
@@ -237,6 +242,7 @@ jobs:
237242
- 'frontend/static/themes/**'
238243
- 'frontend/static/webfonts/**'
239244
- 'frontend/static/challenges/**'
245+
- 'frontend/static/sounds/**'
240246
241247
- name: Set up Node.js
242248
uses: actions/setup-node@v4
@@ -265,7 +271,12 @@ jobs:
265271
- name: Install dependencies
266272
run: pnpm install
267273

274+
- name: Lint styles
275+
if: steps.filter.outputs.styles == 'true'
276+
run: npm run lint-styles
277+
268278
- name: Lint JSON
279+
if: steps.filter.outputs.json == 'true'
269280
run: npm run lint-json-assets
270281

271282
- name: Validate language assets

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,4 @@ frontend/static/webfonts-preview
132132
.turbo
133133
frontend/.env.sentry-build-plugin
134134
.claude/worktrees
135-
1024MiB
135+
1024MiB

CLAUDE.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Be extremely concise. Sacrifice grammar for concision.
22
Frontend is partially migrated from vanilla JS to SolidJS — new components use `.tsx`, legacy code remains vanilla.
33
Single test file: `pnpm vitest run path/to/test.ts`
4+
When running oxc lint, always use `--format agent`.
5+
For typechecking, use `oxc --type-aware --type-check` instead of `tsc`.
46
For styling, use Tailwind CSS, class property, `cn` utility. Do not use classlist. Only colors available are those defined in Tailwind config.
57
In legacy code, use `i` tags with FontAwesome classes. In new code, use `Fa` component.
68
In plan mode, before writing up a plan, ask clarifying questions if needed. At the end of plan mode, give me a list of unresolved questions to answer, if any. Make them concise.

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,4 @@ All of the [contributors](https://github.com/monkeytypegame/monkeytype/graphs/co
6969

7070
# Support
7171

72-
If you wish to support further development and feel extra awesome, you can [donate](https://ko-fi.com/monkeytype), [become a Patron](https://www.patreon.com/monkeytype) or [buy a t-shirt](https://www.monkeytype.store/).
72+
If you wish to support further development and feel extra awesome, you can [donate](https://ko-fi.com/monkeytype), [become a Patron](https://www.patreon.com/monkeytype), or [buy a t-shirt](https://www.monkeytype.store/).

backend/__tests__/__integration__/dal/blocklist.spec.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ describe("BlocklistDal", () => {
2626
const now = 1715082588;
2727
vi.setSystemTime(now);
2828

29-
const name = "user" + new ObjectId().toHexString();
29+
const name = `user${new ObjectId().toHexString()}`;
3030
const email = `${name}@example.com`;
3131

3232
//WHEN
@@ -56,7 +56,7 @@ describe("BlocklistDal", () => {
5656
const now = 1715082588;
5757
vi.setSystemTime(now);
5858

59-
const name = "user" + new ObjectId().toHexString();
59+
const name = `user${new ObjectId().toHexString()}`;
6060
const email = `${name}@example.com`;
6161
const discordId = `${name}DiscordId`;
6262

@@ -78,7 +78,7 @@ describe("BlocklistDal", () => {
7878
const now = 1715082588;
7979
vi.setSystemTime(now);
8080

81-
const name = "user" + new ObjectId().toHexString();
81+
const name = `user${new ObjectId().toHexString()}`;
8282
const email = `${name}@example.com`;
8383
const email2 = `${name}@otherdomain.com`;
8484
await BlacklistDal.add({ name, email });
@@ -114,9 +114,9 @@ describe("BlocklistDal", () => {
114114
const now = 1715082588;
115115
vi.setSystemTime(now);
116116

117-
const name = "user" + new ObjectId().toHexString();
117+
const name = `user${new ObjectId().toHexString()}`;
118118
const email = `${name}@example.com`;
119-
const name2 = "user" + new ObjectId().toHexString();
119+
const name2 = `user${new ObjectId().toHexString()}`;
120120
await BlacklistDal.add({ name, email });
121121

122122
//WHEN
@@ -136,8 +136,8 @@ describe("BlocklistDal", () => {
136136
const now = 1715082588;
137137
vi.setSystemTime(now);
138138

139-
const name = "user" + new ObjectId().toHexString();
140-
const name2 = "user" + new ObjectId().toHexString();
139+
const name = `user${new ObjectId().toHexString()}`;
140+
const name2 = `user${new ObjectId().toHexString()}`;
141141
const email = `${name}@example.com`;
142142
const discordId = `${name}DiscordId`;
143143

@@ -160,7 +160,7 @@ describe("BlocklistDal", () => {
160160
describe("contains", () => {
161161
it("contains user", async () => {
162162
//GIVEN
163-
const name = "user" + new ObjectId().toHexString();
163+
const name = `user${new ObjectId().toHexString()}`;
164164
const email = `${name}@example.com`;
165165
const discordId = `${name}DiscordId`;
166166
await BlacklistDal.add({ name, email, discordId });
@@ -229,7 +229,7 @@ describe("BlocklistDal", () => {
229229
describe("remove", () => {
230230
it("removes existing username", async () => {
231231
//GIVEN
232-
const name = "user" + new ObjectId().toHexString();
232+
const name = `user${new ObjectId().toHexString()}`;
233233
const email = `${name}@example.com`;
234234
await BlacklistDal.add({ name, email });
235235
await BlacklistDal.add({ name: "test", email: "test@example.com" });
@@ -251,7 +251,7 @@ describe("BlocklistDal", () => {
251251
});
252252
it("removes existing email", async () => {
253253
//GIVEN
254-
const name = "user" + new ObjectId().toHexString();
254+
const name = `user${new ObjectId().toHexString()}`;
255255
const email = `${name}@example.com`;
256256
await BlacklistDal.add({ name, email });
257257
await BlacklistDal.add({ name: "test", email: "test@example.com" });
@@ -273,7 +273,7 @@ describe("BlocklistDal", () => {
273273
});
274274
it("removes existing discordId", async () => {
275275
//GIVEN
276-
const name = "user" + new ObjectId().toHexString();
276+
const name = `user${new ObjectId().toHexString()}`;
277277
const email = `${name}@example.com`;
278278
const discordId = `${name}DiscordId`;
279279
await BlacklistDal.add({ name, email, discordId });
@@ -304,7 +304,7 @@ describe("BlocklistDal", () => {
304304
});
305305
it("removes existing username,email and discordId", async () => {
306306
//GIVEN
307-
const name = "user" + new ObjectId().toHexString();
307+
const name = `user${new ObjectId().toHexString()}`;
308308
const email = `${name}@example.com`;
309309
const discordId = `${name}DiscordId`;
310310
await BlacklistDal.add({ name, email, discordId });
@@ -336,7 +336,7 @@ describe("BlocklistDal", () => {
336336

337337
it("does not remove for empty user", async () => {
338338
//GIVEN
339-
const name = "user" + new ObjectId().toHexString();
339+
const name = `user${new ObjectId().toHexString()}`;
340340
const email = `${name}@example.com`;
341341
const discordId = `${name}DiscordId`;
342342
await BlacklistDal.add({ name, email, discordId });

backend/__tests__/__integration__/dal/leaderboards.isolated.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,7 @@ async function createUser(
496496
userProperties?: Partial<UserDal.DBUser>,
497497
): Promise<UserDal.DBUser> {
498498
const uid = new ObjectId().toHexString();
499-
await UserDal.addUser("User " + uid, uid + "@example.com", uid);
499+
await UserDal.addUser(`User ${uid}`, `${uid}@example.com`, uid);
500500

501501
await DB.getDb()
502502
?.collection<UserDal.DBUser>("users")
@@ -505,8 +505,8 @@ async function createUser(
505505
{
506506
$set: {
507507
timeTyping: 7200,
508-
discordId: "discord " + uid,
509-
discordAvatar: "avatar " + uid,
508+
discordId: `discord ${uid}`,
509+
discordAvatar: `avatar ${uid}`,
510510
...userProperties,
511511
lbPersonalBests,
512512
},

backend/__tests__/__integration__/dal/user.spec.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ describe("UserDal", () => {
128128

129129
it("isNameAvailable should correctly check if a username is available", async () => {
130130
// given
131-
const name1 = "user" + new ObjectId().toHexString();
132-
const name2 = "user" + new ObjectId().toHexString();
131+
const name1 = `user${new ObjectId().toHexString()}`;
132+
const name2 = `user${new ObjectId().toHexString()}`;
133133
const { uid: user1 } = await UserTestData.createUser({ name: name1 });
134134
await UserTestData.createUser({ name: name2 });
135135

@@ -160,8 +160,8 @@ describe("UserDal", () => {
160160

161161
it("updatename should not allow unavailable usernames", async () => {
162162
// given
163-
const name1 = "user" + new ObjectId().toHexString();
164-
const name2 = "user" + new ObjectId().toHexString();
163+
const name1 = `user${new ObjectId().toHexString()}`;
164+
const name2 = `user${new ObjectId().toHexString()}`;
165165
const user1 = await UserTestData.createUser({ name: name1 });
166166
const user2 = await UserTestData.createUser({ name: name2 });
167167
const _decoy = await UserTestData.createUser();
@@ -173,8 +173,8 @@ describe("UserDal", () => {
173173
});
174174

175175
it("same usernames (different casing) should be available only for the same user", async () => {
176-
const name1 = "user" + new ObjectId().toHexString();
177-
const name2 = "user" + new ObjectId().toHexString();
176+
const name1 = `user${new ObjectId().toHexString()}`;
177+
const name2 = `user${new ObjectId().toHexString()}`;
178178
const user1 = await UserTestData.createUser({ name: name1 });
179179
const user2 = await UserTestData.createUser({ name: name2 });
180180

@@ -192,8 +192,8 @@ describe("UserDal", () => {
192192

193193
it("UserDAL.updateName should change the name of a user", async () => {
194194
// given
195-
const name = "user" + new ObjectId().toHexString();
196-
const renamed = "renamed" + new ObjectId().toHexString();
195+
const name = `user${new ObjectId().toHexString()}`;
196+
const renamed = `renamed${new ObjectId().toHexString()}`;
197197
const testUser = await UserTestData.createUser({ name: name });
198198

199199
// when
@@ -1696,7 +1696,7 @@ describe("UserDal", () => {
16961696

16971697
it("increments bananas", async () => {
16981698
//GIVEN
1699-
const name = "user" + new ObjectId().toHexString();
1699+
const name = `user${new ObjectId().toHexString()}`;
17001700
const { uid } = await UserTestData.createUser({
17011701
name,
17021702
bananas: 1,

backend/__tests__/__testData__/connections.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export async function createConnection(
55
data: Partial<ConnectionsDal.DBConnection>,
66
maxPerUser = 25,
77
): Promise<ConnectionsDal.DBConnection> {
8-
const defaultName = "user" + new ObjectId().toHexString();
8+
const defaultName = `user${new ObjectId().toHexString()}`;
99
const result = await ConnectionsDal.create(
1010
{
1111
uid: data.initiatorUid ?? new ObjectId().toHexString(),

backend/__tests__/__testData__/users.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export async function createUser(
77
user?: Partial<UserDAL.DBUser>,
88
): Promise<UserDAL.DBUser> {
99
const uid = new ObjectId().toHexString();
10-
await UserDAL.addUser("user" + uid, uid + "@example.com", uid);
10+
await UserDAL.addUser(`user${uid}`, `${uid}@example.com`, uid);
1111
await DB.collection("users").updateOne({ uid }, { $set: { ...user } });
1212
return await UserDAL.getUser(uid, "test");
1313
}
@@ -16,7 +16,7 @@ export async function createUserWithoutMigration(
1616
user?: Partial<UserDAL.DBUser>,
1717
): Promise<UserDAL.DBUser> {
1818
const uid = new ObjectId().toHexString();
19-
await UserDAL.addUser("user" + uid, uid + "@example.com", uid);
19+
await UserDAL.addUser(`user${uid}`, `${uid}@example.com`, uid);
2020
await DB.collection("users").updateOne({ uid }, { $set: { ...user } });
2121
await DB.collection("users").updateOne(
2222
{ uid },

0 commit comments

Comments
 (0)