Compare commits

...

3 Commits

Author SHA1 Message Date
Stavros 7380cbfe44 refactor: generate mdx docs with tabs for each config option 2026-07-12 17:53:34 +03:00
Stavros 791adbb54d fix: remove omitempty suffix from docs gen 2026-07-11 17:18:35 +03:00
dependabot[bot] 4cd4d67bda chore(deps): bump the minor-patch group in /frontend with 3 updates (#991)
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-11 16:23:04 +03:00
6 changed files with 94 additions and 45 deletions
+4 -2
View File
@@ -4,6 +4,10 @@
# The base URL where the app is hosted.
TINYAUTH_APPURL=
# Path to config file.
TINYAUTH_CONFIGFILE=
# Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment.
TINYAUTH_LABELPROVIDER="auto"
# database config
@@ -233,8 +237,6 @@ TINYAUTH_TAILSCALE_APITOKENFILE=
TINYAUTH_TAILSCALE_TAILNET=
# Cache duration for Tailscale device and user lists in seconds.
TINYAUTH_TAILSCALE_CACHEDURATION=300
# Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment.
TINYAUTH_LABELPROVIDER="auto"
# log config
+3 -3
View File
@@ -23,16 +23,16 @@
"axios": "^1.18.1",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"i18next": "^26.3.4",
"i18next": "^26.3.6",
"i18next-browser-languagedetector": "^8.2.1",
"i18next-resources-to-backend": "^1.2.1",
"lucide-react": "^1.23.0",
"lucide-react": "^1.24.0",
"next-themes": "^0.4.6",
"radix-ui": "^1.6.2",
"react": "^19.2.7",
"react-dom": "^19.2.7",
"react-hook-form": "^7.81.0",
"react-i18next": "^17.0.8",
"react-i18next": "^17.0.9",
"react-markdown": "^10.1.0",
"react-router": "^8.2.0",
"sonner": "^2.0.7",
+18 -18
View File
@@ -42,8 +42,8 @@ importers:
specifier: ^2.1.1
version: 2.1.1
i18next:
specifier: ^26.3.4
version: 26.3.4(typescript@6.0.3)
specifier: ^26.3.6
version: 26.3.6(typescript@6.0.3)
i18next-browser-languagedetector:
specifier: ^8.2.1
version: 8.2.1
@@ -51,8 +51,8 @@ importers:
specifier: ^1.2.1
version: 1.2.1
lucide-react:
specifier: ^1.23.0
version: 1.23.0(react@19.2.7)
specifier: ^1.24.0
version: 1.24.0(react@19.2.7)
next-themes:
specifier: ^0.4.6
version: 0.4.6(react-dom@19.2.7(react@19.2.7))(react@19.2.7)
@@ -69,8 +69,8 @@ importers:
specifier: ^7.81.0
version: 7.81.0(react@19.2.7)
react-i18next:
specifier: ^17.0.8
version: 17.0.8(i18next@26.3.4(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)
specifier: ^17.0.9
version: 17.0.9(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3)
react-markdown:
specifier: ^10.1.0
version: 10.1.0(@types/react@19.2.17)(react@19.2.7)
@@ -1772,10 +1772,10 @@ packages:
i18next-resources-to-backend@1.2.1:
resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==}
i18next@26.3.4:
resolution: {integrity: sha512-pa7m0d7pBDqGHZxljT+WPFeyFgQ7P7SciPPo1tTqYuO0z4sqADYhwnBESmmGp/wEof1inwdls/k8ZgTg8rxFHA==}
i18next@26.3.6:
resolution: {integrity: sha512-Bu5Z2nAXgfVyM8xvW3jk9EKRIuX37PudsrBViThNFx7CR7aaYTpP01cxNB/E4c4UUzTDiAZRstEhsRfPOL/8xA==}
peerDependencies:
typescript: ^5 || ^6
typescript: ^5 || ^6 || ^7
peerDependenciesMeta:
typescript:
optional: true
@@ -1957,8 +1957,8 @@ packages:
lru-cache@5.1.1:
resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
lucide-react@1.23.0:
resolution: {integrity: sha512-38BpJcD0JhFosxHApP/BYsBetLpQFRoTRzEzstM/XCc3jsAG7wqaY1lgVwxiUe3xqYE+lNxo2PkCmYwXWrwwIw==}
lucide-react@1.24.0:
resolution: {integrity: sha512-YT6mBD8lGKkg4nM39enlm94/sfJIiW0YKUT60fBy4YK8tai31ylg1VhGNWxkpSKHo9UagfnZqwIff3HTDQwXeA==}
peerDependencies:
react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0
@@ -2173,14 +2173,14 @@ packages:
peerDependencies:
react: ^16.8.0 || ^17 || ^18 || ^19
react-i18next@17.0.8:
resolution: {integrity: sha512-0ooKbGLU8JXhe1zwpQUWIeXSgLPOfwJmgheWRIUpcoA0CpyabpGhayjdG+/eA5esC1AQ8h2jWpXjJfzQzeDOCw==}
react-i18next@17.0.9:
resolution: {integrity: sha512-buLzOSqHtXxjf+qgSrLWNTXVZ1jSwO6kUv3uJqSP1roGBPgNnbhFm7OmdVwWcgf2gIbUyP0J333uPyx+Btsi3w==}
peerDependencies:
i18next: '>= 26.2.0'
react: '>= 16.8.0'
react-dom: '*'
react-native: '*'
typescript: ^5 || ^6
typescript: ^5 || ^6 || ^7
peerDependenciesMeta:
react-dom:
optional: true
@@ -4220,7 +4220,7 @@ snapshots:
dependencies:
'@babel/runtime': 7.29.2
i18next@26.3.4(typescript@6.0.3):
i18next@26.3.6(typescript@6.0.3):
optionalDependencies:
typescript: 6.0.3
@@ -4347,7 +4347,7 @@ snapshots:
dependencies:
yallist: 3.1.1
lucide-react@1.23.0(react@19.2.7):
lucide-react@1.24.0(react@19.2.7):
dependencies:
react: 19.2.7
@@ -4736,11 +4736,11 @@ snapshots:
dependencies:
react: 19.2.7
react-i18next@17.0.8(i18next@26.3.4(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3):
react-i18next@17.0.9(i18next@26.3.6(typescript@6.0.3))(react-dom@19.2.7(react@19.2.7))(react@19.2.7)(typescript@6.0.3):
dependencies:
'@babel/runtime': 7.29.7
html-parse-stringify: 3.0.1
i18next: 26.3.4(typescript@6.0.3)
i18next: 26.3.6(typescript@6.0.3)
react: 19.2.7
use-sync-external-store: 1.6.0(react@19.2.7)
optionalDependencies:
+4 -1
View File
@@ -46,11 +46,14 @@ func generateExampleEnv() {
func buildEnvEntry(child reflect.StructField, childValue reflect.Value, parentPath string, entries *[]EnvEntry) {
desc := child.Tag.Get("description")
tag := child.Tag.Get("yaml")
gen := child.Tag.Get("gen")
if tag == "-" {
if tag == "-" && gen != "include" {
return
}
tag = strings.TrimSuffix(tag, ",omitempty")
value := childValue.Interface()
entry := EnvEntry{
+63 -19
View File
@@ -1,7 +1,6 @@
package main
import (
"bytes"
"errors"
"fmt"
"io/fs"
@@ -13,9 +12,13 @@ import (
"github.com/tinyauthapp/tinyauth/internal/model"
)
type ConfigOptions struct {
Env string
Flag string
YAML string
}
type MarkdownEntry struct {
Env string
Flag string
Options ConfigOptions
Description string
Default any
}
@@ -47,16 +50,27 @@ func generateMarkdown() {
func buildMdEntry(child reflect.StructField, childValue reflect.Value, parentPath string, entries *[]MarkdownEntry) {
desc := child.Tag.Get("description")
tag := child.Tag.Get("yaml")
gen := child.Tag.Get("gen")
if tag == "-" {
if tag == "-" && gen != "include" {
return
}
tag = strings.TrimSuffix(tag, ",omitempty")
value := childValue.Interface()
configOptions := ConfigOptions{
Env: strings.ToUpper(strings.ReplaceAll(parentPath, ".", "_")) + strings.ToUpper(child.Name),
Flag: fmt.Sprintf("--%s%s", strings.TrimPrefix(parentPath, "tinyauth."), strings.ToLower(child.Name)),
}
if tag != "-" && tag != "" {
configOptions.YAML = strings.TrimPrefix(parentPath, "tinyauth.") + tag
}
entry := MarkdownEntry{
Env: strings.ToUpper(strings.ReplaceAll(parentPath, ".", "_")) + strings.ToUpper(child.Name),
Flag: fmt.Sprintf("--%s%s", strings.TrimPrefix(parentPath, "tinyauth."), strings.ToLower(child.Name)),
Options: configOptions,
Description: desc,
}
@@ -83,11 +97,14 @@ func buildMdMapEntry(child reflect.StructField, parentPath string, entries *[]Ma
}
tag := child.Tag.Get("yaml")
gen := child.Tag.Get("gen")
if tag == "-" {
if tag == "-" && gen != "include" {
return
}
tag = strings.TrimSuffix(tag, ",omitempty")
mapPath := parentPath + tag + ".[name]."
valueType := fieldType.Elem()
@@ -102,27 +119,54 @@ func buildMdChildPath(parent string, child string) string {
}
func compileMd(entries []MarkdownEntry) []byte {
buffer := bytes.Buffer{}
buffer := strings.Builder{}
buffer.WriteString("<!--- This file is automatically generated by gen/gen_md.go. Do not edit manually. --->\n\n")
buffer.WriteString("# Tinyauth configuration reference\n\n")
buffer.WriteString("| Environment | Flag | Description | Default |\n")
buffer.WriteString("| - | - | - | - |\n")
buffer.WriteString("{/* This part is automatically generated by gen/gen_md.go in the main repository. DO NOT EDIT. */}\n\n")
buffer.WriteString("import { Tabs, TabItem } from '@astrojs/starlight/components';\n\n")
buffer.WriteString("<Tabs>\n")
renderTabItem(&buffer, entries, "Environment")
renderTabItem(&buffer, entries, "Flags")
renderTabItem(&buffer, entries, "YAML")
buffer.WriteString("</Tabs>\n")
return []byte(buffer.String())
}
func renderTabItem(buffer *strings.Builder, entries []MarkdownEntry, section string) {
buffer.WriteString(fmt.Sprintf(" <TabItem label=\"%s\">\n", section))
buffer.WriteString(" ### main\n\n")
buffer.WriteString(" | Option | Description | Default |\n")
buffer.WriteString(" | - | - | - |\n")
configType := strings.ToLower(section)
previousSection := ""
for _, entry := range entries {
if strings.Count(entry.Env, "_") > 1 {
section := strings.Split(strings.TrimPrefix(entry.Env, "TINYAUTH_"), "_")[0]
section := strings.Split(entry.Options.YAML, ".")[0]
var option string
switch configType {
case "yaml":
option = entry.Options.YAML
case "flags":
option = entry.Options.Flag
case "environment":
option = entry.Options.Env
}
if option == "" {
continue
}
if strings.Count(entry.Options.YAML, ".") >= 1 {
if section != previousSection {
buffer.WriteString("\n## " + strings.ToLower(section) + "\n\n")
buffer.WriteString("| Environment | Flag | Description | Default |\n")
buffer.WriteString("| - | - | - | - |\n")
buffer.WriteString("\n ### " + strings.ToLower(section) + "\n\n")
buffer.WriteString(" | Option | Description | Default |\n")
buffer.WriteString(" | - | - | - |\n")
previousSection = section
}
}
fmt.Fprintf(&buffer, "| `%s` | `%s` | %s | %s |\n", entry.Env, entry.Flag, entry.Description, entry.Default)
fmt.Fprintf(buffer, " | `%s` | %s | %s |\n", option, entry.Description, entry.Default)
}
return buffer.Bytes()
buffer.WriteString(" </TabItem>\n")
}
+2 -2
View File
@@ -103,6 +103,8 @@ func NewDefaultConfiguration(runtimeEnv RuntimeEnv) *Config {
type Config struct {
AppURL string `description:"The base URL where the app is hosted." yaml:"appUrl,omitempty"`
ConfigFile string `description:"Path to config file." yaml:"-" gen:"include"`
LabelProvider string `description:"Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment." yaml:"labelProvider,omitempty"`
Database DatabaseConfig `description:"Database configuration." yaml:"database,omitempty"`
Analytics AnalyticsConfig `description:"Analytics configuration." yaml:"analytics,omitempty"`
Resources ResourcesConfig `description:"Resources configuration." yaml:"resources,omitempty"`
@@ -115,9 +117,7 @@ type Config struct {
LDAP LDAPConfig `description:"LDAP configuration." yaml:"ldap,omitempty"`
Experimental ExperimentalConfig `description:"Experimental features, use with caution." yaml:"experimental,omitempty"`
Tailscale TailscaleConfig `description:"Tailscale configuration." yaml:"tailscale,omitempty"`
LabelProvider string `description:"Label provider to use for ACLs (auto, docker, kubernetes or none to disable). auto detects the environment." yaml:"labelProvider,omitempty"`
Log LogConfig `description:"Logging configuration." yaml:"log,omitempty"`
ConfigFile string `description:"Path to config file." yaml:"-"`
}
type DatabaseConfig struct {