Loading...
Loading...
Use when building, extending or using pdf-forge multi-tenant PDF template engine with Typst
npx skill4agent add rendis/pdf-forge pdf-forgenpx skills add https://github.com/rendis/pdf-forge --skill pdf-forgeTenant → Workspace → Template → Version (DRAFT→PUBLISHED)
↓
Injectables (variables)
↓
Render → PDF// core/extensions/register.go
func Register(engine *sdk.Engine) {
engine.RegisterInjector(&CustomerNameInjector{})
engine.SetMapper(&MyMapper{})
engine.SetInitFunc(MyInit())
}
// core/cmd/api/main.go
func main() {
engine := sdk.NewWithConfig("settings/app.yaml").
SetI18nFilePath("settings/injectors.i18n.yaml")
extensions.Register(engine)
if err := engine.Run(); err != nil {
slog.Error("failed to run engine", slog.String("error", err.Error()))
os.Exit(1)
}
}type CustomerNameInjector struct{}
func (i *CustomerNameInjector) Code() string { return "customer_name" }
func (i *CustomerNameInjector) Resolve() (sdk.ResolveFunc, []string) {
return func(ctx context.Context, injCtx *sdk.InjectorContext) (*sdk.InjectorResult, error) {
payload := injCtx.RequestPayload().(map[string]any)
return &sdk.InjectorResult{Value: sdk.StringValue(payload["name"].(string))}, nil
}, nil // dependencies
}
func (i *CustomerNameInjector) IsCritical() bool { return true }
func (i *CustomerNameInjector) Timeout() time.Duration { return 5 * time.Second }
func (i *CustomerNameInjector) DataType() sdk.ValueType { return sdk.ValueTypeString }
func (i *CustomerNameInjector) DefaultValue() *sdk.InjectableValue { return nil }
func (i *CustomerNameInjector) Formats() *sdk.FormatConfig { return nil }| Type | Constructor | Constant |
|---|---|---|
| Text | | |
| Number | | |
| Boolean | | |
| Date/Time | | |
| Image | | |
| Table | | |
| List | | |
| Code | Type | Formats |
|---|---|---|
| TIME | DD/MM/YYYY, MM/DD/YYYY, YYYY-MM-DD |
| TIME | HH:mm, HH:mm:ss, hh:mm a |
| TIME | Combined |
| NUMBER | - |
| NUMBER | number, name, short_name |
| NUMBER | - |
| On Error |
|---|---|
| Aborts render |
| Uses |
| Extension | Purpose | Register |
|---|---|---|
| Injector | Data resolvers | |
| Mapper | Request parsing | |
| InitFunc | Shared setup | |
| Provider | Dynamic injectables | |
| Auth | Custom render auth | |
| Middleware | Request handling | |
| Frontend | Embedded SPA | |
| Lifecycle | Startup/shutdown | |
authmake build # Build frontend + embed + Go binary (single binary)
make embed-app # Build frontend and copy to Go embed location
make run # Run API server (with embedded frontend)
make dev # Hot reload backend (air)
make migrate # Apply database migrations
make test # Run tests
make lint # Run linter
make swagger # Regenerate OpenAPI spec
make doctor # Check system dependencies| Wrong | Correct |
|---|---|
| |
| |
| Forgetting dependencies | |
| Provide |
| Header | Purpose | Used By |
|---|---|---|
| | All auth routes |
| Tenant UUID | Panel routes |
| Workspace UUID | Panel routes |
| Tenant code (e.g. | Render routes |
| Workspace code (e.g. | Render routes |