Skip to content

Commit

Permalink
Merge pull request #540 from webkom/svelte-tsconfig
Browse files Browse the repository at this point in the history
Implement use of .svelte-kit with hot-reloading
  • Loading branch information
PeterJFB committed Mar 28, 2023
2 parents 8add756 + fc65683 commit 0187422
Show file tree
Hide file tree
Showing 33 changed files with 335 additions and 220 deletions.
3 changes: 3 additions & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ module.exports = {
},
],
},
settings: {
'svelte3/typescript': () => require('typescript')
},
env: {
es6: true,
node: true,
Expand Down
7 changes: 4 additions & 3 deletions app.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import express, { Request, Response, NextFunction } from 'express';
import express from 'express';
import type { Request, Response, NextFunction } from 'express';
import mongoose from 'mongoose';
import bodyParser from 'body-parser';
import cookieParser from 'cookie-parser';
Expand All @@ -13,7 +14,7 @@ import raven from 'raven';
import router from './app/routes';
import User from './app/models/user';
import env from './env';
import { HTTPError } from './app/errors';
import type { HTTPError } from './app/errors';
import path from 'path';
import { fileURLToPath } from 'url';

Expand Down Expand Up @@ -47,7 +48,7 @@ if (['development', 'protractor'].includes(env.NODE_ENV)) {
const webpackMiddleware = await import('webpack-dev-middleware');
// eslint-disable-next-line
// @ts-ignore
const config = await import('./webpack.config.js');
const config = await import('./webpack.config.ts');

app.use(
webpackMiddleware.default(webpack.default(config.default), {
Expand Down
28 changes: 14 additions & 14 deletions app/algorithms/normal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import isEmpty from 'lodash/isEmpty';
import { Status, Vote, Alternative, ElectionResult, Count } from './types';
import { PopulatedVote, AlternativeType } from '../../app/types/types';
import type { AlternativeType, PopulatedVote } from '../types/types';
import type { Vote, Alternative, ElectionResult, Count } from './types';
import { Status } from './types';

/**
* @param votes - All votes for the election
Expand Down Expand Up @@ -65,26 +66,25 @@ const calculateWinnerUsingNormal = (
const thr = winningThreshold(votes, useStrict);

// Winner key
const maxKey: string = Object.keys(count).reduce((a, b) =>
const maxKey = Object.keys(count).reduce((a, b) =>
count[a] > count[b] ? a : b
);

// Check if we can call the vote Resolved based on
const status = count[maxKey] >= thr ? Status.resolved : Status.unresolved;

// Create winner alternative from maxKey
const winner =
count[maxKey] >= thr
? {
...alternatives.find((a) => a.description === maxKey),
count: count[maxKey],
}
: undefined;
let status: Status = Status.unresolved;
let winner: Alternative = undefined;
if (count[maxKey] >= thr) {
winner = {
...alternatives.find((a) => a.description === maxKey),
count: count[maxKey],
};
status = Status.resolved;
}

return {
result: {
status,
winners: winner ? [winner] : undefined,
winners: winner ? [winner] : [],
},
thr,
seats,
Expand Down
5 changes: 3 additions & 2 deletions app/algorithms/stv.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import cloneDeep from 'lodash/cloneDeep';
import { Status, Vote, Alternative, ElectionResult, Count } from './types';
import { PopulatedVote, AlternativeType } from '../../app/types/types';
import { Status } from './types';
import type { Vote, Alternative, ElectionResult, Count } from './types';
import type { PopulatedVote, AlternativeType } from '../../app/types/types';

enum Action {
iteration = 'ITERATION',
Expand Down
3 changes: 2 additions & 1 deletion app/algorithms/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { STVEvent } from './stv';
import type { STVEvent } from './stv';

export type Count = { [key: string]: number };

export type Alternative = {
_id: string;
description: string;
election: string;
count?: number;
};

export type Vote = {
Expand Down
5 changes: 2 additions & 3 deletions app/controllers/alternative.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ import type { RequestHandler } from 'express';
import mongoose from 'mongoose';
import Alternative from '../models/alternative';
import errors from '../errors';
import type { ReqWithElection } from './election';

export const list: RequestHandler = async (req: ReqWithElection, res) => {
export const list: RequestHandler = async (req, res) => {
const election = await req.election.populate('alternatives');
return res.json(election.alternatives);
};

export const create: RequestHandler = async (req: ReqWithElection, res) => {
export const create: RequestHandler = async (req, res) => {
try {
const election = req.election;
await election.populate('alternatives');
Expand Down
93 changes: 40 additions & 53 deletions app/controllers/election.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import type {
RequestParamHandler,
Request,
Response,
RequestHandler,
} from 'express';
import mongoose, { Types, HydratedDocument } from 'mongoose';
import type { RequestParamHandler, RequestHandler } from 'express';
import mongoose, { type HydratedDocument, Types } from 'mongoose';
import Election from '../models/election';
import User from '../models/user';
import Alternative from '../models/alternative';
Expand All @@ -13,18 +8,10 @@ import app from '../../app';
import type { Server } from 'socket.io';
import type {
ElectionType,
IElectionMethods,
AlternativeType,
IElectionMethods,
} from '../types/types';

export interface ReqWithElection extends Request {
election: HydratedDocument<ElectionType, IElectionMethods>;
}

export interface TypedRequestBody<T> extends Request {
body: T;
}

type CreateElection = Pick<
ElectionType,
'title' | 'description' | 'seats' | 'type' | 'useStrict' | 'physical'
Expand All @@ -35,12 +22,7 @@ type CreateElection = Pick<
}[];
};

export const load: RequestParamHandler = (
req: ReqWithElection,
res,
next,
electionId: string
) =>
export const load: RequestParamHandler = (req, res, next, electionId) =>
Election.findById(electionId)
.then((election) => {
if (!election) throw new errors.NotFoundError('election');
Expand All @@ -54,10 +36,7 @@ export const load: RequestParamHandler = (
throw err;
});

export const retrieveActive = (
req: ReqWithElection,
res: Response
): Promise<Response> =>
export const retrieveActive: RequestHandler = (req, res) =>
Election.findOne({
active: true,
hasVotedUsers: { $ne: new Types.ObjectId(req.user._id) },
Expand Down Expand Up @@ -97,10 +76,11 @@ export const retrieveActive = (
return res.status(200).json(election);
});

export const create = async (
req: TypedRequestBody<CreateElection>,
res: Response
): Promise<Response<ElectionType>> => {
export const create: RequestHandler<
unknown,
ElectionType,
CreateElection
> = async (req, res) => {
try {
const election = await Election.create({
title: req.body.title,
Expand Down Expand Up @@ -132,59 +112,64 @@ export const create = async (
}
};

export const list = (
req: Request,
res: Response
): Promise<Response<ElectionType[]>> =>
export const list: RequestHandler<unknown, ElectionType[]> = (req, res) =>
Election.find()
.populate('alternatives')
.exec()
.then((elections) => res.status(200).json(elections));

export const retrieve = async (
req: ReqWithElection,
res: Response
): Promise<Response<ElectionType>> => {
export const retrieve: RequestHandler<unknown, ElectionType> = async (
req,
res
) => {
if (!req.election) throw new errors.NotFoundError('election');

await req.election.populate('alternatives');

return res.status(200).json(req.election);
};

const setElectionStatus = (
req: ReqWithElection,
res: Response,
election: HydratedDocument<ElectionType, IElectionMethods>,
active: boolean
) => {
req.election.active = active;
return req.election.save();
election.active = active;
return election.save();
};

export const activate = async (
req: ReqWithElection,
res: Response
): Promise<Response> => {
export const activate: RequestHandler = async (req, res) => {
if (!req.election) throw new errors.NotFoundError('election');

const otherActiveElection = await Election.findOne({ active: true });
if (otherActiveElection) {
throw new errors.AlreadyActiveElectionError();
}
return setElectionStatus(req, res, true).then((election) => {
return setElectionStatus(req.election, true).then((election) => {
const io: Server = app.get('io');
io.emit('election');
return res.status(200).json(election);
});
};

export const deactivate: RequestHandler = (req: ReqWithElection, res) =>
setElectionStatus(req, res, false).then((election) => {
export const deactivate: RequestHandler = (req, res) => {
if (!req.election) throw new errors.NotFoundError('election');

return setElectionStatus(req.election, false).then((election) => {
const io: Server = app.get('io');
io.emit('election');
res.status(200).json(election);
});
};

export const elect: RequestHandler = (req: ReqWithElection, res) =>
req.election.elect().then((result) => res.json(result));
export const elect: RequestHandler = (req, res) => {
if (!req.election) throw new errors.NotFoundError('election');

return req.election.elect().then((result) => res.json(result));
};

export const deleteElection: RequestHandler = (req, res) => {
if (!req.election) throw new errors.NotFoundError('election');

export const deleteElection: RequestHandler = (req: ReqWithElection, res) => {
if (req.election.active) {
throw new errors.ActiveElectionError('Cannot delete an active election.');
}
Expand All @@ -197,7 +182,9 @@ export const deleteElection: RequestHandler = (req: ReqWithElection, res) => {
);
};

export const count: RequestHandler = (req: ReqWithElection, res) => {
export const count: RequestHandler = (req, res) => {
if (!req.election) throw new errors.NotFoundError('election');

res.json({
users: req.election.hasVotedUsers.length,
});
Expand Down
4 changes: 2 additions & 2 deletions app/controllers/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import { badRequestError, duplicateError } from '../errors/error-checks';
import crypto from 'crypto';
import { mailHandler, MailAction } from '../digital/mail';
import short from 'short-uuid';
import { RequestHandler } from 'express';
import { UserType } from '../types/types';
import type { RequestHandler } from 'express';
import type { UserType } from '../types/types';

export const count: RequestHandler = async (req, res) => {
const query: mongoose.FilterQuery<UserType> = {
Expand Down
2 changes: 1 addition & 1 deletion app/controllers/vote.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { RequestHandler } from 'express';
import Client from 'ioredis';
import Redlock, { ExecutionError } from 'redlock';
import Redlock from 'redlock';

import Election from '../models/election';
import Vote from '../models/vote';
Expand Down
2 changes: 1 addition & 1 deletion app/digital/mail.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import nodemailer, { Transporter } from 'nodemailer';
import nodemailer, { type Transporter } from 'nodemailer';
import fs from 'fs';
import path from 'path';
import handlebars from 'handlebars';
Expand Down
2 changes: 1 addition & 1 deletion app/errors/error-checks.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { HTTPError } from './index';
import type { HTTPError } from './index';

export const duplicateError = (err: HTTPError): boolean =>
err.code === 11000 || err.code === 11001;
Expand Down
6 changes: 3 additions & 3 deletions app/errors/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Response } from 'express';
import { IAlternative, IElection } from '../types/types';
import mongoose from 'mongoose';
import type { Response } from 'express';
import type { IAlternative, IElection } from '../types/types';
import type mongoose from 'mongoose';

export class HTTPError extends Error {
status: number;
Expand Down
2 changes: 1 addition & 1 deletion app/models/alternative.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import mongoose, { Schema } from 'mongoose';
import { AlternativeType, AlternativeModel } from '../types/types';
import type { AlternativeType, AlternativeModel } from '../types/types';

const alternativeSchema = new Schema<AlternativeType, AlternativeModel>({
description: {
Expand Down
8 changes: 4 additions & 4 deletions app/models/election.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ import errors from '../errors';
import mongoose, {
Schema,
Types,
HydratedDocument,
HydratedDocumentFromSchema,
type HydratedDocument,
type HydratedDocumentFromSchema,
} from 'mongoose';
import Vote from './vote';
import calculateWinnerUsingNormal from '../algorithms/normal';
import calculateWinnerUsingSTV from '../algorithms/stv';
import crypto from 'crypto';
import {
ElectionSystems,
import { ElectionSystems } from '../types/types';
import type {
AlternativeType,
IElectionMethods,
ElectionModel,
Expand Down
2 changes: 1 addition & 1 deletion app/models/register.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import mongoose, { Schema } from 'mongoose';
import { RegisterType } from '../types/types';
import type { RegisterType } from '../types/types';

const registerSchema = new Schema<RegisterType>({
identifier: {
Expand Down
4 changes: 2 additions & 2 deletions app/models/user.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import _ from 'lodash';
import bcrypt from 'bcryptjs';
import mongoose, { Schema, HydratedDocumentFromSchema } from 'mongoose';
import mongoose, { Schema, type HydratedDocumentFromSchema } from 'mongoose';
import errors from '../errors';
import { UserType, UserModel, IUserMethods } from '../types/types';
import type { UserType, UserModel, IUserMethods } from '../types/types';

export const userSchema = new Schema<UserType, UserModel, IUserMethods>({
username: {
Expand Down
2 changes: 1 addition & 1 deletion app/models/vote.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import mongoose, { Schema } from 'mongoose';
import { VoteType } from '../types/types';
import type { VoteType } from '../types/types';

const voteSchema = new Schema<VoteType>({
hash: {
Expand Down
2 changes: 1 addition & 1 deletion app/routes/api/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Request, Response, NextFunction } from 'express';
import type { Request, Response, NextFunction } from 'express';
import routerFactory from 'express-promise-router';
const router = routerFactory();
import electionRoutes from './election';
Expand Down

0 comments on commit 0187422

Please sign in to comment.