diff --git a/cmd/migrate-up/main.go b/bin/migrate-up/main.go similarity index 100% rename from cmd/migrate-up/main.go rename to bin/migrate-up/main.go diff --git a/cmd/server/handler/request.go b/bin/server/handler/request.go similarity index 100% rename from cmd/server/handler/request.go rename to bin/server/handler/request.go diff --git a/cmd/server/main.go b/bin/server/main.go similarity index 52% rename from cmd/server/main.go rename to bin/server/main.go index d91c128..f77bf27 100644 --- a/cmd/server/main.go +++ b/bin/server/main.go @@ -7,13 +7,15 @@ package main import ( "fmt" "net/http" + "strings" "gitserver.in/patialtech/mux" "gitserver.in/patialtech/mux/middleware" - "gitserver.in/patialtech/rano/cmd/server/handler" + "gitserver.in/patialtech/rano/bin/server/handler" "gitserver.in/patialtech/rano/config" "gitserver.in/patialtech/rano/graph" "gitserver.in/patialtech/rano/util/logger" + "gitserver.in/patialtech/rano/web" ) func main() { @@ -24,6 +26,7 @@ func main() { // CORS r.Use(middleware.CORS(middleware.CORSOption{ AllowedHeaders: []string{"Content-Type"}, + AllowedOrigins: []string{config.Read().WebURL}, MaxAge: 60, })) // Secure Headers @@ -40,7 +43,37 @@ func main() { // catch all r.GET("/", func(w http.ResponseWriter, r *http.Request) { - w.Write([]byte("hello there")) + var ( + resourcePath string + path = r.URL.Path + ) + + if strings.HasPrefix(path, "/_app") { + resourcePath = "public/build" + path + } else if strings.HasSuffix(path, ".png") || + strings.HasSuffix(path, ".ico") || + strings.HasSuffix(path, ".svg") || + strings.HasSuffix(path, "robot.txt") || + strings.HasSuffix(path, "site.webmanifest") { + resourcePath = "public" + path + } else { + resourcePath = "public/build/fallback.html" + } + + if b, err := web.Public.ReadFile(resourcePath); err != nil { + _, _ = w.Write([]byte("hello there")) + } else { + if strings.HasSuffix(path, ".js") { + w.Header().Set("Content-Type", "text/javascript") + } else if strings.HasSuffix(path, ".css") { + w.Header().Set("Content-Type", "text/css") + } else { + w.Header().Set("Content-Type", http.DetectContentType(b)) + } + + w.WriteHeader(http.StatusOK) + _, _ = w.Write(b) + } }) r.Serve(func(srv *http.Server) error { diff --git a/config/config.go b/config/config.go index 2ffac1e..2da3474 100644 --- a/config/config.go +++ b/config/config.go @@ -18,17 +18,13 @@ import ( const ( // projDir need to be same as project code root dir name - projDir = "rano" - EnvDev = "development" - EnvProd = "production" - EnvStage = "staging" - + projDir = "rano" AuthUserCtxKey = "AuthUser" ) var ( conf *Config - AppEnv Env = EnvDev + AppEnv = "development" // production | staging ) type ( @@ -47,7 +43,7 @@ type ( func init() { var base string - if AppEnv == EnvDev { + if AppEnv == "development" { // AppEnv will be changed on build time using ldflags -X wd, _ := os.Getwd() idx := strings.Index(wd, projDir) if idx > -1 { @@ -57,6 +53,8 @@ func init() { base, _ = os.Executable() } + logger.Info("*** %s", AppEnv) + envVar, err := dotenv.Read(base, fmt.Sprintf(".env.%s", AppEnv)) if err != nil { panic(err) diff --git a/svelte.config.js b/svelte.config.js index 80b60b3..50cce16 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,7 +1,5 @@ -import path from 'node:path'; import adapter from '@sveltejs/adapter-static'; -const webDir = path.resolve('.', 'web'); /** @type {import('@sveltejs/kit').Config} */ const config = { @@ -9,16 +7,15 @@ const config = { // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. // If your environment is not supported, or you settled on a specific environment, switch out the adapter. // See https://kit.svelte.dev/docs/adapters for more information about adapters. - adapter: adapter(), files: { - appTemplate: path.resolve(webDir, 'app.html'), - routes: path.resolve(webDir, 'routes'), - lib: path.resolve(webDir, 'lib'), - assets: path.resolve(webDir, 'public') + appTemplate: "web/app.html" , + routes: "web/routes", + lib: "web/lib", + assets: "public/lib" }, alias: { - $image: path.resolve(webDir, 'assets', 'image'), - $svg: path.resolve(webDir, 'assets', 'svg') + $image: "web/assets/image", + $svg: "web/assets/svg" }, paths: { assets: process.env.ASSETS_HOST ?? '' @@ -28,8 +25,8 @@ const config = { pollInterval: 1000 * 60 * 1 // 5 minutes }, adapter: adapter({ - pages: path.resolve(webDir, 'public', 'build'), - assets: path.resolve(webDir, 'public', 'build'), + pages: "web/public/build", + assets: "web/public/build", fallback: 'fallback.html', strict: true }) diff --git a/taskfile.yml b/taskfile.yml index dfce2fc..9e0154a 100644 --- a/taskfile.yml +++ b/taskfile.yml @@ -1,9 +1,12 @@ version: '3' +dotenv: ['.env.{{.ENV}}'] + env: ENV: development -dotenv: ['.env.{{.ENV}}'] +vars: + MOD_NAME: gitserver.in/patialtech/rano tasks: install: @@ -14,7 +17,7 @@ tasks: start-graph: desc: run graph server cmds: - - cmd: go run ./cmd/server + - cmd: go run ./bin/server start-web: desc: run web in dev mode @@ -44,11 +47,11 @@ tasks: - cmd: deno task codegen ent-new: - desc: create new db Emtity - cmd: cd ./db && go run -mod=mod entgo.io/ent/cmd/ent new {{.name}} + desc: create new db Entity + cmd: cd ./db && go run -mod=mod entry.io/ent/cmd/ent new {{.name}} ent-gen: - desc: genertate from ent schema + desc: generate from ent schema cmds: - go generate ./db/ent @@ -61,4 +64,17 @@ tasks: desc: apply automatically migration using Ent schema cmds: - task: ent-gen - - go run ./cmd/migrate-up + - go run ./bin/migrate-up + + build-web-prod: + desc: apply automatically migration using Ent schema + cmds: + - deno task build + env: + ASSETS_HOST: + + build-prod: + desc: apply automatically migration using Ent schema + cmds: + - task: build-web-prod + - CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -ldflags "-X '{{.MOD_NAME}}/config.AppEnv=production'" -o ./server ./bin/server \ No newline at end of file diff --git a/web/public/android-chrome-192x192.png b/web/public/android-chrome-192x192.png new file mode 100644 index 0000000..cc8a461 Binary files /dev/null and b/web/public/android-chrome-192x192.png differ diff --git a/web/public/android-chrome-512x512.png b/web/public/android-chrome-512x512.png new file mode 100644 index 0000000..8448885 Binary files /dev/null and b/web/public/android-chrome-512x512.png differ diff --git a/web/public/apple-touch-icon.png b/web/public/apple-touch-icon.png new file mode 100644 index 0000000..f7c2d22 Binary files /dev/null and b/web/public/apple-touch-icon.png differ diff --git a/web/public/favicon-16x16.png b/web/public/favicon-16x16.png new file mode 100644 index 0000000..ff9b21e Binary files /dev/null and b/web/public/favicon-16x16.png differ diff --git a/web/public/favicon-32x32.png b/web/public/favicon-32x32.png new file mode 100644 index 0000000..ac578dc Binary files /dev/null and b/web/public/favicon-32x32.png differ diff --git a/web/public/favicon.ico b/web/public/favicon.ico new file mode 100644 index 0000000..8cead2a Binary files /dev/null and b/web/public/favicon.ico differ diff --git a/web/public/site.webmanifest b/web/public/site.webmanifest new file mode 100644 index 0000000..0b08af1 --- /dev/null +++ b/web/public/site.webmanifest @@ -0,0 +1,11 @@ +{ + "name": "", + "short_name": "", + "icons": [ + { "src": "/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, + { "src": "/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } + ], + "theme_color": "#ffffff", + "background_color": "#ffffff", + "display": "standalone" +} diff --git a/web/web.go b/web/web.go new file mode 100644 index 0000000..13b12cc --- /dev/null +++ b/web/web.go @@ -0,0 +1,6 @@ +package web + +import "embed" + +//go:embed public public/build/_app +var Public embed.FS