moving to dev server
This commit is contained in:
parent
6c5c03338f
commit
1afeee0226
21 changed files with 5030 additions and 0 deletions
11
README.md
11
README.md
|
@ -1,2 +1,13 @@
|
|||
# monsterdon-bingo
|
||||
|
||||
## Desired functionality
|
||||
|
||||
minimal
|
||||
|
||||
- [ ] Add terms to db
|
||||
- [ ] Render random bingo card
|
||||
|
||||
basic
|
||||
|
||||
- [ ] login from masto
|
||||
- [ ] create weekly bingo card
|
||||
|
|
6
client/.babelrc
Normal file
6
client/.babelrc
Normal file
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react"
|
||||
]
|
||||
}
|
32
client/config/webpack.common.js
Normal file
32
client/config/webpack.common.js
Normal file
|
@ -0,0 +1,32 @@
|
|||
const path = require('path');
|
||||
const HtmlWebPackPlugin = require( 'html-webpack-plugin' );
|
||||
|
||||
module.exports = {
|
||||
entry: './src/index.js',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
exclude: /node_modules/,
|
||||
use: ['babel-loader'],
|
||||
},
|
||||
// {
|
||||
// test: /\.(png|j?g|svg|gif|mp3)?$/,
|
||||
// use: [require.resolve('file-loader')]
|
||||
// }
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx', '*'],
|
||||
},
|
||||
plugins: [
|
||||
new HtmlWebPackPlugin({
|
||||
template: path.resolve( __dirname, '../public/index.html' ),
|
||||
title: "Monsterdon Bingo"
|
||||
}),
|
||||
],
|
||||
output: {
|
||||
filename: 'bundle.js',
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
},
|
||||
};
|
58
client/config/webpack.dev.js
Normal file
58
client/config/webpack.dev.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
const webpack = require('webpack')
|
||||
const { merge } = require('webpack-merge')
|
||||
const path = require( 'path' );
|
||||
|
||||
// const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
|
||||
|
||||
const common = require('./webpack.common.js')
|
||||
|
||||
|
||||
module.exports = merge(common, {
|
||||
// Set the mode to development or production
|
||||
mode: 'development',
|
||||
// watch: true,
|
||||
// watchOptions: {
|
||||
// ignored: '**/node_modules/',
|
||||
// },
|
||||
|
||||
devServer: {
|
||||
// watchOptions: {
|
||||
// ignored: '**/node_modules/'
|
||||
// },
|
||||
client: {
|
||||
webSocketURL: 'auto://0.0.0.0:0/ws'
|
||||
},
|
||||
|
||||
|
||||
},
|
||||
|
||||
// Control how source maps are generated
|
||||
devtool: 'inline-source-map',
|
||||
|
||||
module: {
|
||||
rules: [
|
||||
// Styles: Inject CSS into the head with source maps
|
||||
{
|
||||
test:/\.(s[ac]ss)$/i,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader',
|
||||
'sass-loader'
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader'
|
||||
]
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
plugins: [
|
||||
// Only update what has changed on hot reload
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
// new ReactRefreshWebpackPlugin()
|
||||
],
|
||||
})
|
39
client/config/webpack.prod.js
Normal file
39
client/config/webpack.prod.js
Normal file
|
@ -0,0 +1,39 @@
|
|||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||
const { merge } = require('webpack-merge')
|
||||
const path = require( 'path' );
|
||||
const common = require('./webpack.common.js')
|
||||
|
||||
module.exports = merge(common, {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(s[ac]ss)$/i,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader',
|
||||
'sass-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
MiniCssExtractPlugin.loader,
|
||||
'css-loader'
|
||||
]
|
||||
}
|
||||
],
|
||||
},
|
||||
optimization: {
|
||||
minimize: true,
|
||||
minimizer: [new CssMinimizerPlugin(), '...'],
|
||||
},
|
||||
performance: {
|
||||
hints: false,
|
||||
maxEntrypointSize: 512000,
|
||||
maxAssetSize: 512000,
|
||||
},
|
||||
plugins: [new MiniCssExtractPlugin()]
|
||||
})
|
32
client/package.json
Normal file
32
client/package.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "@monsterdon-bingo/client",
|
||||
"version": "1.0.0",
|
||||
"description": "react client for monsterdon bingo",
|
||||
"main": "index.js",
|
||||
"repository": "https://git.jon-e.net/jonny/monsterdon-bingo",
|
||||
"author": "sneakers-the-rat <j@nny.fyi>",
|
||||
"license": "AGPL-3.0",
|
||||
"scripts": {
|
||||
"start": "NODE_ENV=development webpack serve -c ./config/webpack.dev.js --mode development"
|
||||
},
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"sass": "^1.65.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.22.10",
|
||||
"@babel/preset-env": "^7.22.10",
|
||||
"@babel/preset-react": "^7.22.5",
|
||||
"babel-loader": "^9.1.3",
|
||||
"css-loader": "^6.8.1",
|
||||
"css-minimizer-webpack-plugin": "^5.0.1",
|
||||
"html-webpack-plugin": "^5.5.3",
|
||||
"mini-css-extract-plugin": "^2.7.6",
|
||||
"sass-loader": "^13.3.2",
|
||||
"style-loader": "^3.3.3",
|
||||
"webpack": "^5.88.2",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-dev-server": "^4.15.1"
|
||||
}
|
||||
}
|
17
client/public/index.html
Normal file
17
client/public/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Bingo, for monsterdon!"
|
||||
/>
|
||||
<title>Monsterdon Bingo!</title>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
</body>
|
||||
</html>
|
18
client/src/app.js
Normal file
18
client/src/app.js
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React from 'react';
|
||||
|
||||
|
||||
function App(){
|
||||
return(
|
||||
<div className={"app-container"}>
|
||||
<div className={"app"}>
|
||||
<div className={"app-header-bar"}>
|
||||
<header className={"app-header-title"}>
|
||||
Monsterdon Bingo!
|
||||
</header>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default App
|
17
client/src/index.js
Normal file
17
client/src/index.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
|
||||
import App from './app';
|
||||
|
||||
import './sass/index.scss';
|
||||
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root')
|
||||
)
|
||||
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
1
client/src/sass/index.scss
Normal file
1
client/src/sass/index.scss
Normal file
|
@ -0,0 +1 @@
|
|||
@charset "utf-8";
|
25
package.json
Normal file
25
package.json
Normal file
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"name": "monsterdon-bingo",
|
||||
"private": true,
|
||||
"workspaces": [
|
||||
"client",
|
||||
"server"
|
||||
],
|
||||
"scripts": {
|
||||
"start:client": "npm run start --prefix client",
|
||||
"start:server": "npm run start --prefix server",
|
||||
"start": "concurrently -k -n \"CLIENT,SERVER\" -c \"bgBlue.bold,bgRed.bold\" \"npm run start:client\" \"npm run start:server\"",
|
||||
"build:client": "npm run build --prefix client",
|
||||
"build:server": "npm run build --prefix server",
|
||||
"build": "npm run build:client; npm run build:server"
|
||||
},
|
||||
"version": "1.0.0",
|
||||
"description": "bingo for monsterdon on the fediverse",
|
||||
"main": "index.js",
|
||||
"repository": "https://git.jon-e.net/jonny/monsterdon-bingo.git",
|
||||
"author": "sneakers-the-rat <JLSaunders987@gmail.com>",
|
||||
"license": "AGPL-3.0",
|
||||
"devDependencies": {
|
||||
"concurrently": "^8.2.0"
|
||||
}
|
||||
}
|
9
server/config/custom-environment-variables.js
Executable file
9
server/config/custom-environment-variables.js
Executable file
|
@ -0,0 +1,9 @@
|
|||
export default {
|
||||
port: 'PORT',
|
||||
sqliteFile: "SQLITE_FILE",
|
||||
logDir: 'LOG_DIR',
|
||||
cookies: {
|
||||
key1: "COOKIE_KEY_1",
|
||||
key2: "COOKIE_KEY_2"
|
||||
}
|
||||
}
|
4
server/config/defaults.js
Executable file
4
server/config/defaults.js
Executable file
|
@ -0,0 +1,4 @@
|
|||
export default {
|
||||
port: '8999',
|
||||
logDir: '/var/chatbridge'
|
||||
}
|
5
server/example.env
Normal file
5
server/example.env
Normal file
|
@ -0,0 +1,5 @@
|
|||
PORT=9001
|
||||
SQLITE_FILE=$HOME/.mastodon-bingo/mastodon-bingo.sqlite
|
||||
LOG_DIR=$HOME/.mastodon-bingo/logs
|
||||
COOKIE_KEY_1=mysecurekey1
|
||||
COOKIE_KEY_2=mysecurekey2
|
17
server/package.json
Normal file
17
server/package.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "@monsterdon-bingo/server",
|
||||
"version": "1.0.0",
|
||||
"description": "server for monsterdon bingo!",
|
||||
"main": "index.js",
|
||||
"repository": "https://git.jon-e.net/jonny/monsterdon-bingo",
|
||||
"author": "sneakers-the-rat <j@nny.fyi>",
|
||||
"license": "AGPL-3.0",
|
||||
"dependencies": {
|
||||
"@prisma/client": "^5.1.1",
|
||||
"config": "^3.3.9",
|
||||
"cookie-session": "^2.0.0",
|
||||
"dotenv": "^16.3.1",
|
||||
"express": "^4.18.2",
|
||||
"typeorm": "^0.3.17"
|
||||
}
|
||||
}
|
36
server/prisma/schema.prisma
Normal file
36
server/prisma/schema.prisma
Normal file
|
@ -0,0 +1,36 @@
|
|||
generator client {
|
||||
provider = "prisma-client-js"
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
url = "file:./mastodon-bingo.db"
|
||||
}
|
||||
|
||||
model Term {
|
||||
id Int @id @default(autoincrement())
|
||||
createdAt DateTime @default(now())
|
||||
text String
|
||||
user User @relation(fields: [userId], references: [id])
|
||||
userId Int
|
||||
}
|
||||
|
||||
model User {
|
||||
id Int @id @default(autoincrement())
|
||||
terms Term[]
|
||||
instance Instance @relation(fields: [instanceId], references: [id])
|
||||
instanceId Int
|
||||
|
||||
displayName String
|
||||
handle String
|
||||
}
|
||||
|
||||
model Instance {
|
||||
id Int @id @default(autoincrement())
|
||||
users User[]
|
||||
name String
|
||||
appName String?
|
||||
appClientId String?
|
||||
appClientSecret String?
|
||||
|
||||
}
|
45
server/prisma/seed.js
Normal file
45
server/prisma/seed.js
Normal file
|
@ -0,0 +1,45 @@
|
|||
const { PrismaClient } = require('@prisma/client')
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
||||
const instanceData = {
|
||||
name: "example.com",
|
||||
appName: 'fake_app',
|
||||
appClientId: "fake_client_id",
|
||||
appClientSecret: "fake_client_secret",
|
||||
users: {
|
||||
create: [
|
||||
{
|
||||
displayName: 'fake_user',
|
||||
handle: '@fakeuser',
|
||||
terms: {
|
||||
create: [
|
||||
{text: "Big Lasers"},
|
||||
{text: "Big Monsters!"}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log(`Start seeding ...`)
|
||||
for (const u of instanceData) {
|
||||
const instance = await prisma.instance.create({
|
||||
data: u,
|
||||
})
|
||||
console.log(`Created instance with id: ${instance.id}`)
|
||||
}
|
||||
console.log(`Seeding finished.`)
|
||||
}
|
||||
|
||||
main()
|
||||
.then(async () => {
|
||||
await prisma.$disconnect()
|
||||
})
|
||||
.catch(async (e) => {
|
||||
console.error(e)
|
||||
await prisma.$disconnect()
|
||||
process.exit(1)
|
||||
})
|
23
server/src/app.js
Normal file
23
server/src/app.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
require('dotenv').config();
|
||||
import express, { NextFunction, Request, Response } from 'express';
|
||||
import config from 'config';
|
||||
|
||||
import { AppDataSource } from './db/data-source';
|
||||
|
||||
import {cookieMiddleware} from './middleware/cookies';
|
||||
|
||||
AppDataSource.initialize()
|
||||
.then(async () => {
|
||||
|
||||
const app = express();
|
||||
app.use(cookieMiddleware);
|
||||
|
||||
app.all('*', (req, res, next) => {
|
||||
next(new AppError(404, `Route ${req.originalUrl} not found`));
|
||||
});
|
||||
|
||||
const port = config.get('port');
|
||||
const server = app.listen(port);
|
||||
|
||||
|
||||
})
|
13
server/src/db/data-source.js
Normal file
13
server/src/db/data-source.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
require('dotenv').config();
|
||||
import config from 'config';
|
||||
|
||||
|
||||
import {DataSource} from 'typeorm';
|
||||
|
||||
const DB_FILE = config.get('sqliteFile') ? config.get('sqliteFile') : ":memory:";
|
||||
export const AppDataSource = new DataSource({
|
||||
type: "sqlite",
|
||||
database: config.get('sqliteFile'),
|
||||
synchronize: true,
|
||||
entities: ['src/entities/**/*.entity.js']
|
||||
})
|
19
server/src/middleware/cookies.js
Normal file
19
server/src/middleware/cookies.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
import cookieSession from 'cookie-session';
|
||||
import config from 'config';
|
||||
import {Request, Response, NextFunction} from "express";
|
||||
import { tokenHasher, hashed_token } from "../auth";
|
||||
import {AppDataSource} from "../db/data-source";
|
||||
import {Bridge} from "../entities/bridge.entity";
|
||||
|
||||
const bridgeRepository = AppDataSource.getRepository(Bridge)
|
||||
|
||||
|
||||
const cookieConfig = config.get('cookies')
|
||||
|
||||
export const cookieMiddleware = cookieSession({
|
||||
name: 'session',
|
||||
keys: [cookieConfig.key1, cookieConfig.key2],
|
||||
signed: true,
|
||||
maxAge: 24*60*60*1000 // 24 hours
|
||||
})
|
||||
|
Loading…
Reference in a new issue