remake in Golang
This commit is contained in:
@@ -32,3 +32,5 @@
|
||||
**/dist
|
||||
LICENSE
|
||||
README.md
|
||||
|
||||
**/app
|
||||
@@ -1,5 +1,3 @@
|
||||
DB_HOST=iceberg-gaming.com
|
||||
DB_PORT=3306
|
||||
DB_USERNAME=user
|
||||
DB_PASSWORD=pass
|
||||
DB_DATABASE=dbname
|
||||
mariadb.connectionstring=user:password@tcp(localhost:3306)/dbname?parseTime=true
|
||||
api.prefix=/api/v1
|
||||
api.port=1323
|
||||
7
.gitignore
vendored
7
.gitignore
vendored
@@ -1,2 +1,5 @@
|
||||
node_modules
|
||||
.env
|
||||
*.exe
|
||||
**/*.log*
|
||||
**/*.log
|
||||
!**.gitkeep
|
||||
.env
|
||||
37
Dockerfile
37
Dockerfile
@@ -1,32 +1,15 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
# Comments are provided throughout this file to help you get started.
|
||||
# If you need more help, visit the Dockerfile reference guide at
|
||||
# https://docs.docker.com/engine/reference/builder/
|
||||
|
||||
ARG NODE_VERSION=16.17.0
|
||||
|
||||
FROM node:${NODE_VERSION}-alpine
|
||||
|
||||
# Use production node environment by default.
|
||||
ENV NODE_ENV production
|
||||
# Build golang
|
||||
FROM golang:1.22.0 as builder
|
||||
WORKDIR /usr/src/api
|
||||
COPY ./api .
|
||||
RUN go mod download
|
||||
RUN go build -o /docker-api .
|
||||
|
||||
|
||||
WORKDIR /usr/src/app
|
||||
|
||||
# Download dependencies as a separate step to take advantage of Docker's caching.
|
||||
# Leverage a cache mount to /root/.npm to speed up subsequent builds.
|
||||
COPY package-lock.json package.json ./
|
||||
RUN --mount=type=cache,target=/root/.npm \
|
||||
npm ci --omit=dev
|
||||
FROM ubuntu:latest
|
||||
|
||||
# Run the application as a non-root user.
|
||||
USER node
|
||||
WORKDIR /usr/src/api
|
||||
COPY --from=builder /docker-api /usr/src/api/docker-api
|
||||
|
||||
COPY server.js .
|
||||
|
||||
# Expose the port that the application listens on.
|
||||
EXPOSE 4000
|
||||
|
||||
# Run the application.
|
||||
CMD node server.js
|
||||
CMD ["./docker-api"]
|
||||
|
||||
39
README.md
39
README.md
@@ -1,21 +1,34 @@
|
||||
# 17th-UnitTracker-API
|
||||
# Unit Tracker API
|
||||
|
||||
## Configure
|
||||
|
||||
1. Copy `.env.example` to `.env`
|
||||
1. Set the environment variables in `.env`
|
||||
|
||||
## Run
|
||||
|
||||
1. Put your static files in the `static` folder
|
||||
1. Run the server
|
||||
|
||||
### Docker
|
||||
|
||||
```docker
|
||||
docker-compose up -d --build
|
||||
# Startup
|
||||
docker compose -f "docker-compose.yaml" up -d --build
|
||||
# Shutdown
|
||||
docker compose -f "docker-compose.yaml" down
|
||||
```
|
||||
|
||||
OR
|
||||
### Build binary with Go toolchain
|
||||
|
||||
if running as basic container, uncomment the dotenv line in server.js
|
||||
|
||||
```docker
|
||||
docker build -t unit-tracker-api .
|
||||
docker run -p 4000:4000 unit-tracker-api
|
||||
```powershell
|
||||
go build -o unit-tracker-api.exe ./api
|
||||
.\unit-tracker-api.exe
|
||||
```
|
||||
|
||||
OR
|
||||
## Use
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm start
|
||||
```
|
||||
Example endpoints:
|
||||
|
||||
http://localhost:1323/api/v1/members
|
||||
http://localhost:1323/api/v1/members/3
|
||||
|
||||
55
api/config.go
Normal file
55
api/config.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/logger"
|
||||
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var Config *viper.Viper
|
||||
|
||||
func LoadConfig() error {
|
||||
setConfigDefaults()
|
||||
|
||||
// Read in environment variables
|
||||
viper.AutomaticEnv() // read in environment variables that match
|
||||
|
||||
// Use config file (like json or yaml)
|
||||
// viper.SetConfigName("config") // name of config file (without extension)
|
||||
// viper.SetConfigType("yaml") // REQUIRED if the config file does not have the extension in the name
|
||||
// Use .env file
|
||||
viper.SetConfigFile(".env") // name of config file (without extension
|
||||
|
||||
// viper.AddConfigPath("/etc/appname/") // path to look for the config file in
|
||||
// viper.AddConfigPath("$HOME/.appname") // call multiple times to add many search paths
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
return fmt.Errorf("fatal error config file: %w", err)
|
||||
}
|
||||
|
||||
if err := viper.ReadInConfig(); err != nil {
|
||||
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
|
||||
// Config file not found; ignore error if desired
|
||||
return fmt.Errorf("config file not found: %w", err)
|
||||
} else {
|
||||
// Config file was found but another error was produced
|
||||
return fmt.Errorf("fatal error config file: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Config file found and successfully parsed
|
||||
Config = viper.GetViper()
|
||||
|
||||
logger.Log.Debug().Interface("config", Config.AllSettings()).Msg("Configuration loaded")
|
||||
return nil
|
||||
}
|
||||
|
||||
func setConfigDefaults() {
|
||||
viper.SetDefault("MARIADB_CONNSTRING", "user:password@tcp(localhost:3306)/dbname?parseTime=true")
|
||||
viper.SetDefault("API_PREFIX", "/api/v1")
|
||||
viper.SetDefault("API_PORT", "1323")
|
||||
}
|
||||
46
api/db/main.go
Normal file
46
api/db/main.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"sync"
|
||||
|
||||
_ "github.com/go-sql-driver/mysql"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var ActiveDB *sql.DB
|
||||
var lock = new(sync.Mutex)
|
||||
|
||||
func GetDB() (*sql.DB, error) {
|
||||
|
||||
if ActiveDB != nil {
|
||||
return ActiveDB, nil
|
||||
}
|
||||
|
||||
db, err := ConnectDB()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ActiveDB = db
|
||||
return db, nil
|
||||
}
|
||||
|
||||
func ConnectDB() (*sql.DB, error) {
|
||||
lock.Lock()
|
||||
defer lock.Unlock()
|
||||
|
||||
if ActiveDB != nil {
|
||||
ActiveDB.Close()
|
||||
ActiveDB = nil
|
||||
}
|
||||
|
||||
cfg := viper.GetViper()
|
||||
db, err := sql.Open("mysql", cfg.GetString("MARIADB_CONNSTRING"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ActiveDB = db
|
||||
return db, nil
|
||||
}
|
||||
43
api/go.mod
Normal file
43
api/go.mod
Normal file
@@ -0,0 +1,43 @@
|
||||
module gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API
|
||||
|
||||
go 1.22
|
||||
|
||||
require (
|
||||
github.com/go-sql-driver/mysql v1.7.1
|
||||
github.com/labstack/echo/v4 v4.11.4
|
||||
github.com/labstack/gommon v0.4.2
|
||||
github.com/spf13/viper v1.18.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/magiconair/properties v1.8.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||
github.com/rs/zerolog v1.32.0 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.0 // indirect
|
||||
github.com/spf13/cast v1.6.0 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/crypto v0.20.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect
|
||||
golang.org/x/net v0.21.0 // indirect
|
||||
golang.org/x/sys v0.17.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/time v0.5.0 // indirect
|
||||
gopkg.in/guregu/null.v3 v3.5.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
105
api/go.sum
Normal file
105
api/go.sum
Normal file
@@ -0,0 +1,105 @@
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
|
||||
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/labstack/echo/v4 v4.11.4 h1:vDZmA+qNeh1pd/cCkEicDMrjtrnMGQ1QFI9gWN1zGq8=
|
||||
github.com/labstack/echo/v4 v4.11.4/go.mod h1:noh7EvLwqDsmh/X/HWKPUl1AjzJrhyptRyEbQJfxen8=
|
||||
github.com/labstack/gommon v0.4.2 h1:F8qTUNXgG1+6WQmqoUWnz8WiEU60mXVVw0P4ht1WRA0=
|
||||
github.com/labstack/gommon v0.4.2/go.mod h1:QlUFxVM+SNXhDL/Z7YhocGIBYOiwB0mXm1+1bAPHPyU=
|
||||
github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY=
|
||||
github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.32.0 h1:keLypqrlIjaFsbmJOBdB/qvyF8KEtCWHwobLp5l/mQ0=
|
||||
github.com/rs/zerolog v1.32.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0=
|
||||
github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8=
|
||||
github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY=
|
||||
github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/crypto v0.20.0 h1:jmAMJJZXr5KiCw05dfYK9QnqaqKLYXijU23lsEdcQqg=
|
||||
golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ=
|
||||
golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc=
|
||||
golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
|
||||
golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
|
||||
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
|
||||
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/guregu/null.v3 v3.5.0 h1:xTcasT8ETfMcUHn0zTvIYtQud/9Mx5dJqD554SZct0o=
|
||||
gopkg.in/guregu/null.v3 v3.5.0/go.mod h1:E4tX2Qe3h7QdL+uZ3a0vqvYwKQsRSQKM5V4YltdgH9Y=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
37
api/logger/logger.go
Normal file
37
api/logger/logger.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package logger
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/rs/zerolog"
|
||||
"gopkg.in/natefinch/lumberjack.v2"
|
||||
)
|
||||
|
||||
var Log zerolog.Logger
|
||||
|
||||
func init() {
|
||||
|
||||
// Set up logging
|
||||
var logPath string
|
||||
logPath = "logs/server_api.log"
|
||||
apiLogger := &lumberjack.Logger{
|
||||
Filename: logPath,
|
||||
MaxSize: 10, // megabytes
|
||||
MaxBackups: 3,
|
||||
MaxAge: 28, // days
|
||||
}
|
||||
apiLogger.Rotate()
|
||||
|
||||
Log = zerolog.New(
|
||||
zerolog.MultiLevelWriter( // Send logs to both console and file
|
||||
// zerolog.ConsoleWriter{Out: os.Stdout},
|
||||
os.Stdout,
|
||||
// zerolog.ConsoleWriter{
|
||||
// Out: apiLogger,
|
||||
// NoColor: true,
|
||||
// },
|
||||
apiLogger,
|
||||
),
|
||||
).With().Timestamp().Logger()
|
||||
|
||||
}
|
||||
94
api/main.go
Normal file
94
api/main.go
Normal file
@@ -0,0 +1,94 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/logger"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"github.com/rs/zerolog"
|
||||
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/db"
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/routes"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
var err error
|
||||
|
||||
// err = godotenv.Load(".env")
|
||||
// if err != nil {
|
||||
// logger.Log.Warn().Err(err).Msg("Error loading .env file")
|
||||
// }
|
||||
|
||||
e := echo.New()
|
||||
|
||||
// Set up logging
|
||||
zerolog.TimeFieldFormat = time.RFC3339
|
||||
logger.Log = logger.Log.Level(zerolog.TraceLevel)
|
||||
// logger.Log = logger.Log.Level(zerolog.DebugLevel)
|
||||
// logger.Log = logger.Log.Level(zerolog.InfoLevel)
|
||||
logger.Log.Info().Msg("Logger initialized")
|
||||
|
||||
e.GET("/", func(c echo.Context) error {
|
||||
return c.String(http.StatusOK, "Hello, World!")
|
||||
})
|
||||
|
||||
err = LoadConfig()
|
||||
if err != nil {
|
||||
logger.Log.Fatal().Err(err).Msg("Error loading configuration")
|
||||
} else {
|
||||
logger.Log.Info().Msg("Configuration loaded")
|
||||
}
|
||||
|
||||
// Connect to the database
|
||||
_, err = db.GetDB()
|
||||
if err != nil {
|
||||
logger.Log.Fatal().Err(err).Msg("Error connecting to the database")
|
||||
} else {
|
||||
logger.Log.Info().Msg("Connected to the database")
|
||||
}
|
||||
|
||||
// Middleware
|
||||
e.Use(middleware.RequestLoggerWithConfig(middleware.RequestLoggerConfig{
|
||||
LogLatency: true,
|
||||
LogURIPath: true,
|
||||
LogMethod: true,
|
||||
LogReferer: true,
|
||||
LogUserAgent: true,
|
||||
LogContentLength: true,
|
||||
LogError: true,
|
||||
LogRemoteIP: true,
|
||||
LogURI: true,
|
||||
LogStatus: true,
|
||||
LogHost: true,
|
||||
LogRoutePath: true,
|
||||
LogRequestID: true,
|
||||
LogValuesFunc: func(c echo.Context, v middleware.RequestLoggerValues) error {
|
||||
logger.Log.Trace().
|
||||
Caller().
|
||||
Interface("RequestLoggerValues", v).
|
||||
Send()
|
||||
return nil
|
||||
|
||||
},
|
||||
}))
|
||||
e.Use(middleware.SecureWithConfig(middleware.SecureConfig{
|
||||
XSSProtection: "",
|
||||
ContentTypeNosniff: "",
|
||||
XFrameOptions: "",
|
||||
HSTSMaxAge: 3600,
|
||||
// ContentSecurityPolicy: "default-src 'self'",
|
||||
}))
|
||||
|
||||
e.IPExtractor = echo.ExtractIPDirect()
|
||||
e.Use(middleware.Recover())
|
||||
|
||||
// Routes
|
||||
routes.SetupRoutes(e)
|
||||
e.Use(middleware.Static("static"))
|
||||
|
||||
e.Logger.Fatal(e.Start(":" + Config.GetString("API_PORT")))
|
||||
}
|
||||
198
api/ops/member.go
Normal file
198
api/ops/member.go
Normal file
@@ -0,0 +1,198 @@
|
||||
package ops
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/db"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"gopkg.in/guregu/null.v3"
|
||||
)
|
||||
|
||||
/*
|
||||
|
||||
DDL
|
||||
|
||||
CREATE TABLE `members` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`timezone` varchar(5) DEFAULT NULL,
|
||||
`email` varchar(100) DEFAULT NULL,
|
||||
`website` varchar(240) DEFAULT NULL,
|
||||
`guilded_id` varchar(10) DEFAULT NULL,
|
||||
`steam_id_64` varchar(17) DEFAULT NULL,
|
||||
`teamspeak_uid` varchar(32) DEFAULT NULL,
|
||||
`steam_profile_name` varchar(32) DEFAULT NULL,
|
||||
`discord_id` varchar(20) DEFAULT NULL,
|
||||
`discord_username` varchar(32) DEFAULT NULL,
|
||||
`aliases` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`aliases`)),
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`deleted` tinyint(4) DEFAULT NULL,
|
||||
`remarks` text DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name` (`name`),
|
||||
UNIQUE KEY `steamId64` (`steam_id_64`) USING BTREE,
|
||||
UNIQUE KEY `discordId` (`discord_id`) USING BTREE,
|
||||
UNIQUE KEY `guilded_id` (`guilded_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=186 DEFAULT CHARSET=utf8mb4;
|
||||
*/
|
||||
|
||||
// Member is a struct that represents a member
|
||||
type Member struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Timezone null.String `json:"timezone"`
|
||||
Email null.String `json:"email"`
|
||||
Website null.String `json:"website"`
|
||||
GuildedID null.String `json:"guilded_id"`
|
||||
SteamID64 null.String `json:"steam_id_64"`
|
||||
TeamspeakUID null.String `json:"teamspeak_uid"`
|
||||
SteamProfileName null.String `json:"steam_profile_name"`
|
||||
DiscordID null.String `json:"discord_id"`
|
||||
DiscordUsername null.String `json:"discord_username"`
|
||||
Aliases null.String `json:"aliases"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
Deleted null.Int `json:"deleted"`
|
||||
Remarks null.String `json:"remarks"`
|
||||
}
|
||||
|
||||
/*
|
||||
DDL
|
||||
|
||||
CREATE TABLE `members` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(100) NOT NULL,
|
||||
`timezone` varchar(5) DEFAULT NULL,
|
||||
`email` varchar(100) DEFAULT NULL,
|
||||
`website` varchar(240) DEFAULT NULL,
|
||||
`guilded_id` varchar(10) DEFAULT NULL,
|
||||
`steam_id_64` varchar(17) DEFAULT NULL,
|
||||
`teamspeak_uid` varchar(32) DEFAULT NULL,
|
||||
`steam_profile_name` varchar(32) DEFAULT NULL,
|
||||
`discord_id` varchar(20) DEFAULT NULL,
|
||||
`discord_username` varchar(32) DEFAULT NULL,
|
||||
`aliases` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL CHECK (json_valid(`aliases`)),
|
||||
`created_at` datetime NOT NULL DEFAULT current_timestamp(),
|
||||
`updated_at` datetime NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
`deleted` tinyint(4) DEFAULT NULL,
|
||||
`remarks` text DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `name` (`name`),
|
||||
UNIQUE KEY `steamId64` (`steam_id_64`) USING BTREE,
|
||||
UNIQUE KEY `discordId` (`discord_id`) USING BTREE,
|
||||
UNIQUE KEY `guilded_id` (`guilded_id`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=186 DEFAULT CHARSET=utf8mb4;
|
||||
*/
|
||||
|
||||
// GetMembers returns a list of all members
|
||||
func GetMembers(c echo.Context) error {
|
||||
|
||||
members := []Member{}
|
||||
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(),
|
||||
2*time.Second,
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
rows, err := db.ActiveDB.QueryContext(
|
||||
ctx,
|
||||
"SELECT * FROM members",
|
||||
)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"error": "request timed out",
|
||||
})
|
||||
}
|
||||
|
||||
// scan the rows into the members slice
|
||||
for rows.Next() {
|
||||
var m Member
|
||||
err = rows.Scan(
|
||||
&m.ID,
|
||||
&m.Name,
|
||||
&m.Timezone,
|
||||
&m.Email,
|
||||
&m.Website,
|
||||
&m.GuildedID,
|
||||
&m.SteamID64,
|
||||
&m.TeamspeakUID,
|
||||
&m.SteamProfileName,
|
||||
&m.DiscordID,
|
||||
&m.DiscordUsername,
|
||||
&m.Aliases,
|
||||
&m.CreatedAt,
|
||||
&m.UpdatedAt,
|
||||
&m.Deleted,
|
||||
&m.Remarks,
|
||||
)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
members = append(members, m)
|
||||
}
|
||||
|
||||
return c.JSON(200, members)
|
||||
}
|
||||
|
||||
// GetMember returns a single member by ID
|
||||
func GetMember(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
|
||||
if id == "" {
|
||||
return fmt.Errorf("id is required")
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(),
|
||||
2*time.Second,
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
returnMember := Member{}
|
||||
err := db.ActiveDB.QueryRowContext(
|
||||
ctx,
|
||||
"SELECT * FROM members WHERE id = ?",
|
||||
id,
|
||||
).Scan(
|
||||
&returnMember.ID,
|
||||
&returnMember.Name,
|
||||
&returnMember.Timezone,
|
||||
&returnMember.Email,
|
||||
&returnMember.Website,
|
||||
&returnMember.GuildedID,
|
||||
&returnMember.SteamID64,
|
||||
&returnMember.TeamspeakUID,
|
||||
&returnMember.SteamProfileName,
|
||||
&returnMember.DiscordID,
|
||||
&returnMember.DiscordUsername,
|
||||
&returnMember.Aliases,
|
||||
&returnMember.CreatedAt,
|
||||
&returnMember.UpdatedAt,
|
||||
&returnMember.Deleted,
|
||||
&returnMember.Remarks,
|
||||
)
|
||||
if err != nil {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
})
|
||||
}
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
return c.JSON(500, map[string]interface{}{
|
||||
"error": "request timed out",
|
||||
})
|
||||
}
|
||||
|
||||
return c.JSON(200, returnMember)
|
||||
}
|
||||
40
api/routes/handler.go
Normal file
40
api/routes/handler.go
Normal file
@@ -0,0 +1,40 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/db"
|
||||
"gitea.iceberg-gaming.com/17th-Ranger-Battalion-ORG/17th-UnitTracker-API/ops"
|
||||
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
var ErrInvalidPath = errors.New("invalid path")
|
||||
|
||||
func SetupRoutes(
|
||||
e *echo.Echo,
|
||||
) {
|
||||
|
||||
cfg := viper.GetViper()
|
||||
prefixURL := strings.TrimRight(cfg.GetString("API_PREFIX"), "/")
|
||||
mainPrefix := e.Group(prefixURL, func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// do something before the next handler
|
||||
// ensure we always have a db connection
|
||||
_, err := db.GetDB()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return next(c)
|
||||
}
|
||||
})
|
||||
|
||||
// MEMBER OPERATIONS
|
||||
g := mainPrefix.Group("/members")
|
||||
|
||||
g.GET("", ops.GetMembers)
|
||||
g.GET("/:id", ops.GetMember)
|
||||
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
name: 17th-unittracker-api
|
||||
|
||||
services:
|
||||
server:
|
||||
env_file:
|
||||
- .env
|
||||
api:
|
||||
image: 17th-unittracker-api
|
||||
env_file: .env
|
||||
container_name: 17th-unittracker-api
|
||||
build:
|
||||
context: .
|
||||
environment:
|
||||
NODE_ENV: production
|
||||
DB_HOST: ${DB_HOST}
|
||||
DB_PORT: ${DB_PORT}
|
||||
DB_USERNAME: ${DB_USERNAME}
|
||||
DB_PASSWORD: ${DB_PASSWORD}
|
||||
DB_DATABASE: ${DB_DATABASE}
|
||||
dockerfile: Dockerfile
|
||||
volumes:
|
||||
- ./.env:/usr/src/api/.env
|
||||
- ./logs:/usr/src/api/logs
|
||||
- ./static:/usr/src/api/static
|
||||
ports:
|
||||
- 4000:4000
|
||||
- ${API_PORT}:${API_PORT}
|
||||
|
||||
|
||||
56
go.work.sum
Normal file
56
go.work.sum
Normal file
@@ -0,0 +1,56 @@
|
||||
cloud.google.com/go v0.110.10/go.mod h1:v1OoFqYxiBkUrruItNM3eT4lLByNjxmJSV/xDKJNnic=
|
||||
cloud.google.com/go/compute v1.23.3/go.mod h1:VCgBUoMnIVIR0CscqQiPJLAG25E3ZRZMzcFZeQ+h8CI=
|
||||
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
|
||||
cloud.google.com/go/firestore v1.14.0/go.mod h1:96MVaHLsEhbvkBEdZgfN+AS/GIkco1LRpH9Xp9YZfzQ=
|
||||
cloud.google.com/go/iam v1.1.5/go.mod h1:rB6P/Ic3mykPbFio+vo7403drjlgvoWfYpJhMXEbzv8=
|
||||
cloud.google.com/go/longrunning v0.5.4/go.mod h1:zqNVncI0BOP8ST6XQD1+VcvuShMmq7+xFSzOL++V0dI=
|
||||
cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8=
|
||||
github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4=
|
||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||
github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
|
||||
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw=
|
||||
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0=
|
||||
github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
|
||||
github.com/googleapis/google-cloud-go-testing v0.0.0-20210719221736-1c9a4c676720/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
|
||||
github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8=
|
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4=
|
||||
github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
|
||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/nats-io/nats.go v1.31.0/go.mod h1:di3Bm5MLsoB4Bx61CBTsxuarI36WbhAwOm8QrW39+i8=
|
||||
github.com/nats-io/nkeys v0.4.6/go.mod h1:4DxZNzenSVd1cYQoAa8948QY3QDjrHfcfVADymtkpts=
|
||||
github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
|
||||
github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk=
|
||||
github.com/sagikazarmark/crypt v0.17.0/go.mod h1:SMtHTvdmsZMuY/bpZoqokSoChIrcJ/epOxZN58PbZDg=
|
||||
go.etcd.io/etcd/api/v3 v3.5.10/go.mod h1:TidfmT4Uycad3NM/o25fG3J07odo4GBB9hoxaodFCtI=
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.10/go.mod h1:DYivfIviIuQ8+/lCq4vcxuseg2P2XbHygkKwFo9fc8U=
|
||||
go.etcd.io/etcd/client/v2 v2.305.10/go.mod h1:m3CKZi69HzilhVqtPDcjhSGp+kA1OmbNn0qamH80xjA=
|
||||
go.etcd.io/etcd/client/v3 v3.5.10/go.mod h1:RVeBnDz2PUEZqTpgqwAtUd8nAPf5kjyFyND7P1VkOKc=
|
||||
go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo=
|
||||
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw=
|
||||
golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
|
||||
golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM=
|
||||
golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg=
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
|
||||
google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY=
|
||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||
google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc=
|
||||
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
|
||||
google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
0
logs/.gitkeep
Normal file
0
logs/.gitkeep
Normal file
1628
package-lock.json
generated
1628
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
20
package.json
20
package.json
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "17th-unittracker-api",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "server.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "node server.js"
|
||||
},
|
||||
"author": "IndigoFox",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@apollo/server": "^4.7.1",
|
||||
"db2graphql": "^0.12.0",
|
||||
"dotenv": "^16.0.3",
|
||||
"graphql": "^16.6.0",
|
||||
"knex": "^2.4.2",
|
||||
"mysql": "^2.18.1"
|
||||
}
|
||||
}
|
||||
45
server.js
45
server.js
@@ -1,45 +0,0 @@
|
||||
const knex = require('knex');
|
||||
const db2g = require('db2graphql');
|
||||
const { ApolloServer } = require('@apollo/server');
|
||||
const { startStandaloneServer } = require('@apollo/server/standalone');
|
||||
// dotenv - not used if running in docker compose
|
||||
// require('dotenv').config();
|
||||
|
||||
// get env variables
|
||||
const { DB_HOST, DB_PORT, DB_USERNAME, DB_PASSWORD, DB_DATABASE } = process.env;
|
||||
|
||||
const start = async (cb) => {
|
||||
|
||||
/**************************************/
|
||||
const api = new db2g('mariadb', knex({
|
||||
client: 'mysql',
|
||||
connection: {
|
||||
host: DB_HOST,
|
||||
port: DB_PORT,
|
||||
user: DB_USERNAME,
|
||||
password: DB_PASSWORD,
|
||||
database: DB_DATABASE
|
||||
}
|
||||
}));
|
||||
await api.connect(DB_DATABASE); // Connects to database and extracts database schema
|
||||
|
||||
// Get generated schema and resolvers
|
||||
const schema = api.getSchema();
|
||||
const resolvers = api.getResolvers();
|
||||
/**************************************/
|
||||
|
||||
// Create Apollo Server and start
|
||||
if (!schema) throw new Error('Error: empty schema');
|
||||
console.log(schema);
|
||||
const server = new ApolloServer({
|
||||
typeDefs: schema,
|
||||
resolvers,
|
||||
introspection: true,
|
||||
playground: true,
|
||||
});
|
||||
startStandaloneServer(server).then(({ url }) => {
|
||||
console.log(`🚀 Server ready at ${url}`);
|
||||
});
|
||||
}
|
||||
|
||||
start();
|
||||
0
static/.gitkeep
Normal file
0
static/.gitkeep
Normal file
Reference in New Issue
Block a user