├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── ghcr.yml ├── .gitignore ├── .yarnclean ├── Dockerfile ├── LICENSE ├── README.md ├── __test__ ├── gameservers.test.js ├── maplist.test.js ├── mapstats.test.js ├── matches.test.js ├── playerstats.test.js ├── seasons.test.js ├── teams.test.js ├── users.test.js ├── vetoes.test.js └── vetosides.test.js ├── app.ts ├── bin └── www.ts ├── config ├── .gitkeep ├── development.json.template ├── production.json.template └── test.json.template ├── docker-compose.yml ├── jest.config.js ├── jest_config ├── jest.gameservers.config.cjs ├── jest.maplist.config.cjs ├── jest.mapstats.config.cjs ├── jest.matches.config.cjs ├── jest.playerstats.config.cjs ├── jest.seasons.config.cjs ├── jest.teams.config.cjs ├── jest.users.config.cjs ├── jest.vetoes.config.cjs ├── jest.vetosides.config.cjs └── test-teardown-globals.cjs ├── jsdoc.conf.json ├── migrations ├── development │ ├── 20191109191155-get5db.js │ ├── 20201011041344-get5db.js │ ├── 20201017154717-get5db.js │ ├── 20201017172331-get5db.js │ ├── 20201017183917-get5db.js │ ├── 20201024182100-get5db.js │ ├── 20201026130830-get5db.js │ ├── 20201117134259-get5db.js │ ├── 20201118184033-get5db.js │ ├── 20210107194928-get5db.js │ ├── 20210115022423-get5db.js │ ├── 20210123062442-get5db.js │ ├── 20210124162658-get5db.js │ ├── 20210201015955-get5db.js │ ├── 20211125150429-get5db.js │ ├── 20220211220305-get5db.js │ ├── 20220217155106-get5db.js │ ├── 20220224150005-get5db.js │ ├── 20220325155055-get5db.js │ ├── 20220713153034-get5db.js │ ├── 20220907171148-get5db.js │ ├── 20220908135836-get5db.js │ ├── 20230615140704-get5db.js │ ├── 20230625215254-get5db.js │ ├── 20230626223210-get5db.js │ ├── 20230629010420-get5db.js │ ├── 20230630204451-get5db.js │ └── package.json ├── production │ ├── 20191109191155-get5db.js │ ├── 20201011041344-get5db.js │ ├── 20201017154717-get5db.js │ ├── 20201017172331-get5db.js │ ├── 20201017183917-get5db.js │ ├── 20201024182100-get5db.js │ ├── 20201026130830-get5db.js │ ├── 20201117134259-get5db.js │ ├── 20201118184033-get5db.js │ ├── 20210107194928-get5db.js │ ├── 20210115022423-get5db.js │ ├── 20210123062442-get5db.js │ ├── 20210124162658-get5db.js │ ├── 20210201015955-get5db.js │ ├── 20211125150429-get5db.js │ ├── 20220211220305-get5db.js │ ├── 20220217155106-get5db.js │ ├── 20220224150005-get5db.js │ ├── 20220325155055-get5db.js │ ├── 20220713153034-get5db.js │ ├── 20220907171148-get5db.js │ ├── 20220908135836-get5db.js │ ├── 20230615140704-get5db.js │ ├── 20230625215254-get5db.js │ ├── 20230626223210-get5db.js │ ├── 20230629010420-get5db.js │ ├── 20230630204451-get5db.js │ └── package.json └── test │ ├── 20191109191155-get5db.js │ ├── 20201011041344-get5db.js │ ├── 20201017154717-get5db.js │ ├── 20201017172331-get5db.js │ ├── 20201017183917-get5db.js │ ├── 20201024182100-get5db.js │ ├── 20201026130830-get5db.js │ ├── 20201117134259-get5db.js │ ├── 20201118184033-get5db.js │ ├── 20210107194928-get5db.js │ ├── 20210115022423-get5db.js │ ├── 20210123062442-get5db.js │ ├── 20210124162658-get5db.js │ ├── 20210201015955-get5db.js │ ├── 20211125150429-get5db.js │ ├── 20220211220305-get5db.js │ ├── 20220217155106-get5db.js │ ├── 20220224150005-get5db.js │ ├── 20220325155055-get5db.js │ ├── 20220713153034-get5db.js │ ├── 20220907171148-get5db.js │ ├── 20220908135836-get5db.js │ ├── 20230615140704-get5db.js │ ├── 20230625215254-get5db.js │ ├── 20230626223210-get5db.js │ ├── 20230629010420-get5db.js │ ├── 20230630204451-get5db.js │ └── package.json ├── package-lock.json ├── package.json ├── prodrun.json ├── public ├── backups │ └── .gitkeep ├── demos │ └── .gitkeep └── img │ └── logos │ └── .gitkeep ├── src ├── @types │ └── express │ │ └── index.d.ts ├── routes │ ├── index.ts │ ├── leaderboard.ts │ ├── legacy │ │ └── api.ts │ ├── maps.ts │ ├── mapstats.ts │ ├── matches │ │ ├── matches.ts │ │ └── matchserver.ts │ ├── playerstats │ │ ├── extrastats.ts │ │ └── playerstats.ts │ ├── seasons.ts │ ├── servers.ts │ ├── teams.ts │ ├── users.ts │ ├── v2 │ │ ├── api.ts │ │ ├── backupapi.ts │ │ └── demoapi.ts │ ├── vetoes.ts │ └── vetosides.ts ├── services │ ├── challonge.ts │ ├── db.ts │ ├── mapflowservices.ts │ └── seriesflowservices.ts ├── types │ ├── Get5_Assist.ts │ ├── Get5_Attacker.ts │ ├── Get5_OnEvent.ts │ ├── Get5_Player.ts │ ├── Get5_Stats.ts │ ├── Get5_Team.ts │ ├── Get5_Weapon.ts │ ├── Get5_Winner.ts │ ├── User.ts │ ├── leaderboard │ │ ├── Player.ts │ │ └── TeamStanding.ts │ ├── map_flow │ │ ├── Get5_OnBombEvent.ts │ │ ├── Get5_OnGoingLive.ts │ │ ├── Get5_OnMatchPausedUnpaused.ts │ │ ├── Get5_OnPlayerBecameMvp.ts │ │ ├── Get5_OnPlayerDeath.ts │ │ ├── Get5_OnRoundEnd.ts │ │ └── Get5_OnRoundStart.ts │ ├── maps │ │ └── MapObject.ts │ ├── mapstats │ │ ├── AccessMessage.ts │ │ └── MapStats.ts │ ├── matches │ │ ├── MatchData.ts │ │ ├── MatchJson.ts │ │ └── MatchPauseData.ts │ ├── playerstats │ │ ├── PlayerDatabaseObject.ts │ │ └── PlayerObject.ts │ ├── seasons │ │ ├── SeasonCvarObject.ts │ │ └── SeasonObject.ts │ ├── series_flow │ │ ├── Get5_OnBackupRestore.ts │ │ ├── Get5_OnMapResult.ts │ │ ├── Get5_OnSeriesResult.ts │ │ └── veto │ │ │ ├── Get5_OnMapPicked.ts │ │ │ ├── Get5_OnMapVetoed.ts │ │ │ └── Get5_OnSidePicked.ts │ ├── serverrcon │ │ └── SteamApiResponse.ts │ ├── servers │ │ └── GameServerObject.ts │ ├── swagger │ │ ├── Get5_Assist.yaml │ │ ├── Get5_Attacker.yaml │ │ ├── Get5_Player.yaml │ │ ├── Get5_Stats.yaml │ │ ├── Get5_Team.yaml │ │ ├── Get5_Weapon.yaml │ │ ├── Get5_Winner.yaml │ │ ├── map_flow │ │ │ ├── Get5_OnBombDefused.yaml │ │ │ ├── Get5_OnBombPlanted.yaml │ │ │ ├── Get5_OnMatchPausedUnpaused.yaml │ │ │ ├── Get5_OnPlayerBecameMvp.yaml │ │ │ ├── Get5_OnPlayerDeath.yaml │ │ │ └── Get5_OnRoundEnd.yaml │ │ └── series_flow │ │ │ ├── Get5_OnBackupRestore.yaml │ │ │ ├── Get5_OnMapResult.yaml │ │ │ ├── Get5_OnSeriesInit.yaml │ │ │ └── Get5_OnSeriesResult.yaml │ ├── teams │ │ ├── AuthData.ts │ │ └── TeamData.ts │ ├── users │ │ └── UserObject.ts │ └── vetoes │ │ ├── VetoObject.ts │ │ └── VetoSideObject.ts └── utility │ ├── auth.ts │ ├── emitter.ts │ ├── mockProfile.ts │ ├── mockstrategy.ts │ ├── serverrcon.ts │ └── utils.ts ├── tsconfig.json └── yarn.lock /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | ko_fi: phlexplexico 4 | patreon: phlexplexico 5 | github: phlexplexico 6 | custom: https://steamcommunity.com/tradeoffer/new/?partner=65378466&token=G3t4Gn5V -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG]" 5 | labels: triage 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Server info** 32 | - OS: [e.g. Ubuntu, CentOS, Windows] 33 | - Version (16.04, 8.1.1911, 10] 34 | - NodeJS version (e.g. 13.13.0) 35 | 36 | **Docker Information** 37 | If you are running through docker, please provide as much information as you can with your docker files. Please make sure to scrub your data and remove any keys such as the DB keys, Steam API key, or MySQL passwords. 38 | 39 | **Additional context** 40 | Add any other context about the problem here. 41 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Request] " 5 | labels: request 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered, or any other workarounds that you have created in the meantime. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/ghcr.yml: -------------------------------------------------------------------------------- 1 | name: Publish to GHCR 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: 6 | - '**' 7 | jobs: 8 | push: 9 | name: Create build and push to GHCR 10 | runs-on: ubuntu-latest 11 | strategy: 12 | fail-fast: false 13 | steps: 14 | - name: Set up QEMU 15 | uses: docker/setup-qemu-action@v2.1.0 16 | with: 17 | image: tonistiigi/binfmt:latest 18 | platforms: all 19 | - name: Set up Docker Buildx 20 | uses: docker/setup-buildx-action@v2.2.1 21 | with: 22 | buildkitd-flags: --debug 23 | - id: string 24 | uses: ASzc/change-string-case-action@v5 25 | with: 26 | string: ${{ github.repository_owner }} 27 | - uses: actions/checkout@v3.3.0 28 | - uses: docker/login-action@v2.1.0 29 | with: 30 | registry: ghcr.io 31 | username: ${{ github.repository_owner }} 32 | password: ${{ secrets.GITHUB_TOKEN }} 33 | - id: getversion 34 | uses: Saionaro/extract-package-version@v1.2.1 35 | - uses: docker/build-push-action@v3.2.0 36 | if: github.ref != 'refs/heads/master' 37 | with: 38 | context: . 39 | file: Dockerfile 40 | platforms: linux/amd64,linux/arm/v7,linux/arm64/v8 41 | push: true 42 | tags: | 43 | ghcr.io/${{ steps.string.outputs.lowercase }}/g5api:next 44 | - uses: docker/build-push-action@v3.2.0 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 }} 53 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | node_modules/ 3 | config/production.json* 4 | config/development.json* 5 | config/test.json 6 | docs/ 7 | public/*.zip 8 | coverage/ 9 | dump.rdb 10 | # Logs 11 | logs 12 | *.log 13 | npm-debug.log* 14 | yarn-debug.log* 15 | yarn-error.log* 16 | lerna-debug.log* 17 | 18 | # Diagnostic reports (https://nodejs.org/api/report.html) 19 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 20 | 21 | # Runtime data 22 | pids 23 | *.pid 24 | *.seed 25 | *.pid.lock 26 | 27 | # Directory for instrumented libs generated by jscoverage/JSCover 28 | lib-cov 29 | 30 | # Compiled binary addons (https://nodejs.org/api/addons.html) 31 | build/Release 32 | 33 | # Optional eslint cache 34 | .eslintcache 35 | 36 | # Optional REPL history 37 | .node_repl_history 38 | 39 | # Output of 'npm pack' 40 | *.tgz 41 | 42 | # Yarn Integrity file 43 | .yarn-integrity 44 | 45 | # dotenv environment variables file 46 | .env 47 | .env.test 48 | 49 | .vscode/ 50 | -------------------------------------------------------------------------------- /.yarnclean: -------------------------------------------------------------------------------- 1 | # test directories 2 | __tests__ 3 | test 4 | tests 5 | powered-test 6 | 7 | # asset directories 8 | docs 9 | doc 10 | website 11 | images 12 | assets 13 | 14 | # examples 15 | example 16 | examples 17 | 18 | # code coverage directories 19 | coverage 20 | .nyc_output 21 | 22 | # build scripts 23 | Makefile 24 | Gulpfile.js 25 | Gruntfile.js 26 | 27 | # configs 28 | appveyor.yml 29 | circle.yml 30 | codeship-services.yml 31 | codeship-steps.yml 32 | wercker.yml 33 | .tern-project 34 | .gitattributes 35 | .editorconfig 36 | .*ignore 37 | .eslintrc 38 | .jshintrc 39 | .flowconfig 40 | .documentup.json 41 | .yarn-metadata.json 42 | .travis.yml 43 | 44 | # misc 45 | *.md 46 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:18-alpine 2 | 3 | RUN apk add gettext python3 build-base 4 | EXPOSE 3301 5 | # clone and move into Get5API folder 6 | WORKDIR /Get5API 7 | COPY . . 8 | RUN yarn 9 | RUN yarn build 10 | # set config with env variables, build, and run application 11 | CMD envsubst < /Get5API/config/production.json.template > /Get5API/config/production.json && \ 12 | sed -i "s/db:create get5$/db:create $DATABASE/" /Get5API/package.json && \ 13 | yarn migrate-create-prod && \ 14 | yarn migrate-prod-upgrade && \ 15 | yarn startprod && \ 16 | yarn pm2 logs 17 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 PhlexPlexico 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /__test__/gameservers.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from "supertest"; 2 | import app from "../app.js"; 3 | const request = agent(app); 4 | const password = "SUPER SECRET DON'T TELL"; 5 | 6 | describe("Test the game server routes.", () => { 7 | beforeAll(() => { 8 | return request.get("/auth/steam/return") 9 | .expect(302); 10 | }); 11 | it("Should return all servers depending on permission of user.", () => { 12 | return request 13 | .get("/servers") 14 | .expect("Content-Type", /json/) 15 | .expect(200); 16 | }); 17 | it("Should setup a new server with the given values.", () => { 18 | let newServerData = [ 19 | { 20 | ip_string: "192.168.0.1", 21 | port: 27015, 22 | display_name: "Phlex's Temp Server", 23 | rcon_password: password, 24 | public_server: 1, 25 | }, 26 | ]; 27 | return request 28 | .post("/servers/") 29 | .set("Content-Type", "application/json") 30 | .set("Accept", "application/json") 31 | .send(newServerData) 32 | .expect((result) => { 33 | expect(result.body.message).toMatch(/successfully/); 34 | }) 35 | .expect(200); 36 | }); 37 | it("Should setup a new server with the given values.", () => { 38 | let newServerData = [ 39 | { 40 | ip_string: "192.168.0.1", 41 | port: 27016, 42 | display_name: "Phlex's Temp Server #2", 43 | rcon_password: password, 44 | public_server: 1, 45 | }, 46 | ]; 47 | return request 48 | .post("/servers/") 49 | .set("Content-Type", "application/json") 50 | .set("Accept", "application/json") 51 | .send(newServerData) 52 | .expect(200) 53 | .expect((result) => { 54 | expect(result.body.message).toMatch(/successfully/); 55 | }); 56 | }); 57 | it("Should setup a new server so we can play with it later.", () => { 58 | let newServerData = [ 59 | { 60 | ip_string: "192.168.0.1", 61 | port: 27020, 62 | display_name: "Phlex's Not So Temp Server", 63 | rcon_password: password, 64 | public_server: 1, 65 | }, 66 | ]; 67 | return request 68 | .post("/servers/") 69 | .set("Content-Type", "application/json") 70 | .set("Accept", "application/json") 71 | .send(newServerData) 72 | .expect(200) 73 | .expect((result) => { 74 | expect(result.body.message).toMatch(/successfully/); 75 | }); 76 | }); 77 | it("Request the information of the inserted server.", () => { 78 | return request 79 | .get("/servers/1") 80 | .expect("Content-Type", /json/) 81 | .expect(200) 82 | // Test to decrypt the password, if it matches then we decrypt/encrypt properly! 83 | .expect((result) => { 84 | expect(result.body.server.rcon_password).toBe(password); 85 | }); 86 | }); 87 | it("Request the information of all users servers.", () => { 88 | return request 89 | .get("/servers/myservers") 90 | .expect("Content-Type", /json/) 91 | .expect(200) 92 | .expect((result) => { 93 | expect(result.body.servers.length).toBeGreaterThanOrEqual(1); 94 | }); 95 | }); 96 | it("Should transfer ownership to the second user.", () => { 97 | let updatedServerData = [ 98 | { 99 | display_name: "Phlex's Temp Server #2 EDITED", 100 | user_id: 2, 101 | server_id: 2, 102 | }, 103 | ]; 104 | return request 105 | .put("/servers/") 106 | .set("Content-Type", "application/json") 107 | .set("Accept", "application/json") 108 | .send(updatedServerData) 109 | .expect(200) 110 | .expect((result) => { 111 | expect(result.body.message).toMatch(/successfully/); 112 | }); 113 | }); 114 | it("Should delete the information of the first server.", () => { 115 | let deleteData = [{ server_id: 1 }]; 116 | return request 117 | .delete("/servers/") 118 | .set("Content-Type", "application/json") 119 | .set("Accept", "application/json") 120 | .send(deleteData) 121 | .expect((result) => { 122 | expect(result.body.message).toMatch(/successfully/); 123 | }) 124 | .expect(200); 125 | }); 126 | it("Request the information of the second server, now no longer owned by us.", () => { 127 | return request 128 | .get("/servers/2") 129 | .expect("Content-Type", /json/) 130 | .expect(200) 131 | .expect((result) => { 132 | expect(result.body.rcon_password).toEqual(undefined); 133 | }); 134 | }); 135 | it("Should try and fail to edit server 2.", () => { 136 | let updatedServerData = [ 137 | { 138 | display_name: "Phlex's Temp Server #2 EDITED BAD ACT0R", 139 | user_id: 1, 140 | server_id: 2, 141 | }, 142 | ]; 143 | return request 144 | .put("/servers/") 145 | .set("Content-Type", "application/json") 146 | .set("Accept", "application/json") 147 | .send(updatedServerData) 148 | .expect(403) 149 | .expect((result) => { 150 | expect(result.body.message).toMatch(/not authorized/); 151 | }); 152 | }); 153 | }); -------------------------------------------------------------------------------- /__test__/maplist.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | let adminCheck = 0; 5 | 6 | describe("Test the maplist routes", () => { 7 | beforeAll(async () => { 8 | await request.get('/auth/steam/return') 9 | .expect(302); 10 | return; 11 | }); 12 | it('Should return all users.', () => { 13 | return request.get('/maps') 14 | .expect('Content-Type', /json/) 15 | .expect(200); 16 | }); 17 | it('Should get a users map list with a given database ID.', () => { 18 | return request.get('/maps/1') 19 | .expect('Content-Type', /json/) 20 | .expect((result) => { 21 | expect(result.body.maplist[0].id).toEqual(1); 22 | }) 23 | .expect(200); 24 | }); 25 | it('Should setup a new map for the map list.', () => { 26 | let newMapData = [{ 27 | user_id: 1, 28 | map_name: "de_cbble", 29 | map_display_name: "Cobblestoner" 30 | }]; 31 | return request.post('/maps') 32 | .set('Content-Type', 'application/json') 33 | .set('Accept', 'application/json') 34 | .send(newMapData) 35 | .expect(200); 36 | }); 37 | it('Should disable a map from a users\' list.', () => { 38 | let updatedUserData = [{ 39 | enabled: false, 40 | id: 1 41 | }]; 42 | return request.put('/maps') 43 | .set('Content-Type', 'application/json') 44 | .set('Accept', 'application/json') 45 | .send(updatedUserData) 46 | .expect(200); 47 | }); 48 | it('Should attempt to delete a users entry for a map.', () => { 49 | let newUserData = [{ 50 | id: 2 51 | }]; 52 | return request.delete('/maps') 53 | .set('Content-Type', 'application/json') 54 | .set('Accept', 'application/json') 55 | .send(newUserData) 56 | .expect(200); 57 | }); 58 | }); 59 | 60 | -------------------------------------------------------------------------------- /__test__/mapstats.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | 5 | describe("Test the mapstats routes", () => { 6 | beforeAll(async () => { 7 | await request.get('/auth/steam/return') 8 | .expect(302); 9 | return; 10 | }); 11 | // Note: Match 3 is the one being modified sequentially. 12 | it('Should get all map stats in the system.', () => { 13 | return request.get('/mapstats/') 14 | .expect(404); 15 | }); 16 | it('Should create stats of a map based on the third match.', () => { 17 | let teamData = [{ 18 | match_id: 3, 19 | map_number: 1, 20 | map_name: 'de_anubis', 21 | start_time: new Date().toISOString().slice(0, 19).replace("T", " ") 22 | }]; 23 | return request 24 | .post('/mapstats') 25 | .set("Content-Type", "application/json") 26 | .set("Accept", "application/json") 27 | .send(teamData) 28 | .expect((result) => { 29 | expect(result.body.message).toMatch(/successfully/); 30 | }) 31 | .expect(200); 32 | }); 33 | it('Should create stats of a map based on the third match.', () => { 34 | let teamData = [{ 35 | match_id: 3, 36 | map_number: 1, 37 | map_name: 'de_dust2', 38 | start_time: new Date().toISOString().slice(0, 19).replace("T", " ") 39 | }]; 40 | return request 41 | .post('/mapstats') 42 | .set("Content-Type", "application/json") 43 | .set("Accept", "application/json") 44 | .send(teamData) 45 | .expect((result) => { 46 | expect(result.body.message).toMatch(/successfully/); 47 | }) 48 | .expect(200); 49 | }); 50 | it('Should update stats of a map based on the third match.', () => { 51 | let teamData = [{ 52 | map_stats_id: 1, 53 | end_time: new Date().toISOString().slice(0, 19).replace("T", " ") 54 | }]; 55 | return request 56 | .put('/mapstats') 57 | .set("Content-Type", "application/json") 58 | .set("Accept", "application/json") 59 | .send(teamData) 60 | .expect((result) => { 61 | expect(result.body.message).toMatch(/successfully/); 62 | }) 63 | .expect(200); 64 | }); 65 | it('Should delete stats of a map based on the third match.', () => { 66 | let teamData = [{ 67 | map_stats_id: 1, 68 | }]; 69 | return request 70 | .delete('/mapstats') 71 | .set("Content-Type", "application/json") 72 | .set("Accept", "application/json") 73 | .send(teamData) 74 | .expect(200) 75 | .expect((result) => { 76 | expect(result.body.message).toMatch(/successfully/); 77 | }); 78 | }); 79 | }); 80 | 81 | 82 | describe('Delete Mapstats', () => { 83 | 84 | }); 85 | -------------------------------------------------------------------------------- /__test__/matches.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | 5 | describe("Test the matches routes", () => { 6 | beforeAll(() => { 7 | return request.get('/auth/steam/return') 8 | .expect(302); 9 | }); 10 | it('Should retrieve all matches, even if none.', () => { 11 | return request.get('/matches/') 12 | .expect(404); 13 | }); 14 | it('Should create a single match that is ready to be played with teams.', () => { 15 | // Min required data. 16 | let newMatchData = [ 17 | { 18 | server_id: 3, 19 | team1_id: 4, 20 | team2_id: 3, 21 | max_maps: 1, 22 | title: "Map {MAPNUMBER} of {MAXMAPS}", 23 | veto_mappool: "de_dust2, de_cache, de_mirage", 24 | skip_veto: 0, 25 | ignore_server: true 26 | } 27 | ]; 28 | return request 29 | .post("/matches/") 30 | .set("Content-Type", "application/json") 31 | .set("Accept", "application/json") 32 | .send(newMatchData) 33 | .expect((result) => { 34 | expect(result.body.message).toMatch(/successfully/); 35 | }) 36 | .expect(200); 37 | }); 38 | it('Should update a match with a start time and a test CVAR.', () => { 39 | let updatedMatchData = [ 40 | { 41 | match_id: 1, 42 | start_time: new Date().toISOString().slice(0, 19).replace('T', ' '), 43 | plugin_version: '0.7.2', 44 | match_cvars: { 45 | "mp_autobalanceteams": "1", 46 | "mp_test_value": 0 47 | } 48 | } 49 | ]; 50 | return request 51 | .put("/matches/") 52 | .set("Content-Type", "application/json") 53 | .set("Accept", "application/json") 54 | .send(updatedMatchData) 55 | .expect(200) 56 | .expect((result) => { 57 | expect(result.body.message).toMatch(/successfully/); 58 | }); 59 | }); 60 | it('Should retrieve the config for a match.', () => { 61 | return request.get("/matches/1/config") 62 | .expect(200) 63 | .expect((result) => { 64 | expect(result.body.cvars.get5_web_api_url).toMatch(/http/); 65 | }); 66 | }); 67 | it('Should get the first match.', () => { 68 | return request.get('/matches/1') 69 | .expect(200) 70 | .expect((result) => { 71 | expect(result.body.match.api_key).not.toBeUndefined(); 72 | }); 73 | }); 74 | it('Should first update the first match to attempt to break things right after.', () => { 75 | let updatedMatchData = [ 76 | { 77 | match_id: 1, 78 | user_id: 2 79 | } 80 | ]; 81 | return request 82 | .put("/matches/") 83 | .set("Content-Type", "application/json") 84 | .set("Accept", "application/json") 85 | .send(updatedMatchData) 86 | .expect(200) 87 | .expect((result) => { 88 | expect(result.body.message).toMatch(/successfully/); 89 | }); 90 | }); 91 | it('Should attempt to get the API key of the match.', () => { 92 | return request.get('/matches/1') 93 | .expect(200) 94 | .expect((result) => { 95 | expect(result.body.match.api_key).toBeUndefined(); 96 | }); 97 | }); 98 | it('Should attempt to forfeit the match.', () => { 99 | let updatedMatchData = [ 100 | { 101 | match_id: 1, 102 | forfeit: 1 103 | } 104 | ]; 105 | return request 106 | .put("/matches/") 107 | .set("Content-Type", "application/json") 108 | .set("Accept", "application/json") 109 | .send(updatedMatchData) 110 | .expect(403) 111 | .expect((result) => { 112 | expect(result.body.message).toMatch(/not authorized/); 113 | }); 114 | }); 115 | it('Should attempt to delete the match.', () => { 116 | let updatedMatchData = [ 117 | { 118 | match_id: 1 119 | } 120 | ]; 121 | return request 122 | .delete("/matches/") 123 | .set("Content-Type", "application/json") 124 | .set("Accept", "application/json") 125 | .send(updatedMatchData) 126 | .expect(403) 127 | .expect((result) => { 128 | expect(result.body.message).toMatch(/not authorized/); 129 | }); 130 | }); 131 | it('Should create a single match that is ready to be cancelled.', () => { 132 | let newMatchData = [ 133 | { 134 | server_id: 2, 135 | team1_id: 4, 136 | team2_id: 3, 137 | max_maps: 1, 138 | title: "Map {MAPNUMBER} of {MAXMAPS}", 139 | veto_mappool: "de_vertigo, de_inferno, de_mirage", 140 | skip_veto: 1, 141 | ignore_server: true 142 | }, 143 | ]; 144 | return request 145 | .post("/matches/") 146 | .set("Content-Type", "application/json") 147 | .set("Accept", "application/json") 148 | .send(newMatchData) 149 | .expect((result) => { 150 | expect(result.body.message).toMatch(/successfully/); 151 | }) 152 | .expect(200); 153 | }); 154 | it('Should forfeit the match.', () => { 155 | let updatedMatchData = [ 156 | { 157 | match_id: 2, 158 | forfeit: 1, 159 | end_time: new Date().toISOString().slice(0, 19).replace('T', ' ') 160 | }, 161 | ]; 162 | return request 163 | .put("/matches/") 164 | .set("Content-Type", "application/json") 165 | .set("Accept", "application/json") 166 | .send(updatedMatchData) 167 | .expect(200) 168 | .expect((result) => { 169 | expect(result.body.message).toMatch(/successfully/); 170 | }); 171 | }); 172 | it('Should delete the match.', () => { 173 | let updatedMatchData = [ 174 | { 175 | match_id: 2 176 | }, 177 | ]; 178 | return request 179 | .delete("/matches/") 180 | .set("Content-Type", "application/json") 181 | .set("Accept", "application/json") 182 | .send(updatedMatchData) 183 | .expect(200) 184 | .expect((result) => { 185 | expect(result.body.message).toMatch(/successfully/); 186 | }); 187 | }); 188 | it('Should create a single match that is ready for further testing.', () => { 189 | let newMatchData = [ 190 | { 191 | server_id: 2, 192 | team1_id: 4, 193 | team2_id: 3, 194 | max_maps: 1, 195 | title: "Map {MAPNUMBER} of {MAXMAPS}", 196 | veto_mappool: "de_vertigo, de_inferno, de_mirage", 197 | skip_veto: 1, 198 | ignore_server: true 199 | }, 200 | ]; 201 | return request 202 | .post("/matches/") 203 | .set("Content-Type", "application/json") 204 | .set("Accept", "application/json") 205 | .send(newMatchData) 206 | .expect(200) 207 | .expect((result) => { 208 | expect(result.body.message).toMatch(/successfully/); 209 | }); 210 | }); 211 | }); -------------------------------------------------------------------------------- /__test__/playerstats.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app) 4 | let apiKey = ""; 5 | 6 | describe("Test the playerstats routes", () => { 7 | beforeAll(async () => { 8 | await request.get('/auth/steam/return') 9 | .expect(302); 10 | return; 11 | }); 12 | // Note: Match 3 is the one being modified sequentially. 13 | it('Should get all player stats in the system.', () => { 14 | return request.get('/playerstats/') 15 | .expect(404); 16 | }); 17 | it('Should get the player stats of the mock user.', () => { 18 | return request.get('/playerstats/76561198025644194') 19 | .expect(404); 20 | }); 21 | it('Should get the player stats of the third match.', () => { 22 | return request.get('/playerstats/match/3') 23 | .expect(404); 24 | }); 25 | it('Should get the API key of the third match.', () => { 26 | return request.get('/matches/3') 27 | .expect((result) => { 28 | apiKey = result.body.match.api_key; 29 | }) 30 | .expect(200); 31 | }); 32 | it('Should insert a player stat into the third match', () => { 33 | // Min required data. 34 | let statData = [{ 35 | match_id: 3, 36 | map_id: 2, 37 | team_id: 4, 38 | steam_id: '12345678901011121', 39 | name: 'Actually Phlex', 40 | api_key: apiKey 41 | }]; 42 | return request 43 | .post('/playerstats/') 44 | .set("Content-Type", "application/json") 45 | .set("Accept", "application/json") 46 | .send(statData) 47 | .expect((result) => { 48 | expect(result.body.message).toMatch(/successfully/); 49 | }) 50 | .expect(200); 51 | }); 52 | it('Should update a player stat in the third match', () => { 53 | // Min required data. 54 | let statData = [{ 55 | match_id: 3, 56 | map_id: 2, 57 | team_id: 4, 58 | steam_id: '12345678901011121', 59 | api_key: apiKey, 60 | kills: 4, 61 | headshot_kills: 2, 62 | damage: 139, 63 | firstkill_t: 1 64 | }]; 65 | return request 66 | .put('/playerstats/') 67 | .set("Content-Type", "application/json") 68 | .set("Accept", "application/json") 69 | .send(statData) 70 | .expect((result) => { 71 | expect(result.body.message).toMatch(/successfully/); 72 | }) 73 | .expect(200); 74 | }); 75 | it('Should update a player stat in the third match with invalid API key.', () => { 76 | // Min required data. 77 | let statData = [{ 78 | match_id: 3, 79 | map_id: 2, 80 | team_id: 4, 81 | steam_id: '12345678901011121', 82 | api_key: '1234', 83 | kills: 4, 84 | headshot_kills: 2, 85 | damage: 139, 86 | firstkill_t: 1 87 | }]; 88 | return request 89 | .put('/playerstats/') 90 | .set("Content-Type", "application/json") 91 | .set("Accept", "application/json") 92 | .send(statData) 93 | .expect((result) => { 94 | expect(result.body.message).toMatch(/not authorized/); 95 | }) 96 | .expect(403); 97 | }); 98 | it('Should insert an invalid player stat into the third match', () => { 99 | // Min required data. 100 | let statData = [{ 101 | match_id: 3, 102 | map_id: 2, 103 | team_id: 4, 104 | steam_id: '12345678901011121', 105 | name: 'Actually Phlex', 106 | api_key: 'NOTAGOODAPIKEY' 107 | }]; 108 | return request 109 | .post('/playerstats/') 110 | .set("Content-Type", "application/json") 111 | .set("Accept", "application/json") 112 | .send(statData) 113 | .expect((result) => { 114 | expect(result.body.message).toMatch(/not authorized/); 115 | }) 116 | .expect(403); 117 | }); 118 | it('Should attempt to delete a live match.', () => { 119 | // Min required data. 120 | let deleteData = [{ 121 | match_id: 3 122 | }]; 123 | return request 124 | .delete('/playerstats/') 125 | .set("Content-Type", "application/json") 126 | .set("Accept", "application/json") 127 | .send(deleteData) 128 | .expect((result) => { 129 | expect(result.body.message).toMatch(/currently live/); 130 | }) 131 | .expect(401); 132 | }); 133 | }); -------------------------------------------------------------------------------- /__test__/seasons.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | 5 | describe("Test the season routes", () => { 6 | beforeAll(() => { 7 | return request.get('/auth/steam/return') 8 | .expect(302); 9 | }); 10 | it('Should return 404 with no seasons.', () => { 11 | return request.get('/seasons/') 12 | .expect(404); 13 | }); 14 | it('Should create a new season.', () => { 15 | // Min required data. 16 | let newSeasonData = [ 17 | { 18 | name: "Phlex's Temp Season", 19 | start_date: new Date().toISOString().slice(0, 10).replace('T', ' ') 20 | } 21 | ]; 22 | return request 23 | .post("/seasons/") 24 | .set("Content-Type", "application/json") 25 | .set("Accept", "application/json") 26 | .send(newSeasonData) 27 | .expect((result) => { 28 | expect(result.body.message).toMatch(/successfully/); 29 | }) 30 | .expect(200); 31 | }); 32 | it('Should create a new season again.', () => { 33 | // Min required data. 34 | let newSeasonData = [ 35 | { 36 | name: "Phlex's Bad Actor", 37 | start_date: new Date().toISOString().slice(0, 10).replace('T', ' ') 38 | } 39 | ]; 40 | return request 41 | .post("/seasons/") 42 | .set("Content-Type", "application/json") 43 | .set("Accept", "application/json") 44 | .send(newSeasonData) 45 | .expect((result) => { 46 | expect(result.body.message).toMatch(/successfully/); 47 | }) 48 | .expect(200); 49 | }); 50 | it('Should update the bad actor to allow us to attempt to do malicious things.', () => { 51 | let updateSeasonData = [ 52 | { 53 | season_id: 2, 54 | user_id: 2 55 | } 56 | ]; 57 | return request 58 | .put("/seasons/") 59 | .set("Content-Type", "application/json") 60 | .set("Accept", "application/json") 61 | .send(updateSeasonData) 62 | .expect((result) => { 63 | expect(result.body.message).toMatch(/successfully/); 64 | }) 65 | .expect(200); 66 | }); 67 | it('Should attempt to delete the second season.', () => { 68 | let deleteSeasonData = [ 69 | { 70 | season_id: 2 71 | } 72 | ]; 73 | return request 74 | .delete("/seasons/") 75 | .set("Content-Type", "application/json") 76 | .set("Accept", "application/json") 77 | .send(deleteSeasonData) 78 | .expect((result) => { 79 | expect(result.body.message).toMatch(/not authorized/); 80 | }) 81 | .expect(403); 82 | }); 83 | it('Should return 404 with no seasons.', () => { 84 | let updateSeasonData = [ 85 | { 86 | match_id: 3, 87 | season_id: 1 88 | } 89 | ]; 90 | return request 91 | .put("/matches/") 92 | .set("Content-Type", "application/json") 93 | .set("Accept", "application/json") 94 | .send(updateSeasonData) 95 | .expect((result) => { 96 | expect(result.body.message).toMatch(/successfully/); 97 | }) 98 | .expect(200); 99 | }); 100 | it('Should delete the second season.', () => { 101 | let deleteSeasonData = [ 102 | { 103 | season_id: 1 104 | } 105 | ]; 106 | return request 107 | .delete("/seasons/") 108 | .set("Content-Type", "application/json") 109 | .set("Accept", "application/json") 110 | .send(deleteSeasonData) 111 | .expect((result) => { 112 | expect(result.body.message).toMatch(/successfully/); 113 | }) 114 | .expect(200); 115 | }); 116 | }); 117 | -------------------------------------------------------------------------------- /__test__/users.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js' 3 | const request = agent(app); 4 | let adminCheck = 0; 5 | 6 | describe("Test the user routes", () => { 7 | beforeAll(async () => { 8 | await request.get('/auth/steam/return') 9 | .expect(302); 10 | return; 11 | }); 12 | it("Should get 200 from all users", () => { 13 | return request 14 | .get('/users') 15 | .expect(200); 16 | }); 17 | it('Should return all users.', () => { 18 | return request.get('/users') 19 | .expect('Content-Type', /json/) 20 | .expect(200); 21 | }); 22 | it('Should setup a new user only if we are an admin or super_admin.', () => { 23 | let newUserData = [{ 24 | id: 1, 25 | steam_id: 1234, 26 | name: "Test User", 27 | admin: 0, 28 | super_admin: 0 29 | }]; 30 | return request.post('/users'). 31 | set('Content-Type', 'application/json'). 32 | set('Accept', 'application/json'). 33 | send(newUserData). 34 | expect(200); 35 | }); 36 | it('Should get a user with a given database ID.', () => { 37 | return request.get('/users/1') 38 | .expect('Content-Type', /json/) 39 | .expect((res) => { 40 | expect(res.body.user.id).toEqual(1); 41 | }) 42 | .expect(200); 43 | adminCheck = result.body.user.admin + result.body.user.super_admin; 44 | }); 45 | it('Should get a users steam url from database ID or Steam ID.', () => { 46 | return request.get('/users/1/steam') 47 | .expect('Content-Type', /json/) 48 | .expect(200) 49 | .expect((res) => { 50 | expect(res.body.url).toMatch(/steamcommunity/); 51 | }); 52 | }); 53 | it('Should update the existing test user to remove admin privileges.', () => { 54 | let updatedUserData = [{ 55 | id: 1, 56 | steam_id: '76561198025644194', 57 | name: "Get Updated Kid", 58 | admin: 0, 59 | super_admin: 0 60 | }]; 61 | return request.put('/users') 62 | .set('Content-Type', 'application/json') 63 | .set('Accept', 'application/json') 64 | .send(updatedUserData) 65 | .expect(200); 66 | }); 67 | it('Should attempt to create a user without permission.', async () => { 68 | let newUserData = [{ 69 | id: 1, 70 | steam_id: 10001, 71 | name: "Bad Act0r", 72 | admin: 1, 73 | super_admin: 1 74 | }]; 75 | return request.post('/users') 76 | .set('Content-Type', 'application/json') 77 | .set('Accept', 'application/json') 78 | .send(newUserData) 79 | .expect(403); 80 | }); 81 | }); -------------------------------------------------------------------------------- /__test__/vetoes.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | let vetoId; 5 | 6 | describe("Test the veto routes", () => { 7 | beforeAll(() => { 8 | return request.get('/auth/steam/return') 9 | .expect(302); 10 | }); 11 | it('Should retrieve all vetoes, even if none.', () => { 12 | return request.get('/vetoes/') 13 | .expect(404); 14 | }); 15 | it('Should create a single veto that is tied to a match.', () => { 16 | // Min required data. 17 | let newVetoData = [ 18 | { 19 | match_id: 3, 20 | team_name: "PRVSHLF2", 21 | map_name: "de_vertigo", 22 | pick_or_ban: "veto" 23 | } 24 | ]; 25 | return request 26 | .post("/vetoes/") 27 | .set("Content-Type", "application/json") 28 | .set("Accept", "application/json") 29 | .send(newVetoData) 30 | .expect((result) => { 31 | expect(result.body.message).toMatch(/successfully/); 32 | }) 33 | .expect(200); 34 | }); 35 | it('Should create another ban for a different team.', () => { 36 | // Min required data. 37 | let newVetoData = [ 38 | { 39 | match_id: 3, 40 | team_name: "PRVSHLF3", 41 | map_name: "de_inferno", 42 | pick_or_ban: "veto" 43 | } 44 | ]; 45 | return request 46 | .post("/vetoes/") 47 | .set("Content-Type", "application/json") 48 | .set("Accept", "application/json") 49 | .send(newVetoData) 50 | .expect((result) => { 51 | expect(result.body.message).toMatch(/successfully/); 52 | }) 53 | .expect(200); 54 | }); 55 | it('Should create a last ban for a different team so it matches the veto_mappool in match.', () => { 56 | // Min required data. 57 | let newVetoData = [ 58 | { 59 | match_id: 3, 60 | team_name: "PRVSHLF2", 61 | map_name: "de_mirage", 62 | pick_or_ban: "veto" 63 | } 64 | ]; 65 | return request 66 | .post("/vetoes/") 67 | .set("Content-Type", "application/json") 68 | .set("Accept", "application/json") 69 | .send(newVetoData) 70 | .expect((result) => { 71 | expect(result.body.message).toMatch(/successfully/); 72 | }) 73 | .expect(200); 74 | }); 75 | it('Should retrieve all vetoes, even if none.', () => { 76 | return request.get('/vetoes/3') 77 | .expect(200) 78 | .expect((result) => { 79 | expect(result.body.vetoes.length).toEqual(3); 80 | }); 81 | }); 82 | it('Should delete all match vetoes.', () => { 83 | let deleteVetoData = [ 84 | { 85 | match_id: 3 86 | } 87 | ]; 88 | return request 89 | .delete("/vetoes/") 90 | .set("Content-Type", "application/json") 91 | .set("Accept", "application/json") 92 | .send(deleteVetoData) 93 | .expect(200) 94 | .expect((result) => { 95 | expect(result.body.message).toMatch(/successfully/); 96 | }); 97 | }); 98 | it('Should create a single veto that is tied to a match.', () => { 99 | // Min required data. 100 | let newVetoData = [ 101 | { 102 | match_id: 3, 103 | team_name: "PRVSHLF2", 104 | map_name: "de_vertigo", 105 | pick_or_ban: "veto" 106 | } 107 | ]; 108 | return request 109 | .post("/vetoes/") 110 | .set("Content-Type", "application/json") 111 | .set("Accept", "application/json") 112 | .send(newVetoData) 113 | .expect((result) => { 114 | expect(result.body.message).toMatch(/successfully/); 115 | }) 116 | .expect(200); 117 | }); 118 | it('Should create another ban for a different team.', () => { 119 | // Min required data. 120 | let newVetoData = [ 121 | { 122 | match_id: 3, 123 | team_name: "PRVSHLF3", 124 | map_name: "de_inferno", 125 | pick_or_ban: "veto" 126 | } 127 | ]; 128 | return request 129 | .post("/vetoes/") 130 | .set("Content-Type", "application/json") 131 | .set("Accept", "application/json") 132 | .send(newVetoData) 133 | .expect((result) => { 134 | expect(result.body.message).toMatch(/successfully/); 135 | }) 136 | .expect(200); 137 | }); 138 | it('Should create a last ban for a different team so it matches the veto_mappool in match.', () => { 139 | // Min required data. 140 | let newVetoData = [ 141 | { 142 | match_id: 3, 143 | team_name: "PRVSHLF2", 144 | map_name: "de_mirage", 145 | pick_or_ban: "veto" 146 | } 147 | ]; 148 | return request 149 | .post("/vetoes/") 150 | .set("Content-Type", "application/json") 151 | .set("Accept", "application/json") 152 | .send(newVetoData) 153 | .expect((result) => { 154 | expect(result.body.message).toMatch(/successfully/); 155 | vetoId = result.body.id; 156 | }) 157 | .expect(200); 158 | }); 159 | it('Should update the match to include the ID.', () => { 160 | // Min required data. 161 | let updVetoData = [ 162 | { 163 | veto_id: vetoId, 164 | match_id: 3 165 | } 166 | ]; 167 | return request 168 | .put("/vetoes/") 169 | .set("Content-Type", "application/json") 170 | .set("Accept", "application/json") 171 | .send(updVetoData) 172 | .expect((result) => { 173 | expect(result.body.message).toMatch(/successfully/); 174 | }) 175 | .expect(200); 176 | }); 177 | }); -------------------------------------------------------------------------------- /__test__/vetosides.test.js: -------------------------------------------------------------------------------- 1 | import { agent } from 'supertest'; 2 | import app from '../app.js'; 3 | const request = agent(app); 4 | let vetoId; 5 | 6 | describe("Test the vetosides routes", () => { 7 | beforeAll(async () => { 8 | await request.get('/auth/steam/return') 9 | .expect(302); 10 | return; 11 | }); 12 | it('Should retrieve all vetoes, even if none.', () => { 13 | return request.get('/vetosides/') 14 | .expect(404); 15 | }); 16 | it('Should create a single veto side that is tied to a match and veto.', () => { 17 | // Min required data. 18 | let newVetoData = [ 19 | { 20 | match_id: 3, 21 | team_name: "PRVSHLF2", 22 | map_name: "de_vertigo", 23 | side: "CT" 24 | } 25 | ]; 26 | return request 27 | .post("/vetosides/") 28 | .set("Content-Type", "application/json") 29 | .set("Accept", "application/json") 30 | .send(newVetoData) 31 | .expect((result) => { 32 | expect(result.body.message).toMatch(/successfully/); 33 | }) 34 | .expect(200); 35 | }); 36 | it('Should create another side selection for a different team.', () => { 37 | // Min required data. 38 | let newVetoData = [ 39 | { 40 | match_id: 3, 41 | team_name: "PRVSHLF3", 42 | map_name: "de_inferno", 43 | side: "T" 44 | } 45 | ]; 46 | return request 47 | .post("/vetosides/") 48 | .set("Content-Type", "application/json") 49 | .set("Accept", "application/json") 50 | .send(newVetoData) 51 | .expect((result) => { 52 | expect(result.body.message).toMatch(/successfully/); 53 | }) 54 | .expect(200); 55 | }); 56 | it('Should create a last side selection for a different team.', () => { 57 | // Min required data. 58 | let newVetoData = [ 59 | { 60 | match_id: 3, 61 | team_name: "PRVSHLF2", 62 | map_name: "de_mirage", 63 | side: "T" 64 | } 65 | ]; 66 | return request 67 | .post("/vetosides/") 68 | .set("Content-Type", "application/json") 69 | .set("Accept", "application/json") 70 | .send(newVetoData) 71 | .expect((result) => { 72 | expect(result.body.message).toMatch(/successfully/); 73 | }) 74 | .expect(200); 75 | }); 76 | it('Should retrieve all veto sides, even if none.', () => { 77 | return request.get('/vetosides/3') 78 | .expect((result) => { 79 | expect(result.body.vetoes.length).toEqual(3); 80 | }) 81 | .expect(200); 82 | }); 83 | it('Should delete all match side selection data.', () => { 84 | let deleteVetoData = [ 85 | { 86 | match_id: 3 87 | } 88 | ]; 89 | return request 90 | .delete("/vetosides/") 91 | .set("Content-Type", "application/json") 92 | .set("Accept", "application/json") 93 | .send(deleteVetoData) 94 | .expect(200) 95 | .expect((result) => { 96 | expect(result.body.message).toMatch(/successfully/); 97 | }); 98 | }); 99 | it('Should create a single veto that is tied to a match.', () => { 100 | // Min required data. 101 | let newVetoData = [ 102 | { 103 | match_id: 3, 104 | team_name: "PRVSHLF2", 105 | map_name: "de_vertigo", 106 | side: "CT" 107 | } 108 | ]; 109 | return request 110 | .post("/vetosides/") 111 | .set("Content-Type", "application/json") 112 | .set("Accept", "application/json") 113 | .send(newVetoData) 114 | .expect((result) => { 115 | expect(result.body.message).toMatch(/successfully/); 116 | }) 117 | .expect(200); 118 | }); 119 | it('Should create another side selection for a different team.', () => { 120 | // Min required data. 121 | let newVetoData = [ 122 | { 123 | match_id: 3, 124 | team_name: "PRVSHLF3", 125 | map_name: "de_inferno", 126 | side: "T" 127 | } 128 | ]; 129 | return request 130 | .post("/vetosides/") 131 | .set("Content-Type", "application/json") 132 | .set("Accept", "application/json") 133 | .send(newVetoData) 134 | .expect((result) => { 135 | expect(result.body.message).toMatch(/successfully/); 136 | }) 137 | .expect(200); 138 | }); 139 | it('Should create a last side selection for a match.', () => { 140 | // Min required data. 141 | let newVetoData = [ 142 | { 143 | match_id: 3, 144 | team_name: "PRVSHLF2", 145 | map_name: "de_mirage", 146 | side: "T" 147 | } 148 | ]; 149 | return request 150 | .post("/vetosides/") 151 | .set("Content-Type", "application/json") 152 | .set("Accept", "application/json") 153 | .send(newVetoData) 154 | .expect((result) => { 155 | expect(result.body.message).toMatch(/successfully/); 156 | vetoId = result.body.id; 157 | }) 158 | .expect(200); 159 | }); 160 | it('Should update the match to include the ID.', () => { 161 | // Min required data. 162 | let updVetoData = [ 163 | { 164 | veto_id: vetoId, 165 | match_id: 3, 166 | side: "CT" 167 | } 168 | ]; 169 | return request 170 | .put("/vetosides/") 171 | .set("Content-Type", "application/json") 172 | .set("Accept", "application/json") 173 | .send(updVetoData) 174 | .expect((result) => { 175 | expect(result.body.message).toMatch(/successfully/); 176 | }) 177 | .expect(200); 178 | }); 179 | }); -------------------------------------------------------------------------------- /bin/www.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Checking for node_env 5 | */ 6 | if(!process.env.NODE_ENV || process.env.NODE_ENV == undefined) { 7 | console.warn("\x1b[31m%s\x1b[0m", "No NODE_ENV set. Please set NODE_ENV or else default is DEVELOPMENT."); 8 | process.env.NODE_ENV = 'development'; 9 | } 10 | /** 11 | * Module dependencies. 12 | */ 13 | 14 | import app from '../app.js'; 15 | import debug from 'debug'; 16 | import { createServer } from 'http'; 17 | import config from 'config'; 18 | 19 | /** 20 | * Get port from environment and store in Express. 21 | */ 22 | var port = normalizePort(config.get("server.port") || '3000'); 23 | app.set('port', port); 24 | 25 | /** 26 | * Create HTTP server. 27 | */ 28 | 29 | var server = createServer(app); 30 | 31 | 32 | /** 33 | * Listen on provided port, on all network interfaces. 34 | */ 35 | 36 | server.listen(port); 37 | server.on('error', onError); 38 | server.on('listening', onListening); 39 | 40 | /** 41 | * Normalize a port into a number, string, or false. 42 | */ 43 | 44 | function normalizePort(val: any) { 45 | var port = parseInt(val, 10); 46 | 47 | if (isNaN(port)) { 48 | // named pipe 49 | return val; 50 | } 51 | 52 | if (port >= 0) { 53 | // port number 54 | return port; 55 | } 56 | 57 | return false; 58 | } 59 | 60 | /** 61 | * Event listener for HTTP server "error" event. 62 | */ 63 | 64 | function onError(error: any) { 65 | if (error.syscall !== 'listen') { 66 | throw error; 67 | } 68 | 69 | var bind = typeof port === 'string' 70 | ? 'Pipe ' + port 71 | : 'Port ' + port; 72 | 73 | // handle specific listen errors with friendly messages 74 | switch (error.code) { 75 | case 'EACCES': 76 | console.error(bind + ' requires elevated privileges'); 77 | process.exit(1); 78 | break; 79 | case 'EADDRINUSE': 80 | console.error(bind + ' is already in use'); 81 | process.exit(1); 82 | break; 83 | default: 84 | throw error; 85 | } 86 | } 87 | 88 | /** 89 | * Event listener for HTTP server "listening" event. 90 | */ 91 | 92 | function onListening() { 93 | var addr: any = server.address(); 94 | var bind = typeof addr === 'string' 95 | ? 'pipe ' + addr 96 | : 'port ' + addr.port; 97 | debug('Listening on ' + bind); 98 | } 99 | -------------------------------------------------------------------------------- /config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhlexPlexico/G5API/626c74b276e8425f8cf8a607703eb2f755d2aba2/config/.gitkeep -------------------------------------------------------------------------------- /config/development.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "port": 3301, 4 | "hostname": "http://localhost", 5 | "dbKey": "Database 16 Byte Key.", 6 | "steamAPIKey": "API Key For Steam Calls.", 7 | "sharedSecret": "a secure secret for session sigining.", 8 | "clientHome": "http://localhost:8080", 9 | "useRedis": true, 10 | "apiURL": "http://localhost:8080/api/", 11 | "uploadDemos": false, 12 | "localLoginEnabled": true, 13 | "redisUrl": "redis://:super_secure@localhost:6379", 14 | "redisTTL": 86400 15 | }, 16 | "development": { 17 | "driver": "mysql", 18 | "user": "get5_user", 19 | "password": "", 20 | "database": "get5dev", 21 | "multipleStatements": true, 22 | "flags": { "ENV": "MYSQL_FLAGS" }, 23 | "host": "127.0.0.1", 24 | "port": 3306, 25 | "connectionLimit": 15 26 | }, 27 | "admins": { 28 | "steam_ids": "admins,go,here" 29 | }, 30 | "super_admins": { 31 | "steam_ids": "super_admins,go,here" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config/production.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "port": $PORT, 4 | "hostname": "$HOSTNAME", 5 | "dbKey": "$DBKEY", 6 | "steamAPIKey": "$STEAMAPIKEY", 7 | "sharedSecret": "$SHAREDSECRET", 8 | "clientHome": "$CLIENTHOME", 9 | "useRedis": $USEREDIS, 10 | "apiURL": "$APIURL", 11 | "uploadDemos": $UPLOADDEMOS, 12 | "localLoginEnabled": $LOCALLOGINS, 13 | "redisUrl": "$REDISURL", 14 | "redisTTL": $REDISTTL 15 | }, 16 | "production": { 17 | "driver": "mysql", 18 | "user": "$SQLUSER", 19 | "password": "$SQLPASSWORD", 20 | "database": "$DATABASE", 21 | "multipleStatements": true, 22 | "flags": { "ENV": "MYSQL_FLAGS" }, 23 | "host": "$SQLHOST", 24 | "port": $SQLPORT, 25 | "connectionLimit": 15 26 | }, 27 | "admins": { 28 | "steam_ids": "$ADMINS" 29 | }, 30 | "super_admins": { 31 | "steam_ids": "$SUPERADMINS" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /config/test.json.template: -------------------------------------------------------------------------------- 1 | { 2 | "server": { 3 | "port": 3301, 4 | "hostname": "http://localhost", 5 | "dbKey": "Database 16 Byte Key.", 6 | "steamAPIKey": "API Key For Steam Calls.", 7 | "sharedSecret": "a secure secret for session sigining.", 8 | "clientHome": "http://localhost:8080", 9 | "useRedis": false, 10 | "apiURL": "http://localhost:8080/api/", 11 | "uploadDemos": false, 12 | "localLoginEnabled": true, 13 | "redisUrl": "redis://:super_secure@localhost:6379", 14 | "redisTTL": 86400 15 | }, 16 | "test": { 17 | "driver": "mysql", 18 | "user": "get5_user", 19 | "password": "", 20 | "database": "get5test", 21 | "multipleStatements": true, 22 | "flags": { "ENV": "MYSQL_FLAGS" }, 23 | "host": "127.0.0.1", 24 | "port": 3306, 25 | "connectionLimit": 15 26 | }, 27 | "admins": { 28 | "steam_ids": "admins,go,here" 29 | }, 30 | "super_admins": { 31 | "steam_ids": "super_admins,go,here" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | redis: 5 | image: redis:6 6 | command: redis-server --requirepass super_secure_password_change_me 7 | container_name: redis 8 | networks: 9 | - get5 10 | restart: always 11 | 12 | get5db: 13 | image: yobasystems/alpine-mariadb 14 | container_name: get5db 15 | restart: always 16 | networks: 17 | - get5 18 | environment: 19 | - MYSQL_ROOT_PASSWORD= 20 | - MYSQL_DATABASE=get5 21 | - MYSQL_USER=get5 22 | - MYSQL_PASSWORD= 23 | - MYSQL_CHARSET=utf8mb4 24 | - MYSQL_COLLATION=utf8mb4_general_ci 25 | 26 | caddy: 27 | image: lucaslorentz/caddy-docker-proxy:ci-alpine 28 | container_name: caddy-reverse-proxy 29 | restart: unless-stopped 30 | networks: 31 | - get5 32 | volumes: 33 | - /var/run/docker.sock:/var/run/docker.sock 34 | ports: 35 | - 80:80 36 | - 443:443 37 | environment: 38 | - CADDY_INGRESS_NETWORKS=get5 39 | 40 | g5api: 41 | image: ghcr.io/phlexplexico/g5api:latest 42 | depends_on: 43 | - get5db 44 | container_name: G5API 45 | networks: 46 | - get5 47 | labels: 48 | caddy: localhost 49 | caddy.handle_path: /api/* 50 | caddy.handle_path.0_reverse_proxy: "{{upstreams 3301}}" 51 | volumes: 52 | - ./public:/Get5API/public 53 | environment: 54 | - NODE_ENV=production 55 | - PORT=3301 56 | - DBKEY= 57 | - STEAMAPIKEY= 58 | - HOSTNAME=https://localhost 59 | - SHAREDSECRET= 60 | - CLIENTHOME=https://localhost 61 | - APIURL=https://localhost/api 62 | - SQLUSER=get5 63 | - SQLPASSWORD= 64 | - SQLPORT=3306 65 | - DATABASE=get5 66 | - SQLHOST=get5db 67 | - ADMINS= 68 | - SUPERADMINS= 69 | - REDISURL=redis://:super_secure_password_change_me@redis:6379 70 | - REDISTTL=86400 71 | - USEREDIS=true 72 | - UPLOADDEMOS=true 73 | - LOCALLOGINS=false 74 | restart: always 75 | 76 | g5v: 77 | image: ghcr.io/phlexplexico/g5v:latest 78 | depends_on: 79 | - g5api 80 | container_name: G5V-Front-End 81 | networks: 82 | - get5 83 | restart: always 84 | labels: 85 | caddy: localhost 86 | caddy.reverse_proxy: "{{upstreams}}" 87 | 88 | networks: 89 | get5: 90 | external: true 91 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: 'ts-jest', 4 | testEnvironment: 'node', 5 | }; -------------------------------------------------------------------------------- /jest_config/jest.teams.config.cjs: -------------------------------------------------------------------------------- 1 | // For a detailed explanation regarding each configuration property, visit: 2 | // https://jestjs.io/docs/en/configuration.html 3 | process.env.NODE_ENV = "test"; 4 | module.exports = { 5 | preset: 'ts-jest/presets/js-with-ts-esm', 6 | // A path to a custom resolver 7 | resolver: "jest-ts-webcompat-resolver", 8 | // All imported modules in your tests should be mocked automatically 9 | // automock: false, 10 | 11 | // Stop running tests after `n` failures 12 | // bail: 0, 13 | 14 | // Respect "browser" field in package.json when resolving modules 15 | // browser: false, 16 | 17 | // The directory where Jest should store its cached dependency information 18 | // cacheDirectory: "/private/var/folders/4t/ph0r897n5350cj4k8s41606h0000gn/T/jest_dx", 19 | 20 | // Automatically clear mock calls and instances between every test 21 | clearMocks: true, 22 | 23 | // Indicates whether the coverage information should be collected while executing the test 24 | // collectCoverage: false, 25 | 26 | // An array of glob patterns indicating a set of files for which coverage information should be collected 27 | // collectCoverageFrom: undefined, 28 | 29 | // The directory where Jest should output its coverage files 30 | coverageDirectory: "coverage", 31 | 32 | // An array of regexp pattern strings used to skip coverage collection 33 | coveragePathIgnorePatterns: [ 34 | "/node_modules/" 35 | ], 36 | 37 | // A list of reporter names that Jest uses when writing coverage reports 38 | // coverageReporters: [ 39 | // "json", 40 | // "text", 41 | // "lcov", 42 | // "clover" 43 | // ], 44 | 45 | // An object that configures minimum threshold enforcement for coverage results 46 | // coverageThreshold: undefined, 47 | 48 | // A path to a custom dependency extractor 49 | // dependencyExtractor: undefined, 50 | 51 | // Make calling deprecated APIs throw helpful error messages 52 | // errorOnDeprecated: false, 53 | 54 | // Force coverage collection from ignored files using an array of glob patterns 55 | // forceCoverageMatch: [], 56 | 57 | // A path to a module which exports an async function that is triggered once before all test suites 58 | // globalSetup: undefined, 59 | 60 | // A path to a module which exports an async function that is triggered once after all test suites 61 | globalTeardown: "./test-teardown-globals.cjs", 62 | 63 | // A set of global variables that need to be available in all test environments 64 | // globals: {}, 65 | 66 | // 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. 67 | // maxWorkers: "50%", 68 | 69 | // An array of directory names to be searched recursively up from the requiring module's location 70 | // moduleDirectories: [ 71 | // "node_modules" 72 | // ], 73 | 74 | // An array of file extensions your modules use 75 | // moduleFileExtensions: [ 76 | // "js", 77 | // "json", 78 | // "jsx", 79 | // "ts", 80 | // "tsx", 81 | // "node" 82 | // ], 83 | 84 | // A map from regular expressions to module names that allow to stub out resources with a single module 85 | // moduleNameMapper: {}, 86 | 87 | // An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader 88 | // modulePathIgnorePatterns: [], 89 | 90 | // Activates notifications for test results 91 | // notify: false, 92 | 93 | // An enum that specifies notification mode. Requires { notify: true } 94 | // notifyMode: "failure-change", 95 | 96 | // A preset that is used as a base for Jest's configuration 97 | // preset: undefined, 98 | 99 | // Run tests from one or more projects 100 | // projects: undefined, 101 | 102 | // Use this configuration option to add custom reporters to Jest 103 | // reporters: undefined, 104 | 105 | // Automatically reset mock state between every test 106 | // resetMocks: false, 107 | 108 | // Reset the module registry before running each individual test 109 | // resetModules: false, 110 | 111 | // A path to a custom resolver 112 | // resolver: undefined, 113 | 114 | // Automatically restore mock state between every test 115 | // restoreMocks: false, 116 | 117 | // The root directory that Jest should scan for tests and modules within 118 | // rootDir: undefined, 119 | 120 | // A list of paths to directories that Jest should use to search for files in 121 | roots: [ 122 | "../__test__" 123 | ], 124 | 125 | // Allows you to use a custom runner instead of Jest's default test runner 126 | // runner: "jest-runner", 127 | 128 | // The paths to modules that run some code to configure or set up the testing environment before each test 129 | // setupFiles: [], 130 | 131 | // A list of paths to modules that run some code to configure or set up the testing framework before each test 132 | // setupFilesAfterEnv: [], 133 | 134 | // A list of paths to snapshot serializer modules Jest should use for snapshot testing 135 | // snapshotSerializers: [], 136 | 137 | // The test environment that will be used for testing 138 | testEnvironment: "node", 139 | 140 | // Options that will be passed to the testEnvironment 141 | // testEnvironmentOptions: {}, 142 | 143 | // Adds a location field to test results 144 | // testLocationInResults: false, 145 | 146 | // The glob patterns Jest uses to detect test files 147 | testMatch: [ 148 | "**/__tests__/**/teams.test.js", 149 | "**/@(teams.)+(spec|test).[tj]s?(x)" 150 | ], 151 | 152 | // An array of regexp pattern strings that are matched against all test paths, matched tests are skipped 153 | // testPathIgnorePatterns: [ 154 | // "/node_modules/" 155 | // ], 156 | 157 | // The regexp pattern or array of patterns that Jest uses to detect test files 158 | // testRegex: [], 159 | 160 | // This option allows the use of a custom results processor 161 | // testResultsProcessor: undefined, 162 | 163 | // This option allows use of a custom test runner 164 | // testRunner: "jasmine2", 165 | 166 | // This option sets the URL for the jsdom environment. It is reflected in properties such as location.href 167 | // testURL: "http://localhost", 168 | 169 | // Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout" 170 | // timers: "real", 171 | 172 | // A map from regular expressions to paths to transformers 173 | // transform: undefined, 174 | 175 | // An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation 176 | // transformIgnorePatterns: [ 177 | // "/node_modules/" 178 | // ], 179 | 180 | // An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them 181 | // unmockedModulePathPatterns: undefined, 182 | 183 | // Indicates whether each individual test should be reported during the run 184 | verbose: false, 185 | 186 | // An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode 187 | // watchPathIgnorePatterns: [], 188 | 189 | // Whether to use watchman for file crawling 190 | // watchman: true, 191 | }; 192 | -------------------------------------------------------------------------------- /jest_config/test-teardown-globals.cjs: -------------------------------------------------------------------------------- 1 | // Forgive me for this, maybe it's time to rewrite the unit tests. 2 | module.exports = () => { 3 | process.exit(0) 4 | }; -------------------------------------------------------------------------------- /jsdoc.conf.json: -------------------------------------------------------------------------------- 1 | { 2 | "tags": { 3 | "allowUnknownTags": true, 4 | "dictionaries": ["jsdoc","closure"] 5 | }, 6 | "source": { 7 | "include": ["dist/src"], 8 | "includePattern": ".+\\.js(doc|x)?$", 9 | "excludePattern": "(^|\\/|\\\\)_" 10 | }, 11 | "plugins": [ 12 | "plugins/markdown" 13 | ], 14 | "templates": { 15 | "cleverLinks": true, 16 | "monospaceLinks": true 17 | }, 18 | "opts": { 19 | "destination": "docs", 20 | "recurse": true, 21 | "readme": "README.md" 22 | } 23 | } -------------------------------------------------------------------------------- /migrations/development/20201011041344-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('user', 'api_key', { type: 'string', length: 170, unique: true }) 20 | .then(() => { 21 | return db.addColumn('match', 'is_pug', { type: 'boolean', defaultValue: false }) 22 | }); 23 | }; 24 | 25 | exports.down = function(db, callback) { 26 | return db.removeColumn('user', 'api_key') 27 | .then(() => { 28 | return db.removeColumn('match', 'is_pug'); 29 | }); 30 | }; 31 | 32 | exports._meta = { 33 | "version": 2 34 | }; 35 | -------------------------------------------------------------------------------- /migrations/development/20201017154717-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_cvar_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('match_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 3 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/development/20201017172331-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'kast', { type: 'int', length: 5 }) 20 | .then(() => { 21 | return db.addColumn('player_stats', 'contribution_score', { type: 'int', length: 5 }); 22 | }); 23 | 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('player_stats', 'kast') 28 | .then(() => { 29 | return db.removeColumn('player_stats', 'contribution_score'); 30 | }); 31 | }; 32 | 33 | exports._meta = { 34 | "version": 4 35 | }; 36 | -------------------------------------------------------------------------------- /migrations/development/20201017183917-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('season_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | season_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'season_id_season_cvar_fk', 25 | table: 'season', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('season_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 5 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/development/20201024182100-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'flag', { type: 'string', length: 4 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('game_server', 'flag'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 6 28 | }; -------------------------------------------------------------------------------- /migrations/development/20201026130830-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'captain', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'captain'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 7 28 | }; -------------------------------------------------------------------------------- /migrations/development/20201117134259-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'players_per_team', { type: 'int', defaultValue: 5, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'players_per_team'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 8 28 | }; -------------------------------------------------------------------------------- /migrations/development/20201118184033-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'winner', { type: 'boolean', defaultValue: 0, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'winner'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 9 28 | }; -------------------------------------------------------------------------------- /migrations/development/20210107194928-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'gotv_port', { type: 'int', defaultValue: null }) 20 | .then(() => { 21 | return db.createTable('veto_side', { 22 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 23 | veto_id: { 24 | type: 'int', 25 | foreignKey: { 26 | name: 'veto_id_veto_side_fk', 27 | table: 'veto', 28 | rules: { 29 | onDelete: 'CASCADE', 30 | onUpdate: 'RESTRICT' 31 | }, 32 | mapping: 'id' 33 | }, 34 | length: 11, 35 | notNull: false 36 | }, 37 | match_id: { 38 | type: 'int', 39 | foreignKey: { 40 | name: 'match_id_veto_side_fk', 41 | table: 'match', 42 | rules: { 43 | onDelete: 'CASCADE', 44 | onUpdate: 'RESTRICT' 45 | }, 46 | mapping: 'id' 47 | }, 48 | length: 11, 49 | notNull: false 50 | }, 51 | team_name: { type: 'string', length: 64, notNull: true }, 52 | map: { type: 'string', length: 32, notNull: true }, 53 | side: { type: 'string', length: 10, notNull: true }, 54 | }); 55 | }); 56 | }; 57 | 58 | exports.down = function(db, callback) { 59 | return db.removeColumn('game_server', 'gotv_port') 60 | .then(() => {return db.dropTable('veto_side')}); 61 | }; 62 | 63 | exports._meta = { 64 | "version": 10 65 | }; -------------------------------------------------------------------------------- /migrations/development/20210115022423-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'mvp', { type: 'int', defaultValue: null }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'mvp'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 11 28 | }; -------------------------------------------------------------------------------- /migrations/development/20210123062442-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'min_spectators_to_ready', { type: 'int', defaultValue: 0 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'min_spectators_to_ready'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 12 28 | }; -------------------------------------------------------------------------------- /migrations/development/20210201015955-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('map_list', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | user_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'user_id_map_list_fk', 25 | table: 'user', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | map_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 36 | map_display_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 37 | enabled: { type: 'boolean', defaultValue: true, notNull: true}, 38 | inserted_at: { type: 'datetime', defaultValue: new String('now()'), notNull: true }, 39 | }); 40 | }; 41 | 42 | exports.down = function(db, callback) { 43 | return db.dropTable('map_list'); 44 | }; 45 | 46 | exports._meta = { 47 | "version": 14 48 | }; -------------------------------------------------------------------------------- /migrations/development/20211125150429-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE player_stats ADD COLUMN team_name varchar(64) AFTER mvp;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'team_name'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 15 28 | }; 29 | -------------------------------------------------------------------------------- /migrations/development/20220211220305-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE match_spectator ADD COLUMN spectator_name varchar(40) AFTER auth;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match_spectator', 'spectator_name'); 24 | }; 25 | exports._meta = { 26 | "version": 16 27 | }; 28 | -------------------------------------------------------------------------------- /migrations/development/20220217155106-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_pause', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_pause_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | pause_type: { type: 'string', length: 10 }, 36 | team_paused: { type: 'string', length: 40 }, 37 | paused: {type: 'boolean', notNull: false, default: true } 38 | }); 39 | }; 40 | 41 | exports.down = function(db, callback) { 42 | return db.dropTable('match_pause'); 43 | }; 44 | exports._meta = { 45 | "version": 17 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/development/20220224150005-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE user ADD COLUMN password varchar(170) AFTER api_key;') 20 | .then(() => {return db.runSql('ALTER TABLE user ADD COLUMN username varchar(170) UNIQUE AFTER password;');}); 21 | }; 22 | 23 | exports.down = function(db, callback) { 24 | return db.removeColumn('user', 'password') 25 | .then(() => {return db.removeColumn('user', 'username');}); 26 | }; 27 | exports._meta = { 28 | "version": 18 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/development/20220325155055-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE season ADD COLUMN is_challonge boolean AFTER end_date;') 20 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_svg VARCHAR(256) AFTER is_challonge;');}) 21 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_url VARCHAR(256) AFTER challonge_svg;');}) 22 | .then(() => {return db.runSql('ALTER TABLE team ADD COLUMN challonge_team_id INT AFTER public_team;');}) 23 | .then(() => {return db.addColumn('user', 'challonge_api_key', { type: 'string', length: 170, unique: true });}); 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('season', 'is_challonge') 28 | .then(() => {return db.removeColumn('season', 'challonge_svg');}) 29 | .then(() => {return db.removeColumn('season', 'challonge_url');}) 30 | .then(() => {return db.removeColumn('team', 'challonge_team_id');}) 31 | .then(() => {return db.removeColumn('user', 'challonge_api_key');}); 32 | }; 33 | exports._meta = { 34 | "version": 19 35 | }; -------------------------------------------------------------------------------- /migrations/development/20220713153034-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'coach', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'coach'); 24 | }; 25 | exports._meta = { 26 | "version": 20 27 | }; -------------------------------------------------------------------------------- /migrations/development/20220907171148-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'map_sides', { type: 'string', length: 75, notNull: false }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'map_sides'); 24 | }; 25 | exports._meta = { 26 | "version": 21 27 | }; -------------------------------------------------------------------------------- /migrations/development/20220908135836-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.runSql( 19 | "CREATE TABLE player_stat_extras (" + 20 | "id int(11) NOT NULL AUTO_INCREMENT," + 21 | "player_steam_id varchar(17) NOT NULL," + 22 | "player_name varchar(75) NOT NULL," + 23 | "player_side varchar(5) NOT NULL," + 24 | "map_id int(11)," + 25 | "match_id int(11)," + 26 | "team_id int(11)," + 27 | "round_number int(11) NOT NULL," + 28 | "round_time int(11) NOT NULL," + 29 | "attacker_steam_id varchar(17) DEFAULT NULL," + 30 | "attacker_name varchar(75) DEFAULT NULL," + 31 | "attacker_side varchar(5) DEFAULT NULL," + 32 | "weapon varchar(15) NOT NULL," + 33 | "bomb tinyint(1) NOT NULL DEFAULT 0," + 34 | "headshot tinyint(1) NOT NULL DEFAULT 0," + 35 | "thru_smoke tinyint(1) NOT NULL DEFAULT 0," + 36 | "attacker_blind tinyint(1) NOT NULL DEFAULT 0," + 37 | "no_scope tinyint(1) NOT NULL DEFAULT 0," + 38 | "suicide tinyint(1) NOT NULL DEFAULT 0," + 39 | "friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 40 | "assister_steam_id varchar(17) DEFAULT NULL," + 41 | "assister_name varchar(75) DEFAULT NULL," + 42 | "assister_side varchar(5) DEFAULT NULL," + 43 | "assist_friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 44 | "flash_assist tinyint(1) NOT NULL DEFAULT 0," + 45 | "PRIMARY KEY (id)," + 46 | "KEY map_id_extras_fk (map_id)," + 47 | "KEY match_id_extras_fk (match_id)," + 48 | "KEY team_id_extras_fk (team_id)," + 49 | "CONSTRAINT map_id_extras_fk FOREIGN KEY (map_id) REFERENCES map_stats (id) ON DELETE SET NULL," + 50 | "CONSTRAINT match_id_extras_fk FOREIGN KEY (match_id) REFERENCES `match` (id) ON DELETE SET NULL," + 51 | "CONSTRAINT team_id_extras_fk FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE SET NULL," + 52 | "INDEX player_steam_id_idx(player_steam_id)," + 53 | "INDEX attacker_steam_id_idx(attacker_steam_id)" + 54 | ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" 55 | ); 56 | }; 57 | 58 | exports.down = function (db) { 59 | return db.dropTable("player_stat_extras"); 60 | }; 61 | 62 | exports._meta = { 63 | version: 22 64 | }; 65 | -------------------------------------------------------------------------------- /migrations/development/20230615140704-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.createTable("match_bomb_plants", { 19 | id: { type: "int", primaryKey: true, autoIncrement: true, length: 11 }, 20 | match_id: { 21 | type: "int", 22 | foreignKey: { 23 | name: "match_id_bomb_plants_fk", 24 | table: "match", 25 | rules: { 26 | onDelete: "CASCADE", 27 | onUpdate: "RESTRICT" 28 | }, 29 | mapping: "id" 30 | }, 31 | length: 11, 32 | notNull: false 33 | }, 34 | map_id: { 35 | type: "int", 36 | foreignKey: { 37 | name: "map_id_bomb_plants_fk", 38 | table: "map_stats", 39 | rules: { 40 | onDelete: "CASCADE", 41 | onUpdate: "RESTRICT" 42 | }, 43 | mapping: "id" 44 | }, 45 | length: 11, 46 | notNull: false 47 | }, 48 | player_stats_id: { 49 | type: "int", 50 | foreignKey: { 51 | name: "player_stats_id_bomb_plants_fk", 52 | table: "player_stats", 53 | rules: { 54 | onDelete: "CASCADE", 55 | onUpdate: "RESTRICT" 56 | }, 57 | mapping: "id" 58 | }, 59 | length: 11, 60 | notNull: false 61 | }, 62 | round_number: { type: "int", length: 11, notNull: true }, 63 | round_time: { type: "int", length: 11, notNull: true }, 64 | site: { type: "string", length: 10, notNull: true }, 65 | defused: { type: "boolean", notNull: false }, 66 | bomb_time_remaining: { type: "int", length: 11, notNull: false } 67 | }); 68 | }; 69 | 70 | exports.down = function (db) { 71 | return db.dropTable("match_bomb_plants"); 72 | }; 73 | 74 | exports._meta = { 75 | version: 23 76 | }; 77 | -------------------------------------------------------------------------------- /migrations/development/20230625215254-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `map_stats` ADD COLUMN round_restored tinyint(1) DEFAULT 0 AFTER end_time;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("map_stats", "round_restored"); 26 | }; 27 | exports._meta = { 28 | version: 24 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/development/20230626223210-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `match` ADD COLUMN wingman tinyint(1) DEFAULT 0 AFTER map_sides;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("match", "wingman"); 26 | }; 27 | exports._meta = { 28 | version: 25 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/development/20230630204451-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.addColumn("match_bomb_plants", "bomb_time_remaining", { 20 | type: "int", 21 | length: 10, 22 | notNull: true, 23 | defaultValue: 0 24 | }); 25 | }; 26 | 27 | exports.down = function (db, callback) { 28 | return db.removeColumn("match_bomb_plants", "bomb_time_remaining"); 29 | }; 30 | exports._meta = { 31 | version: 27 32 | }; 33 | -------------------------------------------------------------------------------- /migrations/development/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"commonjs" 3 | } -------------------------------------------------------------------------------- /migrations/production/20201011041344-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('user', 'api_key', { type: 'string', length: 170, unique: true }) 20 | .then(() => { 21 | return db.addColumn('match', 'is_pug', { type: 'boolean', defaultValue: false }) 22 | }); 23 | }; 24 | 25 | exports.down = function(db, callback) { 26 | return db.removeColumn('user', 'api_key') 27 | .then(() => { 28 | return db.removeColumn('match', 'is_pug'); 29 | }); 30 | }; 31 | 32 | exports._meta = { 33 | "version": 2 34 | }; 35 | -------------------------------------------------------------------------------- /migrations/production/20201017154717-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_cvar_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('match_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 3 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/production/20201017172331-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'kast', { type: 'int', length: 5 }) 20 | .then(() => { 21 | return db.addColumn('player_stats', 'contribution_score', { type: 'int', length: 5 }); 22 | }); 23 | 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('player_stats', 'kast') 28 | .then(() => { 29 | return db.removeColumn('player_stats', 'contribution_score'); 30 | }); 31 | }; 32 | 33 | exports._meta = { 34 | "version": 4 35 | }; 36 | -------------------------------------------------------------------------------- /migrations/production/20201017183917-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('season_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | season_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'season_id_season_cvar_fk', 25 | table: 'season', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('season_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 5 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/production/20201024182100-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'flag', { type: 'string', length: 4 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('game_server', 'flag'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 6 28 | }; -------------------------------------------------------------------------------- /migrations/production/20201026130830-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'captain', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'captain'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 7 28 | }; -------------------------------------------------------------------------------- /migrations/production/20201117134259-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'players_per_team', { type: 'int', defaultValue: 5, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'players_per_team'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 8 28 | }; -------------------------------------------------------------------------------- /migrations/production/20201118184033-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'winner', { type: 'boolean', defaultValue: 0, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'winner'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 9 28 | }; -------------------------------------------------------------------------------- /migrations/production/20210107194928-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'gotv_port', { type: 'int', defaultValue: null }) 20 | .then(() => { 21 | return db.createTable('veto_side', { 22 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 23 | veto_id: { 24 | type: 'int', 25 | foreignKey: { 26 | name: 'veto_id_veto_side_fk', 27 | table: 'veto', 28 | rules: { 29 | onDelete: 'CASCADE', 30 | onUpdate: 'RESTRICT' 31 | }, 32 | mapping: 'id' 33 | }, 34 | length: 11, 35 | notNull: false 36 | }, 37 | match_id: { 38 | type: 'int', 39 | foreignKey: { 40 | name: 'match_id_veto_side_fk', 41 | table: 'match', 42 | rules: { 43 | onDelete: 'CASCADE', 44 | onUpdate: 'RESTRICT' 45 | }, 46 | mapping: 'id' 47 | }, 48 | length: 11, 49 | notNull: false 50 | }, 51 | team_name: { type: 'string', length: 64, notNull: true }, 52 | map: { type: 'string', length: 32, notNull: true }, 53 | side: { type: 'string', length: 10, notNull: true }, 54 | }); 55 | }); 56 | }; 57 | 58 | exports.down = function(db, callback) { 59 | return db.removeColumn('game_server', 'gotv_port') 60 | .then(() => {return db.dropTable('veto_side')}); 61 | }; 62 | 63 | exports._meta = { 64 | "version": 10 65 | }; -------------------------------------------------------------------------------- /migrations/production/20210115022423-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'mvp', { type: 'int', defaultValue: null }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'mvp'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 11 28 | }; -------------------------------------------------------------------------------- /migrations/production/20210123062442-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'min_spectators_to_ready', { type: 'int', defaultValue: 0 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'min_spectators_to_ready'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 12 28 | }; -------------------------------------------------------------------------------- /migrations/production/20210201015955-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('map_list', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | user_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'user_id_map_list_fk', 25 | table: 'user', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | map_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 36 | map_display_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 37 | enabled: { type: 'boolean', defaultValue: true, notNull: true}, 38 | inserted_at: { type: 'datetime', defaultValue: new String('now()'), notNull: true }, 39 | }); 40 | }; 41 | 42 | exports.down = function(db, callback) { 43 | return db.dropTable('map_list'); 44 | }; 45 | 46 | exports._meta = { 47 | "version": 14 48 | }; -------------------------------------------------------------------------------- /migrations/production/20211125150429-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE player_stats ADD COLUMN team_name varchar(64) AFTER mvp;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'team_name'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 15 28 | }; 29 | -------------------------------------------------------------------------------- /migrations/production/20220211220305-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE match_spectator ADD COLUMN spectator_name varchar(40) AFTER auth;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match_spectator', 'spectator_name'); 24 | }; 25 | exports._meta = { 26 | "version": 16 27 | }; 28 | -------------------------------------------------------------------------------- /migrations/production/20220217155106-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_pause', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_pause_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | pause_type: { type: 'string', length: 10 }, 36 | team_paused: { type: 'string', length: 40 }, 37 | paused: {type: 'boolean', notNull: false, default: true } 38 | }); 39 | }; 40 | 41 | exports.down = function(db, callback) { 42 | return db.dropTable('match_pause'); 43 | }; 44 | exports._meta = { 45 | "version": 17 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/production/20220224150005-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE user ADD COLUMN password varchar(170) AFTER api_key;') 20 | .then(() => {return db.runSql('ALTER TABLE user ADD COLUMN username varchar(170) UNIQUE AFTER password;');}); 21 | }; 22 | 23 | exports.down = function(db, callback) { 24 | return db.removeColumn('user', 'password') 25 | .then(() => {return db.removeColumn('user', 'username');}); 26 | }; 27 | exports._meta = { 28 | "version": 18 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/production/20220325155055-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE season ADD COLUMN is_challonge boolean AFTER end_date;') 20 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_svg VARCHAR(256) AFTER is_challonge;');}) 21 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_url VARCHAR(256) AFTER challonge_svg;');}) 22 | .then(() => {return db.runSql('ALTER TABLE team ADD COLUMN challonge_team_id INT AFTER public_team;');}) 23 | .then(() => {return db.addColumn('user', 'challonge_api_key', { type: 'string', length: 170, unique: true });}); 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('season', 'is_challonge') 28 | .then(() => {return db.removeColumn('season', 'challonge_svg');}) 29 | .then(() => {return db.removeColumn('season', 'challonge_url');}) 30 | .then(() => {return db.removeColumn('team', 'challonge_team_id');}) 31 | .then(() => {return db.removeColumn('user', 'challonge_api_key');}); 32 | }; 33 | exports._meta = { 34 | "version": 19 35 | }; -------------------------------------------------------------------------------- /migrations/production/20220713153034-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'coach', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'coach'); 24 | }; 25 | exports._meta = { 26 | "version": 20 27 | }; -------------------------------------------------------------------------------- /migrations/production/20220907171148-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'map_sides', { type: 'string', length: 75, notNull: false }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'map_sides'); 24 | }; 25 | exports._meta = { 26 | "version": 21 27 | }; -------------------------------------------------------------------------------- /migrations/production/20220908135836-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.runSql( 19 | "CREATE TABLE player_stat_extras (" + 20 | "id int(11) NOT NULL AUTO_INCREMENT," + 21 | "player_steam_id varchar(17) NOT NULL," + 22 | "player_name varchar(75) NOT NULL," + 23 | "player_side varchar(5) NOT NULL," + 24 | "map_id int(11)," + 25 | "match_id int(11)," + 26 | "team_id int(11)," + 27 | "round_number int(11) NOT NULL," + 28 | "round_time int(11) NOT NULL," + 29 | "attacker_steam_id varchar(17) DEFAULT NULL," + 30 | "attacker_name varchar(75) DEFAULT NULL," + 31 | "attacker_side varchar(5) DEFAULT NULL," + 32 | "weapon varchar(15) NOT NULL," + 33 | "bomb tinyint(1) NOT NULL DEFAULT 0," + 34 | "headshot tinyint(1) NOT NULL DEFAULT 0," + 35 | "thru_smoke tinyint(1) NOT NULL DEFAULT 0," + 36 | "attacker_blind tinyint(1) NOT NULL DEFAULT 0," + 37 | "no_scope tinyint(1) NOT NULL DEFAULT 0," + 38 | "suicide tinyint(1) NOT NULL DEFAULT 0," + 39 | "friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 40 | "assister_steam_id varchar(17) DEFAULT NULL," + 41 | "assister_name varchar(75) DEFAULT NULL," + 42 | "assister_side varchar(5) DEFAULT NULL," + 43 | "assist_friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 44 | "flash_assist tinyint(1) NOT NULL DEFAULT 0," + 45 | "PRIMARY KEY (id)," + 46 | "KEY map_id_extras_fk (map_id)," + 47 | "KEY match_id_extras_fk (match_id)," + 48 | "KEY team_id_extras_fk (team_id)," + 49 | "CONSTRAINT map_id_extras_fk FOREIGN KEY (map_id) REFERENCES map_stats (id) ON DELETE SET NULL," + 50 | "CONSTRAINT match_id_extras_fk FOREIGN KEY (match_id) REFERENCES `match` (id) ON DELETE SET NULL," + 51 | "CONSTRAINT team_id_extras_fk FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE SET NULL," + 52 | "INDEX player_steam_id_idx(player_steam_id)," + 53 | "INDEX attacker_steam_id_idx(attacker_steam_id)" + 54 | ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" 55 | ); 56 | }; 57 | 58 | exports.down = function (db) { 59 | return db.dropTable("player_stat_extras"); 60 | }; 61 | 62 | exports._meta = { 63 | version: 22 64 | }; 65 | -------------------------------------------------------------------------------- /migrations/production/20230615140704-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.createTable("match_bomb_plants", { 19 | id: { type: "int", primaryKey: true, autoIncrement: true, length: 11 }, 20 | match_id: { 21 | type: "int", 22 | foreignKey: { 23 | name: "match_id_bomb_plants_fk", 24 | table: "match", 25 | rules: { 26 | onDelete: "CASCADE", 27 | onUpdate: "RESTRICT" 28 | }, 29 | mapping: "id" 30 | }, 31 | length: 11, 32 | notNull: false 33 | }, 34 | map_id: { 35 | type: "int", 36 | foreignKey: { 37 | name: "map_id_bomb_plants_fk", 38 | table: "map_stats", 39 | rules: { 40 | onDelete: "CASCADE", 41 | onUpdate: "RESTRICT" 42 | }, 43 | mapping: "id" 44 | }, 45 | length: 11, 46 | notNull: false 47 | }, 48 | player_stats_id: { 49 | type: "int", 50 | foreignKey: { 51 | name: "player_stats_id_bomb_plants_fk", 52 | table: "player_stats", 53 | rules: { 54 | onDelete: "CASCADE", 55 | onUpdate: "RESTRICT" 56 | }, 57 | mapping: "id" 58 | }, 59 | length: 11, 60 | notNull: false 61 | }, 62 | round_number: { type: "int", length: 11, notNull: true }, 63 | round_time: { type: "int", length: 11, notNull: true }, 64 | site: { type: "string", length: 10, notNull: true }, 65 | defused: { type: "boolean", notNull: false } 66 | }); 67 | }; 68 | 69 | exports.down = function (db) { 70 | return db.dropTable("match_bomb_plants"); 71 | }; 72 | 73 | exports._meta = { 74 | version: 23 75 | }; 76 | -------------------------------------------------------------------------------- /migrations/production/20230625215254-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `map_stats` ADD COLUMN round_restored tinyint(1) DEFAULT 0 AFTER end_time;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("map_stats", "round_restored"); 26 | }; 27 | exports._meta = { 28 | version: 24 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/production/20230626223210-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `match` ADD COLUMN wingman tinyint(1) DEFAULT 0 AFTER map_sides;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("match", "wingman"); 26 | }; 27 | exports._meta = { 28 | version: 25 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/production/20230630204451-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.addColumn("match_bomb_plants", "bomb_time_remaining", { 20 | type: "int", 21 | length: 10, 22 | notNull: true, 23 | defaultValue: 0 24 | }); 25 | }; 26 | 27 | exports.down = function (db, callback) { 28 | return db.removeColumn("match_bomb_plants", "bomb_time_remaining"); 29 | }; 30 | exports._meta = { 31 | version: 27 32 | }; 33 | -------------------------------------------------------------------------------- /migrations/production/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"commonjs" 3 | } -------------------------------------------------------------------------------- /migrations/test/20201011041344-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('user', 'api_key', { type: 'string', length: 170, unique: true }) 20 | .then(() => { 21 | return db.addColumn('match', 'is_pug', { type: 'boolean', defaultValue: false }) 22 | }); 23 | }; 24 | 25 | exports.down = function(db, callback) { 26 | return db.removeColumn('user', 'api_key') 27 | .then(() => { 28 | return db.removeColumn('match', 'is_pug'); 29 | }); 30 | }; 31 | 32 | exports._meta = { 33 | "version": 2 34 | }; 35 | -------------------------------------------------------------------------------- /migrations/test/20201017154717-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_cvar_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('match_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 3 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/test/20201017172331-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'kast', { type: 'int', length: 5 }) 20 | .then(() => { 21 | return db.addColumn('player_stats', 'contribution_score', { type: 'int', length: 5 }); 22 | }); 23 | 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('player_stats', 'kast') 28 | .then(() => { 29 | return db.removeColumn('player_stats', 'contribution_score'); 30 | }); 31 | }; 32 | 33 | exports._meta = { 34 | "version": 4 35 | }; 36 | -------------------------------------------------------------------------------- /migrations/test/20201017183917-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('season_cvar', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | season_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'season_id_season_cvar_fk', 25 | table: 'season', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | cvar_name: { type: 'string', length: 150 }, 36 | cvar_value: { type: 'string', length: 150 } 37 | }); 38 | }; 39 | 40 | exports.down = function(db, callback) { 41 | return db.dropTable('season_cvar'); 42 | }; 43 | 44 | exports._meta = { 45 | "version": 5 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/test/20201024182100-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'flag', { type: 'string', length: 4 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('game_server', 'flag'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 6 28 | }; -------------------------------------------------------------------------------- /migrations/test/20201026130830-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'captain', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'captain'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 7 28 | }; -------------------------------------------------------------------------------- /migrations/test/20201117134259-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'players_per_team', { type: 'int', defaultValue: 5, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'players_per_team'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 8 28 | }; -------------------------------------------------------------------------------- /migrations/test/20201118184033-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'winner', { type: 'boolean', defaultValue: 0, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'winner'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 9 28 | }; -------------------------------------------------------------------------------- /migrations/test/20210107194928-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('game_server', 'gotv_port', { type: 'int', defaultValue: null }) 20 | .then(() => { 21 | return db.createTable('veto_side', { 22 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 23 | veto_id: { 24 | type: 'int', 25 | foreignKey: { 26 | name: 'veto_id_veto_side_fk', 27 | table: 'veto', 28 | rules: { 29 | onDelete: 'CASCADE', 30 | onUpdate: 'RESTRICT' 31 | }, 32 | mapping: 'id' 33 | }, 34 | length: 11, 35 | notNull: false 36 | }, 37 | match_id: { 38 | type: 'int', 39 | foreignKey: { 40 | name: 'match_id_veto_side_fk', 41 | table: 'match', 42 | rules: { 43 | onDelete: 'CASCADE', 44 | onUpdate: 'RESTRICT' 45 | }, 46 | mapping: 'id' 47 | }, 48 | length: 11, 49 | notNull: false 50 | }, 51 | team_name: { type: 'string', length: 64, notNull: true }, 52 | map: { type: 'string', length: 32, notNull: true }, 53 | side: { type: 'string', length: 10, notNull: true }, 54 | }); 55 | }); 56 | }; 57 | 58 | exports.down = function(db, callback) { 59 | return db.removeColumn('game_server', 'gotv_port') 60 | .then(() => {return db.dropTable('veto_side')}); 61 | }; 62 | 63 | exports._meta = { 64 | "version": 10 65 | }; -------------------------------------------------------------------------------- /migrations/test/20210115022423-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('player_stats', 'mvp', { type: 'int', defaultValue: null }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'mvp'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 11 28 | }; -------------------------------------------------------------------------------- /migrations/test/20210123062442-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'min_spectators_to_ready', { type: 'int', defaultValue: 0 }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'min_spectators_to_ready'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 12 28 | }; -------------------------------------------------------------------------------- /migrations/test/20210201015955-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('map_list', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | user_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'user_id_map_list_fk', 25 | table: 'user', 26 | rules: { 27 | onDelete: 'SET NULL', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | map_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 36 | map_display_name: { type: 'string', length: 32, notNull: true, defaultValue: ''}, 37 | enabled: { type: 'boolean', defaultValue: true, notNull: true}, 38 | inserted_at: { type: 'datetime', defaultValue: new String('now()'), notNull: true }, 39 | }); 40 | }; 41 | 42 | exports.down = function(db, callback) { 43 | return db.dropTable('map_list'); 44 | }; 45 | 46 | exports._meta = { 47 | "version": 14 48 | }; -------------------------------------------------------------------------------- /migrations/test/20211125150429-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE player_stats ADD COLUMN team_name varchar(64) AFTER mvp;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('player_stats', 'team_name'); 24 | }; 25 | 26 | exports._meta = { 27 | "version": 15 28 | }; 29 | -------------------------------------------------------------------------------- /migrations/test/20220211220305-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE match_spectator ADD COLUMN spectator_name varchar(40) AFTER auth;'); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match_spectator', 'spectator_name'); 24 | }; 25 | exports._meta = { 26 | "version": 16 27 | }; 28 | -------------------------------------------------------------------------------- /migrations/test/20220217155106-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.createTable('match_pause', { 20 | id: { type: 'int', primaryKey: true, autoIncrement: true, length: 11 }, 21 | match_id: { 22 | type: 'int', 23 | foreignKey: { 24 | name: 'match_id_match_pause_fk', 25 | table: 'match', 26 | rules: { 27 | onDelete: 'CASCADE', 28 | onUpdate: 'RESTRICT' 29 | }, 30 | mapping: 'id' 31 | }, 32 | length: 11, 33 | notNull: false 34 | }, 35 | pause_type: { type: 'string', length: 10 }, 36 | team_paused: { type: 'string', length: 40 }, 37 | paused: {type: 'boolean', notNull: false, default: true } 38 | }); 39 | }; 40 | 41 | exports.down = function(db, callback) { 42 | return db.dropTable('match_pause'); 43 | }; 44 | exports._meta = { 45 | "version": 17 46 | }; 47 | -------------------------------------------------------------------------------- /migrations/test/20220224150005-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE user ADD COLUMN password varchar(170) AFTER api_key;') 20 | .then(() => {return db.runSql('ALTER TABLE user ADD COLUMN username varchar(170) UNIQUE AFTER password;');}); 21 | }; 22 | 23 | exports.down = function(db, callback) { 24 | return db.removeColumn('user', 'password') 25 | .then(() => {return db.removeColumn('user', 'username');}); 26 | }; 27 | exports._meta = { 28 | "version": 18 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/test/20220325155055-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.runSql('ALTER TABLE season ADD COLUMN is_challonge boolean AFTER end_date;') 20 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_svg VARCHAR(256) AFTER is_challonge;');}) 21 | .then(() => {return db.runSql('ALTER TABLE season ADD COLUMN challonge_url VARCHAR(256) AFTER challonge_svg;');}) 22 | .then(() => {return db.runSql('ALTER TABLE team ADD COLUMN challonge_team_id INT AFTER public_team;');}) 23 | .then(() => {return db.addColumn('user', 'challonge_api_key', { type: 'string', length: 170, unique: true });}); 24 | }; 25 | 26 | exports.down = function(db, callback) { 27 | return db.removeColumn('season', 'is_challonge') 28 | .then(() => {return db.removeColumn('season', 'challonge_svg');}) 29 | .then(() => {return db.removeColumn('season', 'challonge_url');}) 30 | .then(() => {return db.removeColumn('team', 'challonge_team_id');}) 31 | .then(() => {return db.removeColumn('user', 'challonge_api_key');}); 32 | }; 33 | exports._meta = { 34 | "version": 19 35 | }; -------------------------------------------------------------------------------- /migrations/test/20220713153034-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('team_auth_names', 'coach', { type: 'boolean', defaultValue: false, notNull: true }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('team_auth_names', 'coach'); 24 | }; 25 | exports._meta = { 26 | "version": 20 27 | }; -------------------------------------------------------------------------------- /migrations/test/20220907171148-get5db.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require('async'); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function(options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function(db, callback) { 19 | return db.addColumn('match', 'map_sides', { type: 'string', length: 75, notNull: false }); 20 | }; 21 | 22 | exports.down = function(db, callback) { 23 | return db.removeColumn('match', 'map_sides'); 24 | }; 25 | exports._meta = { 26 | "version": 21 27 | }; -------------------------------------------------------------------------------- /migrations/test/20220908135836-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.runSql( 19 | "CREATE TABLE player_stat_extras (" + 20 | "id int(11) NOT NULL AUTO_INCREMENT," + 21 | "player_steam_id varchar(17) NOT NULL," + 22 | "player_name varchar(75) NOT NULL," + 23 | "player_side varchar(5) NOT NULL," + 24 | "map_id int(11)," + 25 | "match_id int(11)," + 26 | "team_id int(11)," + 27 | "round_number int(11) NOT NULL," + 28 | "round_time int(11) NOT NULL," + 29 | "attacker_steam_id varchar(17) DEFAULT NULL," + 30 | "attacker_name varchar(75) DEFAULT NULL," + 31 | "attacker_side varchar(5) DEFAULT NULL," + 32 | "weapon varchar(15) NOT NULL," + 33 | "bomb tinyint(1) NOT NULL DEFAULT 0," + 34 | "headshot tinyint(1) NOT NULL DEFAULT 0," + 35 | "thru_smoke tinyint(1) NOT NULL DEFAULT 0," + 36 | "attacker_blind tinyint(1) NOT NULL DEFAULT 0," + 37 | "no_scope tinyint(1) NOT NULL DEFAULT 0," + 38 | "suicide tinyint(1) NOT NULL DEFAULT 0," + 39 | "friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 40 | "assister_steam_id varchar(17) DEFAULT NULL," + 41 | "assister_name varchar(75) DEFAULT NULL," + 42 | "assister_side varchar(5) DEFAULT NULL," + 43 | "assist_friendly_fire tinyint(1) NOT NULL DEFAULT 0," + 44 | "flash_assist tinyint(1) NOT NULL DEFAULT 0," + 45 | "PRIMARY KEY (id)," + 46 | "KEY map_id_extras_fk (map_id)," + 47 | "KEY match_id_extras_fk (match_id)," + 48 | "KEY team_id_extras_fk (team_id)," + 49 | "CONSTRAINT map_id_extras_fk FOREIGN KEY (map_id) REFERENCES map_stats (id) ON DELETE SET NULL," + 50 | "CONSTRAINT match_id_extras_fk FOREIGN KEY (match_id) REFERENCES `match` (id) ON DELETE SET NULL," + 51 | "CONSTRAINT team_id_extras_fk FOREIGN KEY (team_id) REFERENCES team (id) ON DELETE SET NULL," + 52 | "INDEX player_steam_id_idx(player_steam_id)," + 53 | "INDEX attacker_steam_id_idx(attacker_steam_id)" + 54 | ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4" 55 | ); 56 | }; 57 | 58 | exports.down = function (db) { 59 | return db.dropTable("player_stat_extras"); 60 | }; 61 | 62 | exports._meta = { 63 | version: 22 64 | }; 65 | -------------------------------------------------------------------------------- /migrations/test/20230615140704-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | 7 | /** 8 | * We receive the dbmigrate dependency from dbmigrate initially. 9 | * This enables us to not have to rely on NODE_PATH. 10 | */ 11 | exports.setup = function (options, seedLink) { 12 | dbm = options.dbmigrate; 13 | type = dbm.dataType; 14 | seed = seedLink; 15 | }; 16 | 17 | exports.up = function (db) { 18 | return db.createTable("match_bomb_plants", { 19 | id: { type: "int", primaryKey: true, autoIncrement: true, length: 11 }, 20 | match_id: { 21 | type: "int", 22 | foreignKey: { 23 | name: "match_id_bomb_plants_fk", 24 | table: "match", 25 | rules: { 26 | onDelete: "CASCADE", 27 | onUpdate: "RESTRICT" 28 | }, 29 | mapping: "id" 30 | }, 31 | length: 11, 32 | notNull: false 33 | }, 34 | map_id: { 35 | type: "int", 36 | foreignKey: { 37 | name: "map_id_bomb_plants_fk", 38 | table: "map_stats", 39 | rules: { 40 | onDelete: "CASCADE", 41 | onUpdate: "RESTRICT" 42 | }, 43 | mapping: "id" 44 | }, 45 | length: 11, 46 | notNull: false 47 | }, 48 | player_stats_id: { 49 | type: "int", 50 | foreignKey: { 51 | name: "player_stats_id_bomb_plants_fk", 52 | table: "player_stats", 53 | rules: { 54 | onDelete: "CASCADE", 55 | onUpdate: "RESTRICT" 56 | }, 57 | mapping: "id" 58 | }, 59 | length: 11, 60 | notNull: false 61 | }, 62 | round_number: { type: "int", length: 11, notNull: true }, 63 | round_time: { type: "int", length: 11, notNull: true }, 64 | site: { type: "string", length: 10, notNull: true }, 65 | defused: { type: "boolean", notNull: false } 66 | }); 67 | }; 68 | 69 | exports.down = function (db) { 70 | return db.dropTable("match_bomb_plants"); 71 | }; 72 | 73 | exports._meta = { 74 | version: 23 75 | }; 76 | -------------------------------------------------------------------------------- /migrations/test/20230625215254-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `map_stats` ADD COLUMN round_restored tinyint(1) DEFAULT 0 AFTER end_time;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("map_stats", "round_restored"); 26 | }; 27 | exports._meta = { 28 | version: 24 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/test/20230626223210-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.runSql( 20 | "ALTER TABLE `match` ADD COLUMN wingman tinyint(1) DEFAULT 0 AFTER map_sides;" 21 | ); 22 | }; 23 | 24 | exports.down = function (db, callback) { 25 | return db.removeColumn("match", "wingman"); 26 | }; 27 | exports._meta = { 28 | version: 25 29 | }; 30 | -------------------------------------------------------------------------------- /migrations/test/20230630204451-get5db.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | var dbm; 4 | var type; 5 | var seed; 6 | var async = require("async"); 7 | 8 | /** 9 | * We receive the dbmigrate dependency from dbmigrate initially. 10 | * This enables us to not have to rely on NODE_PATH. 11 | */ 12 | exports.setup = function (options, seedLink) { 13 | dbm = options.dbmigrate; 14 | type = dbm.dataType; 15 | seed = seedLink; 16 | }; 17 | 18 | exports.up = function (db, callback) { 19 | return db.addColumn("match_bomb_plants", "bomb_time_remaining", { 20 | type: "int", 21 | length: 10, 22 | notNull: true, 23 | defaultValue: 0 24 | }); 25 | }; 26 | 27 | exports.down = function (db, callback) { 28 | return db.removeColumn("match_bomb_plants", "bomb_time_remaining"); 29 | }; 30 | exports._meta = { 31 | version: 27 32 | }; 33 | -------------------------------------------------------------------------------- /migrations/test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "type":"commonjs" 3 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "g5api", 3 | "version": "2.1.0.0", 4 | "private": true, 5 | "type": "module", 6 | "licenses": [ 7 | { 8 | "type": "MIT", 9 | "url": "http://opensource.org/licenses/MIT" 10 | } 11 | ], 12 | "homepage": "https://github.com/phlexplexico/G5API/issues", 13 | "repository": { 14 | "type": "git", 15 | "url": "https://github.com/phlexplexico/G5API.git" 16 | }, 17 | "author": { 18 | "name": "Phlex Plexico", 19 | "email": "flexing@phlexplexi.co", 20 | "url": "https://phlexplexi.co" 21 | }, 22 | "engines": { 23 | "node": ">=16.17.0" 24 | }, 25 | "directories": { 26 | "docs": "./docs/", 27 | "bin": "./bin/", 28 | "routes": "./routes/", 29 | "config": "./config" 30 | }, 31 | "scripts": { 32 | "build": "tsc", 33 | "clean": "rm -rf ./dist", 34 | "start": "tsc-watch --project . --outDir ./dist --onSuccess \"nodemon ./dist/bin/www.js\"", 35 | "tsstart": "yarn build; nodemon ./dist/bin/www.js", 36 | "startprod": "pm2 start ./prodrun.json --name \"G5API\"", 37 | "restartprod": "pm2 restart G5API", 38 | "stopprod": "pm2 stop G5API; pm2 delete G5API", 39 | "doc": "tsc && jsdoc -c jsdoc.conf.json", 40 | "docclean": "rm -rf ./docs", 41 | "migrate-create-dev": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --env development --config config/development.json db:create get5dev", 42 | "migrate-create-prod": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --env production --config config/production.json db:create get5", 43 | "migrate-create-test": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --env test --config config/test.json db:create get5test", 44 | "migrate-dev-downgrade": "db-migrate --env development --config config/development.json down:development", 45 | "migrate-dev-upgrade": "db-migrate --env development --config config/development.json up:development", 46 | "migrate-prod-downgrade": "db-migrate --env production --config config/production.json down:production", 47 | "migrate-prod-upgrade": "db-migrate --env production --config config/production.json up:production", 48 | "migrate-test-downgrade": "db-migrate --env test --config config/test.json down:test", 49 | "migrate-test-upgrade": "db-migrate --env test --config config/test.json up:test", 50 | "migrate-drop-dev": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --config config/development.json db:drop get5dev", 51 | "migrate-drop-prod": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --env production --config config/production.json db:drop get5", 52 | "migrate-drop-test": "MYSQL_FLAGS=\"-CONNECT_WITH_DB\" db-migrate --env test --config config/test.json db:drop get5test", 53 | "prod": "NODE_ENV=production yarn migrate-create-prod && yarn migrate-prod-upgrade", 54 | "test": "yarn build && NODE_ENV=test && yarn test:setup-user && yarn migrate-drop-test && yarn migrate-create-test && yarn migrate-test-upgrade && yarn test:user && yarn test:gameservers && yarn test:teams && yarn test:matches && yarn test:seasons && yarn test:vetoes && yarn test:mapstats && yarn test:playerstats && yarn test:vetosides && yarn test:maplists", 55 | "test:gameservers": "yarn test:removeID && NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.gameservers.config.cjs", 56 | "test:mapstats": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.mapstats.config.cjs", 57 | "test:maplists": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.maplist.config.cjs", 58 | "test:matches": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.matches.config.cjs", 59 | "test:playerstats": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.playerstats.config.cjs", 60 | "test:removeID": "sed -i -e 's.\"steam_ids\": \"[0-9][0-9]*\".\"steam_ids\": \"super_admins,go,here\".g' ./config/test.json", 61 | "test:seasons": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.seasons.config.cjs", 62 | "test:setup-user": "export STEAMID=`grep -o -m 1 '[0-9][0-9]*' dist/src/utility/mockProfile.js` && sed -i -e \"s/\\\"super_admins,go,here\\\"/\\\"$STEAMID\\\"/g\" config/test.json", 63 | "test:teams": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.teams.config.cjs", 64 | "test:user": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.users.config.cjs", 65 | "test:vetoes": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.vetoes.config.cjs", 66 | "test:vetosides": "NODE_OPTIONS=--experimental-vm-modules jest --testTimeout=10000 --detectOpenHandles --config ./jest_config/jest.vetosides.config.cjs" 67 | }, 68 | "dependencies": { 69 | "@node-steam/id": "^1.2.0", 70 | "aes-js": "^3.1.2", 71 | "bcrypt": "^5.1.1", 72 | "compare-versions": "^6.1.0", 73 | "config": "^3.3.11", 74 | "connect-redis": "^7.1.1", 75 | "cookie-parser": "~1.4.6", 76 | "cors": "^2.8.5", 77 | "dathost-rcon-client": "^1.0.8", 78 | "db-migrate": "^0.11.13", 79 | "db-migrate-mysql": "^3.0.0", 80 | "debug": "~4.3.4", 81 | "express": "~4.21.2", 82 | "express-bearer-token": "^3.0.0", 83 | "express-rate-limit": "^7.2.0", 84 | "express-session": "^1.18.0", 85 | "helmet": "^7.1.0", 86 | "http-errors": "~2.0.0", 87 | "jszip": "^3.10.1", 88 | "morgan": "^1.10.0", 89 | "mysql2": "^3.14.0", 90 | "node-fetch": "^3.3.2", 91 | "passport": "^0.6.0", 92 | "passport-local": "^1.0.0", 93 | "passport-steam": "^1.0.18", 94 | "pm2": "^5.3.1", 95 | "randomstring": "^1.3.0", 96 | "redis": "^4.6.13", 97 | "steamapi": "^3.0.8", 98 | "swagger-jsdoc": "^6.2.8", 99 | "swagger-ui-express": "^5.0.0" 100 | }, 101 | "devDependencies": { 102 | "@types/aes-js": "^3.1.1", 103 | "@types/bcrypt": "^5.0.2", 104 | "@types/config": "^3.3.0", 105 | "@types/cookie-parser": "^1.4.8", 106 | "@types/cors": "^2.8.17", 107 | "@types/debug": "^4.1.12", 108 | "@types/express": "^4.17.17", 109 | "@types/express-session": "^1.18.1", 110 | "@types/morgan": "^1.9.9", 111 | "@types/node": "^20.2.5", 112 | "@types/passport": "^1.0.17", 113 | "@types/passport-local": "^1.0.38", 114 | "@types/passport-openidconnect": "^0.1.3", 115 | "@types/passport-steam": "^1.0.6", 116 | "@types/randomstring": "^1.3.0", 117 | "@types/steamapi": "^2.2.2", 118 | "@types/swagger-jsdoc": "^6.0.4", 119 | "@types/swagger-ui-express": "^4.1.8", 120 | "jest": "^29.7.0", 121 | "jest-ts-webcompat-resolver": "^1.0.0", 122 | "jsdoc": "^4.0.2", 123 | "nodemon": "^3.1.9", 124 | "passport-openidconnect": "^0.1.2", 125 | "redis-mock": "^0.56.3", 126 | "supertest": "^6.3.3", 127 | "ts-jest": "^29.3.0", 128 | "tsc": "^2.0.4", 129 | "tsc-watch": "^6.2.1", 130 | "typescript": "^5.8.2" 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /prodrun.json: -------------------------------------------------------------------------------- 1 | { 2 | "apps": [ 3 | { 4 | "name": "G5API", 5 | "script": "./dist/bin/www.js", 6 | "instances": 1, 7 | "exec_mode": "fork", 8 | "instance_var": "INSTANCE_ID", 9 | "env": { 10 | "NODE_ENV": "production" 11 | } 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /public/backups/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhlexPlexico/G5API/626c74b276e8425f8cf8a607703eb2f755d2aba2/public/backups/.gitkeep -------------------------------------------------------------------------------- /public/demos/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhlexPlexico/G5API/626c74b276e8425f8cf8a607703eb2f755d2aba2/public/demos/.gitkeep -------------------------------------------------------------------------------- /public/img/logos/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/PhlexPlexico/G5API/626c74b276e8425f8cf8a607703eb2f755d2aba2/public/img/logos/.gitkeep -------------------------------------------------------------------------------- /src/@types/express/index.d.ts: -------------------------------------------------------------------------------- 1 | import { User } from "../../types/User"; 2 | 3 | export { } 4 | 5 | declare global { 6 | namespace Express { 7 | export interface User { 8 | steam_id: string 9 | name: string 10 | admin: boolean | number 11 | super_admin: boolean | number 12 | id: number 13 | small_image: string 14 | medium_image: string 15 | large_image: string 16 | api_key: string 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/routes/index.ts: -------------------------------------------------------------------------------- 1 | import { Router } from "express"; 2 | var router = Router(); 3 | 4 | /** Utility class for various methods used throughout. 5 | * @const */ 6 | import Utils from "../utility/utils.js"; 7 | 8 | /* GET home page. */ 9 | router.get("/", Utils.ensureAuthenticated, function (req, res, next) { 10 | res.json({ message: "Welcome to G5API!" }); 11 | return; 12 | }); 13 | 14 | router.get("/isloggedin", function (req, res, next) { 15 | if (req.user) { 16 | res.json(req.user); 17 | } else { 18 | res.json(false); 19 | } 20 | }); 21 | 22 | export default router; 23 | -------------------------------------------------------------------------------- /src/routes/v2/backupapi.ts: -------------------------------------------------------------------------------- 1 | /** Express API router for remote backup uploads in get5. 2 | * @module routes/v2/demo 3 | * @requires express 4 | * @requires db 5 | */ 6 | 7 | /** 8 | * @swagger 9 | * resourcePath: /v2/demo 10 | * description: Express API for v2 API calls in G5API. 11 | */ 12 | 13 | /** Config to check demo uploads. 14 | * @const 15 | */ 16 | import config from "config"; 17 | 18 | import { db } from "../../services/db.js"; 19 | 20 | import { Request, Response, Router } from "express"; 21 | import Utils from "../../utility/utils.js"; 22 | import { RowDataPacket } from "mysql2"; 23 | 24 | /** 25 | * @const 26 | * Global Server Sent Emitter class for real time data. 27 | */ 28 | import { existsSync, mkdirSync, writeFile } from "fs"; 29 | 30 | /** Express module 31 | * @const 32 | */ 33 | const router: Router = Router(); 34 | 35 | /** 36 | * @swagger 37 | * 38 | * /v2/backup: 39 | * post: 40 | * description: Retrieves the backups from the game servers and stores them in the application. 41 | * produces: 42 | * - application/json 43 | * tags: 44 | * - v2 45 | * parameters: 46 | * - in: header 47 | * name: Get5-FileName 48 | * description: Name of the backup file coming from the game server. 49 | * schema: 50 | * type: string 51 | * required: true 52 | * - in: header 53 | * name: Get5-MapNumber 54 | * description: Zero-indexed map number in the series. 55 | * schema: 56 | * type: string 57 | * required: true 58 | * - in: header 59 | * name: Get5-RoundNumber 60 | * description: Zero-indexed map number in the series, if the match is not live it is -1. 61 | * schema: 62 | * type: string 63 | * required: true 64 | * - in: header 65 | * name: Authorization 66 | * description: The API key provided by the server. 67 | * schema: 68 | * type: string 69 | * required: true 70 | * - in: header 71 | * name: Get5-MatchId 72 | * description: The ID of the match. 73 | * schema: 74 | * type: string 75 | * required: true 76 | * requestBody: 77 | * content: 78 | * application/octet-stream: 79 | * schema: 80 | * format: binary 81 | * responses: 82 | * 200: 83 | * $ref: '#/components/responses/Success' 84 | * 401: 85 | * $ref: '#/components/responses/Unauthorized' 86 | * 403: 87 | * $ref: '#/components/responses/Unauthorized' 88 | * 404: 89 | * $ref: '#/components/responses/NotFound' 90 | */ 91 | router.post("/", async (req: Request, res: Response) => { 92 | try { 93 | const apiKey: string | undefined = req.get("Authorization"); 94 | const matchId: string | undefined = req.get("Get5-MatchId"); 95 | const mapNumber: string | undefined = req.get("Get5-MapNumber"); 96 | const roundNumber: string | undefined = req.get("Get5-RoundNumber"); 97 | // Check that the values have made it across. 98 | if (!apiKey || !matchId || !mapNumber || !roundNumber) { 99 | res.status(401).send({ 100 | message: "API key, Match ID, Map Number, or Round Number not provided." 101 | }); 102 | return; 103 | } 104 | // Check if our API key is correct. 105 | const matchApiCheck: number = await Utils.checkApiKey(apiKey, matchId); 106 | if (matchApiCheck == 1 || matchApiCheck == 2) { 107 | res.status(401).send({ 108 | message: "Invalid API key has been given." 109 | }); 110 | return; 111 | } 112 | if (!existsSync(`public/backups/${matchId}/`)) 113 | mkdirSync(`public/backups/${matchId}/`, { recursive: true }); 114 | 115 | writeFile( 116 | `public/backups/${matchId}/get5_backup_match${matchId}_map${mapNumber}_round${roundNumber}.cfg`, 117 | req.body, 118 | function (err) { 119 | if (err) { 120 | console.error(err); 121 | throw err; 122 | } 123 | } 124 | ); 125 | res.status(200).send({ message: "Success" }); 126 | } catch (error) { 127 | console.error(error); 128 | res.status(500).send({ message: error }); 129 | return; 130 | } 131 | }); 132 | export { router }; 133 | -------------------------------------------------------------------------------- /src/routes/v2/demoapi.ts: -------------------------------------------------------------------------------- 1 | /** Express API router for demo uploads in get5. 2 | * @module routes/v2/demo 3 | * @requires express 4 | * @requires db 5 | */ 6 | 7 | /** 8 | * @swagger 9 | * resourcePath: /v2/demo 10 | * description: Express API for v2 API calls in G5API. 11 | */ 12 | 13 | /** ZIP files. 14 | * @const 15 | */ 16 | import JSZip from "jszip"; 17 | 18 | /** Required to save files. 19 | * @const 20 | */ 21 | import { existsSync, mkdirSync, writeFile } from "fs"; 22 | 23 | /** Config to check demo uploads. 24 | * @const 25 | */ 26 | import config from "config"; 27 | 28 | import { db } from "../../services/db.js"; 29 | 30 | import { Request, Response, Router } from "express"; 31 | import Utils from "../../utility/utils.js"; 32 | import { RowDataPacket } from "mysql2"; 33 | 34 | /** 35 | * @const 36 | * Global Server Sent Emitter class for real time data. 37 | */ 38 | import GlobalEmitter from "../../utility/emitter.js"; 39 | 40 | /** Express module 41 | * @const 42 | */ 43 | const router: Router = Router(); 44 | 45 | /** 46 | * @swagger 47 | * 48 | * /v2/demo: 49 | * post: 50 | * description: Retrieves the demos from the given match and map, zips and stores them on the server. 51 | * produces: 52 | * - application/json 53 | * tags: 54 | * - v2 55 | * parameters: 56 | * - in: header 57 | * name: Get5-FileName 58 | * description: Name of the file as defined by get5_demo_name_format 59 | * schema: 60 | * type: string 61 | * required: true 62 | * - in: header 63 | * name: Get5-MapNumber 64 | * description: Zero-indexed map number in the series. 65 | * schema: 66 | * type: string 67 | * required: true 68 | * - in: header 69 | * name: Authorization 70 | * description: The API key provided by the server. 71 | * schema: 72 | * type: string 73 | * required: true 74 | * - in: header 75 | * name: Get5-MatchId 76 | * description: The ID of the match. 77 | * schema: 78 | * type: string 79 | * required: true 80 | * requestBody: 81 | * content: 82 | * application/octet-stream: 83 | * schema: 84 | * format: binary 85 | * responses: 86 | * 200: 87 | * $ref: '#/components/responses/Success' 88 | * 401: 89 | * $ref: '#/components/responses/Unauthorized' 90 | * 403: 91 | * $ref: '#/components/responses/Unauthorized' 92 | * 404: 93 | * $ref: '#/components/responses/NotFound' 94 | */ 95 | router.post("/", async (req: Request, res: Response) => { 96 | if (!config.get("server.uploadDemos")) { 97 | res.status(403).send({ message: "Demo uploads disabled for this server." }); 98 | return; 99 | } 100 | try { 101 | const apiKey: string | undefined = req.get("Authorization"); 102 | const matchId: string | undefined = req.get("Get5-MatchId"); 103 | const mapNumber: string | undefined = req.get("Get5-MapNumber"); 104 | const demoFilename: string | undefined = req.get("Get5-FileName"); 105 | // Check that the values have made it across. 106 | if (!apiKey || !matchId || !mapNumber || !demoFilename) { 107 | return res 108 | .status(401) 109 | .send({ message: "API key, Match ID, or Map Number not provided." }); 110 | } 111 | // Check if our API key is correct. 112 | const matchApiCheck: number = await Utils.checkApiKey(apiKey, matchId); 113 | if (matchApiCheck == 1) { 114 | return res.status(401).send({ 115 | message: "Invalid API key has been given." 116 | }); 117 | } 118 | // Begin file compression into public/demos and check time variance of 8 minutes. 119 | let zip: JSZip = new JSZip(); 120 | let sqlString: string = 121 | "SELECT id, end_time FROM map_stats WHERE match_id = ? AND map_number = ?"; 122 | const mapInfo: RowDataPacket[] = await db.query(sqlString, [ 123 | matchId, 124 | mapNumber 125 | ]); 126 | if (mapInfo.length == 0) { 127 | return res.status(404).send({ message: "Failed to find map stats object." }); 128 | } 129 | let currentDate: Date = new Date(); 130 | let endTimeMs: Date = new Date(mapInfo[0].end_time); 131 | let timeDifference: number = Math.abs( 132 | currentDate.getTime() - endTimeMs.getTime() 133 | ); 134 | let minuteDifference = Math.floor(timeDifference / 1000 / 60); 135 | let updateStmt: object; 136 | if (minuteDifference > 8) { 137 | return res.status(401).json({ message: "Demo can no longer be uploaded." }); 138 | } 139 | 140 | zip.file(demoFilename, req.body, { binary: true }); 141 | zip 142 | .generateAsync({ type: "nodebuffer", compression: "DEFLATE" }) 143 | .then((buf) => { 144 | writeFile("public/demos/" + demoFilename.replace(".dem", ".zip"), buf, "binary", function (err) { 145 | if (err) { 146 | console.error(err); 147 | throw err; 148 | } 149 | }); 150 | }); 151 | // Update map stats object to include the link to the demo. 152 | updateStmt = { 153 | demoFile: demoFilename.replace(".dem", ".zip") 154 | }; 155 | updateStmt = await db.buildUpdateStatement(updateStmt); 156 | 157 | sqlString = "UPDATE map_stats SET ? WHERE id = ?"; 158 | await db.query(sqlString, [updateStmt, mapInfo[0].id]); 159 | GlobalEmitter.emit("demoUpdate"); 160 | res.status(200).send({message: "Success"}); 161 | return; 162 | } catch (error) { 163 | console.error(error); 164 | res.status(500).send({ message: error }); 165 | return; 166 | } 167 | }); 168 | 169 | export { router }; 170 | -------------------------------------------------------------------------------- /src/services/challonge.ts: -------------------------------------------------------------------------------- 1 | /** Fetch for Challonge API integration. 2 | * @const 3 | */ 4 | import fetch from "node-fetch"; 5 | 6 | import Utils from "../utility/utils.js"; 7 | 8 | /** Database module. 9 | * @const 10 | */ 11 | import {db} from "../services/db.js"; 12 | 13 | 14 | /** 15 | * @const 16 | * Global Server Sent Emitter class for real time data. 17 | */ 18 | import GlobalEmitter from "../utility/emitter.js"; 19 | import { RowDataPacket } from "mysql2"; 20 | 21 | /*** A PUT call to Challonge to update a match that is currently being played. 22 | * @function 23 | * @memberof module:legacy/api 24 | * @param {number} match_id - The internal ID of the match being played. 25 | * @param {number} season_id - The internal ID of the current season of the match being played. 26 | * @param {number} team1_id - The internal team ID of the first team. 27 | * @param {number} team2_id - The internal team ID of the second team. 28 | * @param {number} num_maps - The number of maps in the current match. 29 | * @param {string} [winner=null] - The string value representing the winner of the match. 30 | */ 31 | export default 32 | async function update_challonge_match( 33 | match_id: number | string, 34 | season_id: number, 35 | team1_id: number, 36 | team2_id: number, 37 | num_maps: number, 38 | winner: string | null = null 39 | ): Promise { 40 | // Check if a match has a season ID. 41 | let sql: string = 42 | "SELECT id, challonge_url, user_id FROM season WHERE id = ?"; 43 | let team1Score: number; 44 | let team2Score: number; 45 | const seasonInfo: RowDataPacket[] = await db.query(sql, [season_id]); 46 | if (seasonInfo[0].challonge_url) { 47 | sql = "SELECT challonge_team_id FROM team WHERE id = ?"; 48 | const team1ChallongeId: RowDataPacket[] = await db.query(sql, [team1_id]); 49 | const team2ChallongeId: RowDataPacket[] = await db.query(sql, [team2_id]); 50 | 51 | // Grab API key. 52 | sql = "SELECT challonge_api_key FROM user WHERE id = ?"; 53 | const challongeAPIKey: RowDataPacket[] = await db.query(sql, [seasonInfo[0].user_id]); 54 | let decryptedKey: string | null | undefined = Utils.decrypt( 55 | challongeAPIKey[0].challonge_api_key 56 | ); 57 | // Get info of the current open match with the two IDs. 58 | let challongeResponse = await fetch( 59 | "https://api.challonge.com/v1/tournaments/" + 60 | seasonInfo[0].challonge_url + 61 | "/matches.json?api_key=" + 62 | decryptedKey + 63 | "&state=open&participant_id=" + 64 | team1ChallongeId[0].challonge_team_id + 65 | "&participant_id=" + 66 | team2ChallongeId[0].challonge_team_id 67 | ); 68 | let challongeData: any = await challongeResponse.json(); 69 | if (challongeData) { 70 | if (num_maps == 1) { 71 | // Submit the map stats scores instead. 72 | sql = 73 | "SELECT team1_score, team2_score FROM map_stats WHERE match_id = ?"; 74 | } else { 75 | sql = "SELECT team1_score, team2_score FROM `match` WHERE id = ?"; 76 | } 77 | const mapStats: RowDataPacket[] = await db.query(sql, [match_id]); 78 | // Admins may just make a match that has teams swapped. This is okay as we can change what we 79 | // report to Challonge. 80 | team1Score = 81 | challongeData[0].match.player1_id == 82 | team1ChallongeId[0].challonge_team_id 83 | ? mapStats[0].team1_score 84 | : mapStats[0].team2_score; 85 | team2Score = 86 | challongeData[0].match.player2_id == 87 | team2ChallongeId[0].challonge_team_id 88 | ? mapStats[0].team2_score 89 | : mapStats[0].team1_score; 90 | // Build the PUT body. 91 | let putBody = { 92 | api_key: decryptedKey, 93 | match: { 94 | scores_csv: `${team1Score}-${team2Score}`, 95 | winner_id: 96 | winner === "team1" 97 | ? team1ChallongeId[0].challonge_team_id 98 | : team2ChallongeId[0].challonge_team_id 99 | } 100 | }; 101 | // If we're just updating the score, remove this. 102 | if (winner === null) { 103 | delete putBody.match.winner_id; 104 | } 105 | await fetch( 106 | "https://api.challonge.com/v1/tournaments/" + 107 | seasonInfo[0].challonge_url + 108 | "/matches/" + 109 | challongeData[0].match.id + 110 | ".json", 111 | { 112 | method: "PUT", 113 | headers: { 114 | "Content-Type": "application/json" 115 | }, 116 | body: JSON.stringify(putBody) 117 | } 118 | ); 119 | // Check and see if any matches remain, if not, finalize the tournament. 120 | challongeResponse = await fetch( 121 | "https://api.challonge.com/v1/tournaments/" + 122 | seasonInfo[0].challonge_url + 123 | "/matches.json?api_key=" + 124 | decryptedKey + 125 | "&state=open" 126 | ); 127 | challongeData = await challongeResponse.json(); 128 | if (!challongeData) { 129 | await fetch( 130 | "https://api.challonge.com/v1/tournaments/" + 131 | seasonInfo[0].challonge_url + 132 | "finalize.json?api_key=" + 133 | decryptedKey, 134 | { 135 | method: "POST" 136 | } 137 | ); 138 | // If we are the last map, let's close off the season as well. 139 | sql = "UPDATE season SET end_date = ? WHERE id = ?"; 140 | await db.query(sql, [ 141 | new Date().toISOString().slice(0, 19).replace("T", " "), 142 | seasonInfo[0].id 143 | ]); 144 | GlobalEmitter.emit("seasonUpdate"); 145 | } 146 | } 147 | } 148 | } -------------------------------------------------------------------------------- /src/services/db.ts: -------------------------------------------------------------------------------- 1 | /*Database driver.*/ 2 | import { createPool } from 'mysql2/promise'; 3 | import config from 'config'; 4 | import { FieldPacket, PoolOptions, RowDataPacket } from 'mysql2/typings/mysql'; 5 | interface IStringIndex { 6 | [key: string]: any; 7 | } 8 | const dbCfg = { 9 | host: config.get(process.env.NODE_ENV+".host"), 10 | port: config.get(process.env.NODE_ENV+".port"), 11 | user: config.get(process.env.NODE_ENV+".user"), 12 | password: config.get(process.env.NODE_ENV+".password"), 13 | database: config.get(process.env.NODE_ENV+".database"), 14 | connectionLimit: config.get(process.env.NODE_ENV+".connectionLimit") 15 | } as PoolOptions; 16 | const connPool = createPool(dbCfg); 17 | 18 | class Database { 19 | constructor() { 20 | this.setupAdmins(); 21 | } 22 | 23 | async query(sql: string, args?: object): Promise { 24 | try { 25 | let result: [RowDataPacket[], FieldPacket[]]; 26 | result = await connPool.query(sql, args); 27 | return result[0]; 28 | } catch (error) { 29 | console.error("SQL ERROR SQL ERROR SQL ERROR SQL ERROR SQL ERROR\n" + error); 30 | throw error; 31 | } 32 | } 33 | 34 | async buildUpdateStatement(objValues: IStringIndex): Promise { 35 | for (let key in objValues) { 36 | if (objValues[key] == null || objValues[key] == undefined) delete objValues[key]; 37 | } 38 | return objValues; 39 | } 40 | 41 | async setupAdmins(): Promise { 42 | try { 43 | let listOfAdmins: Array = (config.get("admins.steam_ids") as string).split(','); 44 | let listofSuperAdmins: Array = (config.get("super_admins.steam_ids") as string).split(','); 45 | // Get list of admins from database and compare list and add new admins. 46 | let updateAdmins: string = "UPDATE user SET admin = 1 WHERE steam_id IN (?)"; 47 | let updateSuperAdmins: string = "UPDATE user SET super_admin = 1 WHERE steam_id in(?)"; 48 | await connPool.query(updateAdmins, [listOfAdmins]); 49 | await connPool.query(updateSuperAdmins, [listofSuperAdmins]); 50 | } catch (err) { 51 | console.error("Failed to import users. " + err); 52 | } 53 | } 54 | } 55 | let db = new Database(); 56 | export {db}; 57 | -------------------------------------------------------------------------------- /src/types/Get5_Assist.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Player } from "./Get5_Player" 2 | 3 | export interface Get5_Assist { 4 | player: Get5_Player 5 | friendly_fire: boolean 6 | flash_assist: boolean 7 | } -------------------------------------------------------------------------------- /src/types/Get5_Attacker.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_Attacker { 2 | steamid: string 3 | name: string 4 | user_id: number 5 | side: string 6 | is_bot: boolean 7 | } -------------------------------------------------------------------------------- /src/types/Get5_OnEvent.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnEvent { 2 | event: string 3 | } -------------------------------------------------------------------------------- /src/types/Get5_Player.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Stats } from "./Get5_Stats" 2 | 3 | 4 | export interface Get5_Player { 5 | steamid: string 6 | name: string 7 | stats?: Get5_Stats 8 | user_id?: number, 9 | side?: string, 10 | is_bot?: boolean 11 | } -------------------------------------------------------------------------------- /src/types/Get5_Stats.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_Stats { 2 | kills: number 3 | deaths: number 4 | assists: number 5 | flash_assists: number 6 | team_kills: number 7 | suicides: number 8 | damage: number 9 | utility_damage: number 10 | enemies_flashed: number 11 | friendlies_flashed: number 12 | knife_kills: number 13 | headshot_kills: number 14 | rounds_played: number 15 | bomb_defuses: number 16 | bomb_plants: number 17 | "1k": number 18 | "2k": number 19 | "3k": number 20 | "4k": number 21 | "5k": number 22 | "1v1": number 23 | "1v2": number 24 | "1v3": number 25 | "1v4": number 26 | "1v5": number 27 | first_kills_t: number 28 | first_kills_ct: number 29 | first_deaths_t: number 30 | first_deaths_ct: number 31 | trade_kills: number 32 | kast: number 33 | score: number 34 | mvp: number 35 | } -------------------------------------------------------------------------------- /src/types/Get5_Team.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Player } from "./Get5_Player" 2 | 3 | export interface Get5_Team { 4 | id: string 5 | name: string 6 | series_score: number 7 | score: number 8 | score_ct: number 9 | score_t: number 10 | players: Get5_Player[] 11 | side: string 12 | starting_side: string 13 | } -------------------------------------------------------------------------------- /src/types/Get5_Weapon.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_Weapon { 2 | name: string 3 | id: number 4 | } -------------------------------------------------------------------------------- /src/types/Get5_Winner.ts: -------------------------------------------------------------------------------- 1 | 2 | export interface Get5_Winner { 3 | side: string 4 | team: string 5 | } 6 | -------------------------------------------------------------------------------- /src/types/User.ts: -------------------------------------------------------------------------------- 1 | export interface User { 2 | steam_id: string 3 | name: string 4 | admin: boolean | number 5 | super_admin: boolean | number 6 | id: number 7 | small_image: string 8 | medium_image: string 9 | large_image: string 10 | api_key: string 11 | } -------------------------------------------------------------------------------- /src/types/leaderboard/Player.ts: -------------------------------------------------------------------------------- 1 | export interface Player { 2 | steamId: string 3 | name: string, 4 | kills: number, 5 | deaths: number, 6 | assists: number, 7 | k1: number, 8 | k2: number, 9 | k3: number, 10 | k4: number, 11 | k5: number, 12 | v1: number, 13 | v2: number, 14 | v3: number, 15 | v4: number, 16 | v5: number, 17 | trp: number 18 | fba: number 19 | total_damage: number 20 | hsk: number, 21 | hsp: number, 22 | average_rating: number, 23 | wins: number, 24 | total_maps: number, 25 | enemies_flashed?: number, 26 | friendlies_flashed?: number, 27 | util_damage?: number 28 | } -------------------------------------------------------------------------------- /src/types/leaderboard/TeamStanding.ts: -------------------------------------------------------------------------------- 1 | export interface TeamStanding { 2 | name: string, 3 | wins: number, 4 | losses: number, 5 | rounddiff: number 6 | } -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnBombEvent.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Player } from "../Get5_Player" 2 | 3 | export interface Get5_OnBombEvent { 4 | event: string; 5 | matchid: string; 6 | map_number: number; 7 | round_number: number; 8 | round_time: number; 9 | player: Get5_Player; 10 | site: string; 11 | bomb_time_remaining?: number; 12 | } -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnGoingLive.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnGoingLive { 2 | event: string, 3 | matchid: string, 4 | map_number: number 5 | } -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnMatchPausedUnpaused.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnMatchPausedUnpaused { 2 | event: string 3 | matchid: string 4 | map_number: number 5 | team: string 6 | pause_type: string 7 | } 8 | -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnPlayerBecameMvp.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Player } from "../Get5_Player" 2 | 3 | export interface Get5_OnPlayerBecameMvp { 4 | event: string 5 | matchid: string 6 | map_number: number 7 | round_number: number 8 | player: Get5_Player 9 | reason: number 10 | } -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnPlayerDeath.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Assist } from "../Get5_Assist" 2 | import { Get5_Attacker } from "../Get5_Attacker" 3 | import { Get5_Player } from "../Get5_Player" 4 | import { Get5_Weapon } from "../Get5_Weapon" 5 | 6 | export interface Get5_OnPlayerDeath { 7 | event: string 8 | matchid: string 9 | map_number: number 10 | round_number: number 11 | round_time: number 12 | player: Get5_Player 13 | weapon: Get5_Weapon 14 | bomb: boolean 15 | headshot: boolean 16 | thru_smoke: boolean 17 | penetrated: boolean 18 | attacker_blind: boolean 19 | no_scope: boolean 20 | suicide: boolean 21 | friendly_fire: boolean 22 | attacker: Get5_Attacker 23 | assist: Get5_Assist 24 | } 25 | -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnRoundEnd.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Team } from "../Get5_Team" 2 | import { Get5_Winner } from "../Get5_Winner" 3 | 4 | export interface Get5_OnRoundEnd { 5 | event: string 6 | matchid: string 7 | map_number: number 8 | round_number: number 9 | round_time: number 10 | reason: number 11 | winner: Get5_Winner 12 | team1: Get5_Team 13 | team2: Get5_Team 14 | } -------------------------------------------------------------------------------- /src/types/map_flow/Get5_OnRoundStart.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnRoundStart { 2 | event: string 3 | matchid: string, 4 | map_number: number, 5 | round_number: number 6 | } -------------------------------------------------------------------------------- /src/types/maps/MapObject.ts: -------------------------------------------------------------------------------- 1 | export interface MapObject { 2 | user_id?: number, 3 | map_name?: string, 4 | map_display_name?: string | null, 5 | enabled?: boolean | number | null 6 | } -------------------------------------------------------------------------------- /src/types/mapstats/AccessMessage.ts: -------------------------------------------------------------------------------- 1 | export interface AccessMessage { 2 | status: number, 3 | message: string 4 | } -------------------------------------------------------------------------------- /src/types/mapstats/MapStats.ts: -------------------------------------------------------------------------------- 1 | export interface MapStats { 2 | id?: number, 3 | match_id?: string, 4 | winner?: number | null, 5 | map_number?: number, 6 | map_name?: string | null, 7 | team1_score?: number | null, 8 | team2_score?: number | null, 9 | start_time?: Date | string, 10 | end_time?: Date | string, 11 | round_restored?: boolean | number, 12 | demoFile?: string 13 | } -------------------------------------------------------------------------------- /src/types/matches/MatchData.ts: -------------------------------------------------------------------------------- 1 | export interface MatchData { 2 | match_id?: string, 3 | user_id?: number, 4 | server_id?: number, 5 | team1_id?: number, 6 | team2_id?: number, 7 | season_id?: number, 8 | start_time?: Date | string, 9 | end_time?: Date | string | null, 10 | forfeit?: number | null, 11 | cancelled?: number | null, 12 | team1_score?: number | null, 13 | team2_score?: number | null, 14 | max_maps?: number | null, 15 | title?: string, 16 | skip_veto?: number | null | boolean, 17 | veto_first?: string, 18 | veto_mappool?: string, 19 | side_type?: string, 20 | plugin_version?: string, 21 | private_match?: number | boolean, 22 | enforce_teams?: number | boolean, 23 | api_key?: string, 24 | winner?: number | null, 25 | team1_string?: string, 26 | team2_string?: string, 27 | is_pug?: boolean, 28 | min_player_ready?: number, 29 | players_per_team?: number, 30 | min_spectators_to_ready?: number, 31 | map_sides?: string | null, 32 | wingman?: boolean, 33 | team1_series_score?: number, 34 | team2_series_score?: number, 35 | } -------------------------------------------------------------------------------- /src/types/matches/MatchJson.ts: -------------------------------------------------------------------------------- 1 | export interface MatchJSON { 2 | matchid: number | string, 3 | match_title: string, 4 | side_type: string, 5 | veto_first: string, 6 | skip_veto: boolean, 7 | min_players_to_ready: number 8 | players_per_team: number, 9 | team1: {}, 10 | team2: {}, 11 | cvars: { 12 | get5_web_api_url?: string, 13 | get5_check_auths?: string, 14 | get5_remote_log_url?: string, 15 | get5_remote_log_header_key?: string, 16 | get5_remote_log_header_value?: string, 17 | get5_remote_backup_url?: string, 18 | get5_remote_backup_header_key?: string, 19 | get5_remote_backup_header_value?: string, 20 | get5_demo_upload_url?: string, 21 | get5_demo_upload_header_key?: string, 22 | get5_demo_upload_header_value?: string, 23 | [key: string]: any 24 | }, 25 | spectators: { 26 | players: {[key: string]: any} 27 | }, 28 | maplist?: string | null 29 | min_spectators_to_ready: number, 30 | wingman: boolean, 31 | num_maps?: number, 32 | map_sides?: string, 33 | } -------------------------------------------------------------------------------- /src/types/matches/MatchPauseData.ts: -------------------------------------------------------------------------------- 1 | export interface MatchPauseData { 2 | match_id?: string, 3 | pause_type?: string | null, 4 | team_paused?: string | null, 5 | paused?: boolean 6 | } -------------------------------------------------------------------------------- /src/types/playerstats/PlayerDatabaseObject.ts: -------------------------------------------------------------------------------- 1 | export interface PlayerDatabaseObject { 2 | match_id?: string, 3 | map_id?: number, 4 | team_id?: number | null, 5 | steam_id?: string | null, 6 | name: string | null, 7 | kills: number | null, 8 | deaths: number | null, 9 | roundsplayed: number | null, 10 | assists: number | null, 11 | flashbang_assists: number | null, 12 | teamkills: number | null, 13 | knife_kills: number | null, 14 | suicides: number | null, 15 | headshot_kills: number | null, 16 | damage: number | null, 17 | util_damage: number | null, 18 | enemies_flashed: number | null, 19 | friendlies_flashed: number | null, 20 | bomb_plants: number | null, 21 | bomb_defuses: number | null, 22 | v1: number | null, 23 | v2: number | null, 24 | v3: number | null, 25 | v4: number | null, 26 | v5: number | null, 27 | k1: number | null, 28 | k2: number | null, 29 | k3: number | null, 30 | k4: number | null, 31 | k5: number | null, 32 | firstdeath_ct: number | null, 33 | firstdeath_t: number | null, 34 | firstkill_ct: number | null, 35 | firstkill_t: number | null, 36 | kast: number | null, 37 | contribution_score: number | null, 38 | mvp: number | null 39 | } -------------------------------------------------------------------------------- /src/types/playerstats/PlayerObject.ts: -------------------------------------------------------------------------------- 1 | export interface PlayerInfo { 2 | player_steam_id?: string, 3 | player_name?: string, 4 | player_side?: string, 5 | map_id?: number, 6 | match_id?: string, 7 | team_id?: number, 8 | round_number: number, 9 | round_time: number, 10 | attacker_steam_id: string, 11 | attacker_name: string, 12 | attacker_side: string, 13 | weapon: string, 14 | bomb: string, 15 | deaths: number, 16 | headshot: boolean, 17 | thru_smoke: boolean, 18 | attacker_blind: boolean, 19 | no_scope: boolean, 20 | suicide: boolean, 21 | friendly_fire: boolean, 22 | assister_steam_id: string, 23 | assister_name: string, 24 | assister_side: string, 25 | assist_friendly_fire: boolean, 26 | flash_assist: boolean 27 | } 28 | -------------------------------------------------------------------------------- /src/types/seasons/SeasonCvarObject.ts: -------------------------------------------------------------------------------- 1 | export interface SeasonCvarObject { 2 | id?: number, 3 | season_id: number, 4 | cvar_name: string, 5 | cvar_value: string 6 | } -------------------------------------------------------------------------------- /src/types/seasons/SeasonObject.ts: -------------------------------------------------------------------------------- 1 | export interface SeasonObject { 2 | id?: number; 3 | user_id?: number; 4 | name?: string | null; 5 | start_date?: Date | null; 6 | end_date?: Date | null; 7 | is_challonge?: boolean | null; 8 | challonge_svg?: string | null; 9 | challonge_url?: string | null; 10 | 11 | } -------------------------------------------------------------------------------- /src/types/series_flow/Get5_OnBackupRestore.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnBackupRestore { 2 | event: string 3 | matchid: string 4 | map_number: number 5 | round_number: number 6 | filename: string 7 | } 8 | -------------------------------------------------------------------------------- /src/types/series_flow/Get5_OnMapResult.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Team } from "../Get5_Team" 2 | import { Get5_Winner } from "../Get5_Winner" 3 | 4 | export interface Get5_OnMapResult { 5 | event: string 6 | matchid: string 7 | map_number: number 8 | team1: Get5_Team 9 | team2: Get5_Team 10 | winner: Get5_Winner 11 | } 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/types/series_flow/Get5_OnSeriesResult.ts: -------------------------------------------------------------------------------- 1 | import { Get5_Winner } from "../Get5_Winner" 2 | 3 | export interface Get5_OnSeriesResult { 4 | event: string 5 | matchid: string 6 | team1_series_score: number 7 | team2_series_score: number 8 | winner: Get5_Winner 9 | time_until_restore: number 10 | } -------------------------------------------------------------------------------- /src/types/series_flow/veto/Get5_OnMapPicked.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnMapPicked { 2 | event: string 3 | matchid: string 4 | team: string 5 | map_name: string 6 | map_number: number 7 | } 8 | -------------------------------------------------------------------------------- /src/types/series_flow/veto/Get5_OnMapVetoed.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnMapVetoed { 2 | event: string 3 | matchid: string 4 | team: string 5 | map_name: string 6 | } 7 | -------------------------------------------------------------------------------- /src/types/series_flow/veto/Get5_OnSidePicked.ts: -------------------------------------------------------------------------------- 1 | export interface Get5_OnSidePicked { 2 | event: string 3 | matchid: string 4 | team: string 5 | map_name: string 6 | side: string 7 | map_number: number 8 | } 9 | -------------------------------------------------------------------------------- /src/types/serverrcon/SteamApiResponse.ts: -------------------------------------------------------------------------------- 1 | export interface SteamApiResponse { 2 | response: { 3 | success: boolean 4 | up_to_date: boolean 5 | version_is_listable: boolean 6 | required_version: boolean 7 | message?: string 8 | } 9 | } -------------------------------------------------------------------------------- /src/types/servers/GameServerObject.ts: -------------------------------------------------------------------------------- 1 | export interface GameServerObject { 2 | user_id?: number, 3 | in_use?: number, 4 | ip_string?: string, 5 | port?: number, 6 | rcon_password?: string | null, 7 | display_name?: string, 8 | public_server?: number, 9 | flag?: string, 10 | gotv_port?: number 11 | } -------------------------------------------------------------------------------- /src/types/swagger/Get5_Assist.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Assist.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Assist.yaml 6 | x-comment: >- 7 | Generated from Get5_Assist.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Assist: 14 | properties: 15 | player: 16 | title: Get5_Assist.player 17 | friendly_fire: 18 | title: Get5_Assist.friendly_fire 19 | type: boolean 20 | flash_assist: 21 | title: Get5_Assist.flash_assist 22 | type: boolean 23 | required: 24 | - player 25 | - friendly_fire 26 | - flash_assist 27 | additionalProperties: false 28 | title: Get5_Assist 29 | type: object 30 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Attacker.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Attacker.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Attacker.yaml 6 | x-comment: >- 7 | Generated from Get5_Attacker.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Attacker: 14 | properties: 15 | steamid: 16 | title: Get5_Attacker.steamid 17 | type: string 18 | name: 19 | title: Get5_Attacker.name 20 | type: string 21 | user_id: 22 | title: Get5_Attacker.user_id 23 | type: number 24 | side: 25 | title: Get5_Attacker.side 26 | type: string 27 | is_bot: 28 | title: Get5_Attacker.is_bot 29 | type: boolean 30 | required: 31 | - steamid 32 | - name 33 | - user_id 34 | - side 35 | - is_bot 36 | additionalProperties: false 37 | title: Get5_Attacker 38 | type: object 39 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Player.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Player.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Player.yaml 6 | x-comment: >- 7 | Generated from Get5_Player.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Player: 14 | properties: 15 | steamid: 16 | title: Get5_Player.steamid 17 | type: string 18 | name: 19 | title: Get5_Player.name 20 | type: string 21 | stats: 22 | title: Get5_Player.stats 23 | user_id: 24 | title: Get5_Player.user_id 25 | type: number 26 | side: 27 | title: Get5_Player.side 28 | type: string 29 | is_bot: 30 | title: Get5_Player.is_bot 31 | type: boolean 32 | required: 33 | - steamid 34 | - name 35 | additionalProperties: false 36 | title: Get5_Player 37 | type: object 38 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Stats.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Stats.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Stats.yaml 6 | x-comment: >- 7 | Generated from Get5_Stats.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Stats: 14 | properties: 15 | kills: 16 | title: Get5_Stats.kills 17 | type: number 18 | deaths: 19 | title: Get5_Stats.deaths 20 | type: number 21 | assists: 22 | title: Get5_Stats.assists 23 | type: number 24 | flash_assists: 25 | title: Get5_Stats.flash_assists 26 | type: number 27 | team_kills: 28 | title: Get5_Stats.team_kills 29 | type: number 30 | suicides: 31 | title: Get5_Stats.suicides 32 | type: number 33 | damage: 34 | title: Get5_Stats.damage 35 | type: number 36 | utility_damage: 37 | title: Get5_Stats.utility_damage 38 | type: number 39 | enemies_flashed: 40 | title: Get5_Stats.enemies_flashed 41 | type: number 42 | friendlies_flashed: 43 | title: Get5_Stats.friendlies_flashed 44 | type: number 45 | knife_kills: 46 | title: Get5_Stats.knife_kills 47 | type: number 48 | headshot_kills: 49 | title: Get5_Stats.headshot_kills 50 | type: number 51 | rounds_played: 52 | title: Get5_Stats.rounds_played 53 | type: number 54 | bomb_defuses: 55 | title: Get5_Stats.bomb_defuses 56 | type: number 57 | bomb_plants: 58 | title: Get5_Stats.bomb_plants 59 | type: number 60 | '"1k"': 61 | title: Get5_Stats."1k" 62 | type: number 63 | '"2k"': 64 | title: Get5_Stats."2k" 65 | type: number 66 | '"3k"': 67 | title: Get5_Stats."3k" 68 | type: number 69 | '"4k"': 70 | title: Get5_Stats."4k" 71 | type: number 72 | '"5k"': 73 | title: Get5_Stats."5k" 74 | type: number 75 | '"1v1"': 76 | title: Get5_Stats."1v1" 77 | type: number 78 | '"1v2"': 79 | title: Get5_Stats."1v2" 80 | type: number 81 | '"1v3"': 82 | title: Get5_Stats."1v3" 83 | type: number 84 | '"1v4"': 85 | title: Get5_Stats."1v4" 86 | type: number 87 | '"1v5"': 88 | title: Get5_Stats."1v5" 89 | type: number 90 | first_kills_t: 91 | title: Get5_Stats.first_kills_t 92 | type: number 93 | first_kills_ct: 94 | title: Get5_Stats.first_kills_ct 95 | type: number 96 | first_deaths_t: 97 | title: Get5_Stats.first_deaths_t 98 | type: number 99 | first_deaths_ct: 100 | title: Get5_Stats.first_deaths_ct 101 | type: number 102 | trade_kills: 103 | title: Get5_Stats.trade_kills 104 | type: number 105 | kast: 106 | title: Get5_Stats.kast 107 | type: number 108 | score: 109 | title: Get5_Stats.score 110 | type: number 111 | mvp: 112 | title: Get5_Stats.mvp 113 | type: number 114 | required: 115 | - kills 116 | - deaths 117 | - assists 118 | - flash_assists 119 | - team_kills 120 | - suicides 121 | - damage 122 | - utility_damage 123 | - enemies_flashed 124 | - friendlies_flashed 125 | - knife_kills 126 | - headshot_kills 127 | - rounds_played 128 | - bomb_defuses 129 | - bomb_plants 130 | - '"1k"' 131 | - '"2k"' 132 | - '"3k"' 133 | - '"4k"' 134 | - '"5k"' 135 | - '"1v1"' 136 | - '"1v2"' 137 | - '"1v3"' 138 | - '"1v4"' 139 | - '"1v5"' 140 | - first_kills_t 141 | - first_kills_ct 142 | - first_deaths_t 143 | - first_deaths_ct 144 | - trade_kills 145 | - kast 146 | - score 147 | - mvp 148 | additionalProperties: false 149 | title: Get5_Stats 150 | type: object 151 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Team.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Team.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Team.yaml 6 | x-comment: >- 7 | Generated from Get5_Team.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Team: 14 | properties: 15 | id: 16 | title: Get5_Team.id 17 | type: string 18 | name: 19 | title: Get5_Team.name 20 | type: string 21 | series_score: 22 | title: Get5_Team.series_score 23 | type: number 24 | score: 25 | title: Get5_Team.score 26 | type: number 27 | score_ct: 28 | title: Get5_Team.score_ct 29 | type: number 30 | score_t: 31 | title: Get5_Team.score_t 32 | type: number 33 | players: 34 | items: {} 35 | title: Get5_Team.players 36 | type: array 37 | side: 38 | title: Get5_Team.side 39 | type: string 40 | starting_side: 41 | title: Get5_Team.starting_side 42 | type: string 43 | required: 44 | - id 45 | - name 46 | - series_score 47 | - score 48 | - score_ct 49 | - score_t 50 | - players 51 | - side 52 | - starting_side 53 | additionalProperties: false 54 | title: Get5_Team 55 | type: object 56 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Weapon.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Weapon.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Weapon.yaml 6 | x-comment: >- 7 | Generated from Get5_Weapon.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Weapon: 14 | properties: 15 | name: 16 | title: Get5_Weapon.name 17 | type: string 18 | id: 19 | title: Get5_Weapon.id 20 | type: number 21 | required: 22 | - name 23 | - id 24 | additionalProperties: false 25 | title: Get5_Weapon 26 | type: object 27 | -------------------------------------------------------------------------------- /src/types/swagger/Get5_Winner.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_Winner.yaml with typeconv 4 | version: '1' 5 | x-id: Get5_Winner.yaml 6 | x-comment: >- 7 | Generated from Get5_Winner.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_Winner: 14 | properties: 15 | side: 16 | title: Get5_Winner.side 17 | type: string 18 | team: 19 | title: Get5_Winner.team 20 | type: string 21 | required: 22 | - side 23 | - team 24 | additionalProperties: false 25 | title: Get5_Winner 26 | type: object 27 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnBombDefused.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnBombDefused.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnBombDefused.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnBombDefused.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnBombDefused: 14 | properties: 15 | event: 16 | title: Get5_OnBombDefused.event 17 | type: string 18 | matchid: 19 | title: Get5_OnBombDefused.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnBombDefused.map_number 23 | type: number 24 | round_number: 25 | title: Get5_OnBombDefused.round_number 26 | type: number 27 | round_time: 28 | title: Get5_OnBombDefused.round_time 29 | type: number 30 | player: 31 | title: Get5_OnBombDefused.player 32 | site: 33 | title: Get5_OnBombDefused.site 34 | type: string 35 | bomb_time_remaining: 36 | title: Get5_OnBombDefused.bomb_time_remaining 37 | type: number 38 | required: 39 | - event 40 | - matchid 41 | - map_number 42 | - round_number 43 | - round_time 44 | - player 45 | - site 46 | - bomb_time_remaining 47 | additionalProperties: false 48 | title: Get5_OnBombDefused 49 | type: object 50 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnBombPlanted.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnBombPlanted.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnBombPlanted.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnBombPlanted.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnBombPlanted: 14 | properties: 15 | event: 16 | title: Get5_OnBombPlanted.event 17 | type: string 18 | matchid: 19 | title: Get5_OnBombPlanted.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnBombPlanted.map_number 23 | type: number 24 | round_number: 25 | title: Get5_OnBombPlanted.round_number 26 | type: number 27 | round_time: 28 | title: Get5_OnBombPlanted.round_time 29 | type: number 30 | player: 31 | title: Get5_OnBombPlanted.player 32 | site: 33 | title: Get5_OnBombPlanted.site 34 | type: string 35 | required: 36 | - event 37 | - matchid 38 | - map_number 39 | - round_number 40 | - round_time 41 | - player 42 | - site 43 | additionalProperties: false 44 | title: Get5_OnBombPlanted 45 | type: object 46 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnMatchPausedUnpaused.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnMatchPausedUnpaused.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnMatchPausedUnpaused.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnMatchPausedUnpaused.ts by 8 | core-types-json-schema (https://github.com/grantila/core-types-json-schema) 9 | on behalf of typeconv (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnMatchPausedUnpaused: 14 | properties: 15 | event: 16 | title: Get5_OnMatchPausedUnpaused.event 17 | type: string 18 | matchid: 19 | title: Get5_OnMatchPausedUnpaused.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnMatchPausedUnpaused.map_number 23 | type: number 24 | team: 25 | title: Get5_OnMatchPausedUnpaused.team 26 | type: string 27 | pause_type: 28 | title: Get5_OnMatchPausedUnpaused.pause_type 29 | type: string 30 | required: 31 | - event 32 | - matchid 33 | - map_number 34 | - team 35 | - pause_type 36 | additionalProperties: false 37 | title: Get5_OnMatchPausedUnpaused 38 | type: object 39 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnPlayerBecameMvp.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnPlayerBecameMvp.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnPlayerBecameMvp.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnPlayerBecameMvp.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnPlayerBecameMvp: 14 | properties: 15 | event: 16 | title: Get5_OnPlayerBecameMvp.event 17 | type: string 18 | matchid: 19 | title: Get5_OnPlayerBecameMvp.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnPlayerBecameMvp.map_number 23 | type: number 24 | round_number: 25 | title: Get5_OnPlayerBecameMvp.round_number 26 | type: number 27 | player: 28 | title: Get5_OnPlayerBecameMvp.player 29 | reason: 30 | title: Get5_OnPlayerBecameMvp.reason 31 | type: number 32 | required: 33 | - event 34 | - matchid 35 | - map_number 36 | - round_number 37 | - player 38 | - reason 39 | additionalProperties: false 40 | title: Get5_OnPlayerBecameMvp 41 | type: object 42 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnPlayerDeath.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnPlayerDeath.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnPlayerDeath.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnPlayerDeath.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Root: 14 | properties: 15 | event: 16 | title: Root.event 17 | type: string 18 | matchid: 19 | title: Root.matchid 20 | type: string 21 | map_number: 22 | title: Root.map_number 23 | type: number 24 | round_number: 25 | title: Root.round_number 26 | type: number 27 | round_time: 28 | title: Root.round_time 29 | type: number 30 | player: 31 | title: Root.player 32 | weapon: 33 | title: Root.weapon 34 | bomb: 35 | title: Root.bomb 36 | type: boolean 37 | headshot: 38 | title: Root.headshot 39 | type: boolean 40 | thru_smoke: 41 | title: Root.thru_smoke 42 | type: boolean 43 | penetrated: 44 | title: Root.penetrated 45 | type: boolean 46 | attacker_blind: 47 | title: Root.attacker_blind 48 | type: boolean 49 | no_scope: 50 | title: Root.no_scope 51 | type: boolean 52 | suicide: 53 | title: Root.suicide 54 | type: boolean 55 | friendly_fire: 56 | title: Root.friendly_fire 57 | type: boolean 58 | attacker: 59 | title: Root.attacker 60 | assist: 61 | title: Root.assist 62 | required: 63 | - event 64 | - matchid 65 | - map_number 66 | - round_number 67 | - round_time 68 | - player 69 | - weapon 70 | - bomb 71 | - headshot 72 | - thru_smoke 73 | - penetrated 74 | - attacker_blind 75 | - no_scope 76 | - suicide 77 | - friendly_fire 78 | - attacker 79 | - assist 80 | additionalProperties: false 81 | title: Root 82 | type: object 83 | -------------------------------------------------------------------------------- /src/types/swagger/map_flow/Get5_OnRoundEnd.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnRoundEnd.yaml with typeconv 4 | version: '1' 5 | x-id: map_flow/Get5_OnRoundEnd.yaml 6 | x-comment: >- 7 | Generated from map_flow/Get5_OnRoundEnd.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnRoundEnd: 14 | properties: 15 | event: 16 | title: Get5_OnRoundEnd.event 17 | type: string 18 | matchid: 19 | title: Get5_OnRoundEnd.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnRoundEnd.map_number 23 | type: number 24 | round_number: 25 | title: Get5_OnRoundEnd.round_number 26 | type: number 27 | round_time: 28 | title: Get5_OnRoundEnd.round_time 29 | type: number 30 | reason: 31 | title: Get5_OnRoundEnd.reason 32 | type: number 33 | winner: 34 | title: Get5_OnRoundEnd.winner 35 | team1: 36 | title: Get5_OnRoundEnd.team1 37 | team2: 38 | title: Get5_OnRoundEnd.team2 39 | required: 40 | - event 41 | - matchid 42 | - map_number 43 | - round_number 44 | - round_time 45 | - reason 46 | - winner 47 | - team1 48 | - team2 49 | additionalProperties: false 50 | title: Get5_OnRoundEnd 51 | type: object 52 | -------------------------------------------------------------------------------- /src/types/swagger/series_flow/Get5_OnBackupRestore.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnBackupRestore.yaml with typeconv 4 | version: '1' 5 | x-id: series_flow/Get5_OnBackupRestore.yaml 6 | x-comment: >- 7 | Generated from series_flow/Get5_OnBackupRestore.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnBackupRestore: 14 | properties: 15 | event: 16 | title: Get5_OnBackupRestore.event 17 | type: string 18 | matchid: 19 | title: Get5_OnBackupRestore.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnBackupRestore.map_number 23 | type: number 24 | round_number: 25 | title: Get5_OnBackupRestore.round_number 26 | type: number 27 | filename: 28 | title: Get5_OnBackupRestore.filename 29 | type: string 30 | required: 31 | - event 32 | - matchid 33 | - map_number 34 | - round_number 35 | - filename 36 | additionalProperties: false 37 | title: Get5_OnBackupRestore 38 | type: object 39 | -------------------------------------------------------------------------------- /src/types/swagger/series_flow/Get5_OnMapResult.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnMapResult.yaml with typeconv 4 | version: '1' 5 | x-id: series_flow/Get5_OnMapResult.yaml 6 | x-comment: >- 7 | Generated from series_flow/Get5_OnMapResult.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnMapResult: 14 | properties: 15 | event: 16 | title: Get5_OnMapResult.event 17 | type: string 18 | matchid: 19 | title: Get5_OnMapResult.matchid 20 | type: string 21 | map_number: 22 | title: Get5_OnMapResult.map_number 23 | type: number 24 | team1: 25 | title: Get5_OnMapResult.team1 26 | team2: 27 | title: Get5_OnMapResult.team2 28 | winner: 29 | title: Get5_OnMapResult.winner 30 | required: 31 | - event 32 | - matchid 33 | - map_number 34 | - team1 35 | - team2 36 | - winner 37 | additionalProperties: false 38 | title: Get5_OnMapResult 39 | type: object 40 | -------------------------------------------------------------------------------- /src/types/swagger/series_flow/Get5_OnSeriesInit.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnSeriesInit.yaml with typeconv 4 | version: '1' 5 | x-id: series_flow/Get5_OnSeriesInit.yaml 6 | x-comment: >- 7 | Generated from series_flow/Get5_OnSeriesInit.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnSeriesInit: 14 | properties: 15 | event: 16 | title: Get5_OnSeriesInit.event 17 | type: string 18 | matchid: 19 | title: Get5_OnSeriesInit.matchid 20 | type: string 21 | num_maps: 22 | title: Get5_OnSeriesInit.num_maps 23 | type: number 24 | team1: 25 | title: Get5_OnSeriesInit.team1 26 | team2: 27 | title: Get5_OnSeriesInit.team2 28 | required: 29 | - event 30 | - matchid 31 | - num_maps 32 | - team1 33 | - team2 34 | additionalProperties: false 35 | title: Get5_OnSeriesInit 36 | type: object 37 | -------------------------------------------------------------------------------- /src/types/swagger/series_flow/Get5_OnSeriesResult.yaml: -------------------------------------------------------------------------------- 1 | openapi: 3.0.0 2 | info: 3 | title: Converted from Get5_OnSeriesResult.yaml with typeconv 4 | version: '1' 5 | x-id: series_flow/Get5_OnSeriesResult.yaml 6 | x-comment: >- 7 | Generated from series_flow/Get5_OnSeriesResult.ts by core-types-json-schema 8 | (https://github.com/grantila/core-types-json-schema) on behalf of typeconv 9 | (https://github.com/grantila/typeconv) 10 | paths: {} 11 | components: 12 | schemas: 13 | Get5_OnSeriesResult: 14 | properties: 15 | event: 16 | title: Get5_OnSeriesResult.event 17 | type: string 18 | matchid: 19 | title: Get5_OnSeriesResult.matchid 20 | type: string 21 | team1_series_score: 22 | title: Get5_OnSeriesResult.team1_series_score 23 | type: number 24 | team2_series_score: 25 | title: Get5_OnSeriesResult.team2_series_score 26 | type: number 27 | winner: 28 | title: Get5_OnSeriesResult.winner 29 | time_until_restore: 30 | title: Get5_OnSeriesResult.time_until_restore 31 | type: number 32 | required: 33 | - event 34 | - matchid 35 | - team1_series_score 36 | - team2_series_score 37 | - winner 38 | - time_until_restore 39 | additionalProperties: false 40 | title: Get5_OnSeriesResult 41 | type: object 42 | -------------------------------------------------------------------------------- /src/types/teams/AuthData.ts: -------------------------------------------------------------------------------- 1 | export interface AuthData { 2 | captain: number | null, 3 | coach: number | null, 4 | name: string | null 5 | } -------------------------------------------------------------------------------- /src/types/teams/TeamData.ts: -------------------------------------------------------------------------------- 1 | export interface TeamData { 2 | id?: number | string, 3 | name: string, 4 | tag: string, 5 | flag: string, 6 | logo: string | null, 7 | matchtext?: string | null | undefined, 8 | public_team?: number, 9 | user_id?: number, 10 | [key: string]: any 11 | } -------------------------------------------------------------------------------- /src/types/users/UserObject.ts: -------------------------------------------------------------------------------- 1 | export interface UserObject { 2 | steam_id?: string, 3 | name?: string, 4 | admin?: number, 5 | super_admin?: number, 6 | small_image?: string, 7 | medium_image?: string, 8 | large_image?: string, 9 | api_key?: string | undefined | null, 10 | challonge_api_key?: string | undefined | null, 11 | password?: string | null | undefined, 12 | } -------------------------------------------------------------------------------- /src/types/vetoes/VetoObject.ts: -------------------------------------------------------------------------------- 1 | export interface VetoObject { 2 | match_id: number, 3 | map: string, 4 | team_name: string, 5 | pick_or_veto: string, 6 | } -------------------------------------------------------------------------------- /src/types/vetoes/VetoSideObject.ts: -------------------------------------------------------------------------------- 1 | export interface VetoSideObject { 2 | match_id: number, 3 | veto_id?: number, 4 | map: string, 5 | team_name: string, 6 | side: string 7 | } -------------------------------------------------------------------------------- /src/utility/emitter.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from "events"; 2 | 3 | class GlobalEmitter extends EventEmitter { 4 | constructor() { 5 | super(); 6 | } 7 | } 8 | 9 | export default new GlobalEmitter(); -------------------------------------------------------------------------------- /src/utility/mockProfile.ts: -------------------------------------------------------------------------------- 1 | export default class user { 2 | id = "76561198025644194"; 3 | displayName = "Phlex"; 4 | photos = [ 5 | { 6 | value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004.jpg", 7 | }, 8 | { 9 | value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004_medium.jpg", 10 | }, 11 | { 12 | value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004_full.jpg", 13 | }]; 14 | identifier = 'https://steamcommunity.com/openid/id/76561198025644194'; 15 | super_admin = 1; 16 | admin = 1; 17 | }; 18 | // export const id = "76561198025644194"; 19 | // export const displayName = "Phlex"; 20 | // export const photos = [ 21 | // { 22 | // value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004.jpg", 23 | // }, 24 | // { 25 | // value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004_medium.jpg", 26 | // }, 27 | // { 28 | // value: "https://steamcdn-a.akamaihd.net/steamcommunity/public/images/avatars/d6/d6f3cfd2a1f5131863bbca13675412924cccc004_full.jpg", 29 | // }, 30 | // ]; 31 | -------------------------------------------------------------------------------- /src/utility/mockstrategy.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Author: Michael Weibel 3 | * License: MIT 4 | */ 5 | "use strict"; 6 | 7 | import { Strategy as OpenIDStrategy } from 'passport-openidconnect'; 8 | import { inherits } from 'util'; 9 | import user from "./mockProfile.js"; 10 | 11 | function MockStrategy(this: any, options: { name: any; passAuthentication: any; userId?: any; }, verify: (identifier: any, profile: any, done: any) => Promise) { 12 | this.name = options.name; 13 | this.passAuthentication = options.passAuthentication ? true : false; 14 | this.userId = options.userId || 1; 15 | this.verify = verify; 16 | this.user = new user(); 17 | } 18 | 19 | inherits(MockStrategy, OpenIDStrategy); 20 | 21 | MockStrategy.prototype.authenticate = function authenticate() { 22 | if (this.passAuthentication) { 23 | var self = this; 24 | this.verify(this.user.id, this.user, function(_identifier: any, profile: any, done: any) { 25 | self.success(profile); 26 | }); 27 | } else { 28 | this.fail('Unauthorized'); 29 | } 30 | } 31 | 32 | export default MockStrategy; --------------------------------------------------------------------------------