Skip to content

Commit c92bfb7

Browse files
authored
V2 API Route (#251)
* Bring in new database changes for extra player stats. * Fix Dockerfile to avoid potential COPY errors. * Begin refactor for extra stats as playerstats is too large of a file. * Update DB layout. Begin extra stats documentation. * Include new extra stats route and non-live gets. * Finish CRUD operations. Move onto new API implementation for OnPlayerDeath? * Bring in initial start of call for plugin. Update database to use actual steam IDs and whatnot. * Implement additional stat carry over. Needs to be tested. * Include typescript generation for v2 api. Remove extra player stats from legacy api since they were not finished. Update serverrcon.js - Breakout packet handling to its own function. - Check version for 0.14 or higher. TBD if we can use 0.13. - Set log and backup URLs and keys to use API keys. - Fix formatting Update prodrun to point to dist for compiled js. * Update deps and include types from docs. * Massive refactor of code to follow a better folder structure. Everything mainly in src now, types in types, services (like db and various service calls to database) in services, etc. Bring in start of finding API key and match id. These will be checked before being sent off to different cases. * Continue on rewiring tests. * Tests working, application not. * Tests passing and app launching! * OnSeriesResult implemented. Removed OnSeriesInit as it is not needed. Forfeits are not implemented, but may not be needed right now, can check on round end instead and update as needed. * Fix up some comments. Finish map and series finishing. Start on pick/ban updates. * Bring in team ID in the match configs since it's supported. Update mapupdate to not use team ids from database. Update various TS calls to user lowercase identifiers. * Veto updates and side selection complete. * Properly tag releases on push with version number as well. * Finish series flow service. Adjust imports on map flow service. Update api.ts to include new cases for the series flow. * OnGoingLive implemented. * Update the player stat extras table. Include OnPlayerDeath and OnMatchPaused and OnMatchUnpaused. Update serverrcon to include demo, logs, and backups. Update match creation to get version number if we select a server. * Include bomb plant and defuse events from game server to API calls. Since these are game specific, we will not create public API calls for this. * Finish map and series flows. Update github actions to deploy next and version tag. Begin work on demo uploads. * Change docker tags to use latest and next for now. * Docker debugging. Update package json version. * Add in demo API. Update leaderboard swagger to add success option. Consider moving components to their own JS files for easier typing and location. * Bring in remote backup API calls. * Update JSDocs. Include more docs for the MapFlowService. * Fix error with incomplete packets call. * Fix server rcon values not being respected in strings. Fix match registering version numbers for get5. * Delete match from database if we fail to load on the server. This should fix the bug of multiple matches being generated with the same server. Only update game server if the server is alive and available as well. * Update README.md * Update workflow to push next on any branch but version only on final release. Update README.
1 parent 3b4c815 commit c92bfb7

File tree

96 files changed

+6112
-1470
lines changed

Some content is hidden

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

96 files changed

+6112
-1470
lines changed

.github/workflows/ghcr.yml

+16-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
name: publish to ghcr
1+
name: Publish to GHCR
22
on:
33
workflow_dispatch:
44
push:
55
branches:
6-
- master
6+
- '**'
77
jobs:
88
push:
9-
name: "Create build and push to GHCR"
9+
name: Create build and push to GHCR
1010
runs-on: ubuntu-latest
1111
strategy:
1212
fail-fast: false
@@ -30,12 +30,23 @@ jobs:
3030
registry: ghcr.io
3131
username: ${{ github.repository_owner }}
3232
password: ${{ secrets.GITHUB_TOKEN }}
33+
- id: getversion
34+
uses: Saionaro/[email protected]
3335
- uses: docker/[email protected]
36+
if: github.ref != 'refs/heads/master'
3437
with:
3538
context: .
3639
file: Dockerfile
3740
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
3841
push: true
3942
tags: |
40-
ghcr.io/${{ steps.string.outputs.lowercase }}/g5api:latest
41-
43+
ghcr.io/${{ steps.string.outputs.lowercase }}/g5api:next
44+
- uses: docker/[email protected]
45+
if: github.ref == 'refs/heads/master'
46+
with:
47+
context: .
48+
file: Dockerfile
49+
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
50+
push: true
51+
tags: |
52+
ghcr.io/${{ steps.string.outputs.lowercase }}/g5api:latest,ghcr.io/${{ steps.string.outputs.lowercase }}/g5api:${{ steps.getversion.outputs.version }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
dist/
12
node_modules/
23
config/production.json*
34
config/development.json*

Dockerfile

+2-4
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,9 @@ RUN apk add gettext python3 build-base
55
EXPOSE 3301
66
# clone and move into Get5API folder
77
WORKDIR /Get5API
8-
COPY package*.json .
9-
COPY yarn.lock .
10-
RUN yarn
11-
128
COPY . .
9+
RUN yarn
10+
RUN yarn build
1311

1412
# set config with env variables, build, and run application
1513
CMD envsubst < /Get5API/config/production.json.template > /Get5API/config/production.json && \

README.md

+11-4
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,18 @@ G5API is an API that will allow users to create, manage, and control Counter-Str
2121

2222
This API is complete enough to provide the most functionality out of [get5](https://github.com/splewis/get5).
2323

24-
For the plugin [G5WS](https://github.com/PhlexPlexico/G5WS), the routes currently put into place located in the `./routes/legacy/` and still point to `/match/` on this app.
24+
<details closed>
25+
<summary><b>Note:</b> While available for backwards compatibility, it is recommended you use the <i>latest</i> version of get5, as you will no longer need an additional plugin for enhanced reporting. The only extension needed is SteamWorks. </summary>
26+
<br>
27+
28+
29+
For the plugin [G5WS](https://github.com/PhlexPlexico/G5WS"), the routes currently put into place located in the `./src/routes/legacy/` and still point to `/match/` on this app.
30+
</details>
2531

26-
Game server interaction will still take place under the `/matches/:match_id` directive, but the logic can be found under `./matches/matchserver.js`.
2732

28-
The webapi plugin for this can be downloaded from [here](https://github.com/PhlexPlexico/G5WS) to include the use of vetoes being recorded, as well as demoes being uploaded to the API server once the match is complete.
33+
If you are using get5 0.14 or later, the G5WS plugin is **not** needed, and should be removed or disabled from your game server to avoid any conflicting actions. The new routes are located in `./src/routes/v2`, and the main logic can be found in their respective services under `./src/services`
34+
35+
Game server interaction will still take place under the `/matches/:match_id` directive, but the logic can be found under `./matches/matchserver.js`.
2936

3037
There is also Challonge integration within the API. If a user provides a tournament ID to create a season, it will auto-fill a season start date, empty teams, and will auto-update the brackets at the end of each match if the match exists under the Season/Tournament.
3138

@@ -108,7 +115,7 @@ For more details on these variables, follow along with production.json.template
108115
### Docs:
109116
```yarn doc```
110117

111-
This will generate all the API information that I've created in the app, in the hopes of making it more readable and easier to pickup for anyone who wants to try more implementation, or even creating a front-end for this API. Swagger Express is also included, which can be accessed from `/api-docs` on application launch. This will house all the API calls, where JSDocs will show all the internal function calls in this application.
118+
This will generate all the API information that I've created in the app, in the hopes of making it more readable and easier to pickup for anyone who wants to try implementing more actions, or even creating a front-end for this API. Swagger Express is also included, which can be accessed from `/api-docs` on application launch. This will house all the API calls, where JSDocs will show all the internal function calls in this application. All TypeScript functions will be shown in the JSDocs.
112119

113120
### Coverage Tests
114121
Steam OAuth will be mocked in order to check if a user is "logged in", and create a temporary database (`get5test`) that will insert new values, and check various features of routes. If you wish to alter the "user" it authenticates as, you can edit `utility/mockProfile.js` to the values you prefer.

__test__/users.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { agent } from 'supertest';
2-
import app from '../app.js';
2+
import app from '../app.js'
33
const request = agent(app);
44
let adminCheck = 0;
55

app.js

+29-31
Original file line numberDiff line numberDiff line change
@@ -15,21 +15,25 @@ import swaggerJSDoc from "swagger-jsdoc";
1515
import { serve, setup } from "swagger-ui-express";
1616

1717
// Route Files
18-
import indexRouter from "./routes/index.js";
19-
import leaderboardRouter from "./routes/leaderboard.js";
20-
import legacyAPICalls from "./routes/legacy/api.js";
21-
import mapListRouter from "./routes/maps.js";
22-
import mapstatsRouter from "./routes/mapstats.js";
23-
import matchesRouter from "./routes/matches/matches.js";
24-
import matchServerRouter from "./routes/matches/matchserver.js";
25-
import playerstatsRouter from "./routes/playerstats.js";
26-
import seasonsRouter from "./routes/seasons.js";
27-
import serversRouter from "./routes/servers.js";
28-
import teamsRouter from "./routes/teams.js";
29-
import usersRouter from "./routes/users.js";
30-
import vetoesRouter from "./routes/vetoes.js";
31-
import vetosidesRouter from "./routes/vetosides.js";
32-
import passport from "./utility/auth.js";
18+
import indexRouter from "./src/routes/index.js";
19+
import leaderboardRouter from "./src/routes/leaderboard.js";
20+
import legacyAPICalls from "./src/routes/legacy/api.js";
21+
import mapListRouter from "./src/routes/maps.js";
22+
import mapstatsRouter from "./src/routes/mapstats.js";
23+
import matchesRouter from "./src/routes/matches/matches.js";
24+
import matchServerRouter from "./src/routes/matches/matchserver.js";
25+
import playerstatsRouter from "./src/routes/playerstats/playerstats.js";
26+
import playerstatsextraRouter from "./src/routes/playerstats/extrastats.js";
27+
import seasonsRouter from "./src/routes/seasons.js";
28+
import serversRouter from "./src/routes/servers.js";
29+
import teamsRouter from "./src/routes/teams.js";
30+
import usersRouter from "./src/routes/users.js";
31+
import vetoesRouter from "./src/routes/vetoes.js";
32+
import vetosidesRouter from "./src/routes/vetosides.js";
33+
import passport from "./src/utility/auth.js";
34+
import {router as v2Router} from "./src/routes/v2/api.js";
35+
import {router as v2DemoRouter} from "./src/routes/v2/demoapi.js";
36+
import { router as v2BackupRouter } from "./src/routes/v2/backupapi.js";
3337
// End Route Files
3438

3539

@@ -112,25 +116,15 @@ const options = {
112116
openapi: "3.0.0", // Specification (optional, defaults to swagger: '2.0')
113117
info: {
114118
title: "G5API", // Title (required)
115-
version: "1.7.0", // Version (required)
116-
},
119+
version: "2.0.0" // Version (required)
120+
}
117121
},
118122
// Path to the API docs
119123
apis: [
120-
"./routes/leaderboard.js",
121-
"./routes/legacy/api.js",
122-
"./routes/matches/matches.js",
123-
"./routes/matches/matchserver.js",
124-
"./routes/maps.js",
125-
"./routes/mapstats.js",
126-
"./routes/playerstats.js",
127-
"./routes/seasons.js",
128-
"./routes/servers.js",
129-
"./routes/teams.js",
130-
"./routes/users.js",
131-
"./routes/vetoes.js",
132-
"./routes/vetosides.js",
133-
],
124+
"./dist/src/routes/**/*.js",
125+
"./dist/src/services/**/*.js",
126+
"./dist/src/routes/*.js"
127+
]
134128
};
135129
const swaggerSpec = swaggerJSDoc(options);
136130

@@ -148,10 +142,14 @@ app.use("/vetosides", vetosidesRouter);
148142
app.use("/matches", matchesRouter, matchServerRouter);
149143
app.use("/mapstats", mapstatsRouter);
150144
app.use("/playerstats", playerstatsRouter);
145+
app.use("/playerstatsextra", playerstatsextraRouter);
151146
app.use("/seasons", seasonsRouter);
152147
app.use("/match", legacyAPICalls);
153148
app.use("/leaderboard", leaderboardRouter);
154149
app.use("/maps", mapListRouter);
150+
app.use("/v2", v2Router);
151+
app.use("/v2/demo", v2DemoRouter);
152+
app.use("/v2/backup", v2BackupRouter);
155153
// END ROUTES
156154

157155
// Steam API Calls.

jest.config.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/** @type {import('ts-jest').JestConfigWithTsJest} */
2+
module.exports = {
3+
preset: 'ts-jest',
4+
testEnvironment: 'node',
5+
};

jest_config/jest.gameservers.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.maplist.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.mapstats.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.matches.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.playerstats.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.seasons.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.teams.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.users.config.cjs

+17-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1+
/** @type {import('ts-jest').JestConfigWithTsJest} */
12
// For a detailed explanation regarding each configuration property, visit:
23
// https://jestjs.io/docs/en/configuration.html
34
process.env.NODE_ENV = "test";
45
module.exports = {
6+
preset: 'ts-jest/presets/js-with-ts-esm',
7+
// A path to a custom resolver
8+
resolver: "jest-ts-webcompat-resolver",
59
// All imported modules in your tests should be mocked automatically
610
// automock: false,
711

@@ -58,7 +62,9 @@ module.exports = {
5862
globalTeardown: "./test-teardown-globals.cjs",
5963

6064
// A set of global variables that need to be available in all test environments
61-
// globals: {},
65+
// globals: {
66+
// extensionsToTreatAsEsm: ['.ts', '.js']
67+
// },
6268

6369
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
6470
// maxWorkers: "50%",
@@ -71,11 +77,14 @@ module.exports = {
7177
// An array of file extensions your modules use
7278
moduleFileExtensions: [
7379
"js",
74-
"cjs"
80+
"cjs",
81+
"ts"
7582
],
7683

7784
// A map from regular expressions to module names that allow to stub out resources with a single module
78-
// moduleNameMapper: {},
85+
moduleNameMapper: {
86+
87+
},
7988

8089
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
8190
// modulePathIgnorePatterns: [],
@@ -101,8 +110,6 @@ module.exports = {
101110
// Reset the module registry before running each individual test
102111
// resetModules: false,
103112

104-
// A path to a custom resolver
105-
// resolver: undefined,
106113

107114
// Automatically restore mock state between every test
108115
// restoreMocks: false,
@@ -162,7 +169,11 @@ module.exports = {
162169
// timers: "real",
163170

164171
// A map from regular expressions to paths to transformers
165-
// transform: undefined,
172+
// transform: {'\\.[jt]sx?$': ['ts-jest', { useESM: true }] },
173+
// moduleNameMapper: {
174+
// '(.+)\\.js': '$1'
175+
// },
176+
// extensionsToTreatAsEsm: ['.ts'],
166177

167178
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
168179
// transformIgnorePatterns: [

jest_config/jest.vetoes.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jest_config/jest.vetosides.config.cjs

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
// https://jestjs.io/docs/en/configuration.html
33
process.env.NODE_ENV = "test";
44
module.exports = {
5+
preset: 'ts-jest/presets/js-with-ts-esm',
6+
// A path to a custom resolver
7+
resolver: "jest-ts-webcompat-resolver",
58
// All imported modules in your tests should be mocked automatically
69
// automock: false,
710

jsdoc.conf.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"dictionaries": ["jsdoc","closure"]
55
},
66
"source": {
7-
"include": ["routes"],
7+
"include": ["dist/src"],
88
"includePattern": ".+\\.js(doc|x)?$",
99
"excludePattern": "(^|\\/|\\\\)_"
1010
},

migrations/20220907171148-get5db.js

-27
This file was deleted.

0 commit comments

Comments
 (0)