Skip to content

Commit

Permalink
Run Prettier on all files; update npm scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
caleb531 committed Sep 1, 2024
1 parent 8c991ea commit 699e2f9
Show file tree
Hide file tree
Showing 41 changed files with 371 additions and 390 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ name: docker

on:
push:
branches: [ "main", "develop" ]
branches: ['main', 'develop']
pull_request:
branches: [ "*" ]
branches: ['*']

jobs:
docker:
Expand Down
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ node_modules
.env
.env.*
!.env.example
/.aider*

# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Connect Four

*Copyright 2016-2023, Caleb Evans*
*Released under the MIT License*
_Copyright 2016-2023, Caleb Evans_
_Released under the MIT License_

[![tests](https://github.com/caleb531/connect-four/actions/workflows/tests.yml/badge.svg)](https://github.com/caleb531/connect-four/actions/workflows/tests.yml)

<!-- [![Coverage Status](https://coveralls.io/repos/github/caleb531/connect-four/badge.svg?branch=main)](https://coveralls.io/github/caleb531/connect-four?branch=main) -->

This is the slickest Connect Four app around, written using HTML5, JavaScript,
Expand Down
76 changes: 42 additions & 34 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,39 +1,47 @@
<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Connect Four | <%= pageTitle %></title>
<meta name="viewport" content="width=device-width" />
<meta name="description" content="The slickest way to get 4-in-a-row. Play on your phone or computer, with a friend or against Mr. A.I." />
<meta name="apple-mobile-web-app-title" content="Connect Four" />
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="/icons/favicon.png" />
<link rel="apple-touch-icon" href="/icons/app-icon-192.png" sizes="192x192" />
<script
data-goatcounter="https://calebevans-connectfour.goatcounter.com/count"
data-goatcounter-settings='{"allow_local": true, "path": "/", "title": "Connect Four | Caleb Evans"}'
async
src="https://gc.zgo.at/count.v4.js"
crossorigin="anonymous"
integrity="sha384-nRw6qfbWyJha9LhsOtSb2YJDyZdKvvCFh0fJYlkquSFjUxp9FVNugbfy8q1jdxI+"
></script>
</head>
<body>
<head>
<meta charset="UTF-8" />
<title>Connect Four | <%= pageTitle %></title>
<meta name="viewport" content="width=device-width" />
<meta
name="description"
content="The slickest way to get 4-in-a-row. Play on your phone or computer, with a friend or against Mr. A.I."
/>
<meta name="apple-mobile-web-app-title" content="Connect Four" />
<meta name="theme-color" content="#ffffff" />
<link rel="shortcut icon" href="/icons/favicon.png" />
<link rel="apple-touch-icon" href="/icons/app-icon-192.png" sizes="192x192" />
<script
data-goatcounter="https://calebevans-connectfour.goatcounter.com/count"
data-goatcounter-settings='{"allow_local": true, "path": "/", "title": "Connect Four | Caleb Evans"}'
async
src="https://gc.zgo.at/count.v4.js"
crossorigin="anonymous"
integrity="sha384-nRw6qfbWyJha9LhsOtSb2YJDyZdKvvCFh0fJYlkquSFjUxp9FVNugbfy8q1jdxI+"
></script>
</head>
<body>
<noscript>
<span id="github-link" class="nav-link nav-link-left">
<a href="https://github.com/caleb531/connect-four">View on GitHub</a>
</span>

<noscript>
<span id="github-link" class="nav-link nav-link-left">
<a href="https://github.com/caleb531/connect-four">View on GitHub</a>
</span>
<span id="personal-site-link" class="nav-link nav-link-right">
by <a href="https://calebevans.me">Caleb Evans</a>
</span>
<h1>Connect Four</h1>
<p>
Please
<a href="https://www.whatismybrowser.com/guides/how-to-enable-javascript/"
>enable JavaScript</a
>
to play.
</p>
</noscript>

<span id="personal-site-link" class="nav-link nav-link-right">
by <a href="https://calebevans.me">Caleb Evans</a>
</span>
<h1>Connect Four</h1>
<p>Please <a href="https://www.whatismybrowser.com/guides/how-to-enable-javascript/">enable JavaScript</a> to play.</p>
</noscript>
<main></main>

<main></main>

<script type="module" src="/scripts/index.js"></script>
</body>
<script type="module" src="/scripts/index.js"></script>
</body>
</html>
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"dev": "node server/index.js",
"build": "vite build",
"preview": "NODE_ENV=production DISABLE_SSL=1 node server/index.js",
"lint": "eslint",
"lint": "prettier --check . && eslint .",
"format": "prettier --write .",
"test": "playwright test"
},
"repository": {
Expand Down
37 changes: 11 additions & 26 deletions server/csp.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,18 @@
// Content Security Policy directives for consumption by Helmet package
// (<https://www.npmjs.com/package/helmet>)
export default {
'default-src': [
"'none'"
],
'style-src': [
"'self'",
process.env.NODE_ENV !== 'production' ? "'unsafe-inline'" : ''
],
'img-src': [
"'self'"
],
'font-src': [
"'self'",
'data:'
],
'script-src': [
"'self'",
"https://gc.zgo.at"
],
'default-src': ["'none'"],
'style-src': ["'self'", process.env.NODE_ENV !== 'production' ? "'unsafe-inline'" : ''],
'img-src': ["'self'"],
'font-src': ["'self'", 'data:'],
'script-src': ["'self'", 'https://gc.zgo.at'],
'connect-src': [
"'self'",
"ws://localhost:24678",
"ws://localhost:8080",
"wss://connectfour.calebevans.me",
"http://localhost:24678",
"https://calebevans-connectfour.goatcounter.com/count"
'ws://localhost:24678',
'ws://localhost:8080',
'wss://connectfour.calebevans.me',
'http://localhost:24678',
'https://calebevans-connectfour.goatcounter.com/count'
],
'manifest-src': [
"'self'"
]
'manifest-src': ["'self'"]
};
44 changes: 23 additions & 21 deletions server/express-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import cspDirectives from './csp.js';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
// Ensure that we serve the correct index.html path depending upon the
// environment/context
const indexPath = process.env.NODE_ENV === 'production'
? path.join(path.dirname(__dirname), 'dist', 'index.html')
: path.join(path.dirname(__dirname), 'index.html');
const indexPath =
process.env.NODE_ENV === 'production'
? path.join(path.dirname(__dirname), 'dist', 'index.html')
: path.join(path.dirname(__dirname), 'index.html');

// Generate a secure nonce that can be used to
function generateNonce() {
Expand All @@ -42,7 +43,6 @@ async function transformHtml(vite, req, res, htmlPath, params) {

// Express server
async function createExpressServer() {

const app = express();

// Use EJS as view engine, regardless of file extension (i.e. we need
Expand All @@ -57,27 +57,29 @@ async function createExpressServer() {
}
// Expose nonces to the below CSP (this middleware must be mounted before the
// CSP middleware is mounted))
app.use(((req, res, next) => {
app.use((req, res, next) => {
// Inline <script> nonce for Universal Analytics
res.locals.uaNonce = generateNonce();
// Inline <script> nonce for Google Analytics 4
res.locals.ga4Nonce = generateNonce();
next();
}));
});
// Add the recommended security headers
app.use(helmet({
// Helmet's default value of require-corp for Cross-Origin-Embedder-Policy
// breaks the caching of the Google Fonts CSS via the service worker,
// supposedly because Google Fonts serves an opaque response for the CSS
// which, per the nature of opaque responses, is not explicitly marked as
// loadable from another origin
crossOriginEmbedderPolicy: false,
// Define relatively-strict Content Security Policy (CSP)
contentSecurityPolicy: {
useDefaults: false,
directives: cspDirectives
}
}));
app.use(
helmet({
// Helmet's default value of require-corp for Cross-Origin-Embedder-Policy
// breaks the caching of the Google Fonts CSS via the service worker,
// supposedly because Google Fonts serves an opaque response for the CSS
// which, per the nature of opaque responses, is not explicitly marked as
// loadable from another origin
crossOriginEmbedderPolicy: false,
// Define relatively-strict Content Security Policy (CSP)
contentSecurityPolicy: {
useDefaults: false,
directives: cspDirectives
}
})
);

// Serve assets using gzip compression
app.use(compression());
Expand Down Expand Up @@ -108,13 +110,13 @@ async function createExpressServer() {
app.get('/room/:roomCode', async (req, res) => {
const room = roomManager.getRoom(req.params.roomCode);
if (room) {
const inviteeName = (room.players[0] ? room.players[0].name : 'Someone');
const inviteeName = room.players[0] ? room.players[0].name : 'Someone';
await transformHtml(vite, req, res, indexPath, {
pageTitle: `${inviteeName} invited you to play!`
});
} else {
await transformHtml(vite, req, res, indexPath, {
pageTitle: 'Room doesn\'t exist'
pageTitle: "Room doesn't exist"
});
}
});
Expand Down
22 changes: 17 additions & 5 deletions server/game.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
import Grid from './grid.js';

class Game {

constructor({ players, grid = new Grid({ columnCount: 7, rowCount: 6 }), startingPlayer = null, currentPlayer = null, requestingPlayer = null, inProgress = false, pendingChipColumn = null, winner = null, pendingNewGame = false }) {
constructor({
players,
grid = new Grid({ columnCount: 7, rowCount: 6 }),
startingPlayer = null,
currentPlayer = null,
requestingPlayer = null,
inProgress = false,
pendingChipColumn = null,
winner = null,
pendingNewGame = false
}) {
this.grid = grid;
this.players = players;
this.startingPlayer = startingPlayer;
Expand Down Expand Up @@ -39,7 +48,9 @@ class Game {
if (this.startingPlayer === null) {
this.startingPlayer = this.players[1];
} else {
this.startingPlayer = this.players.find((player) => player.color !== this.startingPlayer.color);
this.startingPlayer = this.players.find(
(player) => player.color !== this.startingPlayer.color
);
}
}

Expand All @@ -60,7 +71,9 @@ class Game {
declareWinner() {
const submittedWinners = this.players.map((player) => player.lastSubmittedWinner || {});
this.winner = this.players.find((player) => {
return player.color === submittedWinners[0].color && player.color === submittedWinners[1].color;
return (
player.color === submittedWinners[0].color && player.color === submittedWinners[1].color
);
});
if (this.winner) {
this.winner.score += 1;
Expand All @@ -81,7 +94,6 @@ class Game {
pendingChipColumn: this.pendingChipColumn
};
}

}

export default Game;
17 changes: 12 additions & 5 deletions server/grid.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
import _ from 'underscore';

class Grid {

// The state of a particular game grid
constructor({ columnCount = 7, rowCount = 6, columns = _.times(columnCount, () => []), lastPlacedChip = null } = {}) {
constructor({
columnCount = 7,
rowCount = 6,
columns = _.times(columnCount, () => []),
lastPlacedChip = null
} = {}) {
this.columnCount = columnCount;
this.rowCount = rowCount;
this.columns = columns;
this.lastPlacedChip = lastPlacedChip;
}

// Reset the grid by removing all placed chips
// Reset the grid by removing all placed chips
resetGrid() {
this.columns.forEach((column) => {
column.length = 0;
Expand All @@ -20,7 +24,11 @@ class Grid {

// Place the given chip into the column defined on it
placeChip(chip) {
if (chip.column >= 0 && chip.column < this.columnCount && this.columns[chip.column].length < this.rowCount) {
if (
chip.column >= 0 &&
chip.column < this.columnCount &&
this.columns[chip.column].length < this.rowCount
) {
this.columns[chip.column].push(chip);
this.lastPlacedChip = chip;
chip.row = this.columns[chip.column].length - 1;
Expand All @@ -35,7 +43,6 @@ class Grid {
lastPlacedChip: this.lastPlacedChip
};
}

}

export default Grid;
Loading

0 comments on commit 699e2f9

Please sign in to comment.