Documentation
¶
Index ¶
- Variables
- func EntityFieldName(entityName string) string
- func EntityListFieldName(entityName string) string
- func GoPackage(name string) string
- func Pluralize(s string) string
- func ProtoPackageBase(protoPackage string) string
- func ProtoPackageVersion(protoPackage string) string
- func ServiceHookFile(name string) string
- func ServicePackage(name string) string
- func ToExportedFieldName(pkg string) string
- func ToKebabCase(s string) string
- func ToPascalCase(s string) string
- func ToProtoPascalCase(s string) string
- func ToSnakeCase(s string) string
Constants ¶
This section is empty.
Variables ¶
var GoInitialisms = []string{
"ACL", "API", "ASCII", "CPU", "CSS", "DB", "DNS", "EOF", "GUID",
"HTML", "HTTP", "HTTPS", "ID", "IO", "IP", "JSON", "JWT", "LHS",
"LLM", "MCP", "QPS",
"RAM", "RHS", "RPC", "SLA", "SMTP", "SQL", "SSH", "TCP",
"TLS", "TTL", "UDP", "UI", "UID", "UUID", "URI", "URL",
"UTF8", "VM", "XML", "XMPP", "XSRF", "XSS",
}
GoInitialisms are common Go initialisms that should be all-caps. This is the single source of truth — all packages must import from here.
var GoInitialismsMap = func() map[string]bool { m := make(map[string]bool, len(GoInitialisms)) for _, v := range GoInitialisms { m[strings.ToLower(v)] = true } return m }()
GoInitialismsMap provides O(1) lookup for initialism detection (lowercase keys).
Functions ¶
func EntityFieldName ¶
EntityFieldName returns the snake_case proto FIELD name that a CRUD create/get/update response uses to carry a single entity — the snake_case of the entity's (PascalCase) message name. For a "ModuleConfig" entity this is "module_config"; protoc-gen-go then generates the Go field "ModuleConfig".
This is the SINGLE source of truth for the entity-carrying field name, shared by three sites that MUST agree or multi-word CRUD silently breaks:
- the entity scaffolder (`forge add entity`) emits `<Entity> <field> = 1;`,
- the CRUD ops emitter references the Go form (ToProtoPascalCase of this),
- the CRUD shape detector (validateCRUDShape) matches the response's observed snake_case field names against this.
The historical bug: the detector compared against strings.ToLower(Name) ("moduleconfig"), which matches neither the scaffolder's "module_config" nor the emitter's "ModuleConfig" — so every multi-word entity fell to the custom-read-shape stub and produced empty CRUD. Routing all three through this helper makes the concatenated-lowercase form impossible to reintroduce.
func EntityListFieldName ¶
EntityListFieldName returns the snake_case proto FIELD name that a CRUD list response uses to carry the repeated entity — the pluralized snake_case of the entity's message name. For "ModuleConfig" this is "module_configs". It is the plural companion to EntityFieldName; see that doc for why the derivation is centralized here.
func GoPackage ¶
GoPackage normalises a CLI/forge.yaml-style name into a Go package identifier in snake_case form. Hyphens convert to underscores; existing underscores are preserved; PascalCase / camelCase boundaries are split (so "AdminServer" → "admin_server", "calibrator_refit" stays "calibrator_refit", "admin-server" → "admin_server"). Distinct from ServicePackage in that it does NOT strip a trailing "Service" — callers using it for workers, operators, and arbitrary package leaves want the raw form.
Snake_case is a valid Go package identifier (Go's spec allows it, `golint` only warns), and matches the on-disk convention proto buf emits for multi-word proto packages (e.g. proto package `services.admin_server.v1` → directory `services/admin_server/v1`). Keeping the package name aligned with the proto path means handler dirs, generated mock files, and wire_gen function names all stay in lockstep without forcing the user to choose between snake on disk and compact in code.
func ProtoPackageBase ¶
ProtoPackageBase returns the proto package with any trailing version segment stripped — the version-INDEPENDENT logical package identity.
"billing.v1" -> "billing" "acme.billing.v1" -> "acme.billing" "billing" -> "billing" (already unversioned)
Pairing ProtoPackageBase + ProtoPackageVersion splits a fused `billing.v1` identity into ("billing", "v1") so the inventory can record the two distinctly. v2 then differs ONLY in Version, sharing the base — the data-model precondition for additive multi-version support.
func ProtoPackageVersion ¶
ProtoPackageVersion extracts the proto API version from a fully-qualified proto package name — the LAST dotted segment when it has the protobuf version shape `v<major>` optionally suffixed with a stability channel (`v1`, `v2`, `v1alpha1`, `v2beta3`). Returns "" when the package carries no version segment.
"billing.v1" -> "v1" "acme.billing.v1" -> "v1" "shop.v2beta1" -> "v2beta1" "billing" -> "" (unversioned) "" -> ""
This is the single source of truth for the version metadata the generated service inventory records (FORGE_SHAPE_REDESIGN — version-aware registry seam). It deliberately reads ONLY the package's own last segment, never the service name, so the inventory's Version field is exactly the proto API version and additive: a future `billing.v2` records Version "v2" as a second version of the same logical service rather than colliding identity.
func ServiceHookFile ¶
ServiceHookFile returns the canonical frontend hook filename for a service. Encodes the rule that the hook file is the service name in kebab-case (with initialisms kept glued) suffixed with `-hooks.ts`.
All file-emitter sites AND the re-export indexer must go through this function. If a future caller needs a different suffix or extension, extract a parameterised helper rather than duplicating the kebab transform — the re-export index only stays in lockstep with on-disk filenames because both go through the same canonical splitter (`ToKebabCase`).
func ServicePackage ¶
ServicePackage is the single canonical Go-package form for a service, binary, frontend, worker, or operator name.
Inputs accepted:
- Forge / CLI names: kebab-case ("admin-server"), snake_case ("admin_server"), or already-compact ("api").
- Proto service names: PascalCase ending in "Service" ("EchoService", "AdminServerService").
Output is always a single lowercase snake_case Go-style identifier. The PascalCase-with-"Service"-suffix branch first trims the suffix so "EchoService" -> "echo" and "AdminServerService" -> "admin_server". The pure-CLI branch normalises hyphens to underscores and PascalCase boundaries to underscores, so "admin-server" / "admin_server" / "AdminServer" all collapse to "admin_server".
One canonical function for every site that emits a handler dir, a generated mock file, a bootstrap import, or a wire alias — keep it the single source of truth so the on-disk dir layout, the codegen keys, and the cleanup sweeper can never disagree.
History: pre-2026-06-08 this function (and GoPackage) emitted compact form (separators stripped — "admin_server" → "adminserver"). The compact convention collided with the universal snake_case dir layout projects actually use (protoc-gen-go emits snake for multi-word proto packages, KCL package names use snake, every existing forge project on disk had snake handler dirs). The bug surface was a duplicate-dir failure where `forge generate` created `handlers/adminserver/` alongside the existing `handlers/admin_server/`, then regenerated wire_gen.go to reference the compact form while user-owned bootstrap.go still referenced the snake form — broken build.
func ToExportedFieldName ¶
ToExportedFieldName converts a lowercase package/field name to an exported Go identifier, respecting Go initialisms. Examples: "api" -> "API", "db" -> "DB", "orders" -> "Orders"
func ToKebabCase ¶
ToKebabCase converts a name to kebab-case, treating known initialisms (LLM, API, URL, JSON, etc. — see GoInitialisms) as a single segment so that "LLMGateway" → "llm-gateway" rather than "l-l-m-gateway".
Accepts input in PascalCase, camelCase, snake_case, or already-kebab- case form; the output is always lowercase, hyphen-separated, with no runs of multiple hyphens. This is the canonical kebab function for every site that emits filenames, slugs, route paths, or import paths that need to round-trip with proto Go names — keep it the single source of truth so frontend hooks files, navigation slugs, and re- export indexers can never disagree on whether "LLMGateway" splits as "l-l-m-gateway" or "llm-gateway".
func ToPascalCase ¶
ToPascalCase converts a hyphenated, underscored, or camelCase name to PascalCase. It handles both '-' and '_' as word separators and capitalizes Go initialisms. e.g. "api-gateway" -> "APIGateway", "user_service" -> "UserService", "http_client" -> "HTTPClient".
func ToProtoPascalCase ¶
ToProtoPascalCase converts a snake_case proto field name to PascalCase using protobuf's Go naming rules: simple title-case each word segment WITHOUT applying Go initialisms. For example:
- "id" → "Id" (not "ID")
- "org_id" → "OrgId" (not "OrgID")
- "http_status" → "HttpStatus" (not "HTTPStatus")
This matches the field names that protoc-gen-go actually generates.
func ToSnakeCase ¶
ToSnakeCase converts a string (camelCase, PascalCase, UPPER_CASE, etc.) to snake_case. e.g. "firstName" -> "first_name", "HTTPStatus" -> "http_status", "UPPER_CASE" -> "upper_case".
Types ¶
This section is empty.