Switching to Rust for the CLI
This commit is contained in:
1 parent
7306ad1b26
commit
f32e5bfea2
30 files changed
+1102
-632
No files matched your search
@@ -9,8 +9,8 @@ public class BackendApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(BackendApplication.class, args);
|
||||
//call the test
|
||||
test t = new test();
|
||||
|
||||
test x = new test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -14,11 +14,10 @@ public class SecurityConfig {
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers("/api/secure").authenticated()
|
||||
.anyRequest().permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2ResourceServer(oauth2 -> oauth2
|
||||
.jwt(Customizer.withDefaults()) // uses issuer-uri/jwk-set-uri
|
||||
.jwt(Customizer.withDefaults())
|
||||
);
|
||||
|
||||
return http.build();
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
GOOS=darwin GOARCH=amd64 go build -o envsync-mac .
|
||||
GOOS=windows GOARCH=amd64 go build -o envsync.exe .
|
||||
GOOS=linux GOARCH=amd64 go build -o envsync-linux .
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// diffCmd represents the diff command
|
||||
var diffCmd = &cobra.Command{
|
||||
Use: "diff",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("diff called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(diffCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// diffCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// diffCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// logCmd represents the log command
|
||||
var logCmd = &cobra.Command{
|
||||
Use: "log",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("log called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(logCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// logCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// logCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// loginCmd represents the login command
|
||||
var loginCmd = &cobra.Command{
|
||||
Use: "login",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("login called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(loginCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// loginCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// loginCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// pullCmd represents the pull command
|
||||
var pullCmd = &cobra.Command{
|
||||
Use: "pull",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("pull called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(pullCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// pullCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// pullCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// pushCmd represents the push command
|
||||
var pushCmd = &cobra.Command{
|
||||
Use: "push",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("push called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(pushCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// pushCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// pushCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
||||
|
||||
// rootCmd represents the base command when called without any subcommands
|
||||
var rootCmd = &cobra.Command{
|
||||
Use: "envsync-cli",
|
||||
Short: "A brief description of your application",
|
||||
Long: `A longer description that spans multiple lines and likely contains
|
||||
examples and usage of using your application. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
// Uncomment the following line if your bare application
|
||||
// has an action associated with it:
|
||||
// Run: func(cmd *cobra.Command, args []string) { },
|
||||
}
|
||||
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Here you will define your flags and configuration settings.
|
||||
// Cobra supports persistent flags, which, if defined here,
|
||||
// will be global for your application.
|
||||
|
||||
// rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.envsync-cli.yaml)")
|
||||
|
||||
// Cobra also supports local flags, which will only run
|
||||
// when this action is called directly.
|
||||
rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// setCmd represents the set command
|
||||
var setCmd = &cobra.Command{
|
||||
Use: "set",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("set called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(setCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// setCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// setCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
// unsetCmd represents the unset command
|
||||
var unsetCmd = &cobra.Command{
|
||||
Use: "unset",
|
||||
Short: "A brief description of your command",
|
||||
Long: `A longer description that spans multiple lines and likely contains examples
|
||||
and usage of using your command. For example:
|
||||
|
||||
Cobra is a CLI library for Go that empowers applications.
|
||||
This application is a tool to generate the needed files
|
||||
to quickly create a Cobra application.`,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
fmt.Println("unset called")
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(unsetCmd)
|
||||
|
||||
// Here you will define your flags and configuration settings.
|
||||
|
||||
// Cobra supports Persistent Flags which will work for this command
|
||||
// and all subcommands, e.g.:
|
||||
// unsetCmd.PersistentFlags().String("foo", "", "A help for foo")
|
||||
|
||||
// Cobra supports local flags which will only run when this command
|
||||
// is called directly, e.g.:
|
||||
// unsetCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||
}
|
||||
Generated
+419
@@ -0,0 +1,419 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43d5b281e737544384e969a5ccad3f1cdd24b48086a0fc1b2a5262a26b8f4f4a"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5192cca8006f1fd4f7237516f40fa183bb07f8fbdfedaa0036de5ea9b0b45e78"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
|
||||
dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"once_cell_polyfill",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "843867be96c8daad0d758b57df9392b6d8d271134fce549de6ce169ff98a92af"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2797f34da339ce31042b27d23607e051786132987f595b02ba4f6a6dffb7030a"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24a241312cea5059b13574bb9b3861cabf758b879c15190b37b6d6fd63ab6876"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.5.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92793da1a46a5f2a02a6f4c46c6496b28c43638adea8306fcb0caa1634f24e5"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3a822ea5bc7590f9d40f1ba12c0dc3c2760f3482c6984db1573ad11031420831"
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
|
||||
|
||||
[[package]]
|
||||
name = "envsync-cli"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6cb138bb79a146c1bd460005623e142ef0181e3d0219cb493e02f7d08a35695"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.182"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
|
||||
dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell_polyfill"
|
||||
version = "1.70.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b"
|
||||
dependencies = [
|
||||
"errno",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86f4aa3ad99f2088c990dfa82d367e19cb29268ed67c574d10d0a4bfe71f07e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.49.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72a2903cd7736441aac9df9d7688bd0ce48edccaadf181c3b90be801e81d3d86"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.1+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
||||
|
||||
[[package]]
|
||||
name = "windows-link"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.60.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.61.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.53.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4945f9f551b88e0d65f3db0bc25c33b8acea4d9e41163edf90dcd0b19f9069f3"
|
||||
dependencies = [
|
||||
"windows-link",
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "960e6da069d81e09becb0ca57a65220ddff016ff2d6af6a223cf372a506593a3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.53.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||
@@ -0,0 +1,8 @@
|
||||
[package]
|
||||
name = "envsync-cli"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
clap = { version = "4.5.60", features = ["derive"] }
|
||||
tokio = { version = "1.49.0", features = ["full"] }
|
||||
@@ -0,0 +1,3 @@
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
-37
@@ -1,37 +0,0 @@
|
||||
module github.com/geneticglitch1/envsync-cli
|
||||
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
|
||||
github.com/charmbracelet/lipgloss v1.1.0 // indirect
|
||||
github.com/charmbracelet/x/ansi v0.8.0 // indirect
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect
|
||||
github.com/charmbracelet/x/term v0.2.1 // indirect
|
||||
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
||||
github.com/go-resty/resty/v2 v2.17.2 // indirect
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
|
||||
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
||||
github.com/joho/godotenv v1.5.1 // indirect
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mattn/go-runewidth v0.0.16 // indirect
|
||||
github.com/muesli/termenv v0.16.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/rivo/uniseg v0.4.7 // indirect
|
||||
github.com/sagikazarmark/locafero v0.11.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
|
||||
github.com/spf13/afero v1.15.0 // indirect
|
||||
github.com/spf13/cast v1.10.0 // indirect
|
||||
github.com/spf13/cobra v1.10.2 // indirect
|
||||
github.com/spf13/pflag v1.0.10 // indirect
|
||||
github.com/spf13/viper v1.21.0 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/crypto v0.48.0 // indirect
|
||||
golang.org/x/net v0.49.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
)
|
||||
-71
@@ -1,71 +0,0 @@
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
|
||||
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
|
||||
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk=
|
||||
github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY=
|
||||
github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30=
|
||||
github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE=
|
||||
github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
|
||||
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
|
||||
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
|
||||
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
|
||||
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
|
||||
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
|
||||
github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk=
|
||||
github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
|
||||
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
|
||||
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
|
||||
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
|
||||
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=
|
||||
github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
|
||||
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
|
||||
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/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
|
||||
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc=
|
||||
github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
|
||||
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
|
||||
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
|
||||
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
|
||||
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
|
||||
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
|
||||
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
|
||||
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
|
||||
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
|
||||
github.com/spf13/cobra v1.10.2 h1:DMTTonx5m65Ic0GOoRY2c16WCbHxOOw6xxezuLaBpcU=
|
||||
github.com/spf13/cobra v1.10.2/go.mod h1:7C1pvHqHw5A4vrJfjNwvOdzYu0Gml16OCs2GRiTUUS4=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
|
||||
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
|
||||
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
|
||||
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
|
||||
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
Whitespace-only changes.
Whitespace-only changes.
-11
@@ -1,11 +0,0 @@
|
||||
/*
|
||||
Copyright © 2026 NAME HERE <EMAIL ADDRESS>
|
||||
|
||||
*/
|
||||
package main
|
||||
|
||||
import "github.com/geneticglitch1/envsync-cli/cmd"
|
||||
|
||||
func main() {
|
||||
cmd.Execute()
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
import { getToken } from "next-auth/jwt";
|
||||
import { NextResponse } from "next/server";
|
||||
import type { NextRequest } from "next/server";
|
||||
|
||||
const BACKEND_SECURE_URL = "http://localhost:8081/api/secure";
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
const token = await getToken({ req: request, secret: process.env.NEXTAUTH_SECRET });
|
||||
|
||||
if (!token || typeof token.accessToken !== "string") {
|
||||
return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
|
||||
}
|
||||
|
||||
const backendResponse = await fetch(BACKEND_SECURE_URL, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token.accessToken}`,
|
||||
Accept: "application/json",
|
||||
},
|
||||
cache: "no-store",
|
||||
});
|
||||
|
||||
const contentType = backendResponse.headers.get("content-type") ?? "";
|
||||
|
||||
if (!backendResponse.ok) {
|
||||
const body = await backendResponse.text();
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "Backend request failed",
|
||||
status: backendResponse.status,
|
||||
body,
|
||||
},
|
||||
{ status: 502 }
|
||||
);
|
||||
}
|
||||
|
||||
if (contentType.includes("application/json")) {
|
||||
const data = await backendResponse.json();
|
||||
return NextResponse.json(data);
|
||||
}
|
||||
|
||||
const text = await backendResponse.text();
|
||||
return NextResponse.json({ data: text });
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
@@ -1,8 +1,8 @@
|
||||
@import "tailwindcss";
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
--background: #050505;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
|
||||
@theme inline {
|
||||
@@ -10,17 +10,104 @@
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-geist-sans);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
}
|
||||
--color-emerald-400: #34d399;
|
||||
--color-emerald-500: #10b981;
|
||||
--color-emerald-600: #059669;
|
||||
--color-emerald-900: #064e3b;
|
||||
--color-emerald-950: #022c22;
|
||||
--color-zinc-400: #a1a1aa;
|
||||
--color-zinc-500: #71717a;
|
||||
--color-zinc-600: #52525b;
|
||||
--color-zinc-700: #3f3f46;
|
||||
--color-zinc-800: #27272a;
|
||||
--color-zinc-900: #18181b;
|
||||
--color-zinc-950: #09090b;
|
||||
}
|
||||
|
||||
body {
|
||||
background: var(--background);
|
||||
color: var(--foreground);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
font-family: var(--font-sans), system-ui, -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
/* Glow effects */
|
||||
.glow-green {
|
||||
box-shadow: 0 0 60px rgba(16, 185, 129, 0.15), 0 0 120px rgba(16, 185, 129, 0.05);
|
||||
}
|
||||
|
||||
.glow-green-sm {
|
||||
box-shadow: 0 0 30px rgba(16, 185, 129, 0.1);
|
||||
}
|
||||
|
||||
/* Grid background pattern */
|
||||
.bg-grid {
|
||||
background-image:
|
||||
linear-gradient(rgba(255, 255, 255, 0.03) 1px, transparent 1px),
|
||||
linear-gradient(90deg, rgba(255, 255, 255, 0.03) 1px, transparent 1px);
|
||||
background-size: 64px 64px;
|
||||
}
|
||||
|
||||
/* Gradient text */
|
||||
.text-gradient {
|
||||
background: linear-gradient(135deg, #34d399 0%, #10b981 50%, #059669 100%);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
}
|
||||
|
||||
/* Animated terminal cursor */
|
||||
@keyframes blink {
|
||||
0%, 50% { opacity: 1; }
|
||||
51%, 100% { opacity: 0; }
|
||||
}
|
||||
.cursor-blink {
|
||||
animation: blink 1s step-end infinite;
|
||||
}
|
||||
|
||||
/* Fade-in on scroll (CSS-only progressive enhancement) */
|
||||
@keyframes fadeInUp {
|
||||
from {
|
||||
opacity: 0;
|
||||
transform: translateY(20px);
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
.animate-fade-in-up {
|
||||
animation: fadeInUp 0.6s ease-out both;
|
||||
}
|
||||
|
||||
/* Staggered delays */
|
||||
.delay-100 { animation-delay: 0.1s; }
|
||||
.delay-200 { animation-delay: 0.2s; }
|
||||
.delay-300 { animation-delay: 0.3s; }
|
||||
.delay-400 { animation-delay: 0.4s; }
|
||||
.delay-500 { animation-delay: 0.5s; }
|
||||
.delay-600 { animation-delay: 0.6s; }
|
||||
|
||||
/* Scrollbar styling */
|
||||
::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #27272a;
|
||||
border-radius: 3px;
|
||||
}
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #3f3f46;
|
||||
}
|
||||
|
||||
/* Code block scrollbar */
|
||||
pre::-webkit-scrollbar {
|
||||
height: 4px;
|
||||
}
|
||||
|
||||
/* Smooth scroll */
|
||||
html {
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
@@ -16,8 +16,18 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: "EnvSync — Encrypted .env Collaboration for Teams",
|
||||
description:
|
||||
"Stop sending .env files over Slack. EnvSync is a CLI + web dashboard that gives your team a single encrypted source of truth for environment variables — with diffing, versioning, and real-time notifications. 100% self-hosted.",
|
||||
keywords: [
|
||||
"environment variables",
|
||||
"secrets management",
|
||||
"self-hosted",
|
||||
"encrypted",
|
||||
"CLI",
|
||||
"dotenv",
|
||||
"team collaboration",
|
||||
],
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
+549
-34
@@ -1,50 +1,565 @@
|
||||
import { getServerSession } from "next-auth";
|
||||
import Link from "next/link";
|
||||
|
||||
import { authOptions } from "@/lib/auth";
|
||||
import { signOut } from "next-auth/react";
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* SVG Icons (inline to avoid extra deps) */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
export default async function Home() {
|
||||
const session = await getServerSession(authOptions);
|
||||
const ShieldIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M9 12.75 11.25 15 15 9.75m-3-7.036A11.959 11.959 0 0 1 3.598 6 11.99 11.99 0 0 0 3 9.749c0 5.592 3.824 10.29 9 11.623 5.176-1.332 9-6.03 9-11.622 0-1.31-.21-2.571-.598-3.751h-.152c-3.196 0-6.1-1.248-8.25-3.285Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const TerminalIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="m6.75 7.5 3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0 0 21 18V6a2.25 2.25 0 0 0-2.25-2.25H5.25A2.25 2.25 0 0 0 3 6v12a2.25 2.25 0 0 0 2.25 2.25Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const BoltIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="m3.75 13.5 10.5-11.25L12 10.5h8.25L9.75 21.75 12 13.5H3.75Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const ClockIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M12 6v6h4.5m4.5 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const UsersIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M15 19.128a9.38 9.38 0 0 0 2.625.372 9.337 9.337 0 0 0 4.121-.952 4.125 4.125 0 0 0-7.533-2.493M15 19.128v-.003c0-1.113-.285-2.16-.786-3.07M15 19.128v.106A12.318 12.318 0 0 1 8.624 21c-2.331 0-4.512-.645-6.374-1.766l-.001-.109a6.375 6.375 0 0 1 11.964-3.07M12 6.375a3.375 3.375 0 1 1-6.75 0 3.375 3.375 0 0 1 6.75 0Zm8.25 2.25a2.625 2.625 0 1 1-5.25 0 2.625 2.625 0 0 1 5.25 0Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const EyeSlashIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M3.98 8.223A10.477 10.477 0 0 0 1.934 12C3.226 16.338 7.244 19.5 12 19.5c.993 0 1.953-.138 2.863-.395M6.228 6.228A10.451 10.451 0 0 1 12 4.5c4.756 0 8.773 3.162 10.065 7.498a10.522 10.522 0 0 1-4.293 5.774M6.228 6.228 3 3m3.228 3.228 3.65 3.65m7.894 7.894L21 21m-3.228-3.228-3.65-3.65m0 0a3 3 0 1 0-4.243-4.243m4.242 4.242L9.88 9.88" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const DiffIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M7.5 21 3 16.5m0 0L7.5 12M3 16.5h13.5m0-13.5L21 7.5m0 0L16.5 12M21 7.5H7.5" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
const ServerIcon = () => (
|
||||
<svg className="h-6 w-6" fill="none" stroke="currentColor" strokeWidth={1.5} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M5.25 14.25h13.5m-13.5 0a3 3 0 0 1-3-3m3 3a3 3 0 1 0 0 6h13.5a3 3 0 1 0 0-6m-16.5-3a3 3 0 0 1 3-3h13.5a3 3 0 0 1 3 3m-19.5 0a4.5 4.5 0 0 1 .9-2.7L5.737 5.1a3.375 3.375 0 0 1 2.7-1.35h7.126c1.062 0 2.062.5 2.7 1.35l2.587 3.45a4.5 4.5 0 0 1 .9 2.7m0 0a3 3 0 0 1-3 3m0 3h.008v.008h-.008v-.008Zm0-6h.008v.008h-.008v-.008Zm-3 6h.008v.008h-.008v-.008Zm0-6h.008v.008h-.008v-.008Z" />
|
||||
</svg>
|
||||
);
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Reusable tiny components */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
function Badge({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<main className="mx-auto flex min-h-screen w-full max-w-3xl flex-col justify-center gap-6 px-6 py-20">
|
||||
<h1 className="text-3xl font-semibold tracking-tight">EnvSync Auth Example</h1>
|
||||
|
||||
<div className="rounded-xl border border-black/10 p-6 dark:border-white/20">
|
||||
{session ? (
|
||||
<>
|
||||
<p className="text-sm text-zinc-600 dark:text-zinc-300">Signed in as</p>
|
||||
<p className="mt-1 text-lg font-medium">{session.user?.email ?? session.user?.name ?? "Keycloak user"}</p>
|
||||
<span className="inline-flex items-center gap-1.5 rounded-full border border-emerald-500/20 bg-emerald-500/10 px-3 py-1 text-xs font-medium tracking-wide text-emerald-400 uppercase">
|
||||
{children}
|
||||
</span>
|
||||
);
|
||||
}
|
||||
|
||||
function SectionHeading({ badge, title, subtitle }: { badge: string; title: string; subtitle: string }) {
|
||||
return (
|
||||
<div className="mx-auto max-w-2xl text-center">
|
||||
<Badge>{badge}</Badge>
|
||||
<h2 className="mt-4 text-3xl font-bold tracking-tight sm:text-4xl">{title}</h2>
|
||||
<p className="mt-4 text-lg leading-relaxed text-zinc-400">{subtitle}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Feature cards data */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const features = [
|
||||
{
|
||||
icon: <TerminalIcon />,
|
||||
title: "CLI-first workflow",
|
||||
desc: "envsync push, pull, diff — feels like git for your .env files. Integrates into any CI/CD pipeline.",
|
||||
},
|
||||
{
|
||||
icon: <ShieldIcon />,
|
||||
title: "End-to-end encryption",
|
||||
desc: "Secrets encrypted client-side with libsodium before ever hitting the server. Zero-knowledge by design.",
|
||||
},
|
||||
{
|
||||
icon: <BoltIcon />,
|
||||
title: "Real-time notifications",
|
||||
desc: "Teammates get notified instantly via Redis pub/sub the moment environment variables change.",
|
||||
},
|
||||
{
|
||||
icon: <DiffIcon />,
|
||||
title: ".env diff viewer",
|
||||
desc: "Visual diff in the web dashboard showing exactly what changed between vault versions.",
|
||||
},
|
||||
{
|
||||
icon: <UsersIcon />,
|
||||
title: "Org & project management",
|
||||
desc: "Multi-team support with role-based access control — Admin, Editor, and Viewer roles.",
|
||||
},
|
||||
{
|
||||
icon: <ClockIcon />,
|
||||
title: "Audit log & versioning",
|
||||
desc: "Full history of who changed what, when, and from where. Rollback to any previous version.",
|
||||
},
|
||||
{
|
||||
icon: <EyeSlashIcon />,
|
||||
title: "Zero-knowledge security",
|
||||
desc: "Server only stores ciphertext. Argon2 key derivation + XChaCha20-Poly1305 encryption.",
|
||||
},
|
||||
{
|
||||
icon: <ServerIcon />,
|
||||
title: "100% self-hosted",
|
||||
desc: "Docker Compose one-liner. PostgreSQL, Redis, MinIO, Keycloak, NGINX — all on your infra.",
|
||||
},
|
||||
];
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Tech stack data */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const techStack = [
|
||||
{ layer: "Frontend", tech: "Next.js 15", detail: "App Router" },
|
||||
{ layer: "Backend", tech: "Spring Boot 3", detail: "Java 21" },
|
||||
{ layer: "Database", tech: "PostgreSQL 16", detail: "Vaults & Audit" },
|
||||
{ layer: "Cache", tech: "Redis 7", detail: "Pub/Sub" },
|
||||
{ layer: "Storage", tech: "MinIO", detail: "S3-compatible" },
|
||||
{ layer: "Auth", tech: "Keycloak", detail: "OIDC / SSO" },
|
||||
{ layer: "Proxy", tech: "NGINX", detail: "TLS termination" },
|
||||
{ layer: "Encryption", tech: "libsodium", detail: "Client-side" },
|
||||
];
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* CLI lines for the terminal animation */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const cliLines = [
|
||||
{ prompt: true, text: "envsync login" },
|
||||
{ prompt: false, text: "✓ Authenticated via Keycloak (SSO)" },
|
||||
{ prompt: true, text: "envsync init --project my-app --env development" },
|
||||
{ prompt: false, text: "✓ Vault initialized for my-app/development" },
|
||||
{ prompt: true, text: "envsync push" },
|
||||
{ prompt: false, text: "✓ Encrypted & pushed 12 variables to vault" },
|
||||
{ prompt: true, text: "envsync diff" },
|
||||
{ prompt: false, text: " + STRIPE_WEBHOOK_SECRET = ●●●●●●●●" },
|
||||
{ prompt: false, text: " ~ DATABASE_URL (modified)" },
|
||||
{ prompt: false, text: " - OLD_API_KEY (removed)" },
|
||||
{ prompt: true, text: "envsync pull" },
|
||||
{ prompt: false, text: "✓ Pulled latest vault → .env (3 changes)" },
|
||||
];
|
||||
|
||||
/* ------------------------------------------------------------------ */
|
||||
/* Architecture nodes */
|
||||
/* ------------------------------------------------------------------ */
|
||||
|
||||
const archNodes = [
|
||||
{ label: "CLI Tool", sub: "push / pull / diff", color: "border-emerald-500/40 bg-emerald-500/5" },
|
||||
{ label: "NGINX", sub: "Reverse Proxy · TLS", color: "border-zinc-600 bg-zinc-800/50" },
|
||||
{ label: "Spring Boot API", sub: "Auth · Vault · Audit", color: "border-emerald-500/30 bg-emerald-500/5" },
|
||||
{ label: "PostgreSQL", sub: "Vaults & Logs", color: "border-blue-500/30 bg-blue-500/5" },
|
||||
{ label: "Redis", sub: "Pub/Sub Notifications", color: "border-red-500/30 bg-red-500/5" },
|
||||
{ label: "MinIO", sub: "Encrypted Backups", color: "border-yellow-500/30 bg-yellow-500/5" },
|
||||
{ label: "Keycloak", sub: "SSO · OIDC · MFA", color: "border-purple-500/30 bg-purple-500/5" },
|
||||
{ label: "Next.js Dashboard", sub: "Web UI · Diff Viewer", color: "border-emerald-500/40 bg-emerald-500/5" },
|
||||
];
|
||||
|
||||
/* ================================================================== */
|
||||
/* PAGE */
|
||||
/* ================================================================== */
|
||||
|
||||
export default function LandingPage() {
|
||||
return (
|
||||
<div className="bg-grid relative min-h-screen overflow-hidden">
|
||||
{/* ───── Ambient glow blobs ───── */}
|
||||
<div className="pointer-events-none fixed inset-0 -z-10">
|
||||
<div className="absolute -top-40 left-1/2 h-[600px] w-[900px] -translate-x-1/2 rounded-full bg-emerald-500/[0.07] blur-[120px]" />
|
||||
<div className="absolute top-[60%] -left-40 h-[400px] w-[400px] rounded-full bg-emerald-600/[0.05] blur-[100px]" />
|
||||
<div className="absolute top-[40%] -right-40 h-[350px] w-[350px] rounded-full bg-emerald-400/[0.04] blur-[100px]" />
|
||||
</div>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* NAV */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<nav className="sticky top-0 z-50 border-b border-white/5 bg-[#050505]/80 backdrop-blur-xl">
|
||||
<div className="mx-auto flex h-16 max-w-6xl items-center justify-between px-6">
|
||||
<Link href="/" className="flex items-center gap-2 text-lg font-bold tracking-tight">
|
||||
<span className="flex h-8 w-8 items-center justify-center rounded-lg bg-emerald-500 text-sm font-black text-black">
|
||||
E
|
||||
</span>
|
||||
EnvSync
|
||||
</Link>
|
||||
|
||||
<div className="hidden items-center gap-8 text-sm text-zinc-400 md:flex">
|
||||
<a href="#features" className="transition hover:text-white">Features</a>
|
||||
<a href="#cli" className="transition hover:text-white">CLI</a>
|
||||
<a href="#architecture" className="transition hover:text-white">Architecture</a>
|
||||
<a href="#security" className="transition hover:text-white">Security</a>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<Link
|
||||
className="mt-4 inline-flex h-10 items-center rounded-md bg-black px-4 text-sm font-medium text-white dark:bg-white dark:text-black"
|
||||
href={"/api/auth/signout"}
|
||||
href="/api/auth/signin/keycloak"
|
||||
className="rounded-lg border border-white/10 px-4 py-2 text-sm font-medium text-zinc-300 transition hover:border-white/20 hover:text-white"
|
||||
>
|
||||
Sign out
|
||||
Sign in
|
||||
</Link>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-sm text-zinc-600 dark:text-zinc-300">You are not signed in.</p>
|
||||
<Link
|
||||
className="mt-4 inline-flex h-10 items-center rounded-md bg-black px-4 text-sm font-medium text-white dark:bg-white dark:text-black"
|
||||
href="https://github.com/yourusername/envsync"
|
||||
target="_blank"
|
||||
className="rounded-lg bg-emerald-500 px-4 py-2 text-sm font-semibold text-black transition hover:bg-emerald-400"
|
||||
>
|
||||
GitHub
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* HERO */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section className="relative mx-auto max-w-6xl px-6 pt-28 pb-20 text-center sm:pt-36 sm:pb-28">
|
||||
<div className="animate-fade-in-up">
|
||||
<Badge>🚧 Under Development</Badge>
|
||||
</div>
|
||||
|
||||
<h1 className="animate-fade-in-up delay-100 mt-8 text-4xl font-extrabold tracking-tight sm:text-6xl lg:text-7xl">
|
||||
Git for your <span className="text-gradient">.env</span> files
|
||||
</h1>
|
||||
|
||||
<p className="animate-fade-in-up delay-200 mx-auto mt-6 max-w-2xl text-lg leading-relaxed text-zinc-400 sm:text-xl">
|
||||
Stop sending secrets over Slack. EnvSync gives your team a single{" "}
|
||||
<span className="text-white font-medium">encrypted source of truth</span> for environment variables
|
||||
— with diffing, versioning, and real-time notifications.{" "}
|
||||
<span className="text-emerald-400">100% self-hosted.</span>
|
||||
</p>
|
||||
|
||||
<div className="animate-fade-in-up delay-300 mt-10 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||
<Link
|
||||
href="https://github.com/yourusername/envsync"
|
||||
target="_blank"
|
||||
className="glow-green-sm inline-flex h-12 items-center gap-2 rounded-xl bg-emerald-500 px-6 text-sm font-semibold text-black transition hover:bg-emerald-400"
|
||||
>
|
||||
<svg className="h-5 w-5" fill="currentColor" viewBox="0 0 24 24">
|
||||
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" />
|
||||
</svg>
|
||||
Star on GitHub
|
||||
</Link>
|
||||
<code className="inline-flex items-center gap-2 rounded-xl border border-white/10 bg-zinc-900/80 px-5 py-3 font-mono text-sm text-zinc-300">
|
||||
<span className="text-emerald-400">$</span> npm install -g envsync-cli
|
||||
</code>
|
||||
</div>
|
||||
|
||||
{/* Hero terminal preview */}
|
||||
<div className="animate-fade-in-up delay-400 glow-green mx-auto mt-16 max-w-2xl overflow-hidden rounded-2xl border border-white/10 bg-zinc-950">
|
||||
<div className="flex items-center gap-2 border-b border-white/5 px-4 py-3">
|
||||
<span className="h-3 w-3 rounded-full bg-red-500/70" />
|
||||
<span className="h-3 w-3 rounded-full bg-yellow-500/70" />
|
||||
<span className="h-3 w-3 rounded-full bg-green-500/70" />
|
||||
<span className="ml-2 text-xs text-zinc-500">Terminal — envsync</span>
|
||||
</div>
|
||||
<div className="p-5 text-left font-mono text-sm leading-7">
|
||||
{cliLines.map((line, i) =>
|
||||
line.prompt ? (
|
||||
<div key={i} className="text-zinc-200">
|
||||
<span className="text-emerald-400">❯ </span>
|
||||
{line.text}
|
||||
</div>
|
||||
) : (
|
||||
<div key={i} className="text-zinc-500 pl-4">{line.text}</div>
|
||||
),
|
||||
)}
|
||||
<div className="text-zinc-200 mt-1">
|
||||
<span className="text-emerald-400">❯ </span>
|
||||
<span className="cursor-blink">▊</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* PROBLEM */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section className="mx-auto max-w-4xl px-6 py-20">
|
||||
<div className="rounded-2xl border border-red-500/20 bg-red-500/[0.03] p-8 sm:p-12">
|
||||
<p className="text-xs font-semibold tracking-widest text-red-400 uppercase">The Problem</p>
|
||||
<h2 className="mt-3 text-2xl font-bold tracking-tight sm:text-3xl">
|
||||
Every dev team has this conversation
|
||||
</h2>
|
||||
<div className="mt-6 space-y-4 font-mono text-sm">
|
||||
<div className="rounded-lg border border-white/5 bg-black/40 p-4">
|
||||
<p className="text-zinc-400">
|
||||
<span className="text-blue-400">@alice:</span>{" "}
|
||||
Hey did you add the new <span className="text-yellow-300">STRIPE_WEBHOOK_SECRET</span> to your .env?
|
||||
</p>
|
||||
</div>
|
||||
<div className="rounded-lg border border-white/5 bg-black/40 p-4">
|
||||
<p className="text-zinc-400">
|
||||
<span className="text-purple-400">@bob:</span>{" "}
|
||||
Wait there's a new one? Since when?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="mt-6 text-zinc-400 leading-relaxed">
|
||||
Environment variable drift causes bugs that are impossible to reproduce, broken local setups,
|
||||
and secrets leaking through Slack DMs.{" "}
|
||||
<span className="font-semibold text-white">EnvSync fixes this</span> — and keeps everything on
|
||||
your own infrastructure.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* FEATURES */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section id="features" className="mx-auto max-w-6xl px-6 py-20">
|
||||
<SectionHeading
|
||||
badge="Features"
|
||||
title="Everything you need to sync secrets"
|
||||
subtitle="A CLI-first tool set paired with a powerful web dashboard. Built for teams who take security seriously."
|
||||
/>
|
||||
|
||||
<div className="mt-14 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{features.map((f, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="group rounded-2xl border border-white/[0.06] bg-zinc-900/40 p-6 transition hover:border-emerald-500/20 hover:bg-emerald-500/[0.03]"
|
||||
>
|
||||
<div className="flex h-11 w-11 items-center justify-center rounded-xl border border-white/10 bg-zinc-800/80 text-emerald-400 transition group-hover:border-emerald-500/30 group-hover:bg-emerald-500/10">
|
||||
{f.icon}
|
||||
</div>
|
||||
<h3 className="mt-4 font-semibold tracking-tight">{f.title}</h3>
|
||||
<p className="mt-2 text-sm leading-relaxed text-zinc-500">{f.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* CLI */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section id="cli" className="mx-auto max-w-6xl px-6 py-20">
|
||||
<SectionHeading
|
||||
badge="CLI"
|
||||
title="Feels like git for secrets"
|
||||
subtitle="Install the CLI, log in via Keycloak SSO, and start syncing env vars in seconds."
|
||||
/>
|
||||
|
||||
<div className="mt-14 grid gap-6 lg:grid-cols-2">
|
||||
{/* Left – command list */}
|
||||
<div className="space-y-3">
|
||||
{[
|
||||
{ cmd: "envsync init --project my-app --env dev", desc: "Initialize a vault for your project" },
|
||||
{ cmd: "envsync push", desc: "Encrypt & push local .env to the vault" },
|
||||
{ cmd: "envsync pull", desc: "Pull latest secrets from the vault" },
|
||||
{ cmd: "envsync diff", desc: "See what changed between local & remote" },
|
||||
{ cmd: "envsync log", desc: "View full audit log for the vault" },
|
||||
{ cmd: "envsync rollback --version 12", desc: "Restore a previous vault version" },
|
||||
{ cmd: "envsync set KEY \"value\"", desc: "Set a single variable remotely" },
|
||||
{ cmd: "envsync envs", desc: "List all environments" },
|
||||
].map((item, i) => (
|
||||
<div key={i} className="flex items-start gap-4 rounded-xl border border-white/[0.06] bg-zinc-900/40 px-5 py-4">
|
||||
<code className="shrink-0 font-mono text-sm text-emerald-400">{item.cmd}</code>
|
||||
<span className="ml-auto text-right text-xs text-zinc-500 min-w-0">{item.desc}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Right – tall terminal */}
|
||||
<div className="overflow-hidden rounded-2xl border border-white/10 bg-zinc-950">
|
||||
<div className="flex items-center gap-2 border-b border-white/5 px-4 py-3">
|
||||
<span className="h-3 w-3 rounded-full bg-red-500/70" />
|
||||
<span className="h-3 w-3 rounded-full bg-yellow-500/70" />
|
||||
<span className="h-3 w-3 rounded-full bg-green-500/70" />
|
||||
<span className="ml-2 text-xs text-zinc-500">zsh — envsync diff</span>
|
||||
</div>
|
||||
<div className="p-5 font-mono text-sm leading-7">
|
||||
<p className="text-zinc-200"><span className="text-emerald-400">❯ </span>envsync diff</p>
|
||||
<p className="mt-3 text-zinc-500">Comparing local .env ↔ vault (v14)</p>
|
||||
<div className="mt-3 rounded-lg border border-white/5 bg-black/50 p-4 space-y-1">
|
||||
<p className="text-green-400">+ STRIPE_WEBHOOK_SECRET=whsec_●●●●●●●●</p>
|
||||
<p className="text-green-400">+ FEATURE_FLAG_V2=true</p>
|
||||
<p className="text-yellow-400">~ DATABASE_URL=postgres://...→...prod</p>
|
||||
<p className="text-red-400">- DEPRECATED_API_KEY</p>
|
||||
<p className="text-zinc-600"> NEXT_PUBLIC_URL=https://app.example.com</p>
|
||||
<p className="text-zinc-600"> REDIS_URL=redis://cache:6379</p>
|
||||
</div>
|
||||
<p className="mt-3 text-zinc-500">3 added · 1 modified · 1 removed · 2 unchanged</p>
|
||||
<p className="mt-3 text-zinc-200">
|
||||
<span className="text-emerald-400">❯ </span>envsync pull
|
||||
</p>
|
||||
<p className="text-zinc-500 pl-4">✓ Pulled vault v14 → .env (4 changes applied)</p>
|
||||
<div className="mt-1 text-zinc-200">
|
||||
<span className="text-emerald-400">❯ </span>
|
||||
<span className="cursor-blink">▊</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* ARCHITECTURE */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section id="architecture" className="mx-auto max-w-6xl px-6 py-20">
|
||||
<SectionHeading
|
||||
badge="Architecture"
|
||||
title="Self-hosted. Zero cloud dependencies."
|
||||
subtitle="Every component runs on your own infrastructure with Docker Compose. Nothing phones home."
|
||||
/>
|
||||
|
||||
<div className="mt-14 grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{archNodes.map((node, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`rounded-2xl border p-5 transition ${node.color}`}
|
||||
>
|
||||
<p className="text-sm font-semibold">{node.label}</p>
|
||||
<p className="mt-1 text-xs text-zinc-500">{node.sub}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Connection hint */}
|
||||
<div className="mt-8 text-center text-xs text-zinc-600">
|
||||
All services connected via Docker internal network · TLS terminated at NGINX
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* TECH STACK */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section className="mx-auto max-w-4xl px-6 py-20">
|
||||
<SectionHeading badge="Stack" title="Built with batteries included" subtitle="Every layer is production-grade, battle-tested open-source tech." />
|
||||
|
||||
<div className="mt-14 overflow-hidden rounded-2xl border border-white/[0.06]">
|
||||
<table className="w-full text-left text-sm">
|
||||
<thead>
|
||||
<tr className="border-b border-white/[0.06] bg-zinc-900/60 text-xs uppercase tracking-wider text-zinc-500">
|
||||
<th className="px-6 py-4 font-medium">Layer</th>
|
||||
<th className="px-6 py-4 font-medium">Technology</th>
|
||||
<th className="px-6 py-4 font-medium hidden sm:table-cell">Detail</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{techStack.map((row, i) => (
|
||||
<tr key={i} className="border-b border-white/[0.03] last:border-0 hover:bg-white/[0.02] transition">
|
||||
<td className="px-6 py-4 text-zinc-400">{row.layer}</td>
|
||||
<td className="px-6 py-4 font-medium text-emerald-400">{row.tech}</td>
|
||||
<td className="px-6 py-4 text-zinc-500 hidden sm:table-cell">{row.detail}</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* SECURITY */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section id="security" className="mx-auto max-w-6xl px-6 py-20">
|
||||
<SectionHeading
|
||||
badge="Security"
|
||||
title="Zero-knowledge encryption"
|
||||
subtitle="Your secrets are encrypted before they leave your machine. The server physically cannot read them."
|
||||
/>
|
||||
|
||||
<div className="mt-14 grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{[
|
||||
{ step: "01", title: "Key derivation", desc: "Password → secret key via Argon2id (memory-hard KDF)" },
|
||||
{ step: "02", title: "Client-side encrypt", desc: "XChaCha20-Poly1305 encrypts your .env before upload" },
|
||||
{ step: "03", title: "Server stores ciphertext", desc: "PostgreSQL only ever sees encrypted blobs — zero knowledge" },
|
||||
{ step: "04", title: "Team sharing", desc: "Vault key wrapped with each member's public key (asymmetric)" },
|
||||
].map((s, i) => (
|
||||
<div key={i} className="rounded-2xl border border-white/[0.06] bg-zinc-900/40 p-6">
|
||||
<span className="font-mono text-2xl font-black text-emerald-500/30">{s.step}</span>
|
||||
<h3 className="mt-3 font-semibold tracking-tight">{s.title}</h3>
|
||||
<p className="mt-2 text-sm leading-relaxed text-zinc-500">{s.desc}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* GETTING STARTED CTA */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<section className="mx-auto max-w-4xl px-6 py-20">
|
||||
<div className="glow-green rounded-3xl border border-emerald-500/20 bg-emerald-500/[0.04] p-10 text-center sm:p-16">
|
||||
<h2 className="text-3xl font-bold tracking-tight sm:text-4xl">
|
||||
Ready to stop the <span className="text-gradient">.env chaos</span>?
|
||||
</h2>
|
||||
<p className="mx-auto mt-4 max-w-xl text-zinc-400 leading-relaxed">
|
||||
Get up and running in under 5 minutes. Clone the repo, run Docker Compose, and your whole team
|
||||
has a single encrypted source of truth.
|
||||
</p>
|
||||
|
||||
<div className="mt-8 overflow-hidden rounded-xl border border-white/10 bg-zinc-950 text-left font-mono text-sm mx-auto max-w-lg">
|
||||
<div className="flex items-center gap-2 border-b border-white/5 px-4 py-2.5">
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-red-500/70" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-yellow-500/70" />
|
||||
<span className="h-2.5 w-2.5 rounded-full bg-green-500/70" />
|
||||
</div>
|
||||
<div className="p-4 leading-7">
|
||||
<p><span className="text-emerald-400">$</span> <span className="text-zinc-300">git clone https://github.com/yourusername/envsync.git</span></p>
|
||||
<p><span className="text-emerald-400">$</span> <span className="text-zinc-300">cd envsync && docker compose up -d</span></p>
|
||||
<p className="text-zinc-600"># PostgreSQL, Redis, MinIO, Keycloak, NGINX — all running ✓</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="mt-8 flex flex-col items-center justify-center gap-4 sm:flex-row">
|
||||
<Link
|
||||
href="https://github.com/yourusername/envsync"
|
||||
target="_blank"
|
||||
className="inline-flex h-12 items-center gap-2 rounded-xl bg-emerald-500 px-6 text-sm font-semibold text-black transition hover:bg-emerald-400"
|
||||
>
|
||||
View on GitHub
|
||||
<svg className="h-4 w-4" fill="none" stroke="currentColor" strokeWidth={2} viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" d="M13.5 4.5 21 12m0 0-7.5 7.5M21 12H3" />
|
||||
</svg>
|
||||
</Link>
|
||||
<Link
|
||||
href="/api/auth/signin/keycloak"
|
||||
className="inline-flex h-12 items-center rounded-xl border border-white/10 px-6 text-sm font-medium text-zinc-300 transition hover:border-white/20 hover:text-white"
|
||||
>
|
||||
Sign in with Keycloak
|
||||
Try the Dashboard
|
||||
</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
{/* FOOTER */}
|
||||
{/* ═══════════════════════════════════════════════════════════ */}
|
||||
<footer className="border-t border-white/5 py-12">
|
||||
<div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-6 px-6 sm:flex-row">
|
||||
<div className="flex items-center gap-2 text-sm font-bold tracking-tight">
|
||||
<span className="flex h-7 w-7 items-center justify-center rounded-md bg-emerald-500 text-xs font-black text-black">
|
||||
E
|
||||
</span>
|
||||
EnvSync
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Link className="rounded-md border border-black/10 px-4 py-2 text-sm dark:border-white/20" href="/server">
|
||||
/server example
|
||||
</Link>
|
||||
<Link className="rounded-md border border-black/10 px-4 py-2 text-sm dark:border-white/20" href="/client">
|
||||
/client example
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
<div className="flex items-center gap-6 text-sm text-zinc-500">
|
||||
<a href="#features" className="transition hover:text-zinc-300">Features</a>
|
||||
<a href="#cli" className="transition hover:text-zinc-300">CLI</a>
|
||||
<a href="#architecture" className="transition hover:text-zinc-300">Architecture</a>
|
||||
<a href="#security" className="transition hover:text-zinc-300">Security</a>
|
||||
<Link href="https://github.com/yourusername/envsync" target="_blank" className="transition hover:text-zinc-300">
|
||||
GitHub
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<p className="text-xs text-zinc-600">
|
||||
Built to solve a real problem. No cloud required.
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import Link from "next/link";
|
||||
|
||||
type PollResult = {
|
||||
ok: boolean;
|
||||
status: number;
|
||||
body: unknown;
|
||||
at: string;
|
||||
};
|
||||
|
||||
export default function PublicPage() {
|
||||
const [latest, setLatest] = useState<PollResult | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
let active = true;
|
||||
|
||||
const run = async () => {
|
||||
try {
|
||||
const response = await fetch("/api/secure", { cache: "no-store" });
|
||||
const body = await response.json().catch(() => null);
|
||||
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
setLatest({
|
||||
ok: response.ok,
|
||||
status: response.status,
|
||||
body,
|
||||
at: new Date().toISOString(),
|
||||
});
|
||||
setError(null);
|
||||
} catch (err) {
|
||||
if (!active) {
|
||||
return;
|
||||
}
|
||||
|
||||
const message = err instanceof Error ? err.message : "Request failed";
|
||||
setError(message);
|
||||
}
|
||||
};
|
||||
|
||||
run();
|
||||
const interval = setInterval(run, 2000);
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
clearInterval(interval);
|
||||
};
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<main className="mx-auto flex min-h-screen w-full max-w-4xl flex-col gap-6 px-6 py-20">
|
||||
<h1 className="text-3xl font-semibold tracking-tight">/public polling example</h1>
|
||||
<p className="text-sm text-zinc-600 dark:text-zinc-300">
|
||||
Polling /api/secure every 2 seconds. The API route forwards your access token to the backend.
|
||||
</p>
|
||||
|
||||
<div className="rounded-xl border border-black/10 p-6 dark:border-white/20">
|
||||
{error && <p className="text-sm text-red-600">{error}</p>}
|
||||
{!error && !latest && <p className="text-sm">Waiting for first response…</p>}
|
||||
{latest && (
|
||||
<div className="space-y-3">
|
||||
<p className="text-sm">
|
||||
Status: <span className="font-medium">{latest.ok ? "success" : "failed"}</span> ({latest.status})
|
||||
</p>
|
||||
<p className="text-xs text-zinc-500">Last updated: {latest.at}</p>
|
||||
<pre className="overflow-x-auto text-sm">{JSON.stringify(latest.body, null, 2)}</pre>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex gap-3">
|
||||
<Link className="rounded-md border border-black/10 px-4 py-2 text-sm dark:border-white/20" href="/">
|
||||
Home
|
||||
</Link>
|
||||
<Link className="rounded-md border border-black/10 px-4 py-2 text-sm dark:border-white/20" href="/server">
|
||||
Server example
|
||||
</Link>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import nextAuthMiddleware from "next-auth/middleware";
|
||||
import type { NextRequestWithAuth } from "next-auth/middleware";
|
||||
import type { NextFetchEvent } from "next/server";
|
||||
|
||||
export function proxy(request: NextRequestWithAuth, event: NextFetchEvent) {
|
||||
return nextAuthMiddleware(request, event);
|
||||
}
|
||||
|
||||
export const config = {
|
||||
matcher: ["/((?!$).*)"],
|
||||
};
|
||||
Reference in new issue
Block a user