Documentation
ΒΆ
Index ΒΆ
Constants ΒΆ
View Source
const AirTomlTemplate = `` /* 981-byte string literal not displayed */
View Source
const BumpCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"strconv"
"strings"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
)
// bumpCmd represents the bump command
var bumpCmd = &cobra.Command{
Use: "bump",
Short: "Bumps the semantic version of the server",
Long: ` + "\n" +
`*** Help Text
Use bump in order to incerment the server
- no flags increments the specific version <0.0.XX>
- -m increments the minor version <0.XX.0>
- -M increments the Major version <XX.0.0>
*** Command
**** Default
--- bash
go build main.go -o {{.Name}}
{{.Name}} bump
---
**** with -e passed
--- bash
go build main.go -o {{.Name}}
{{.Name}} bump -e really-sick-config
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
bump()
print("π₯ Bump Successful")
},
}
var (
Minor bool
Major bool
)
func init() {
rootCmd.AddCommand(bumpCmd)
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
//bumpCmd.PersistentFlags().String("foo", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
bumpCmd.Flags().BoolVarP(&Minor, "minor", "m", false, "bump the minor version")
bumpCmd.Flags().BoolVarP(&Major, "Major", "M", false, "bump the Major version")
}
func bump() {
config := new(configuration.Configuration)
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
panic(err)
}
if Minor && Major {
panic("Major and Minor cannot be used at the same time")
}
semver := config.Semver
vers := strings.Split(semver, ".")
major, err := strconv.Atoi(vers[0])
if err != nil {
panic(err)
}
minor, err := strconv.Atoi(vers[1])
if err != nil {
panic(err)
}
specific, err:= strconv.Atoi(vers[2])
if err != nil {
panic(err)
}
if Major {
major = major+1
} else if Minor {
minor += minor + 1
} else {
specific += 1
}
semver = strings.Join([]string {
strconv.Itoa(major),
strconv.Itoa(minor),
strconv.Itoa(specific),
}, ".")
config.Semver = semver
configBytes, err := yaml.Marshal(config)
if err != nil {
panic(err)
}
if err = configuration.SaveConfiguration(configBytes, Environment); err != nil {
panic(err)
}
return
}
`
View Source
const CONTROLLERS_UserControllerTemplate = `` /* 7742-byte string literal not displayed */
View Source
const CONTROLLER_ControllerTemplate = `` /* 1493-byte string literal not displayed */
View Source
const CONTROLLER_RoutesTemplate = `` /* 1164-byte string literal not displayed */
View Source
const CmdConfigurationConfigurationTemplate = `
/* Generated by egg v0.0.1 */
package configuration
import (
"errors"
"os"
"gopkg.in/yaml.v3"
)
type Configuration struct {
Namespace string ` + "`" + `yaml:"namespace"` + "`" + `
Name string ` + "`" + `yaml:"name"` + "`" + `
Semver string ` + "`" + `yaml:"semver"` + "`" + `
License string ` + "`" + `yaml:"license"` + "`" + `
Copyright struct {
Year int ` + "`" + `yaml:"year"` + "`" + `
Author string ` + "`" + `yaml:"author"` + "`" + `
} ` + "`" + `yaml:"copyright"` + "`" + `
Server struct {
JWT string ` + "`" + `yaml:"jwt"` + "`" + `
Port int ` + "`" + `yaml:"port"` + "`" + `
Frontend struct {
Dir string ` + "`" + `yaml:"dir"` + "`" + `
Api string ` + "`" + `yaml:"api"` + "`" + `
} ` + "`" + `yaml:"frontend"` + "`" + `
} ` + "`" + `yaml:"server"` + "`" + `
Database struct {
URL string ` + "`" + `yaml:"url"` + "`" + `
Sqlc string ` + "`" + `yaml:"sqlc"` + "`" + `
SqlcRepositoryLocation string ` + "`" + `yaml:"repository"` + "`" + `
QueriesLocation string ` + "`" + `yaml:"queries"` + "`" + `
Migration struct {
Protocol string ` + "`" + `yaml:"protocol"` + "`" + `
Destination string ` + "`" + `yaml:"destination"` + "`" + `
} ` + "`" + `yaml:"migration"` + "`" + `
} ` + "`" + `yaml:"database"` + "`" + `
Cache struct {
URL string ` + "`" + `yaml:"url"` + "`" + `
} ` + "`" + `yaml:"cache"` + "`" + `
S3 struct {
URL string ` + "`" + `yaml:"url"` + "`" + `
Access string ` + "`" + `yaml:"access"` + "`" + `
Secret string ` + "`" + `yaml:"secret"` + "`" + `
} ` + "`" + `yaml:"s3"` + "`" + `
}
const ConfigurationDir = "config/"
func LoadConfiguration(environment string) (*Configuration, error) {
configuration := new(Configuration)
configurationFile := ConfigurationDir + environment + ".yaml"
file, err := os.ReadFile(configurationFile)
if err != nil {
return configuration, err
}
if err = yaml.Unmarshal(file, configuration); err != nil {
return configuration, err
}
return configuration, nil
}
func SaveConfiguration(configBytes []byte, environment string) error {
configurationFile := ConfigurationDir + environment + ".yaml"
if _, err := os.Stat(configurationFile); errors.Is(err, os.ErrNotExist) {
return err
}
if err := os.WriteFile(configurationFile, configBytes, 0777); err != nil {
return err
}
return nil
}
func (configuration *Configuration) GenerateConfigurationFile(environment string) error {
// create the config directory if not exists config/
if _, err := os.Stat(ConfigurationDir); errors.Is(err, os.ErrNotExist) {
if err := os.Mkdir(ConfigurationDir, 0777); err != nil {
return err
}
}
if _, err := os.Stat(ConfigurationDir + environment + ".yaml"); errors.Is(err, os.ErrNotExist) {
if _, err := os.Create(ConfigurationDir + environment + ".yaml"); err != nil {
return err
}
}
// write to the file with the yaml content as the configuration
configBytes, err := yaml.Marshal(configuration)
if err != nil {
return err
}
if err := SaveConfiguration(configBytes, environment); err != nil {
return err
}
return nil
}
`
View Source
const DATABASE_MIGRATIONS_INITTemplate = `` /* 720-byte string literal not displayed */
View Source
const DATABASE_QUERIES_TokenTemplate = `` /* 511-byte string literal not displayed */
View Source
const DATABASE_QUERIES_UserTemplate = `` /* 1050-byte string literal not displayed */
View Source
const DBCmdTemplate = `` /* 919-byte string literal not displayed */
View Source
const DockerfileTemplate = `` /* 787-byte string literal not displayed */
View Source
const DockerignoreTemplate = `
# Generated by egg v0.0.1
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with ` + "`go test -c`" + `
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
wiki/
.git/
.github/
.vscode/
# Go workspace file
go.work
go.work.sum
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.next
.git
tmp/
`
View Source
const DownCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bufio"
"errors"
"os"
"os/exec"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
)
// downCmd represents the down command
var downCmd = &cobra.Command{
Use: "down",
Short: " This command uses goose to run down migrations in the ` + "`internal/migrations` " + ` folder",
Long: ` + "`" + `
*** Help Text
this is effectively goose down
*** Command
**** Default
--- bash
go build main.go -o {{.Name}}
./{{.Name}} db down
---
**** with -e passed
--- bash
go build main.go -o {{.Name}}
./{{.Name}} db down -e really-sick-config
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
panic(err)
}
if err = Down(config, args); err != nil {
panic(err)
}
print("π₯ Goose Down Successful")
},
}
func init() {
rootCmd.AddCommand(downCmd)
}
func Down(configuration *configuration.Configuration, args []string) error {
os.Setenv("GOOSE_DRIVER", configuration.Database.Sqlc)
os.Setenv("GOOSE_MIGRATION_DIR", configuration.Database.Migration.Destination)
if len(args) != 0 {
return errors.New("len(args) != 0 so the cli does not know what to do.")
}
output, err := exec.Command("goose", "down", configuration.Database.Sqlc).Output()
if err != nil {
return err
}
writer := bufio.NewWriter(os.Stdout)
_, err = writer.Write(output)
if err != nil {
return err
}
return nil
}
`
View Source
const GenerateCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bufio"
"errors"
"os"
"os/exec"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
)
// generateCmd represents the generate command
var generateCmd = &cobra.Command{
Use: "generate",
Short: "This command uses sqlc to generate the repository code from the ` + "`internal/queries`. `" + `",
Long: ` + "`" + `
*** Help Text
This command uses sql to generate the repository code from the internal/queries.
this command also uses sqlc under the hood so refrence their documentation for generateing code from that.
to configure sqlc please check in the root of the project in sqlc.yml
*** Command
**** Default
--- bash
go build main.go -o {{.Name }}
{{.Name }} db generate
---
**** with -e passed
--- bash
go build main.go -o {{.Name }}
{{ .Name }} db generate -e really-sick-config
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
panic(err)
}
if err := Gen(config, args); err != nil {
panic(err)
}
print("π₯ Sqlc Generate Successful")
},
}
func init() { dbCmd.AddCommand(generateCmd) }
func Gen(configuration *configuration.Configuration, args []string) error {
if len(args) != 0 {
return errors.New("π³ len(args) != 0 so egg does not know what to do with this.")
}
output, err := exec.Command("sqlc", "generate").Output()
if err != nil {
return err
}
writer := bufio.NewWriter(os.Stdout)
_, err = writer.Write(output)
if err != nil {
return err
}
return nil
}
`
View Source
const GitignoreTemplate = `
# Generated by egg v0.0.1
# If you prefer the allow list template instead of the deny list, see community template:
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
#
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
# Test binary, built with ` + "`go test -c`" + `
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Dependency directories (remove the comment below to include it)
# vendor/
# Go workspace file
go.work
go.work.sum
# env file
.env
development.yaml
production.yaml
tmp/
node_modules/
`
View Source
const MIDDLEWARES_CONFIGS_AuthConfigTemplate = `` /* 916-byte string literal not displayed */
View Source
const MIDDLEWARES_CONFIGS_StaticConfigTemplate = `` /* 574-byte string literal not displayed */
View Source
const MODELS_HANDLERS_DeleteUserHandlerTemplate = `` /* 2281-byte string literal not displayed */
View Source
const MODELS_HANDLERS_GetCurrentLoggedInUserHandlerTemplate = `` /* 1922-byte string literal not displayed */
View Source
const MODELS_HANDLERS_GetProfilePictureHandlerTemplate = `` /* 3650-byte string literal not displayed */
View Source
const MODELS_HANDLERS_GetUsersHandlerTemplate = `` /* 2324-byte string literal not displayed */
View Source
const MODELS_HANDLERS_LoginHandlerTemplate = `` /* 2231-byte string literal not displayed */
View Source
const MODELS_HANDLERS_RegisterHandlerTemplate = `` /* 1830-byte string literal not displayed */
View Source
const MODELS_HANDLERS_UploadProfilePictureHandlerTemplate = `` /* 2568-byte string literal not displayed */
View Source
const MODELS_REQUESTS_LoginRequestTemplate = `
/* Generated by egg v0.0.1 */
package requests
type LoginRequest struct {
Username string ` + "`" + `json:"username"` + "`" + `
Email string ` + "`" + `json:"email"` + "`" + `
Password string ` + "`" + `json:"password"` + "`" + `
} // @name LoginRequest
`
View Source
const MODELS_REQUESTS_NewUserRequestTemplate = `
/* Generated by egg v0.0.1 */
package requests
type NewUserRequest struct {
Username string ` + "`" + `json:"username"` + "`" + `
Email string ` + "`" + `json:"email"` + "`" + `
Password string ` + "`" + `json:"password"` + "`" + `
IsAdmin bool ` + "`" + `json:"isAdmin"` + "`" + `
} // @name NewUserRequest
`
View Source
const MODELS_RESPONSE_DeleteUserResponseTemplate = `
package responses
import (
"{{.Namespace}}/{{.Database.SqlcRepositoryLocation}}"
)
type DashboardResponse struct {
AuthenticatedUser *repository.User
PresignedUserProfilePicture *string
}
type DashboardDetailedResponse struct {
Data DashboardResponse ` + "`" + `json:"data"` + "`" + `
Success bool ` + "`" + `json:"success"` + "`" + `
Message string ` + "`" + `json:"message"` + "`" + `
}
`
View Source
const MODELS_RESPONSE_LoginResponseTemplate = `
/* Generated by egg v0.0.1 */
package responses
import (
"{{.Namespace}}/{{.Database.SqlcRepositoryLocation}}"
"github.com/labstack/echo/v4"
)
type LoginResponse struct {
Data *UserData ` + "`" + `json:"data"` + "`" + `
JWT string ` + "`" + `json:"jwt"` + "`" + `
Success bool ` + "`" + `json:"success"` + "`" + `
Message string ` + "`" + `json:"message"` + "`" + `
} // @name LoginResponse
func NewLoginResponse() *LoginResponse {
return &LoginResponse{Success: false, Message: ""}
}
func (LoginResponse *LoginResponse) Fail(ctx echo.Context, code int, err error) error {
LoginResponse.Message = err.Error()
return ctx.JSON(code, LoginResponse)
}
func (LoginResponse *LoginResponse) Successful(ctx echo.Context, user *repository.User, token string) error {
LoginResponse.Data = UserDataFromRepository(user)
LoginResponse.JWT = token
LoginResponse.Success = true
return ctx.JSON(200, LoginResponse)
}
func (LoginResponse *LoginResponse) Handle(
ctx echo.Context,
user *repository.User,
code int,
token string,
err error,
) error {
if err != nil {
return err
}
return ctx.Redirect(200, "/dashboard/"+user.ID.String())
}
`
View Source
const MODELS_RESPONSE_StringResponseTemplate = `
/* Generated by egg v0.0.1 */
package responses
import (
"github.com/labstack/echo/v4"
)
type StringResponse struct {
Data *string ` + "`" + `json:"data"` + "`" + `
Success bool ` + "`" + `json:"success"` + "`" + `
Message string ` + "`" + `json:"message"` + "`" + `
} // @name StringResponse
func NewStringResponse() *StringResponse {
return &StringResponse{Success: false, Message: ""}
}
func (StringResponse *StringResponse) Fail(ctx echo.Context, code int, err error) error {
StringResponse.Message = err.Error()
return ctx.JSON(code, StringResponse)
}
func (StringResponse *StringResponse) Successful(ctx echo.Context, stringLike string) error {
StringResponse.Data = &stringLike
StringResponse.Success = true
return ctx.JSON(200, StringResponse)
}
`
View Source
const MODELS_RESPONSE_UserResponseTemplate = `
/* Generated by egg v0.0.1 */
package responses
import (
"errors"
"time"
"{{.Namespace}}/{{.Database.SqlcRepositoryLocation}}"
"github.com/google/uuid"
"github.com/labstack/echo/v4"
)
type UserData struct {
ID uuid.UUID ` + "`" + `json:"id"` + "`" + `
Email string ` + "`" + `json:"email"` + "`" + `
Username string ` + "`" + `json:"username"` + "`" + `
CreatedDatetime *time.Time ` + "`" + `json:"created_datetime"` + "`" + `
UpdatedDatetime *time.Time ` + "`" + `json:"updated_datetime"` + "`" + `
ProfilePicUrl *string ` + "`" + `json:"profile_pic_url"` + "`" + `
Admin bool ` + "`" + `json:"admin"` + "`" + `
}
type UserResponse struct {
Data *UserData ` + "`" + `json:"data"` + "`" + `
Success bool ` + "`" + `json:"success"` + "`" + `
Message string ` + "`" + `json:"message"` + "`" + `
} // @name UserResponse
func UserDataFromRepository(repository *repository.User) *UserData {
if repository == nil {
return nil
}
return &UserData{
ID: repository.ID,
Email: repository.Email,
Username: repository.Username,
CreatedDatetime: repository.CreatedDatetime,
UpdatedDatetime: repository.UpdatedDatetime,
ProfilePicUrl: repository.ProfilePicUrl,
Admin: repository.Admin,
}
}
func NewUserResponse() *UserResponse {
return &UserResponse{Success: false, Message: ""}
}
func (UserResponse *UserResponse) Fail(ctx echo.Context, code int, err error) error {
UserResponse.Message = err.Error()
return ctx.JSON(code, UserResponse)
}
func (UserResponse *UserResponse) Successful(ctx echo.Context, user *repository.User) error {
UserResponse.Data = UserDataFromRepository(user)
UserResponse.Success = true
return ctx.JSON(200, UserResponse)
}
func (ur *UserResponse) Component(
ctx echo.Context,
user *repository.User,
code int,
err error,
) error {
return errors.New("oops")
}
`
View Source
const MODELS_RESPONSE_UsersResponseTemplate = `
/* Generated by egg v0.0.1 */
package responses
import (
"{{.Namespace}}/{{.Database.SqlcRepositoryLocation}}"
"github.com/labstack/echo/v4"
)
type UsersResponse struct {
Data []UserData ` + "`" + `json:"data"` + "`" + `
Success bool ` + "`" + `json:"success"` + "`" + `
Message string ` + "`" + `json:"message"` + "`" + `
} // @name UsersResponse
func NewUsersResponse() *UsersResponse {
return &UsersResponse{Success: false, Message: ""}
}
func (UsersResponse *UsersResponse) Fail(ctx echo.Context, code int, err error) error {
UsersResponse.Message = err.Error()
return ctx.JSON(code, UsersResponse)
}
func (UsersResponse *UsersResponse) Successful(ctx echo.Context, users []repository.User) error {
UsersResponse.Data = make([]UserData, len(users))
for i, val := range users {
UsersResponse.Data[i] = *UserDataFromRepository(&val)
}
UsersResponse.Success = true
return ctx.JSON(200, UsersResponse)
}
`
View Source
const MainGoTemplate = `` /* 507-byte string literal not displayed */
View Source
const MakefileTemplate = `` /* 378-byte string literal not displayed */
View Source
const MigrateCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bufio"
"errors"
"os"
"os/exec"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
)
// migrateCmd represents the migrate command
var migrateCmd = &cobra.Command{
Use: "migrate",
Short: "This command creates a migration with the migration name passed into the cli.",
Long: ` + "`" + `
*** Help Text
This command calls goose migrations under the hood. And by default it uses
the following environment variables:
--- .env
GOOSE_DRIVER=config.Server.Database.Migration.Protocol
GOOSE_DBSTRING=config.Server.Database.Url
GOOSE_MIGRATION_DIR=config.Server.Database.Migration.Destination
---
this generates a migration file in the GOOSE_MIGRATION_DIR to be
*** Command
**** Default
--- bash
go build main.go -o {{.Name }}
{{.Name }} db migrate <migration-name>
---
**** with -e passed
--- bash
go build main.go -o {{.Name }}
{{.Name }} db migrate <migration-name> -e really-sick-config
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
panic(err)
}
if err = Migrate(config, args); err != nil {
panic(err)
}
print("π₯ Create Migration Successful")
},
}
func init() {
dbCmd.AddCommand(migrateCmd)
}
func Migrate(configuration *configuration.Configuration, args []string) error {
os.Setenv("GOOSE_DRIVER", configuration.Database.Sqlc)
os.Setenv("GOOSE_MIGRATION_DIR", configuration.Database.Migration.Destination)
if len(args) != 1 {
return errors.New("len(args) != 1 so the cli does not know what to do.")
}
migration_name := args[0]
output, err := exec.Command("goose", "create", migration_name, configuration.Database.Sqlc).Output()
if err != nil {
return err
}
writer := bufio.NewWriter(os.Stdout)
_, err = writer.Write(output)
if err != nil {
return err
}
return nil
}
`
View Source
const OpenapitoolsJSONTemplate = `` /* 154-byte string literal not displayed */
View Source
const READMETemplate = `
# Egg Framework
ββββββββββββββββ
ββ ββ
ββββ ββββββββ ββ
ββ ββ ββββ ββ
ββ ββ ββββ ββ
ββ ββ ββββ ββ
ββ ββββββ ββββββββ ββ
ββββ ββββββββββββ ββββ
ββββ ββββββββ ββββ
ββββββ ββββ
ββββββββ ββββββ
ββββββββββββββββββββ
ββββββββββββ
The Egg framework is based on getting things done. In fact it is a framework made to be perfect for the solo developer. You are given all you need to get started extremely quickly. In this generated repository are also ci/cd to have this automatically test, build, and deploy your website to a vps using coolify with docker.
If you do not want to use docker or coolify, great! That is not the point of this framework. You just want to get up and running without having to rebuild the same starter over and over again. This is that. Ok Cheers!
## Getting started
make sure that you have a postgres database running the connection string in the ` + "`config/development.yaml`" + ` is correct. and make sure that the configured s3 storage configuration is correct as well.
Run the command ` + "`air`" + ` to start the server,
or Run the command ` + "`go run main.go`" + ` to start the server
You can change the default port by going into the config/ directory and changing the ` + "`server.port`" + ` value in the development.yaml to what you want.
`
View Source
const RootCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"strconv"
"{{.Namespace}}/cmd/configuration"
"{{.Namespace}}/controllers"
// _ "{{.Namespace}}/docs" // uncomment this to enable swagger docs
"github.com/labstack/echo/v4"
"github.com/spf13/cobra"
)
var Environment string
// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "{{.Name}}",
Short: "Serve the application",
Long: ` + "`" + `
*** Help Text
Serve the application.
The default environment used with this is development,
So configured the application is opend at
http://localhost:{{.Server.Port}}
This can be altered in the
host: 0.0.0.0
port: {{.Server.Port}}
section of the config file. use -e environment when
calling this command to run serve using the configured
values.
*** Command
**** Default
--- bash
go build main.go -o {{.Name }}
./{{.Name }}
---
**** with -e passed
If one had some configuration file really-sick-config.yaml
--- bash
go build main.go -o egg_app
./egg_app -e really-sick-config
---
` + "`" + `,
// Uncomment the following line if your bare application
// has an action associated with it:
Run: func(cmd *cobra.Command, args []string) {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
fmt.Print(err.Error())
os.Exit(1)
}
serve(config)
print("π₯")
os.Exit(1)
},
}
// Execute adds all child commands to the root command and sets flags appropriately.
// This is called by main.main(). It only needs to happen once to the rootCmd.
func Execute() {
err := rootCmd.Execute()
if err != nil {
os.Exit(1)
}
os.Exit(0)
}
func init() {
rootCmd.PersistentFlags().StringVarP(&Environment, "environment", "e", "development", "Choose what environment that should be used when running. Default is development")
}
func serve(config *configuration.Configuration) {
e := echo.New()
e.HideBanner = true
controllers.RegisterRoutes(e, config)
fmt.Printf(` + "`" + `
ββββββββββββββββ
ββ ββ
ββββ ββββββββ ββ
ββ ββ ββββ ββ
ββ ββ ββββ ββ
ββ ββ ββββ ββ
ββ ββββββ ββββββββ ββ
ββββ ββββββββββββ ββββ
ββββ ββββββββ ββββ
ββββββ ββββ
ββββββββ ββββββ
ββββββββββββββββββββ
ββββββββββββ
EGG v0.0.0
%s:%s
` + "`" + `, config.Name, config.Semver)
e.Logger.Fatal(e.Start(":" + strconv.Itoa(config.Server.Port)))
}
`
View Source
const SERVICES_AuthServiceTemplate = `
/* Generated by egg v0.0.1 */
package services
import (
"context"
"fmt"
"time"
"{{.Namespace}}/cmd/configuration"
"{{.Namespace}}/{{.Database.SqlcRepositoryLocation}}"
"github.com/golang-jwt/jwt/v5"
"github.com/google/uuid"
"github.com/jackc/pgx/v5/pgxpool"
)
// CustomJwt represents a JWT token with user-specific information.
type CustomJwt struct {
UserId uuid.UUID ` + "`" + `json:"user_id"` + "`" + `
User string ` + "`" + `json:"user"` + "`" + `
IsAdmin bool ` + "`" + `json:"is_admin"` + "`" + `
ProfilePic string ` + "`" + `json:"profile_pic"` + "`" + `
jwt.RegisteredClaims ` + "`" + `json:"claims"` + "`" + `
}
// AuthService provides authentication services, including creating and checking tokens.
type AuthService struct {
ctx context.Context
conn *pgxpool.Pool
config *configuration.Configuration
}
// newExpiration returns the current time plus 72 hours.
func newExpiration() time.Time {
return time.Now().Add(time.Hour * 72)
}
// jwtFromUser creates a JWT token from a user object.
//
// This function creates a new JWT token with the user's ID, profile picture URL,
// and an expiration time set to 72 hours in the future. The token is signed with
// the server's secret key.
func jwtFromUser(user *repository.User) *CustomJwt {
return &CustomJwt{
UserId: user.ID,
ProfilePic: *user.ProfilePicUrl,
User: user.Username,
IsAdmin: user.Admin,
RegisteredClaims: jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(newExpiration()),
IssuedAt: jwt.NewNumericDate(time.Now()),
ID: user.ID.String(),
Subject: user.ID.String(),
},
}
}
// CreateAuthService creates a new instance of AuthService.
//
// This function takes the context, PostgreSQL connection, and configuration as
// arguments and returns a new AuthService instance.
func CreateAuthService(ctx context.Context, pgPool *pgxpool.Pool, config *configuration.Configuration) *AuthService {
return &AuthService{ctx, pgPool, config}
}
// Create creates a new token for a user.
//
// This function takes a user object and returns the created token as a string
// along with an error. If an error occurs during the creation of the token,
// the error is returned instead of the token.
func (a *AuthService) Create(user *repository.User) (*string, error) {
jwttoken := jwtFromUser(user)
tx, err := a.conn.Begin(a.ctx)
if err != nil {
return nil, err
}
defer tx.Rollback(a.ctx)
expiration := jwttoken.ExpiresAt
// Create token with claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwttoken)
// Sign it with the server JWT_TOKEN
t, err := token.SignedString([]byte(a.config.Server.JWT))
if err != nil {
return nil, err
}
params := repository.CreateTokenParams{
UserID: user.ID,
ExpirationDatetime: &expiration.Time,
Token: &t,
}
repo := repository.New(tx)
row, err := repo.CreateToken(a.ctx, params)
if err != nil {
return nil, err
}
tx.Commit(a.ctx)
return row.Token, nil
}
// CheckToken checks if a given token is valid.
//
// This function takes a token string and returns an error if the token is not
// found in the database. If the token is found but its expiration time has passed,
// an error is also returned.
func (a *AuthService) CheckToken(token string) error {
tx, err := a.conn.Begin(a.ctx)
if err != nil {
return err
}
defer tx.Rollback(a.ctx)
repo := repository.New(tx)
_, err = repo.FindTokenByToken(a.ctx, &token)
if err != nil {
return err
}
tx.Commit(a.ctx)
// check if token is expired
claims := &CustomJwt{}
_, err = jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
return []byte(a.config.Server.JWT), nil
})
if err != nil {
return err
}
if claims.ExpiresAt.Before(time.Now()) {
return err
}
return nil
}
// Update updates an existing token for a user.
//
// This function takes a user object and returns the updated token as a string
// along with an error. If an error occurs during the update of the token,
// the error is returned instead of the token.
func (a *AuthService) Update(user repository.User) (*string, error) {
jwttoken := jwtFromUser(&user)
tx, err := a.conn.Begin(a.ctx)
if err != nil {
fmt.Printf("[ERROR] AuthService.Update{ a.conn.Begin } -> Error beginning transaction: %v", err)
return nil, err
}
defer tx.Rollback(a.ctx)
expiration := jwttoken.ExpiresAt
// Create token with claims
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwttoken)
// Sign it with the server JWT_TOKEN
t, err := token.SignedString([]byte(a.config.Server.JWT))
if err != nil {
fmt.Printf("[ERROR] AuthService.Update{ token.SignedString } -> Error signing token: %v", err)
return nil, err
}
fmt.Printf("[INFO] AuthService.Update{ token.SignedString } -> Token: %v TokenLength: %d", t, len(t))
params := repository.UpdateTokenByUserIdParams{
UserID: user.ID,
ExpirationDatetime: &expiration.Time,
Token: &t,
}
repo := repository.New(tx)
err = repo.UpdateTokenByUserId(a.ctx, params)
if err != nil {
fmt.Printf("[ERROR] AuthService.Update{ repo.UpdateTokenByUserId } -> Error updating token: %v", err)
return nil, err
}
tx.Commit(a.ctx)
return &t, nil
}
`
View Source
const SERVICES_IAuthServiceTemplate = `` /* 278-byte string literal not displayed */
View Source
const SERVICES_IMinioServiceTemplate = `` /* 350-byte string literal not displayed */
View Source
const SERVICES_IRedisServiceTemplate = `` /* 344-byte string literal not displayed */
View Source
const SERVICES_IUserServiceTemplate = `` /* 1992-byte string literal not displayed */
View Source
const SERVICES_MinioServiceTemplate = `` /* 3052-byte string literal not displayed */
View Source
const SERVICES_MockAuthServiceTemplate = `` /* 1312-byte string literal not displayed */
View Source
const SERVICES_MockUserServiceTemplate = `` /* 2199-byte string literal not displayed */
View Source
const SERVICES_RedisServiceTemplate = `` /* 2307-byte string literal not displayed */
View Source
const SERVICES_UserServiceTemplate = `` /* 6930-byte string literal not displayed */
View Source
const SERVICES_ValidatorServiceTemplate = `
/* Generated by egg v0.0.1 */
package services
import (
"context"
"errors"
"fmt"
"net/mail"
"regexp"
"strings"
"unicode"
"{{.Namespace}}/cmd/configuration"
"{{.Namespace}}/models/requests"
"github.com/labstack/echo/v4"
)
// ValidatorService struct
//
// This is a static struct that is used to validate the request body
type ValidatorService struct{}
func (ValidatorService *ValidatorService) Promote(ctx context.Context, config *configuration.Configuration) *ValidatorService {
return ValidatorService
}
func validateUsername(username string) bool {
trimmed := strings.TrimSpace(username)
if trimmed == "" {
return false
}
pattern := ` + "`" + `^[a-zA-Z0-9]+$` + "`" + `
_, err := regexp.MatchString(pattern, trimmed)
if err != nil {
return false
}
return true
}
func validatePassword(s string) (sevenOrMore, number, upper, special bool) {
letters := 0
for _, c := range s {
switch {
case unicode.IsNumber(c):
number = true
case unicode.IsUpper(c):
upper = true
letters++
case unicode.IsPunct(c) || unicode.IsSymbol(c):
special = true
case unicode.IsLetter(c) || c == ' ':
letters++
default:
//return false, false, false, false
}
}
sevenOrMore = letters > 7
return
}
// ValidateNewUserRequest
//
// ValidateNewUserRequest validates the Body by using the echo.Context.Bind(requsts.NewUserRequest)
// and the returns the marshalled object
func (ValidatorService ValidatorService) ValidateNewUserRequest(e echo.Context) (*requests.NewUserRequest, error) {
validRequest := new(requests.NewUserRequest)
if err := e.Bind(&validRequest); err != nil {
return nil, err
}
if !validateUsername(validRequest.Username) {
return nil, fmt.Errorf("Validation failed (%s) is not a valid username", validRequest.Username)
}
_, err := mail.ParseAddress(validRequest.Email)
if err != nil {
return nil, err
}
sevenOrMore, number, upper, special := validatePassword(validRequest.Password)
if !(sevenOrMore && number && upper && special) {
return nil, fmt.Errorf(
"Validation failed. Seven Or More (%t), Number (%t), Upper (%t), Special (%t)",
sevenOrMore,
number,
upper,
special)
}
return validRequest, nil
}
// ValidateLoginRequest validates the Body by using the echo.Context.Bind(requsts.LoginRequest)
// and the returns then last part
func (ValidatorService ValidatorService) ValidateLoginRequest(e echo.Context) (*requests.LoginRequest, error) {
validRequest := new(requests.LoginRequest)
if err := e.Bind(&validRequest); err != nil {
return nil, err
}
return validRequest, nil
}
// Validate LoginFormRequest ()
func (vs ValidatorService ) ValidateLoginFormRequest(e echo.Context) (*requests.LoginRequest, error) {
req := &requests.LoginRequest {
Username: e.FormValue("username"),
Email: e.FormValue("email"),
Password: e.FormValue("password"),
};
if (req.Email == "" && req.Username == "") {
err := errors.New("Email and Username cannot be null")
return nil, err
}
if req.Password == "" {
err := errors.New("You must send a password")
return nil, err
}
return req, nil
}
`
View Source
const SQLCYamlTemplate = `` /* 1052-byte string literal not displayed */
View Source
const SwagCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"os"
"os/exec"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
)
// swagCmd represents the swag command
var swagCmd = &cobra.Command{
Use: "swag",
Short: "A brief description of your command",
Long: ` + "` A long description of your command`" + `,
Run: func(cmd *cobra.Command, args []string) {
if err := swag(); err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
os.Exit(0)
},
}
func init() {
rootCmd.AddCommand(swagCmd)
}
func swag() error {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
return err
}
// first run swag
output, err := exec.Command("swag", "init").Output()
fmt.Printf("%s\n", string(output))
if err != nil {
return err
}
outputDir := config.Server.Frontend.Api
fmt.Printf("%s\n", outputDir)
if _, err = os.Stat(outputDir); os.IsNotExist(err) {
// create the directory
fmt.Println("need to create")
if err := os.Mkdir(outputDir, os.ModePerm); err != nil {
fmt.Printf("%s\n", err.Error())
return err
}
}
// now do the open api
fmt.Println("Scaffolding typescript-fetch api")
output, err = exec.Command(
"openapi-generator-cli",
"generate",
"-g",
"typescript-fetch",
"-o",
outputDir,
"-i",
"docs/swagger.json",
).Output()
if err != nil {
println(err.Error())
fmt.Printf("%s", output)
return err
}
fmt.Printf("%s", output)
return nil
}
`
View Source
const UpCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"bufio"
"errors"
"os"
"os/exec"
"{{.Namespace}}/cmd/configuration"
"github.com/spf13/cobra"
)
// upCmd represents the up command
var upCmd = &cobra.Command{
Use: "up",
Short: "This command uses sql to generate the repository code from the` + " `internal/migrations`." + `",
Long: ` + "`" + `
*** Help Text
This command calls goose migrations under the hood. And by default it uses
the following environment variables:
--- .env
GOOSE_DRIVER=config.Server.Database.Migration.Protocol
GOOSE_DBSTRING=config.Server.Database.Url
GOOSE_MIGRATION_DIR=config.Server.Database.Migration.Destination
---
this is effectively goose up
*** Command
**** Default
--- bash
go build main.go -o {{.Name }}
{{.Name }} db up
---
**** with -e passed
@code bash
--- bash
go build main.go -o {{.Name }}
{{.Name }} db up -e really-sick-config
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
panic(err)
}
if err = Up(config, args); err != nil {
print(err.Error())
panic(err)
}
print("π₯ Goose Up Successful")
},
}
func init() {
dbCmd.AddCommand(upCmd)
}
func Up(configuration *configuration.Configuration, args []string) error {
os.Setenv("GOOSE_DRIVER", configuration.Database.Migration.Protocol)
os.Setenv("GOOSE_MIGRATION_DIR", configuration.Database.Migration.Destination)
os.Setenv("GOOSE_DBSTRING", configuration.Database.URL)
print(configuration.Database.Migration.Destination)
if len(args) != 0 {
return errors.New("len(args) != 0 so the cli does not know what to do.")
}
output, err := exec.Command("goose", "up").Output()
if err != nil {
return err
}
writer := bufio.NewWriter(os.Stdout)
_, err = writer.Write(output)
if err != nil {
return err
}
return nil
}
`
View Source
const VersionCmdTemplate = `
/* Generated by egg v0.0.1
Copyright Β© {{.Copyright.Year}} {{.Copyright.Author}}
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package cmd
import (
"fmt"
"{{.Namespace}}/cmd/configuration"
"github.com/labstack/echo"
"github.com/spf13/cobra"
)
// versionCmd represents the version command
var versionCmd = &cobra.Command{
Use: "version",
Short: "Gets the semantic version of the server ",
Long: ` + "`" + `
*** Help Text
Gets the semantic version of the server.
Based on the environment, passed you could have a different version
of what is a production or a nightly based on ci/cd.
this can also be used in ci/cd piplines to if you want to
use the versioning to determine deployments or using docker to tag
to version docker images.
*** Command
**** Default
--- bash
go build main.go -o {{.Name }}
./{{.Name }} version
---
**** with -e passed
If one had some configuration file really-sick-config.yaml
--- bash
go build main.go -o egg_app
./egg_app version -e really-sick-config
---
**** using to make a docker version
--- bash
go build -o egg_app
EGG_APP_VER=echo(./egg_app version -e really-sick-config)
docker tag repository/user/egg_app:EGG_APP_VER
---
` + "`" + `,
Run: func(cmd *cobra.Command, args []string) {
e := echo.New()
config, err := configuration.LoadConfiguration(Environment)
if err != nil {
e.Logger.Fatal(err.Error())
panic(err.Error())
}
fmt.Println(fmt.Sprintf("%s", config.Semver))
},
}
func init() {
rootCmd.AddCommand(versionCmd)
}
`
Variables ΒΆ
This section is empty.
Functions ΒΆ
func Mapping ΒΆ
func Mapping(config *configuration.Configuration) map[string]*template.Template
Mapping
params:
config: *configuration.Configuration
returns:
type: map[string]*template.Template description: the map of templates with the key as the same as the file name to be rendered
Types ΒΆ
This section is empty.
Source Files
ΒΆ
- AirTomlTemplate.go
- CMD_Bump.go
- CMD_CONFIGURATION_Configuration.go
- CMD_Db.go
- CMD_Down.go
- CMD_Generate.go
- CMD_Migrate.go
- CMD_Root.go
- CMD_Swag.go
- CMD_Up.go
- CMD_Version.go
- CONTROLLERS_Controller.go
- CONTROLLERS_Routes.go
- CONTROLLERS_UserController.go
- DATABASE_MIGRATIONS_Init.go
- DATABASE_QUERIES_Token.go
- DATABASE_QUERIES_User.go
- DockerfileTemplate.go
- DockerignoreTemplate.go
- GitignoreTemplate.go
- MIDDLEWARES_CONFIGS_AuthConfig.go
- MIDDLEWARES_CONFIGS_StaticConfig.go
- MODELS_HANDLERS_DeleteUserHandler.go
- MODELS_HANDLERS_GetCurrentLoggedInUserHandler.go
- MODELS_HANDLERS_GetProfilePictureHandler.go
- MODELS_HANDLERS_GetUsersHandler.go
- MODELS_HANDLERS_LoginHandler.go
- MODELS_HANDLERS_RegisterHandler.go
- MODELS_HANDLERS_UploadProfilePictureHandler.go
- MODELS_REQUESTS_LoginRequest.go
- MODELS_REQUESTS_NewUserRequest.go
- MODELS_RESPONSE_DeleteUserResponse.go
- MODELS_RESPONSE_LoginResponse.go
- MODELS_RESPONSE_StringResponse.go
- MODELS_RESPONSE_UserResponse.go
- MODELS_RESPONSE_UsersResposnse.go
- MainGoTemplate.go
- MakefileTemplate.go
- OpenapiToolsYamlTemplate.go
- READMETemplate.go
- SERVICES_AuthService.go
- SERVICES_IAuthService.go
- SERVICES_IMinioService.go
- SERVICES_IRedisService.go
- SERVICES_IUserService.go
- SERVICES_MinioService.go
- SERVICES_MockAuthService.go
- SERVICES_MockUserService.go
- SERVICES_RedisService.go
- SERVICES_UserService.go
- SERVICES_ValidatorService.go
- SQLCYamlTemplate.go
- mapping.go
Click to show internal directories.
Click to hide internal directories.