Initial commit of Descrybe v2 without local scratch artifacts.
Drop one-shot tmp/axe scripts and agent i18n scratch so the Gitea tree is deployable.
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
package company
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/jackc/pgx/v5/pgxpool"
|
||||
)
|
||||
|
||||
// DefaultLanguage is the content-language fallback when unset.
|
||||
const DefaultLanguage = "en"
|
||||
|
||||
// ContentLanguages is the allowlist for companies.language (AI/product content).
|
||||
// Keep in sync with apps/web/src/lib/content-languages.ts.
|
||||
var ContentLanguages = []string{
|
||||
"en", "fr", "de", "es", "it", "nl", "pt", "pl",
|
||||
"cs", "sk", "hu", "ro", "bg", "hr", "sl",
|
||||
"sv", "da", "fi", "el", "et", "lv", "lt", "mt", "ga",
|
||||
"ja", // CJK plug-in slot (Japanese)
|
||||
}
|
||||
|
||||
// contentLanguageLabels are English display names for AI prompt injection.
|
||||
// Keep in sync with apps/web/src/lib/content-languages.ts labels.
|
||||
var contentLanguageLabels = map[string]string{
|
||||
"en": "English",
|
||||
"fr": "French",
|
||||
"de": "German",
|
||||
"es": "Spanish",
|
||||
"it": "Italian",
|
||||
"nl": "Dutch",
|
||||
"pt": "Portuguese",
|
||||
"pl": "Polish",
|
||||
"cs": "Czech",
|
||||
"sk": "Slovak",
|
||||
"hu": "Hungarian",
|
||||
"ro": "Romanian",
|
||||
"bg": "Bulgarian",
|
||||
"hr": "Croatian",
|
||||
"sl": "Slovenian",
|
||||
"sv": "Swedish",
|
||||
"da": "Danish",
|
||||
"fi": "Finnish",
|
||||
"el": "Greek",
|
||||
"et": "Estonian",
|
||||
"lv": "Latvian",
|
||||
"lt": "Lithuanian",
|
||||
"mt": "Maltese",
|
||||
"ga": "Irish",
|
||||
"ja": "Japanese",
|
||||
}
|
||||
|
||||
var contentLanguageSet map[string]struct{}
|
||||
|
||||
func init() {
|
||||
contentLanguageSet = make(map[string]struct{}, len(ContentLanguages))
|
||||
for _, code := range ContentLanguages {
|
||||
contentLanguageSet[code] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
// NormalizeLanguage trims and lowercases a content-language code.
|
||||
func NormalizeLanguage(raw string) string {
|
||||
return strings.ToLower(strings.TrimSpace(raw))
|
||||
}
|
||||
|
||||
// IsAllowedLanguage reports whether code is in ContentLanguages (after normalize).
|
||||
func IsAllowedLanguage(raw string) bool {
|
||||
_, ok := contentLanguageSet[NormalizeLanguage(raw)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// ParseLanguage validates and normalizes a content-language code.
|
||||
// Empty input returns DefaultLanguage when allowEmptyAsDefault is true;
|
||||
// otherwise empty is an error (use for explicit PATCH language fields).
|
||||
func ParseLanguage(raw string, allowEmptyAsDefault bool) (string, error) {
|
||||
code := NormalizeLanguage(raw)
|
||||
if code == "" {
|
||||
if allowEmptyAsDefault {
|
||||
return DefaultLanguage, nil
|
||||
}
|
||||
return "", fmt.Errorf("language is required")
|
||||
}
|
||||
if !IsAllowedLanguage(code) {
|
||||
return "", fmt.Errorf("unsupported language %q", code)
|
||||
}
|
||||
return code, nil
|
||||
}
|
||||
|
||||
// LanguageLabel returns the English display name for a content-language code
|
||||
// (for AI prompt injection). Empty/unknown codes fall back to English.
|
||||
func LanguageLabel(raw string) string {
|
||||
code, err := ParseLanguage(raw, true)
|
||||
if err != nil {
|
||||
code = DefaultLanguage
|
||||
}
|
||||
if label, ok := contentLanguageLabels[code]; ok {
|
||||
return label
|
||||
}
|
||||
return contentLanguageLabels[DefaultLanguage]
|
||||
}
|
||||
|
||||
// LoadLanguage returns companies.language for companyID, or DefaultLanguage.
|
||||
func LoadLanguage(ctx context.Context, pool *pgxpool.Pool, companyID uuid.UUID) string {
|
||||
if pool == nil {
|
||||
return DefaultLanguage
|
||||
}
|
||||
var raw string
|
||||
err := pool.QueryRow(ctx, `SELECT COALESCE(language, '') FROM companies WHERE id = $1`, companyID).Scan(&raw)
|
||||
if err != nil {
|
||||
return DefaultLanguage
|
||||
}
|
||||
code, err := ParseLanguage(raw, true)
|
||||
if err != nil {
|
||||
return DefaultLanguage
|
||||
}
|
||||
return code
|
||||
}
|
||||
Reference in New Issue
Block a user