{"id":32501905,"url":"https://github.com/Snonky/pocketbase-gogen","last_synced_at":"2025-10-27T17:02:08.391Z","repository":{"id":275542980,"uuid":"923070400","full_name":"Snonky/pocketbase-gogen","owner":"Snonky","description":"A Code Generation Tool for Developers who use PocketBase as a Go Framework","archived":false,"fork":false,"pushed_at":"2025-10-25T15:32:16.000Z","size":127,"stargazers_count":21,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-25T17:26:24.187Z","etag":null,"topics":["codegenerator","pocketbase"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Snonky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-01-27T15:40:58.000Z","updated_at":"2025-10-25T15:31:23.000Z","dependencies_parsed_at":null,"dependency_job_id":"a76ed77b-03f5-4f77-a769-676d891efa5c","html_url":"https://github.com/Snonky/pocketbase-gogen","commit_stats":null,"previous_names":["snonky/pocketbase-gogen"],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/Snonky/pocketbase-gogen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snonky%2Fpocketbase-gogen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snonky%2Fpocketbase-gogen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snonky%2Fpocketbase-gogen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snonky%2Fpocketbase-gogen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Snonky","download_url":"https://codeload.github.com/Snonky/pocketbase-gogen/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Snonky%2Fpocketbase-gogen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":281305249,"owners_count":26478374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-27T02:00:05.855Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegenerator","pocketbase"],"created_at":"2025-10-27T17:00:41.630Z","updated_at":"2025-10-27T17:02:08.378Z","avatar_url":"https://github.com/Snonky.png","language":"Go","funding_links":[],"categories":["Go Plugins"],"sub_categories":[],"readme":"# PocketBase Type-Safe Go Code Generator\n\nA tool for developers using [PocketBase](https://github.com/pocketbase/pocketbase) as a go backend framework.\n\nConvert your PocketBase schema into type-safe accessor structs (\"DAOs\", \"Proxies\") for your code base.\n\nAlso supports custom methods that work with the typed data.\n\n## Usage\n\n### Step 0: Install `pocketbase-gogen`\n```console\ngo install github.com/snonky/pocketbase-gogen@latest\n```\nYou should now have access to the CLI with the `pocketbase-gogen` command.\n\n### Step 1: Generate a template\n```console\npocketbase-gogen template ./path/to/pb_data ./yourmodule/pbschema/template.go\n```\n\nYou will now have `template.go` which is your \"schema as code\" and contains your PB schema as a set of go structs. The file contains a doc comment with a detailed description of what you can do to customize it.\n\n### Step 2: Generate proxies from template\n\n```console\npocketbase-gogen generate ./yourmodule/pbschema/template.go ./yourmodule/generated/proxies.go\n```\n\nYou will now have `proxies.go` which contains the actual proxy structs\nthat you can drop in to use instead of raw `core.Record` structs from PocketBase ([PB doc on proxy usage](https://pocketbase.io/docs/go-record-proxy/)).\n\nOptionally append the following flags:\n\n - `--utils` flag. The [example](#generate-utilsgo) shows what the result of that is.\n - `--hooks` flag. Its effect is also illustrated by [example](#generate-proxy-hooks).\n\n\n\u003e [!IMPORTANT]\n\u003e Do not run the generator against a production data base file.\n\u003e As with any code, please always test your generated code before putting it to use.\n# Example\n\nFor the example we have a simple PB schema of 3 collections `person`, `child` and `bank_account`. They look like this:\n\n\u003cp align=\"center\"\u003e\n        \u003cimg src=\"https://i.imgur.com/yXYQtAD.png\" alt=\"Example Schema Screenshot\" /\u003e\n\u003c/p\u003e\n\n### Running `pocketbase-gogen template` we get this:\n\n```go\ntype BankAccount struct {\n\t// collection-name: bank_account\n\t// system: id\n\tId    string\n\tmoney int\n}\n\ntype Child struct {\n\t// collection-name: child\n\t// system: id\n\tId   string\n\tname string\n\tage  int\n}\n\ntype Person struct {\n\t// collection-name: person\n\t// system: id\n\tId      string\n\tname    string\n\taddress string\n\t// select: HealthSelectType\n\t// - good\n\t// - medium\n\t// - bad\n\thealth   int\n\taccount  *BankAccount\n\tchildren []*Child\n}\n```\n\nThings to note about the template:\n\n - The `Id` field is marked as a system field and thus will not have getters/setters generated.\n - The `health` field is a PocketBase select type field which is always represented as an `int` (or `[]int` for multi select types) in the template. The field comment lists the select options.\n - The relation type fields `account` and `children` are already typed with the other template structs.\n - All template structs have a `// collection-name:` comment on their first field that stores the original collection name.\n\n ### Now running `pocketbase-gogen generate`\n\n The generated code for the three template structs comes out as this (they are in one file but for the example they are shown separately):\n\n ### Bank Account\n```go\ntype BankAccount struct {\n\tcore.BaseRecordProxy\n}\n\nfunc (p *BankAccount) CollectionName() string {\n\treturn \"bank_account\"\n}\n\nfunc (p *BankAccount) Money() int {\n\treturn p.GetInt(\"money\")\n}\n\nfunc (p *BankAccount) SetMoney(money int) {\n\tp.Set(\"money\", money)\n}\n```\n\n### Child\n\n```go\ntype Child struct {\n\tcore.BaseRecordProxy\n}\n\nfunc (p *Child) CollectionName() string {\n\treturn \"child\"\n}\n\nfunc (p *Child) Name() string {\n\treturn p.GetString(\"name\")\n}\n\nfunc (p *Child) SetName(name string) {\n\tp.Set(\"name\", name)\n}\n\nfunc (p *Child) Age() int {\n\treturn p.GetInt(\"age\")\n}\n\nfunc (p *Child) SetAge(age int) {\n\tp.Set(\"age\", age)\n}\n```\n\n### Person \n\n```go\ntype HealthSelectType int\n\nconst (\n\tGood HealthSelectType = iota\n\tMedium\n\tBad\n)\n\nvar zzHealthSelectTypeSelectNameMap = map[string]HealthSelectType{\n\t\"good\":   0,\n\t\"medium\": 1,\n\t\"bad\":    2,\n}\nvar zzHealthSelectTypeSelectIotaMap = map[HealthSelectType]string{\n\t0: \"good\",\n\t1: \"medium\",\n\t2: \"bad\",\n}\n\ntype Person struct {\n\tcore.BaseRecordProxy\n}\n\nfunc (p *Person) CollectionName() string {\n\treturn \"person\"\n}\n\nfunc (p *Person) Name() string {\n\treturn p.GetString(\"name\")\n}\n\nfunc (p *Person) SetName(name string) {\n\tp.Set(\"name\", name)\n}\n\nfunc (p *Person) Address() string {\n\treturn p.GetString(\"address\")\n}\n\nfunc (p *Person) SetAddress(address string) {\n\tp.Set(\"address\", address)\n}\n\nfunc (p *Person) Health() HealthSelectType {\n\toption := p.GetString(\"health\")\n\ti, ok := zzHealthSelectTypeSelectNameMap[option]\n\tif !ok {\n\t\tpanic(\"Unknown select value\")\n\t}\n\treturn i\n}\n\nfunc (p *Person) SetHealth(health HealthSelectType) {\n\ti, ok := zzHealthSelectTypeSelectIotaMap[health]\n\tif !ok {\n\t\tpanic(\"Unknown select value\")\n\t}\n\tp.Set(\"health\", i)\n}\n\nfunc (p *Person) Account() *BankAccount {\n\tvar proxy *BankAccount\n\tif rel := p.ExpandedOne(\"account\"); rel != nil {\n\t\tproxy = \u0026BankAccount{}\n\t\tproxy.Record = rel\n\t}\n\treturn proxy\n}\n\nfunc (p *Person) SetAccount(account *BankAccount) {\n\tvar id string\n\tif account != nil {\n\t\tid = account.Id\n\t}\n\tp.Record.Set(\"account\", id)\n\te := p.Expand()\n\tif account != nil {\n\t\te[\"account\"] = account.Record\n\t} else {\n\t\tdelete(e, \"account\")\n\t}\n\tp.SetExpand(e)\n}\n\nfunc (p *Person) Children() []*Child {\n\trels := p.ExpandedAll(\"children\")\n\tproxies := make([]*Child, len(rels))\n\tfor i := range len(rels) {\n\t\tproxies[i] = \u0026Child{}\n\t\tproxies[i].Record = rels[i]\n\t}\n\treturn proxies\n}\n\nfunc (p *Person) SetChildren(children []*Child) {\n\trecords := make([]*core.Record, len(children))\n\tids := make([]string, len(children))\n\tfor i, r := range children {\n\t\trecords[i] = r.Record\n\t\tids[i] = r.Record.Id\n\t}\n\tp.Record.Set(\"children\", ids)\n\te := p.Expand()\n\te[\"children\"] = records\n\tp.SetExpand(e)\n}\n```\n\nEvery proxy has getters and setters generated for its fields plus a `CollectionName()` convenience method.\n`CollectionName()` is generated from the `// collection-name:` comment in the template.\n\nBank Account and Child are straightforward. Things of interest about the Person generation:\n\n - The `health` select type got its own go type of \n    ```go\n    type HealthSelectType int\n    ```\n    with an accompanying `const` declaration:\n    ```go\n    const (\n        Good HealthSelectType = iota\n        Medium\n        Bad\n    )\n    ```\n    The constants guarantee correct select options in your application code.\n\n - For the relation type fields `SetAccount` and `SetChildren` enable you to pass in other proxies just as easily as primitive types.\n\n## Generate `utils.go`\n### When running `pocketbase-gogen generate` with the `--utils` flag you get `utils.go`\n`utils.go` will be saved in the same package next to your output generated source code file.\n\nIt looks like this:\n```go\ntype Proxy interface{ BankAccount | Child | Person }\n\n// This interface constrains a type parameter of\n// a Proxy core type into its pointer type.\ntype ProxyP[P Proxy] interface {\n\t*P\n\tcore.RecordProxy\n\tCollectionName() string\n}\n\n// Returns the collection name of a proxy type\n//\n//\tcollectionName := CName[ProxyType]()\nfunc CName[P Proxy, PP ProxyP[P]]() string {\n\treturn PP.CollectionName(nil)\n}\n\n// Creates a new record and wraps it in a new proxy\n//\n//\tproxy := NewProxy[ProxyType](app)\nfunc NewProxy[P Proxy, PP ProxyP[P]](app core.App) (PP, error) {\n\tvar p PP = \u0026P{}\n\tcollectionName := p.CollectionName()\n\tcollection, err := app.FindCachedCollectionByNameOrId(collectionName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\trecord := core.NewRecord(collection)\n\tp.SetProxyRecord(record)\n\treturn p, nil\n}\n\n// Wraps a record in a newly created proxy\n//\n//\tproxy := WrapRecord[ProxyType](record)\nfunc WrapRecord[P Proxy, PP ProxyP[P]](record *core.Record) (PP, error) {\n\tcollectionName := record.Collection().Name\n\tproxyCollectionName := PP.CollectionName(nil)\n\tif collectionName != proxyCollectionName {\n\t\treturn nil, errors.New(\"the generic proxy type is not of the same collection as the given record\")\n\t}\n\tvar p PP = \u0026P{}\n\tp.SetProxyRecord(record)\n\treturn p, nil\n}\n\ntype RelationField struct {\n\tFieldName string\n\tIsMulti   bool\n}\n\n// This map contains all relations between the collections that\n// have a proxy struct with a CollectionName() method.\n// It maps like this:\n//\n//\tcollection name\n//\t -\u003e collection names that it is related to\n//\t  -\u003e list of fields that contain the relation values\nvar Relations = map[string]map[string][]RelationField{\n\t\"person\": {\n\t\t\"bank_account\": {\n\t\t\t{\"account\", false},\n\t\t},\n\t\t\"child\": {\n\t\t\t{\"children\", true},\n\t\t},\n\t},\n}\n```\n\n- The util functions are documented with usage examples.\n- The type contstraint interfaces `Proxy` and `ProxyP` can also be used outside the utils for generic parameters of proxy-handling functions.\n- The `Relations` map is a helper for when you need to fetch related records to expand relations. It connects the names of relation type fields with the origin collection of the related records.\n\n## Generate proxy hooks\n### When running `pocketbase-gogen generate` with the `--hooks` flag you get `proxy_events.go` and `proxy_hooks.go`\n\nThis gives you access to the `NewProxyHooks(app core.App)` function. It returns a struct that has various hooks _per proxy type_.\nIn the example, `proxy_hooks.go` looks like this:\n\n\u003cdetails\u003e\n\n\u003csummary\u003eClick here to see the file contents\u003c/summary\u003e\n\n```go\ntype BankAccountEvent = ProxyRecordEvent[BankAccount, *BankAccount]\ntype BankAccountEnrichEvent = ProxyRecordEnrichEvent[BankAccount, *BankAccount]\ntype BankAccountErrorEvent = ProxyRecordErrorEvent[BankAccount, *BankAccount]\ntype BankAccountListRequestEvent = ProxyRecordsListRequestEvent[BankAccount, *BankAccount]\ntype BankAccountRequestEvent = ProxyRecordRequestEvent[BankAccount, *BankAccount]\ntype ChildEvent = ProxyRecordEvent[Child, *Child]\ntype ChildEnrichEvent = ProxyRecordEnrichEvent[Child, *Child]\ntype ChildErrorEvent = ProxyRecordErrorEvent[Child, *Child]\ntype ChildListRequestEvent = ProxyRecordsListRequestEvent[Child, *Child]\ntype ChildRequestEvent = ProxyRecordRequestEvent[Child, *Child]\ntype PersonEvent = ProxyRecordEvent[Person, *Person]\ntype PersonEnrichEvent = ProxyRecordEnrichEvent[Person, *Person]\ntype PersonErrorEvent = ProxyRecordErrorEvent[Person, *Person]\ntype PersonListRequestEvent = ProxyRecordsListRequestEvent[Person, *Person]\ntype PersonRequestEvent = ProxyRecordRequestEvent[Person, *Person]\n\n// This struct is a container for all proxy hooks.\n// Use NewProxyHooks(app core.App) to create it once.\ntype ProxyHooks struct {\n\tOnBankAccountEnrich             *hook.Hook[*BankAccountEnrichEvent]\n\tOnBankAccountValidate           *hook.Hook[*BankAccountEvent]\n\tOnBankAccountCreate             *hook.Hook[*BankAccountEvent]\n\tOnBankAccountCreateExecute      *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterCreateSuccess *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterCreateError   *hook.Hook[*BankAccountErrorEvent]\n\tOnBankAccountUpdate             *hook.Hook[*BankAccountEvent]\n\tOnBankAccountUpdateExecute      *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterUpdateSuccess *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterUpdateError   *hook.Hook[*BankAccountErrorEvent]\n\tOnBankAccountDelete             *hook.Hook[*BankAccountEvent]\n\tOnBankAccountDeleteExecute      *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterDeleteSuccess *hook.Hook[*BankAccountEvent]\n\tOnBankAccountAfterDeleteError   *hook.Hook[*BankAccountErrorEvent]\n\tOnBankAccountListRequest        *hook.Hook[*BankAccountListRequestEvent]\n\tOnBankAccountViewRequest        *hook.Hook[*BankAccountRequestEvent]\n\tOnBankAccountCreateRequest      *hook.Hook[*BankAccountRequestEvent]\n\tOnBankAccountUpdateRequest      *hook.Hook[*BankAccountRequestEvent]\n\tOnBankAccountDeleteRequest      *hook.Hook[*BankAccountRequestEvent]\n\tOnChildEnrich                   *hook.Hook[*ChildEnrichEvent]\n\tOnChildValidate                 *hook.Hook[*ChildEvent]\n\tOnChildCreate                   *hook.Hook[*ChildEvent]\n\tOnChildCreateExecute            *hook.Hook[*ChildEvent]\n\tOnChildAfterCreateSuccess       *hook.Hook[*ChildEvent]\n\tOnChildAfterCreateError         *hook.Hook[*ChildErrorEvent]\n\tOnChildUpdate                   *hook.Hook[*ChildEvent]\n\tOnChildUpdateExecute            *hook.Hook[*ChildEvent]\n\tOnChildAfterUpdateSuccess       *hook.Hook[*ChildEvent]\n\tOnChildAfterUpdateError         *hook.Hook[*ChildErrorEvent]\n\tOnChildDelete                   *hook.Hook[*ChildEvent]\n\tOnChildDeleteExecute            *hook.Hook[*ChildEvent]\n\tOnChildAfterDeleteSuccess       *hook.Hook[*ChildEvent]\n\tOnChildAfterDeleteError         *hook.Hook[*ChildErrorEvent]\n\tOnChildListRequest              *hook.Hook[*ChildListRequestEvent]\n\tOnChildViewRequest              *hook.Hook[*ChildRequestEvent]\n\tOnChildCreateRequest            *hook.Hook[*ChildRequestEvent]\n\tOnChildUpdateRequest            *hook.Hook[*ChildRequestEvent]\n\tOnChildDeleteRequest            *hook.Hook[*ChildRequestEvent]\n\tOnPersonEnrich                  *hook.Hook[*PersonEnrichEvent]\n\tOnPersonValidate                *hook.Hook[*PersonEvent]\n\tOnPersonCreate                  *hook.Hook[*PersonEvent]\n\tOnPersonCreateExecute           *hook.Hook[*PersonEvent]\n\tOnPersonAfterCreateSuccess      *hook.Hook[*PersonEvent]\n\tOnPersonAfterCreateError        *hook.Hook[*PersonErrorEvent]\n\tOnPersonUpdate                  *hook.Hook[*PersonEvent]\n\tOnPersonUpdateExecute           *hook.Hook[*PersonEvent]\n\tOnPersonAfterUpdateSuccess      *hook.Hook[*PersonEvent]\n\tOnPersonAfterUpdateError        *hook.Hook[*PersonErrorEvent]\n\tOnPersonDelete                  *hook.Hook[*PersonEvent]\n\tOnPersonDeleteExecute           *hook.Hook[*PersonEvent]\n\tOnPersonAfterDeleteSuccess      *hook.Hook[*PersonEvent]\n\tOnPersonAfterDeleteError        *hook.Hook[*PersonErrorEvent]\n\tOnPersonListRequest             *hook.Hook[*PersonListRequestEvent]\n\tOnPersonViewRequest             *hook.Hook[*PersonRequestEvent]\n\tOnPersonCreateRequest           *hook.Hook[*PersonRequestEvent]\n\tOnPersonUpdateRequest           *hook.Hook[*PersonRequestEvent]\n\tOnPersonDeleteRequest           *hook.Hook[*PersonRequestEvent]\n}\n\n// Create a new set of proxy hooks and register them\n// on the given app. Keep in mind that calling this\n// multiple times will result in multiple duplicate\n// hooks being registered. So in general that should be\n// avoided.\n//\n// Usage with an exemplary User proxy that has a name field:\n//\n//\tpHooks := NewProxyHooks(app)\n//\tpHooks.OnUserCreate.BindFunc(func(e *UserEvent) error {\n//\t\tvar user *User = e.PRecord // \u003c-- Proxy events contain the proxy in the PRecord field\n//\t\tfmt.Printf(\"Hello new user, %v!\", user.Name())\n//\t\treturn e.Next()\n//\t})\nfunc NewProxyHooks(app core.App) *ProxyHooks {\n\tpHooks := \u0026ProxyHooks{\n\t\tOnBankAccountEnrich:             \u0026hook.Hook[*BankAccountEnrichEvent]{},\n\t\tOnBankAccountValidate:           \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountCreate:             \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountCreateExecute:      \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterCreateSuccess: \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterCreateError:   \u0026hook.Hook[*BankAccountErrorEvent]{},\n\t\tOnBankAccountUpdate:             \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountUpdateExecute:      \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterUpdateSuccess: \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterUpdateError:   \u0026hook.Hook[*BankAccountErrorEvent]{},\n\t\tOnBankAccountDelete:             \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountDeleteExecute:      \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterDeleteSuccess: \u0026hook.Hook[*BankAccountEvent]{},\n\t\tOnBankAccountAfterDeleteError:   \u0026hook.Hook[*BankAccountErrorEvent]{},\n\t\tOnBankAccountListRequest:        \u0026hook.Hook[*BankAccountListRequestEvent]{},\n\t\tOnBankAccountViewRequest:        \u0026hook.Hook[*BankAccountRequestEvent]{},\n\t\tOnBankAccountCreateRequest:      \u0026hook.Hook[*BankAccountRequestEvent]{},\n\t\tOnBankAccountUpdateRequest:      \u0026hook.Hook[*BankAccountRequestEvent]{},\n\t\tOnBankAccountDeleteRequest:      \u0026hook.Hook[*BankAccountRequestEvent]{},\n\t\tOnChildEnrich:                   \u0026hook.Hook[*ChildEnrichEvent]{},\n\t\tOnChildValidate:                 \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildCreate:                   \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildCreateExecute:            \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterCreateSuccess:       \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterCreateError:         \u0026hook.Hook[*ChildErrorEvent]{},\n\t\tOnChildUpdate:                   \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildUpdateExecute:            \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterUpdateSuccess:       \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterUpdateError:         \u0026hook.Hook[*ChildErrorEvent]{},\n\t\tOnChildDelete:                   \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildDeleteExecute:            \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterDeleteSuccess:       \u0026hook.Hook[*ChildEvent]{},\n\t\tOnChildAfterDeleteError:         \u0026hook.Hook[*ChildErrorEvent]{},\n\t\tOnChildListRequest:              \u0026hook.Hook[*ChildListRequestEvent]{},\n\t\tOnChildViewRequest:              \u0026hook.Hook[*ChildRequestEvent]{},\n\t\tOnChildCreateRequest:            \u0026hook.Hook[*ChildRequestEvent]{},\n\t\tOnChildUpdateRequest:            \u0026hook.Hook[*ChildRequestEvent]{},\n\t\tOnChildDeleteRequest:            \u0026hook.Hook[*ChildRequestEvent]{},\n\t\tOnPersonEnrich:                  \u0026hook.Hook[*PersonEnrichEvent]{},\n\t\tOnPersonValidate:                \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonCreate:                  \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonCreateExecute:           \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterCreateSuccess:      \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterCreateError:        \u0026hook.Hook[*PersonErrorEvent]{},\n\t\tOnPersonUpdate:                  \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonUpdateExecute:           \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterUpdateSuccess:      \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterUpdateError:        \u0026hook.Hook[*PersonErrorEvent]{},\n\t\tOnPersonDelete:                  \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonDeleteExecute:           \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterDeleteSuccess:      \u0026hook.Hook[*PersonEvent]{},\n\t\tOnPersonAfterDeleteError:        \u0026hook.Hook[*PersonErrorEvent]{},\n\t\tOnPersonListRequest:             \u0026hook.Hook[*PersonListRequestEvent]{},\n\t\tOnPersonViewRequest:             \u0026hook.Hook[*PersonRequestEvent]{},\n\t\tOnPersonCreateRequest:           \u0026hook.Hook[*PersonRequestEvent]{},\n\t\tOnPersonUpdateRequest:           \u0026hook.Hook[*PersonRequestEvent]{},\n\t\tOnPersonDeleteRequest:           \u0026hook.Hook[*PersonRequestEvent]{},\n\t}\n\tpHooks.registerProxyHooks(app)\n\treturn pHooks\n}\n\nfunc (pHooks *ProxyHooks) registerProxyHooks(app core.App) {\n\tregisterProxyEnrichEventHook(app.OnRecordEnrich(\"bank_account\"), pHooks.OnBankAccountEnrich)\n\tregisterProxyEventHook(app.OnRecordValidate(\"bank_account\"), pHooks.OnBankAccountValidate)\n\tregisterProxyEventHook(app.OnRecordCreate(\"bank_account\"), pHooks.OnBankAccountCreate)\n\tregisterProxyEventHook(app.OnRecordCreateExecute(\"bank_account\"), pHooks.OnBankAccountCreateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterCreateSuccess(\"bank_account\"), pHooks.OnBankAccountAfterCreateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterCreateError(\"bank_account\"), pHooks.OnBankAccountAfterCreateError)\n\tregisterProxyEventHook(app.OnRecordUpdate(\"bank_account\"), pHooks.OnBankAccountUpdate)\n\tregisterProxyEventHook(app.OnRecordUpdateExecute(\"bank_account\"), pHooks.OnBankAccountUpdateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterUpdateSuccess(\"bank_account\"), pHooks.OnBankAccountAfterUpdateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterUpdateError(\"bank_account\"), pHooks.OnBankAccountAfterUpdateError)\n\tregisterProxyEventHook(app.OnRecordDelete(\"bank_account\"), pHooks.OnBankAccountDelete)\n\tregisterProxyEventHook(app.OnRecordDeleteExecute(\"bank_account\"), pHooks.OnBankAccountDeleteExecute)\n\tregisterProxyEventHook(app.OnRecordAfterDeleteSuccess(\"bank_account\"), pHooks.OnBankAccountAfterDeleteSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterDeleteError(\"bank_account\"), pHooks.OnBankAccountAfterDeleteError)\n\tregisterProxyListRequestEventHook(app.OnRecordsListRequest(\"bank_account\"), pHooks.OnBankAccountListRequest)\n\tregisterProxyRequestEventHook(app.OnRecordViewRequest(\"bank_account\"), pHooks.OnBankAccountViewRequest)\n\tregisterProxyRequestEventHook(app.OnRecordCreateRequest(\"bank_account\"), pHooks.OnBankAccountCreateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordUpdateRequest(\"bank_account\"), pHooks.OnBankAccountUpdateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordDeleteRequest(\"bank_account\"), pHooks.OnBankAccountDeleteRequest)\n\tregisterProxyEnrichEventHook(app.OnRecordEnrich(\"child\"), pHooks.OnChildEnrich)\n\tregisterProxyEventHook(app.OnRecordValidate(\"child\"), pHooks.OnChildValidate)\n\tregisterProxyEventHook(app.OnRecordCreate(\"child\"), pHooks.OnChildCreate)\n\tregisterProxyEventHook(app.OnRecordCreateExecute(\"child\"), pHooks.OnChildCreateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterCreateSuccess(\"child\"), pHooks.OnChildAfterCreateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterCreateError(\"child\"), pHooks.OnChildAfterCreateError)\n\tregisterProxyEventHook(app.OnRecordUpdate(\"child\"), pHooks.OnChildUpdate)\n\tregisterProxyEventHook(app.OnRecordUpdateExecute(\"child\"), pHooks.OnChildUpdateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterUpdateSuccess(\"child\"), pHooks.OnChildAfterUpdateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterUpdateError(\"child\"), pHooks.OnChildAfterUpdateError)\n\tregisterProxyEventHook(app.OnRecordDelete(\"child\"), pHooks.OnChildDelete)\n\tregisterProxyEventHook(app.OnRecordDeleteExecute(\"child\"), pHooks.OnChildDeleteExecute)\n\tregisterProxyEventHook(app.OnRecordAfterDeleteSuccess(\"child\"), pHooks.OnChildAfterDeleteSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterDeleteError(\"child\"), pHooks.OnChildAfterDeleteError)\n\tregisterProxyListRequestEventHook(app.OnRecordsListRequest(\"child\"), pHooks.OnChildListRequest)\n\tregisterProxyRequestEventHook(app.OnRecordViewRequest(\"child\"), pHooks.OnChildViewRequest)\n\tregisterProxyRequestEventHook(app.OnRecordCreateRequest(\"child\"), pHooks.OnChildCreateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordUpdateRequest(\"child\"), pHooks.OnChildUpdateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordDeleteRequest(\"child\"), pHooks.OnChildDeleteRequest)\n\tregisterProxyEnrichEventHook(app.OnRecordEnrich(\"person\"), pHooks.OnPersonEnrich)\n\tregisterProxyEventHook(app.OnRecordValidate(\"person\"), pHooks.OnPersonValidate)\n\tregisterProxyEventHook(app.OnRecordCreate(\"person\"), pHooks.OnPersonCreate)\n\tregisterProxyEventHook(app.OnRecordCreateExecute(\"person\"), pHooks.OnPersonCreateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterCreateSuccess(\"person\"), pHooks.OnPersonAfterCreateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterCreateError(\"person\"), pHooks.OnPersonAfterCreateError)\n\tregisterProxyEventHook(app.OnRecordUpdate(\"person\"), pHooks.OnPersonUpdate)\n\tregisterProxyEventHook(app.OnRecordUpdateExecute(\"person\"), pHooks.OnPersonUpdateExecute)\n\tregisterProxyEventHook(app.OnRecordAfterUpdateSuccess(\"person\"), pHooks.OnPersonAfterUpdateSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterUpdateError(\"person\"), pHooks.OnPersonAfterUpdateError)\n\tregisterProxyEventHook(app.OnRecordDelete(\"person\"), pHooks.OnPersonDelete)\n\tregisterProxyEventHook(app.OnRecordDeleteExecute(\"person\"), pHooks.OnPersonDeleteExecute)\n\tregisterProxyEventHook(app.OnRecordAfterDeleteSuccess(\"person\"), pHooks.OnPersonAfterDeleteSuccess)\n\tregisterProxyErrorEventHook(app.OnRecordAfterDeleteError(\"person\"), pHooks.OnPersonAfterDeleteError)\n\tregisterProxyListRequestEventHook(app.OnRecordsListRequest(\"person\"), pHooks.OnPersonListRequest)\n\tregisterProxyRequestEventHook(app.OnRecordViewRequest(\"person\"), pHooks.OnPersonViewRequest)\n\tregisterProxyRequestEventHook(app.OnRecordCreateRequest(\"person\"), pHooks.OnPersonCreateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordUpdateRequest(\"person\"), pHooks.OnPersonUpdateRequest)\n\tregisterProxyRequestEventHook(app.OnRecordDeleteRequest(\"person\"), pHooks.OnPersonDeleteRequest)\n}\n```\n\n\u003c/details\u003e\n\n### Here's an example on how to use the proxy hooks\n\n```go\npHooks := NewProxyHooks(app)\n\npHooks.OnPersonCreate(func(e *PersonEvent) error {\n\tvar *Person person = e.PRecord // The event carries a proxy of the changed record\n\tfmt.Printf(\"Hello new person, %v!\", person.Name())\n\treturn e.Next()\n})\n```\n\nThe following PocketBase hooks will be generated as proxy hooks:\n\n - `OnRecordEnrich`\n - `OnRecordValidate`\n - `OnRecordCreate`\n - `OnRecordCreateExecute`\n - `OnRecordAfterCreateSuccess`\n - `OnRecordAfterCreateError`\n - `OnRecordCreateRequest`\n - `OnRecordUpdate`\n - `OnRecordUpdateExecute`\n - `OnRecordAfterUpdateSuccess`\n - `OnRecordAfterUpdateError`\n - `OnRecordUpdateRequest`\n - `OnRecordDelete`\n - `OnRecordDeleteExecute`\n - `OnRecordAfterDeleteSuccess`\n - `OnRecordAfterDeleteError`\n - `OnRecordDeleteRequest`\n - `OnRecordsListRequest`\n - `OnRecordViewRequest`\n \nEach of these hooks gets generated for every proxy type.\nThe corresponding proxy hooks are named by replacing \"`Record`\" with the proxy struct name (e.g. `OnPersonCreate`).\n\n## Custom Methods\n### `pocketbase-gogen` also converts methods that you manually add to your template\n\n \u003e [!IMPORTANT]  \n\u003e As said before, always test your generated code especially with custom methods.\n\nFor example:\n\n```go\nfunc (a *BankAccount) Withdraw(amount int) {\n\tnewAmount := a.money - amount\n\tif newAmount \u003c 0 {\n\t\tfmt.Println(\"You are out of money!\")\n\t\treturn\n\t}\n\ta.money = newAmount\n}\n```\n\nWill generate this:\n\n```go\nfunc (a *BankAccount) Withdraw(amount int) {\n\tnewAmount := a.Money() - amount\n\tif newAmount \u003c 0 {\n\t\tfmt.Println(\"You are out of money!\")\n\t\treturn\n\t}\n\ta.SetMoney(newAmount)\n}\n```\n\nAs you can see, the generator replaced all template field accessors with the appropriate getters and setters so you use the method for editing your data.\n\nA few more examples:\n\n\u003ctable align=\"center\" width=\"100%\"\u003e\n\u003ctr\u003e\n\u003cth\u003e Template\u003c/th\u003e\n\u003cth\u003e Generated\u003c/code\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```go\nfunc (a *BankAccount) Deposit(amount int) {\n\ta.money += amount\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```go\nfunc (a *BankAccount) Deposit(amount int) {\n\ta.SetMoney(a.Money() + amount)\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ctable align=\"center\" width=\"100%\"\u003e\n\u003ctr\u003e\n\u003cth\u003e Template\u003c/th\u003e\n\u003cth\u003e Generated\u003c/code\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```go\n// Doctor approved logic\nfunc (p *Person) UpdateHealth() {\n\tif len(p.children) \u003c= 2 {\n\t\tp.health = 0\n\t} else if len(p.children) \u003c= 4 {\n\t\tp.health = 1\n\t} else {\n\t\tp.health = 2\n\t}\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```go\n// Doctor approved logic\nfunc (p *Person) UpdateHealth() {\n\tif len(p.Children()) \u003c= 2 {\n\t\tp.SetHealth(HealthSelectType(0))\n\t} else if len(p.Children()) \u003c= 4 {\n\t\tp.SetHealth(HealthSelectType(1))\n\t} else {\n\t\tp.SetHealth(HealthSelectType(2))\n\t}\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ctable align=\"center\" width=\"100%\"\u003e\n\u003ctr\u003e\n\u003cth\u003e Template\u003c/th\u003e\n\u003cth\u003e Generated\u003c/code\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```go\nfunc (p *Person) BearChild(child *Child) {\n\tp.children = append(p.children, child)\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```go\nfunc (p *Person) BearChild(child *Child) {\n\tp.SetChildren(append(p.Children(), child))\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003ctable align=\"center\" width=\"100%\"\u003e\n\u003ctr\u003e\n\u003cth\u003e Template\u003c/th\u003e\n\u003cth\u003e Generated\u003c/code\u003e\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd\u003e\n\n```go\nfunc (p *Person) SwitchMyLifeUp() {\n\tp.name, p.address = p.address, p.name\n\tp.account.Withdraw(999999)\n\tp.children = []*Child{}\n}\n```\n\n\u003c/td\u003e\n\u003ctd\u003e\n\n```go\nfunc (p *Person) SwitchMyLifeUp() {\n\tname, address := p.Address(), p.Name()\n\tp.SetAddress(address)\n\tp.SetName(name)\n\tp.Account().Withdraw(999999)\n\tp.SetChildren([]*Child{})\n}\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Details\n\n- The generator protects you from accidentially shadowing any names from the `core.Record` struct which could compromise your data in obscure ways.\n  For example you can't define `func (p *Person) Id()`. The generator will error.\n- There is no support for creating new records from inside of custom template methods.\n- When using out-of-bounds indices for select types the getters/setters will panic.\n- You can access most system fields in custom methods because they have their getters/setters directly in `core.Record`. Double check what you are doing with those.\n- You can rename almost everything in the template. The comment at the top of the template file has instructions for that.\n- The `pocketbase-gogen` command needs access to go module imports that you are using (mostly the PocketBase module). Best run it from inside your project directory.\n- If you have reserved go keywords (e.g. `func`) as field names in your PB schema, the generator will escape them using a trailing underscore (`func_`).\n- When you delete the `// collection-name:` comment from a template struct, the `CollectionName()` method will not be generated and because of that the proxy type will not work with the functions from `utils.go`. It will also not get proxy hooks generated when using `--hooks`. The generator will warn of the missing comment.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSnonky%2Fpocketbase-gogen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FSnonky%2Fpocketbase-gogen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FSnonky%2Fpocketbase-gogen/lists"}