export

package
v1.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 8, 2025 License: MIT Imports: 5 Imported by: 0

README

Export

This package provides the functionality to export Golang and TypeScript code based on the files in the .projectforge/export directory accessible from the project root.

Key Terms

Model: A data structure that represents a full object and its fields. Models can generate a full database-backed service, a rich UI, and more. Defined in app/lib/metamodel/model/model.go

Enum: A data structure that represents a set of named constants. Enums can be used to define the possible values for a field in a model, and are backed by rich Go/TS objects. Defined in app/lib/metamodel/enum/enum.go

Event: A data structure an event and its fields. Basically a lightweight model, these aren't persisted (automatically) in a database. Defined in app/lib/metamodel/model/event.go

Group: A data structure that represents a group that models can belong to. Groups can be used to organize models into a hierarchy. Defined in app/lib/metamodel/model/group.go

Export Directory Structure

The export directory can contain the following:

  • enum: Directory of exported enums, each a JSON file that serializes to an Enum
  • model: Directory of exported models, each a JSON file that serializes to a Model
  • event: Directory of exported events, each a JSON file that serializes to an Event
  • groups.json: A JSON file that contains an array of groups that models can belong to. They conform to Group.
  • types.json: A JSON file that contains an array of extra types that can be used in the export. They conform to Model, but are not actually models used in the app

Exported Files

Enumerations

There are two types of enumerations. Simple enums are represented as a string alias, while complex enums are represented as a struct.

Both serialize to a string for JSON and friends, and provide utility functions.

"Simple" Enums

For the following configuration file, saved as .projectforge/export/enums/widget.json:

{
  "name": "widget",
  "package": "inventory",
  "description": "Widget",
  "icon": "star",
  "values": ["a", "b", "c", "d"]
}

The following code will be generated as app/inventory/widget.go:

package inventory

var AllWidgets = Widgets{WidgetA, WidgetB, WidgetC, WidgetD}

type (
	Widget  string
	Widgets []Widget
)

const (
	WidgetA Widget = "a"
	WidgetB Widget = "b"
	WidgetC Widget = "c"
	WidgetD Widget = "d"
)
"Complex" Enums

As soon as at least one enum value carries metadata (name, description, icon, default flag, or extras), an enum is considered "complex".

For the following configuration file, saved as .projectforge/export/enums/box.json:

{
  "name": "box",
  "package": "inventory",
  "description": "A complex enum",
  "icon": "star",
  "values": [
    { "key": "small", "name": "Small Box", "extra": { "flaps": 1 } },
    { "key": "large", "name": "Large Box", "extra": { "flaps": 4 } }
  ]
}

...the following files will be emitted to app/inventory/box*.go:

  • Struct definition Box with the fixed fields Key, Name, Description, Icon, plus one field per field defined in extra. Extra field types are inferred from sample data, can be overridden with config.type:<field>.
  • For each value, a package-level variable like BoxSmall (a *Box) is declared, collecting all configured fields.
  • Type alias Boxes, defined as []*Box, and variable AllBoxes, aggregating the variables so the enum can be iterated.
  • Collection alias type Boxes []Box with helpers: Keys(), Strings(), Help() string (comma-separated options), Random().
  • Lookup functions on Boxes:
    • Get(key string, logger util.Logger) compares case-insensitively against the Key field.
    • GetByName(name string, logger util.Logger) mirrors the same logic for the Name field.
    • For each extra field, a helper is emitted, such as GetByFlaps(value int, logger util.Logger) *Box if values are unique; otherwise GetByFlaps(value) Boxes.
  • func BoxParse(logger util.Logger, keys ...string) *Box maps raw strings to the appropriate enum value by Key. Empty input returns nil.

Every lookup logs a warning through the supplied logger when no match is found. If an enum value is marked as the default, that value is returned on missing or blank input; otherwise a sentinel {Key: "_error", Name: "error: ..."} is produced so callers can detect configuration issues.

Events

Events are used to represent ephemeral structs that are (usually) not stored in the database. They're useful as WebSocket messages, event-driven pipelines, and really any time you need a rich struct in Go or TypeScript.

For the following configuration file, saved as .projectforge/export/events/config.json:

{
  "name": "config",
  "package": "state",
  "group": ["game"],
  "description": "The configuration for this particular game state",
  "icon": "star",
  "columns": [
    { "name": "written_language", "type": "string" },
    { "name": "verbose_logging", "type": "bool" },
    { "name": "extra", "type": "map" }
  ]
}

...the following will be emitted to app/game/state/config.go:

  • The Config struct, with correctly-typed fields, in this case string, bool, util.ValueMap.
  • Two constructors, NewConfig and ConfigFromMap, and RandomConfig which is useful for testing.
  • Transformation methods ToMap, ToOrderedMap, Strings, ToCSV, ToData.
  • A Clone method to create a deep copy of the struct.
  • A Diff method to compare two instances and return a list of differences.
  • Type Alias Configs []*Config, with methods Clone, ToMaps, ToOrderedMaps, and accessors by every unique or indexed field.
Models

Models are used to represent persistent structs that have a primary key (composite keys supported). They are often stored in the database, and UI and managed service are required. They're useful as the foundation for your application's data model.

For the following configuration file, saved as .projectforge/export/models/config.json:

{
  "name": "config",
  "package": "state",
  "description": "The configuration for this particular game state",
  "icon": "star",
  "columns": [
    { "name": "id", "type": "uuid", "pk": true },
    { "name": "written_language", "type": "string" },
    { "name": "verbose_logging", "type": "bool" },
    { "name": "extra", "type": "map" }
  ]
}

...several file will be emitted to app/state:

  • config.go, containing:

    • The Config struct, with correctly-typed fields, in this case uuid.UUID, string, bool, util.ValueMap.
    • Two constructors, NewConfig and ConfigFromMap, and RandomConfig which is useful for testing.
    • Transformation methods String, Strings, ToCSV, ToData.
    • A Clone method to create a deep copy of the struct.
  • configdiff.go

    • A Diff method to compare two instances and return a list of differences.
  • configmap.go

    • Transformation methods ToMap, FromMap, ToOrderedMap.
  • configs.go

    • Type Alias Configs []*Config, with methods Clone, ToMaps, ToOrderedMaps, and accessors by every unique or indexed field.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Helpers = func() map[string][]string {
	ret := map[string][]string{}
	add := func(k string, v string) {
		ret[k] = []string{v}
	}

	add("enum.values", "Possible values for this enumeration")
	add("model.name", "The name, usually corresponding to the name of your database table")
	add("model.package", "package")
	add("model.group", "The model's group, as a path, like [foo/bar]")
	add("model.description", "description")
	add("model.icon", "icon")
	add("model.ordering", "ordering")
	add("model.view", "view")
	add("model.search", "search")
	add("model.tags", "tags")
	add("model.titleOverride", "titleOverride")
	add("model.properOverride", "properOverride")
	add("model.config", "config")
	add("model.columns", "columns")
	add("model.relations", "relations")
	add("model.indexes", "indexes")

	return ret
}()

Functions

This section is empty.

Types

type Service

type Service struct{}

func NewService

func NewService() *Service

func (*Service) Files

func (s *Service) Files(p *project.Project, linebreak string) (_ file.Files, e error)

Directories

Path Synopsis
gql
sql
svc

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL