Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbd853fb56 | ||
|
|
1fcf9627a6 | ||
|
|
04a9c935e7 | ||
|
|
aa96ada505 |
@@ -1,5 +0,0 @@
|
|||||||
node_modules
|
|
||||||
.env
|
|
||||||
.env.example
|
|
||||||
npm-debug.log
|
|
||||||
out
|
|
||||||
@@ -1,95 +0,0 @@
|
|||||||
name: Docker
|
|
||||||
|
|
||||||
# This workflow uses actions that are not certified by GitHub.
|
|
||||||
# They are provided by a third-party and are governed by
|
|
||||||
# separate terms of service, privacy policy, and support
|
|
||||||
# documentation.
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [ "main" ]
|
|
||||||
# Publish semver tags as releases.
|
|
||||||
tags: [ 'v*.*.*' ]
|
|
||||||
pull_request:
|
|
||||||
branches: [ "main" ]
|
|
||||||
|
|
||||||
env:
|
|
||||||
# Use docker.io for Docker Hub if empty
|
|
||||||
REGISTRY: ghcr.io
|
|
||||||
# github.repository as <account>/<repo>
|
|
||||||
IMAGE_NAME: ${{ github.repository }}
|
|
||||||
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build:
|
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
# This is used to complete the identity challenge
|
|
||||||
# with sigstore/fulcio when running outside of PRs.
|
|
||||||
id-token: write
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout repository
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
# Install the cosign tool except on PR
|
|
||||||
# https://github.com/sigstore/cosign-installer
|
|
||||||
- name: Install cosign
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
uses: sigstore/cosign-installer@6e04d228eb30da1757ee4e1dd75a0ec73a653e06 #v3.1.1
|
|
||||||
with:
|
|
||||||
cosign-release: 'v2.1.1'
|
|
||||||
|
|
||||||
# Workaround: https://github.com/docker/build-push-action/issues/461
|
|
||||||
- name: Setup Docker buildx
|
|
||||||
uses: docker/setup-buildx-action@79abd3f86f79a9d68a23c75a09a9a85889262adf
|
|
||||||
|
|
||||||
# Login against a Docker registry except on PR
|
|
||||||
# https://github.com/docker/login-action
|
|
||||||
- name: Log into registry ${{ env.REGISTRY }}
|
|
||||||
if: github.event_name != 'pull_request'
|
|
||||||
uses: docker/login-action@28218f9b04b4f3f62068d7b6ce6ca5b26e35336c
|
|
||||||
with:
|
|
||||||
registry: ${{ env.REGISTRY }}
|
|
||||||
username: ${{ github.actor }}
|
|
||||||
password: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
# Extract metadata (tags, labels) for Docker
|
|
||||||
# https://github.com/docker/metadata-action
|
|
||||||
- name: Extract Docker metadata
|
|
||||||
id: meta
|
|
||||||
uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38
|
|
||||||
with:
|
|
||||||
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
|
||||||
|
|
||||||
# Build and push Docker image with Buildx (don't push on PR)
|
|
||||||
# https://github.com/docker/build-push-action
|
|
||||||
- name: Build and push Docker image
|
|
||||||
id: build-and-push
|
|
||||||
uses: docker/build-push-action@ac9327eae2b366085ac7f6a2d02df8aa8ead720a
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
|
||||||
tags: ${{ steps.meta.outputs.tags }}
|
|
||||||
labels: ${{ steps.meta.outputs.labels }}
|
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
||||||
|
|
||||||
|
|
||||||
# Sign the resulting Docker image digest except on PRs.
|
|
||||||
# This will only write to the public Rekor transparency log when the Docker
|
|
||||||
# repository is public to avoid leaking data. If you would like to publish
|
|
||||||
# transparency data even for private images, pass --force to cosign below.
|
|
||||||
# https://github.com/sigstore/cosign
|
|
||||||
- name: Sign the published Docker image
|
|
||||||
if: ${{ github.event_name != 'pull_request' }}
|
|
||||||
env:
|
|
||||||
# https://docs.github.com/en/actions/security-guides/security-hardening-for-github-actions#using-an-intermediate-environment-variable
|
|
||||||
TAGS: ${{ steps.meta.outputs.tags }}
|
|
||||||
DIGEST: ${{ steps.build-and-push.outputs.digest }}
|
|
||||||
# This step uses the identity token to provision an ephemeral certificate
|
|
||||||
# against the sigstore community Fulcio instance.
|
|
||||||
run: echo "${TAGS}" | xargs -I {} cosign sign --yes {}@${DIGEST}
|
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
FROM node:18
|
|
||||||
|
|
||||||
WORKDIR /usr/src/app
|
|
||||||
|
|
||||||
COPY package*.json ./
|
|
||||||
RUN npm ci --omit=dev
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
EXPOSE 3001
|
|
||||||
|
|
||||||
CMD [ "npm", "run", "startServer"]
|
|
||||||
+10
-10
File diff suppressed because one or more lines are too long
+2
-2
@@ -11,14 +11,14 @@ info:
|
|||||||
description: |-
|
description: |-
|
||||||
Stats tracking API for Titanfall 2 Northstar
|
Stats tracking API for Titanfall 2 Northstar
|
||||||
|
|
||||||
All query params can be negated using `!`. Example : (`https://toneapi.ovh/v2/client/gamemodes?gamemode=!sns`)
|
All query params can be negated using `!`. Example : (`https://tone.sleepycat.date/v2/client/gamemodes?gamemode=!sns`)
|
||||||
tags:
|
tags:
|
||||||
- name: client
|
- name: client
|
||||||
description: Routes accessibles by everyone
|
description: Routes accessibles by everyone
|
||||||
- name: server
|
- name: server
|
||||||
description: Routes accessibles only to server owners
|
description: Routes accessibles only to server owners
|
||||||
servers:
|
servers:
|
||||||
- url: 'https://toneapi.ovh/v2'
|
- url: 'https://tone.sleepycat.date/v2'
|
||||||
paths:
|
paths:
|
||||||
/client/hosts:
|
/client/hosts:
|
||||||
get:
|
get:
|
||||||
|
|||||||
Generated
+30
-31
@@ -4,7 +4,6 @@
|
|||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "ToneAPI_backend",
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/ws": "^8.5.4",
|
"@types/ws": "^8.5.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@@ -143,9 +142,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@babel/core/node_modules/semver": {
|
"node_modules/@babel/core/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -244,9 +243,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
"node_modules/@babel/helper-compilation-targets/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -337,9 +336,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
|
"node_modules/@babel/helper-define-polyfill-provider/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -1830,9 +1829,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@babel/preset-env/node_modules/semver": {
|
"node_modules/@babel/preset-env/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -3495,9 +3494,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
|
"node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -4476,9 +4475,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/eslint-plugin-import/node_modules/semver": {
|
"node_modules/eslint-plugin-import/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -5695,9 +5694,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/istanbul-lib-instrument/node_modules/semver": {
|
"node_modules/istanbul-lib-instrument/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -6509,9 +6508,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/make-dir/node_modules/semver": {
|
"node_modules/make-dir/node_modules/semver": {
|
||||||
"version": "6.3.1",
|
"version": "6.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"semver": "bin/semver.js"
|
"semver": "bin/semver.js"
|
||||||
@@ -7535,9 +7534,9 @@
|
|||||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||||
},
|
},
|
||||||
"node_modules/semver": {
|
"node_modules/semver": {
|
||||||
"version": "7.5.4",
|
"version": "7.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
|
||||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
"integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lru-cache": "^6.0.0"
|
"lru-cache": "^6.0.0"
|
||||||
@@ -8253,9 +8252,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/word-wrap": {
|
"node_modules/word-wrap": {
|
||||||
"version": "1.2.5",
|
"version": "1.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
|
"resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz",
|
||||||
"integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
|
"integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
|
|||||||
+24
-24
@@ -1,13 +1,13 @@
|
|||||||
import { promises as fs } from "fs";
|
import { promises as fs } from 'fs'
|
||||||
import {
|
import {
|
||||||
FileMigrationProvider,
|
FileMigrationProvider,
|
||||||
Kysely,
|
Kysely,
|
||||||
Migrator,
|
Migrator,
|
||||||
PostgresDialect,
|
PostgresDialect
|
||||||
} from "kysely";
|
} from 'kysely'
|
||||||
import * as path from "path";
|
import * as path from 'path'
|
||||||
import { Pool } from "pg";
|
import { Pool } from 'pg'
|
||||||
import Database from "./model";
|
import type Database from './model'
|
||||||
|
|
||||||
async function migrateToLatest () {
|
async function migrateToLatest () {
|
||||||
const db = new Kysely<Database>({
|
const db = new Kysely<Database>({
|
||||||
@@ -16,37 +16,37 @@ async function migrateToLatest() {
|
|||||||
host: process.env.POSTGRES_HOST,
|
host: process.env.POSTGRES_HOST,
|
||||||
database: process.env.POSTGRES_DATABASE,
|
database: process.env.POSTGRES_DATABASE,
|
||||||
user: process.env.POSTGRES_USER,
|
user: process.env.POSTGRES_USER,
|
||||||
password: process.env.POSTGRES_PASSWORD,
|
password: process.env.POSTGRES_PASSWORD
|
||||||
}),
|
})
|
||||||
}),
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
const migrator = new Migrator({
|
const migrator = new Migrator({
|
||||||
db,
|
db,
|
||||||
provider: new FileMigrationProvider({
|
provider: new FileMigrationProvider({
|
||||||
fs,
|
fs,
|
||||||
path,
|
path,
|
||||||
migrationFolder: path.join(__dirname, "./migrations"),
|
migrationFolder: path.join(__dirname, './migrations')
|
||||||
}),
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
const { error, results } = await migrator.migrateToLatest();
|
const { error, results } = await migrator.migrateToLatest()
|
||||||
|
|
||||||
results?.forEach((it) => {
|
results?.forEach((it) => {
|
||||||
if (it.status === "Success") {
|
if (it.status === 'Success') {
|
||||||
console.log(`migration "${it.migrationName}" was executed successfully`);
|
console.log(`migration "${it.migrationName}" was executed successfully`)
|
||||||
} else if (it.status === "Error") {
|
} else if (it.status === 'Error') {
|
||||||
console.error(`failed to execute migration "${it.migrationName}"`);
|
console.error(`failed to execute migration "${it.migrationName}"`)
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error("failed to migrate");
|
console.error('failed to migrate')
|
||||||
console.error(error);
|
console.error(error)
|
||||||
process.exit(1);
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
await db.destroy();
|
await db.destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
export default migrateToLatest;
|
export default migrateToLatest
|
||||||
|
|||||||
@@ -0,0 +1,140 @@
|
|||||||
|
import { sql, type Kysely } from 'kysely'
|
||||||
|
|
||||||
|
export async function up (db: Kysely<any>): Promise<void> {
|
||||||
|
await db.schema.createSchema('ToneAPI').ifNotExists().execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.host')
|
||||||
|
.addColumn('host_name', 'varchar(50)', (col) => col.notNull())
|
||||||
|
.addColumn('host_id', 'integer', (col) => col.notNull().primaryKey().autoIncrement())
|
||||||
|
.addColumn('host_token', 'varchar(50)', (col) => col.notNull().defaultTo(sql`gen_random_uuid()`))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.server')
|
||||||
|
.addColumn('server_name', 'varchar(64)', (col) => col.notNull())
|
||||||
|
.addColumn('host_id', 'integer', (col) => col.notNull().references('ToneAPI.host.host_id'))
|
||||||
|
.addPrimaryKeyConstraint('server_pkey', ['server_name', 'host_id'])
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.match')
|
||||||
|
.addColumn('match_id', 'integer', (col) => col.notNull().primaryKey().autoIncrement())
|
||||||
|
.addColumn('host_id', 'integer', (col) => col.notNull().primaryKey())
|
||||||
|
.addColumn('server_name', 'varchar(64)', (col) => col.notNull())
|
||||||
|
.addColumn('game_map', 'varchar(30)', (col) => col.notNull())
|
||||||
|
.addColumn('gamemode', 'varchar(10)', (col) => col.notNull())
|
||||||
|
.addColumn('air_accel', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addForeignKeyConstraint('fk_match_host_of_server', ['host_id', 'server_name'], 'ToneAPI.server', ['host_id', 'server_name'])
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.player')
|
||||||
|
.addColumn('player_id', 'bigint', (col) => col.notNull().primaryKey())
|
||||||
|
.addColumn('player_name', 'varchar(50)', (col) => col.notNull())
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.weapon')
|
||||||
|
.addColumn('weapon_id', 'varchar(50)', (col) => col.notNull().primaryKey())
|
||||||
|
.addColumn('weapon_name', 'varchar(50)', (col) => col.notNull())
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.mods_on_weapon')
|
||||||
|
.addColumn('mod_id', 'integer', (col) => col.notNull().primaryKey())
|
||||||
|
.addColumn('speedloader', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('extra_ammo', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('gunrunner', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('gun_ready', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('quickswap', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('tactikill', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('suppressor', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('ricochet', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.addColumn('pro_screen', 'boolean', (col) => col.notNull().defaultTo(false))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.titan_chassis')
|
||||||
|
.addColumn('titan_id', 'varchar(30)', (col) => col.notNull().primaryKey())
|
||||||
|
.addColumn('chassis_name', 'varchar(30)', (col) => col.notNull())
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.loadout')
|
||||||
|
.addColumn('loadout_id', 'integer', (col) => col.notNull().primaryKey().autoIncrement())
|
||||||
|
.addColumn('primary_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('primary_mod_id', 'integer', (col) => col.references('ToneAPI.mods_on_weapon.mod_id'))
|
||||||
|
.addColumn('secondary_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('secondary_mod_id', 'integer', (col) => col.references('ToneAPI.mods_on_weapon.mod_id'))
|
||||||
|
.addColumn('anti_titan_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('anti_titan_mod_id', 'integer', (col) => col.references('ToneAPI.mods_on_weapon.mod_id'))
|
||||||
|
.addColumn('ordnance', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('tactical', 'varchar(50)')
|
||||||
|
.addColumn('titan_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('pilot_passive_1', 'varchar(50)')
|
||||||
|
.addColumn('pilot_passive_2', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_1', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_2', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_3', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_4', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_5', 'varchar(50)')
|
||||||
|
.addColumn('titan_passive_6', 'varchar(50)')
|
||||||
|
.addColumn('titan_special', 'varchar(50)')
|
||||||
|
.addColumn('titan_anti_rodeo', 'varchar(50)')
|
||||||
|
.addColumn('titan_primary_mod', 'varchar(50)')
|
||||||
|
.addColumn('titan_id', 'varchar(50)', (col) => col.references('ToneAPI.titan_chassis.titan_id'))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.kill')
|
||||||
|
.addColumn('kill_id', 'bigint', (col) => col.notNull().primaryKey().autoIncrement())
|
||||||
|
.addColumn('attacker_id', 'bigint', (col) => col.notNull().references('ToneAPI.player.player_id'))
|
||||||
|
.addColumn('victim_id', 'bigint', (col) => col.notNull().references('ToneAPI.player.player_id'))
|
||||||
|
.addColumn('match_id', 'integer', (col) => col.notNull().references('ToneAPI.match.match_id'))
|
||||||
|
.addColumn('attacker_loadout_id', 'integer', (col) => col.notNull().references('ToneAPI.loadout.loadout_id'))
|
||||||
|
.addColumn('victim_loadout_id', 'integer', (col) => col.notNull().references('ToneAPI.loadout.loadout_id'))
|
||||||
|
.addColumn('attacker_speed', 'integer')
|
||||||
|
.addColumn('victim_speed', 'integer')
|
||||||
|
.addColumn('attacker_movementstate', 'varchar(50)')
|
||||||
|
.addColumn('victim_movementstate', 'varchar(50)')
|
||||||
|
.addColumn('distance', 'integer')
|
||||||
|
.addColumn('unix_time', 'timestamp')
|
||||||
|
.addColumn('game_time', 'decimal')
|
||||||
|
.addColumn('cause_of_death', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('attacker_held_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('victim_held_weapon', 'varchar(50)', (col) => col.references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.titan_stats_in_match')
|
||||||
|
.addColumn('match_id', 'integer', (col) => col.notNull().references('ToneAPI.match.match_id'))
|
||||||
|
.addColumn('player_id', 'bigint', (col) => col.notNull().references('ToneAPI.player.player_id'))
|
||||||
|
.addColumn('titan_id', 'varchar(50)', (col) => col.notNull().references('ToneAPI.titan_chassis.titan_id'))
|
||||||
|
.addColumn('playtime', 'bigint')
|
||||||
|
.addColumn('shots_fired', 'integer')
|
||||||
|
.addColumn('shots_hit', 'integer')
|
||||||
|
.addColumn('headshots', 'integer')
|
||||||
|
.addPrimaryKeyConstraint('titan_stats_in_match_pkey', ['match_id', 'player_id', 'titan_id'])
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.weapon_stats_in_match')
|
||||||
|
.addColumn('match_id', 'integer', (col) => col.notNull().references('ToneAPI.match.match_id'))
|
||||||
|
.addColumn('player_id', 'bigint', (col) => col.notNull().references('ToneAPI.player.player_id'))
|
||||||
|
.addColumn('weapon_id', 'varchar(50)', (col) => col.notNull().references('ToneAPI.weapon.weapon_id'))
|
||||||
|
.addColumn('playtime', 'bigint')
|
||||||
|
.addColumn('shots_fired', 'integer')
|
||||||
|
.addColumn('shots_hit', 'integer')
|
||||||
|
.addColumn('headshots', 'integer')
|
||||||
|
.addColumn('ricochets', 'integer')
|
||||||
|
.addPrimaryKeyConstraint('weapon_stats_in_match_pkey', ['match_id', 'player_id', 'weapon_id'])
|
||||||
|
.execute()
|
||||||
|
|
||||||
|
await db.schema.createTable('ToneAPI.player_stats_in_match')
|
||||||
|
.addColumn('match_id', 'integer', (col) => col.notNull().references('ToneAPI.match.match_id'))
|
||||||
|
.addColumn('player_id', 'bigint', (col) => col.notNull().references('ToneAPI.player.player_id'))
|
||||||
|
.addColumn('shots_fired', 'integer')
|
||||||
|
.addColumn('shots_hit', 'integer')
|
||||||
|
.addColumn('headshots', 'integer')
|
||||||
|
.addColumn('ricochets', 'integer')
|
||||||
|
.addColumn('overall_distance_covered', 'bigint')
|
||||||
|
.addColumn('time_grounded', 'bigint')
|
||||||
|
.addColumn('time_wall', 'bigint')
|
||||||
|
.addColumn('time_air', 'bigint')
|
||||||
|
.addPrimaryKeyConstraint('playerstats_in_match_pkey', ['match_id', 'player_id'])
|
||||||
|
.execute()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down (db: Kysely<any>): Promise<void> {
|
||||||
|
|
||||||
|
}
|
||||||
+133
-46
@@ -1,47 +1,129 @@
|
|||||||
import { type Generated } from 'kysely'
|
import { type Generated } from 'kysely'
|
||||||
|
|
||||||
|
interface HostTable {
|
||||||
|
host_name: string
|
||||||
|
host_id: Generated<number>
|
||||||
|
host_token: Generated<string>
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ServerTable {
|
||||||
|
server_name: string
|
||||||
|
host_id: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MatchTable {
|
||||||
|
match_id: Generated<number>
|
||||||
|
host_id: number
|
||||||
|
server_name: string
|
||||||
|
game_map: string
|
||||||
|
gamemode: string
|
||||||
|
air_accel: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PlayerTable {
|
||||||
|
weapon_id: string
|
||||||
|
weapon_name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface WeaponTable {
|
||||||
|
playername: string
|
||||||
|
player_id: number
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ModsOnWeaponTable {
|
||||||
|
mod_id: number
|
||||||
|
speedloader: boolean
|
||||||
|
extra_ammo: boolean
|
||||||
|
gunrunner: boolean
|
||||||
|
gun_ready: boolean
|
||||||
|
quickswap: boolean
|
||||||
|
tactikill: boolean
|
||||||
|
suppressor: boolean
|
||||||
|
ricochet: boolean
|
||||||
|
pro_screen: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TitanChassisTable {
|
||||||
|
titan_id: string
|
||||||
|
chassis_name: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface LoadoutTable {
|
||||||
|
loadout_id: Generated<number>
|
||||||
|
primary_weapon: string
|
||||||
|
secondary_weapon: string
|
||||||
|
anti_titan_weapon: string
|
||||||
|
primary_mod_id: number
|
||||||
|
secondary_mod_id: number
|
||||||
|
anti_titan_mod_id: number
|
||||||
|
ordnance: string
|
||||||
|
tactical: string
|
||||||
|
titan_weapon: string
|
||||||
|
pilot_passive_1: string
|
||||||
|
pilot_passive_2: string
|
||||||
|
titan_passive_1: string
|
||||||
|
titan_passive_2: string
|
||||||
|
titan_passive_3: string
|
||||||
|
titan_passive_4: string
|
||||||
|
titan_passive_5: string
|
||||||
|
titan_passive_6: string
|
||||||
|
titan_special: string
|
||||||
|
titan_anti_rodeo: string
|
||||||
|
titan_primary_mod: string
|
||||||
|
titan_id: string
|
||||||
|
}
|
||||||
|
|
||||||
export interface KillTable {
|
export interface KillTable {
|
||||||
id: Generated<number>
|
kill_id: Generated<bigint>
|
||||||
servername: string
|
attacker_id: bigint
|
||||||
host: number
|
victim_id: bigint
|
||||||
killstat_version: string
|
match_id: number
|
||||||
match_id: string
|
attacker_loadout_id: number
|
||||||
game_mode: string
|
victim_loadout_id: number
|
||||||
map: string
|
attacker_speed: number
|
||||||
unix_time: Generated<Date>
|
victim_speed: number
|
||||||
game_time: number
|
attacker_movementstate: string
|
||||||
player_count: number
|
victim_movementstate: string
|
||||||
attacker_name: string
|
|
||||||
attacker_id: string
|
|
||||||
attacker_current_weapon: string
|
|
||||||
attacker_current_weapon_mods: number
|
|
||||||
attacker_weapon_1: string
|
|
||||||
attacker_weapon_1_mods: number
|
|
||||||
attacker_weapon_2: string
|
|
||||||
attacker_weapon_2_mods: number
|
|
||||||
attacker_weapon_3: string
|
|
||||||
attacker_weapon_3_mods: number
|
|
||||||
attacker_offhand_weapon_1: string
|
|
||||||
attacker_offhand_weapon_1_mods: number
|
|
||||||
attacker_offhand_weapon_2: string
|
|
||||||
attacker_offhand_weapon_2_mods: number
|
|
||||||
victim_name: string
|
|
||||||
victim_id: string
|
|
||||||
victim_current_weapon: string
|
|
||||||
victim_current_weapon_mods: number
|
|
||||||
victim_weapon_1: string
|
|
||||||
victim_weapon_1_mods: number
|
|
||||||
victim_weapon_2: string
|
|
||||||
victim_weapon_2_mods: number
|
|
||||||
victim_weapon_3: string
|
|
||||||
victim_weapon_3_mods: string
|
|
||||||
victim_offhand_weapon_1: string
|
|
||||||
victim_offhand_weapon_1_mods: number
|
|
||||||
victim_offhand_weapon_2: string
|
|
||||||
victim_offhand_weapon_2_mods: number
|
|
||||||
cause_of_death: string
|
|
||||||
distance: number
|
distance: number
|
||||||
titan?: string
|
unix_time: Date
|
||||||
|
game_time: number
|
||||||
|
cause_of_death: string
|
||||||
|
attacker_held_weapon: string
|
||||||
|
victim_held_weapon: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TitanStatsInMatchTable {
|
||||||
|
match_id: number
|
||||||
|
player_id: bigint
|
||||||
|
titan_id: string
|
||||||
|
playtime: bigint
|
||||||
|
shots_fired: number
|
||||||
|
shots_hit: number
|
||||||
|
headshots: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WeaponStatsInMatchTable {
|
||||||
|
match_id: number
|
||||||
|
player_id: bigint
|
||||||
|
weapon_id: string
|
||||||
|
playtime: bigint
|
||||||
|
shots_fired: number
|
||||||
|
shots_hit: number
|
||||||
|
headshots: number
|
||||||
|
ricochets: number
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PlayerStatsInMatchTable {
|
||||||
|
match_id: number
|
||||||
|
player_id: bigint
|
||||||
|
shots_fired: number
|
||||||
|
shots_hit: number
|
||||||
|
headshots: number
|
||||||
|
ricochets: number
|
||||||
|
overall_distance_covered: bigint
|
||||||
|
time_grounded: bigint
|
||||||
|
time_wall: bigint
|
||||||
|
time_air: bigint
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface KillViewTable {
|
export interface KillViewTable {
|
||||||
@@ -59,15 +141,20 @@ export interface KillViewTable {
|
|||||||
total_distance: number
|
total_distance: number
|
||||||
}
|
}
|
||||||
|
|
||||||
interface HosterTable {
|
|
||||||
id: Generated<number>
|
|
||||||
name: string
|
|
||||||
token: Generated<string>
|
|
||||||
}
|
|
||||||
interface Database {
|
interface Database {
|
||||||
kill_view: KillViewTable
|
kill_view: KillViewTable
|
||||||
|
host: HostTable
|
||||||
|
server: ServerTable
|
||||||
|
match: MatchTable
|
||||||
|
player: PlayerTable
|
||||||
|
weapon: WeaponTable
|
||||||
|
mods_on_weapon: ModsOnWeaponTable
|
||||||
|
titan_chassis: TitanChassisTable
|
||||||
|
loadout: LoadoutTable
|
||||||
kill: KillTable
|
kill: KillTable
|
||||||
host: HosterTable
|
titan_stats_in_match: TitanStatsInMatchTable
|
||||||
|
weapon_stats_in_match: WeaponStatsInMatchTable
|
||||||
|
player_stats_in_match: PlayerStatsInMatchTable
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Database
|
export default Database
|
||||||
|
|||||||
Reference in New Issue
Block a user