diff --git a/.env b/.env
new file mode 100644
index 0000000..2411a66
--- /dev/null
+++ b/.env
@@ -0,0 +1,2 @@
+ADMIN_TOKEN=admin
+DATABASE_URL=postgresql://root:admin@192.168.0.15:5432/skyvillage
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/discord.xml b/.idea/discord.xml
new file mode 100644
index 0000000..d8e9561
--- /dev/null
+++ b/.idea/discord.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..9b42af1
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/skyvillage-api.iml b/.idea/skyvillage-api.iml
new file mode 100644
index 0000000..5e764c4
--- /dev/null
+++ b/.idea/skyvillage-api.iml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000..fe5f0a7
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,15 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "name": "Launch Package",
+ "type": "go",
+ "request": "launch",
+ "mode": "auto",
+ "program": "/home/bendi/Dokumentumok/skyvillage-api/main.go"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/Makefile b/Makefile
index 7cf1b52..75c7667 100644
--- a/Makefile
+++ b/Makefile
@@ -1,2 +1,8 @@
migrate:
- go run github.com/prisma/prisma-client-go migrate dev --name init
\ No newline at end of file
+ go run github.com/prisma/prisma-client-go migrate dev --name init
+
+format:
+ go run github.com/prisma/prisma-client-go format
+
+studio:
+ go run github.com/prisma/prisma-client-go studio
\ No newline at end of file
diff --git a/database/db.go b/database/db.go
new file mode 100644
index 0000000..8957246
--- /dev/null
+++ b/database/db.go
@@ -0,0 +1,18 @@
+package database
+
+import (
+ "log"
+
+ "github.com/SkyVillageMc/skyvillage-api/db"
+)
+
+var DB *db.PrismaClient
+
+func Init() {
+ DB = db.NewClient()
+
+ if err := DB.Prisma.Connect(); err != nil {
+ //This shouldn't happen
+ log.Fatalf("Error connecting to the db\n%s\n", err.Error())
+ }
+}
diff --git a/dev.db b/dev.db
index 58028e9..0d67969 100644
Binary files a/dev.db and b/dev.db differ
diff --git a/dev.db-journal b/dev.db-journal
index 9c2a78e..8146a0b 100644
Binary files a/dev.db-journal and b/dev.db-journal differ
diff --git a/go.mod b/go.mod
index 3c9e881..2ebc8a2 100644
--- a/go.mod
+++ b/go.mod
@@ -3,16 +3,17 @@ module github.com/SkyVillageMc/skyvillage-api
go 1.17
require (
- github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365
- github.com/joho/godotenv v1.3.0
+ github.com/gin-gonic/gin v1.7.4
+ github.com/gorilla/websocket v1.4.2
+ github.com/iancoleman/strcase v0.2.0
+ github.com/joho/godotenv v1.4.0
github.com/prisma/prisma-client-go v0.11.0
- github.com/shopspring/decimal v1.2.0
+ github.com/shopspring/decimal v1.3.0
github.com/takuoki/gocase v1.0.0
)
require (
github.com/gin-contrib/sse v0.1.0 // indirect
- github.com/gin-gonic/gin v1.7.4 // indirect
github.com/go-playground/locales v0.14.0 // indirect
github.com/go-playground/universal-translator v0.18.0 // indirect
github.com/go-playground/validator/v10 v10.9.0 // indirect
@@ -24,8 +25,9 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/ugorji/go/codec v1.2.6 // indirect
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 // indirect
- golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect
+ golang.org/x/sys v0.0.0-20211013075003-97ac67df715c // indirect
golang.org/x/text v0.3.7 // indirect
+ golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
google.golang.org/protobuf v1.27.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 64a69ca..a591187 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,4 @@
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -7,6 +6,7 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
+github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
@@ -21,20 +21,27 @@ github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaW
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365 h1:ECW73yc9MY7935nNYXUkK7Dz17YuSUI9yqRqYS8aBww=
+github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/iancoleman/strcase v0.0.0-20190422225806-e506e3ef7365/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE=
-github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc=
+github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
+github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
+github.com/joho/godotenv v1.4.0 h1:3l4+N6zfMWnkbPEXKng2o2/MR5mSwTrBih4ZEkkz1lg=
+github.com/joho/godotenv v1.4.0/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
@@ -54,12 +61,13 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN
github.com/prisma/prisma-client-go v0.11.0 h1:n1MxhIOOShaUFaEeqLa0OuCsnOkkUIsA7BHvmwQXXEI=
github.com/prisma/prisma-client-go v0.11.0/go.mod h1:M8YaRRW8pd/uUgrz8zW6JwnlaywqD15g1ETo9fXpmSQ=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
+github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
-github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.0 h1:KK3gWIXskZ2O1U/JNTisNcvH+jveJxZYrjbTsrbbnh8=
+github.com/shopspring/decimal v1.3.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
-github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
@@ -86,8 +94,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac h1:oN6lz7iLW/YC7un8pq+9bOLyXrprv2+DKfkJY+2LJJw=
-golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.0.0-20211013075003-97ac67df715c h1:taxlMj0D/1sOAuv/CbSD+MMDof2vbyPTqz5FNYKpXt8=
+golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@@ -97,18 +105,21 @@ golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/main.go b/main.go
index 40a2d63..2a67bc0 100644
--- a/main.go
+++ b/main.go
@@ -3,6 +3,7 @@ package main
import (
"log"
+ "github.com/SkyVillageMc/skyvillage-api/database"
"github.com/SkyVillageMc/skyvillage-api/routes"
"github.com/gin-gonic/gin"
)
@@ -11,6 +12,17 @@ func main() {
log.Println("Starting...")
r := gin.Default()
+ database.Init()
+ defer func() {
+ if err := database.DB.Prisma.Disconnect(); err != nil {
+ //Pretty sure this wouldn't happen anytime soon(maybe because of sqlite)
+ log.Fatalf("Error diconnecting from the db\n%s\n", err.Error())
+ }
+ }()
+
+ routes.InitWs(r)
+ routes.InitPresence(r.Group("/presence"))
+ routes.InitUsers(r.Group("/user"))
routes.InitAuth(r.Group("/auth"))
r.GET("/ping", func(c *gin.Context) {
diff --git a/migrations/20211015172655_init/migration.sql b/migrations/20211015172655_init/migration.sql
new file mode 100644
index 0000000..dafcaab
--- /dev/null
+++ b/migrations/20211015172655_init/migration.sql
@@ -0,0 +1,54 @@
+-- CreateTable
+CREATE TABLE "User" (
+ "id" TEXT NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+ "name" TEXT NOT NULL,
+ "role" INTEGER NOT NULL DEFAULT 0,
+ "presence_id" INTEGER NOT NULL,
+ "party_id" TEXT NOT NULL,
+
+ CONSTRAINT "User_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateTable
+CREATE TABLE "Presence" (
+ "user_id" TEXT NOT NULL,
+ "state" TEXT NOT NULL DEFAULT E'',
+ "large_image_key" TEXT NOT NULL DEFAULT E'logo_large',
+ "small_image_key" TEXT NOT NULL DEFAULT E'loading',
+ "start_time" BIGINT NOT NULL DEFAULT 0,
+ "end_time" BIGINT NOT NULL DEFAULT 0,
+ "details" TEXT NOT NULL DEFAULT E'',
+ "large_image_text" TEXT NOT NULL DEFAULT E'',
+ "small_image_text" TEXT NOT NULL DEFAULT E'',
+ "party_id" TEXT NOT NULL,
+
+ CONSTRAINT "Presence_pkey" PRIMARY KEY ("user_id")
+);
+
+-- CreateTable
+CREATE TABLE "Party" (
+ "id" TEXT NOT NULL,
+ "min" INTEGER NOT NULL DEFAULT 0,
+ "max" INTEGER NOT NULL DEFAULT 5,
+ "join_secret" TEXT NOT NULL DEFAULT E'',
+ "owner_id" TEXT NOT NULL,
+
+ CONSTRAINT "Party_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "Party_owner_id_unique" ON "Party"("owner_id");
+
+-- AddForeignKey
+ALTER TABLE "User" ADD CONSTRAINT "User_id_fkey" FOREIGN KEY ("id") REFERENCES "Presence"("user_id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "User" ADD CONSTRAINT "User_party_id_fkey" FOREIGN KEY ("party_id") REFERENCES "Party"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Presence" ADD CONSTRAINT "Presence_party_id_fkey" FOREIGN KEY ("party_id") REFERENCES "Party"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
+
+-- AddForeignKey
+ALTER TABLE "Party" ADD CONSTRAINT "Party_owner_id_fkey" FOREIGN KEY ("owner_id") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
diff --git a/migrations/20211015175235_init/migration.sql b/migrations/20211015175235_init/migration.sql
new file mode 100644
index 0000000..be177b9
--- /dev/null
+++ b/migrations/20211015175235_init/migration.sql
@@ -0,0 +1,14 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `owner_id` on the `Party` table. All the data in the column will be lost.
+
+*/
+-- DropForeignKey
+ALTER TABLE "Party" DROP CONSTRAINT "Party_owner_id_fkey";
+
+-- DropIndex
+DROP INDEX "Party_owner_id_unique";
+
+-- AlterTable
+ALTER TABLE "Party" DROP COLUMN "owner_id";
diff --git a/migrations/migration_lock.toml b/migrations/migration_lock.toml
new file mode 100644
index 0000000..fbffa92
--- /dev/null
+++ b/migrations/migration_lock.toml
@@ -0,0 +1,3 @@
+# Please do not edit this file manually
+# It should be added in your version-control system (i.e. Git)
+provider = "postgresql"
\ No newline at end of file
diff --git a/models/models.go b/models/models.go
new file mode 100644
index 0000000..bd019f6
--- /dev/null
+++ b/models/models.go
@@ -0,0 +1,13 @@
+package models
+
+type Presence struct {
+ State string `json:"state" binding:"required"`
+ LargeImageKey string `json:"large_image_key" binding:"required"`
+ SmallImageKey string `json:"small_image_key" binding:"required"`
+ StartTime int64 `json:"start_time"`
+ EndTime int64 `json:"end_time"`
+ Details string `json:"details" binding:"required"`
+ LargeImageText string `json:"large_image_text" binding:"required"`
+ SmallImageText string `json:"small_image_text" binding:"required"`
+ PartyId string `json:"party_id" binding:"required"`
+}
diff --git a/routes/auth.go b/routes/auth.go
index ec2c1c3..f2cb78e 100644
--- a/routes/auth.go
+++ b/routes/auth.go
@@ -1,6 +1,12 @@
package routes
-import "github.com/gin-gonic/gin"
+import (
+ "context"
+
+ "github.com/SkyVillageMc/skyvillage-api/database"
+ "github.com/SkyVillageMc/skyvillage-api/db"
+ "github.com/gin-gonic/gin"
+)
func InitAuth(r *gin.RouterGroup) {
@@ -10,6 +16,16 @@ func InitAuth(r *gin.RouterGroup) {
}
if c.BindJSON(&data) == nil {
+ database.DB.User.CreateOne(
+ db.User.Name.Set(data.Name),
+ db.User.Presence.Link(
+ db.Presence.PartyID.Equals("asd"),
+ ),
+ db.User.PresenceID.Set(0),
+ db.User.Party.Link(
+ db.Party.ID.Equals("asd"),
+ ),
+ ).Exec(context.TODO())
c.JSON(200, gin.H{
"status": "success",
})
diff --git a/routes/party.go b/routes/party.go
new file mode 100644
index 0000000..c38e309
--- /dev/null
+++ b/routes/party.go
@@ -0,0 +1,32 @@
+package routes
+
+import (
+ "errors"
+
+ "github.com/SkyVillageMc/skyvillage-api/database"
+ "github.com/SkyVillageMc/skyvillage-api/db"
+ "github.com/gin-gonic/gin"
+)
+
+func InitParties(r *gin.RouterGroup) {
+ r.GET("/:id", func(c *gin.Context) {
+ party, err := database.DB.Party.FindFirst(
+ db.Party.ID.Equals(c.Param("id")),
+ ).Exec(ctx)
+
+ if err != nil {
+ if errors.Is(err, db.ErrNotFound) {
+ c.JSON(404, gin.H{
+ "error": "no user found",
+ })
+ return
+ }
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+
+ c.JSON(200, *party)
+ })
+}
diff --git a/routes/presence.go b/routes/presence.go
new file mode 100644
index 0000000..53f1112
--- /dev/null
+++ b/routes/presence.go
@@ -0,0 +1,97 @@
+package routes
+
+import (
+ "context"
+ "errors"
+ "log"
+
+ "github.com/SkyVillageMc/skyvillage-api/database"
+ "github.com/SkyVillageMc/skyvillage-api/db"
+ "github.com/SkyVillageMc/skyvillage-api/models"
+ "github.com/gin-gonic/gin"
+)
+
+var ctx = context.Background()
+
+func InitPresence(r *gin.RouterGroup) {
+
+ r.GET("/:id", func(c *gin.Context) {
+ presence, err := database.DB.Presence.FindFirst(
+ db.Presence.UserID.Equals(c.Param("id")),
+ ).Exec(ctx)
+
+ if err != nil {
+ if errors.Is(err, db.ErrNotFound) {
+ c.JSON(404, gin.H{
+ "error": "no presence found",
+ })
+ return
+ }
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+
+ c.JSON(200, *presence)
+ })
+
+ r.PATCH("/:id", func(c *gin.Context) {
+
+ var data models.Presence
+
+ if err := c.BindJSON(&data); err != nil {
+ log.Println(err.Error())
+ c.JSON(400, gin.H{
+ "error": "incomplete data",
+ })
+ return
+ }
+
+ _, err := database.DB.Presence.UpsertOne(db.Presence.UserID.Equals(c.Param("id"))).Update(
+ db.Presence.UserID.Set(c.Param("id")),
+ db.Presence.User.Link(
+ db.User.ID.Equals(c.Param("id")),
+ ),
+ db.Presence.State.Set(data.State),
+ db.Presence.LargeImageKey.Set(data.LargeImageKey),
+ db.Presence.SmallImageKey.Set(data.SmallImageKey),
+ db.Presence.StartTime.Set(db.BigInt(data.StartTime)),
+ db.Presence.EndTime.Set(db.BigInt(data.EndTime)),
+ db.Presence.Details.Set(data.Details),
+ db.Presence.LargeImageText.Set(data.LargeImageText),
+ db.Presence.SmallImageText.Set(data.SmallImageText),
+ db.Presence.PartyID.Set(data.PartyId),
+ db.Presence.Party.Link(
+ db.Party.ID.Equals(data.PartyId),
+ ),
+ ).Exec(ctx)
+
+ presence, _ := database.DB.Presence.FindFirst(
+ db.Presence.UserID.Equals(c.Param("id")),
+ ).Exec(ctx)
+
+ SendToUser(c.Param("id"), gin.H{
+ "event": "presence-update",
+ "data": presence,
+ })
+
+ if err != nil {
+ log.Println(err.Error())
+ if errors.Is(err, db.ErrNotFound) {
+ c.JSON(404, gin.H{
+ "error": "no presence found",
+ })
+ return
+ }
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+
+ c.JSON(200, gin.H{
+ "status": "success",
+ })
+ })
+}
diff --git a/routes/user.go b/routes/user.go
new file mode 100644
index 0000000..c6f1c8b
--- /dev/null
+++ b/routes/user.go
@@ -0,0 +1,32 @@
+package routes
+
+import (
+ "errors"
+
+ "github.com/SkyVillageMc/skyvillage-api/database"
+ "github.com/SkyVillageMc/skyvillage-api/db"
+ "github.com/gin-gonic/gin"
+)
+
+func InitUsers(r *gin.RouterGroup) {
+ r.GET("/:name", func(c *gin.Context) {
+ user, err := database.DB.User.FindFirst(
+ db.User.Name.Equals(c.Param("name")),
+ ).Exec(ctx)
+
+ if err != nil {
+ if errors.Is(err, db.ErrNotFound) {
+ c.JSON(404, gin.H{
+ "error": "no user found",
+ })
+ return
+ }
+ c.JSON(500, gin.H{
+ "error": err.Error(),
+ })
+ return
+ }
+
+ c.JSON(200, *user)
+ })
+}
diff --git a/routes/websocket.go b/routes/websocket.go
new file mode 100644
index 0000000..e631d6b
--- /dev/null
+++ b/routes/websocket.go
@@ -0,0 +1,74 @@
+package routes
+
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gorilla/websocket"
+)
+
+var upgrader = websocket.Upgrader{}
+
+type ConnectedSocket struct {
+ Connection *websocket.Conn
+ UserId string
+}
+
+var sockets map[string]ConnectedSocket
+
+func InitWs(r *gin.Engine) {
+
+ sockets = make(map[string]ConnectedSocket)
+
+ upgrader.CheckOrigin = func(r *http.Request) bool {
+ return true
+ }
+
+ r.GET("/ws", func(c *gin.Context) {
+
+ if c.Query("id") == "" {
+ c.String(401, "please provide user id")
+ return
+ }
+
+ conn, err := upgrader.Upgrade(c.Writer, c.Request, c.Writer.Header())
+ if err != nil {
+ log.Println(err.Error())
+ return
+ }
+
+ sockets[c.Query("id")] = ConnectedSocket{
+ Connection: conn,
+ UserId: c.Query("id"),
+ }
+
+ defer conn.Close()
+
+ for {
+ _, message, err := conn.ReadMessage()
+ if err != nil {
+ conn.WriteJSON(gin.H{
+ "error": "read error",
+ })
+ break
+ }
+
+ err = conn.WriteMessage(1, message)
+ if err != nil {
+ log.Println("Error during message writing:", err)
+ break
+ }
+ }
+ })
+}
+
+func SendToUser(id string, json gin.H) error {
+ s := sockets[id]
+
+ if s.Connection == nil {
+ return nil
+ }
+
+ return s.Connection.WriteJSON(json)
+}
diff --git a/schema.prisma b/schema.prisma
index a17fde8..29e648a 100644
--- a/schema.prisma
+++ b/schema.prisma
@@ -1,6 +1,6 @@
datasource db {
- provider = "sqlite"
- url = "file:dev.db"
+ provider = "postgresql"
+ url = env("DATABASE_URL")
}
generator db {
@@ -8,9 +8,43 @@ generator db {
}
model User {
- id String @default(cuid()) @id
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- name String
- role Int @default(0)
+ id String @id @default(cuid())
+ createdAt DateTime @default(now())
+ updatedAt DateTime @updatedAt
+ name String
+ role Int @default(0)
+ presence Presence @relation(fields: [id], references: [user_id])
+ presence_id Int
+
+ party Party @relation(fields: [party_id], references: [id])
+ party_id String
+}
+
+model Presence {
+ user_id String @id
+ user User?
+ state String @default("")
+ large_image_key String @default("logo_large")
+ small_image_key String @default("loading")
+ start_time BigInt @default(0)
+ end_time BigInt @default(0)
+ details String @default("")
+ large_image_text String @default("")
+ small_image_text String @default("")
+
+ party_id String
+ party Party? @relation(fields: [party_id], references: [id])
+}
+
+model Party {
+ id String @id @default(cuid())
+
+ Presence Presence[]
+
+ min Int @default(0)
+ max Int @default(5)
+
+ join_secret String @default("")
+
+ players User[]
}
diff --git a/skyvillage-api b/skyvillage-api
new file mode 100755
index 0000000..8efb791
Binary files /dev/null and b/skyvillage-api differ
diff --git a/target/golist.json b/target/golist.json
new file mode 100644
index 0000000..997b6e0
--- /dev/null
+++ b/target/golist.json
@@ -0,0 +1 @@
+{"version":"v1","main":"github.com/SkyVillageMc/skyvillage-api","packages":[{"package":"github.com/gin-gonic/gin","version":"1.7.4","deps":[{"package":"github.com/gin-contrib/sse","version":"0.1.0"},{"package":"github.com/gin-gonic/gin/binding@github.com/gin-gonic/gin","version":"1.7.4"},{"package":"github.com/gin-gonic/gin/internal/bytesconv@github.com/gin-gonic/gin","version":"1.7.4"},{"package":"github.com/gin-gonic/gin/internal/json@github.com/gin-gonic/gin","version":"1.7.4"},{"package":"github.com/gin-gonic/gin/render@github.com/gin-gonic/gin","version":"1.7.4"},{"package":"github.com/go-playground/locales","version":"0.14.0"},{"package":"github.com/go-playground/locales/currency@github.com/go-playground/locales","version":"0.14.0"},{"package":"github.com/go-playground/universal-translator","version":"0.18.0"},{"package":"github.com/go-playground/validator/v10","version":"10.9.0"},{"package":"github.com/golang/protobuf/proto@github.com/golang/protobuf","version":"1.5.2"},{"package":"github.com/leodido/go-urn","version":"1.2.1"},{"package":"github.com/mattn/go-isatty","version":"0.0.14"},{"package":"github.com/ugorji/go/codec","version":"1.2.6"},{"package":"golang.org/x/crypto/sha3@golang.org/x/crypto","version":"0.0.0-20210921155107-089bfa567519"},{"package":"golang.org/x/sys/internal/unsafeheader@golang.org/x/sys","version":"0.0.0-20211007075335-d3039528d8ac"},{"package":"golang.org/x/sys/unix@golang.org/x/sys","version":"0.0.0-20211007075335-d3039528d8ac"},{"package":"golang.org/x/text/internal/language@golang.org/x/text","version":"0.3.7"},{"package":"golang.org/x/text/internal/language/compact@golang.org/x/text","version":"0.3.7"},{"package":"golang.org/x/text/internal/tag@golang.org/x/text","version":"0.3.7"},{"package":"golang.org/x/text/language@golang.org/x/text","version":"0.3.7"},{"package":"google.golang.org/protobuf/encoding/prototext@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/encoding/protowire@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/descfmt@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/descopts@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/detrand@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/encoding/defval@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/encoding/messageset@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/encoding/tag@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/encoding/text@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/errors@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/filedesc@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/filetype@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/flags@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/genid@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/impl@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/order@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/pragma@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/set@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/strs@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/internal/version@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/proto@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/reflect/protodesc@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/reflect/protoreflect@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/reflect/protoregistry@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/runtime/protoiface@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/runtime/protoimpl@google.golang.org/protobuf","version":"1.27.1"},{"package":"google.golang.org/protobuf/types/descriptorpb@google.golang.org/protobuf","version":"1.27.1"},{"package":"gopkg.in/yaml.v2","version":"2.4.0"}]},{"package":"github.com/iancoleman/strcase","version":"0.0.0-20190422225806-e506e3ef7365"},{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries/unpack@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"}]},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/engine/mock@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/builder@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/runtime/builder@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/runtime/lifecycle@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/runtime/raw@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/builder@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/transaction@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/runtime/transaction@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/joho/godotenv","version":"1.3.0"},{"package":"github.com/prisma/prisma-client-go/binaries@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/binaries/platform@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/engine@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/logger@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/builder@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0"},{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/prisma/prisma-client-go/runtime/types@github.com/prisma/prisma-client-go","version":"0.11.0","deps":[{"package":"github.com/shopspring/decimal","version":"1.2.0"}]},{"package":"github.com/shopspring/decimal","version":"1.2.0"},{"package":"github.com/takuoki/gocase","version":"1.0.0"}]}
\ No newline at end of file