{"id":31006530,"url":"https://github.com/aosasona/mirror","last_synced_at":"2025-10-05T18:58:41.254Z","repository":{"id":216874745,"uuid":"742581163","full_name":"aosasona/mirror","owner":"aosasona","description":"Runtime type generation from Go types","archived":false,"fork":false,"pushed_at":"2025-08-08T21:20:21.000Z","size":320,"stargazers_count":14,"open_issues_count":9,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-09-13T02:22:47.094Z","etag":null,"topics":["go","typescript"],"latest_commit_sha":null,"homepage":"https://pkg.go.dev/go.trulyao.dev/mirror/v2","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/aosasona.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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}},"created_at":"2024-01-12T19:51:21.000Z","updated_at":"2025-08-26T17:15:15.000Z","dependencies_parsed_at":null,"dependency_job_id":"fc0b9b86-933f-4a8f-ae49-f5ad5a9c22c5","html_url":"https://github.com/aosasona/mirror","commit_stats":null,"previous_names":["aosasona/mirror"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/aosasona/mirror","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aosasona%2Fmirror","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aosasona%2Fmirror/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aosasona%2Fmirror/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aosasona%2Fmirror/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aosasona","download_url":"https://codeload.github.com/aosasona/mirror/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aosasona%2Fmirror/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278503204,"owners_count":25997718,"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-05T02:00:06.059Z","response_time":54,"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":["go","typescript"],"created_at":"2025-09-13T02:14:16.991Z","updated_at":"2025-10-05T18:58:41.232Z","avatar_url":"https://github.com/aosasona.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Mirror 🪞\n\n[![Go Reference](https://pkg.go.dev/badge/go.trulyao.dev/mirror/v2.svg)](https://pkg.go.dev/go.trulyao.dev/mirror/v2)\n\n\u003e [!WARNING]\n\u003e This documentation is a work-in-progress and will be updated as required, if you are unclear if mirror supports your usecase or how to do something, please have a look at the GoDocs or open an issue.\n\nMirror allows you to generate types for other languages using your existing Go types, this can be useful for some form of end-to-end type safety.\n\n# Installation\n\nMirror can be installed directly using the command below:\n\n```sh\ngo get go.trulyao.dev/mirror/v2@latest\n```\n\n## Usage\n\nThe library exposes a large surface area to enable users hook into various parts like the parser and add support for other unsupported languages in user-land, but a normal usage generating typescript types using mirror (with mostly default options) would look like this:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"time\"\n\n\t\"go.trulyao.dev/mirror/v2\"\n\t\"go.trulyao.dev/mirror/v2/config\"\n\t\"go.trulyao.dev/mirror/v2/generator/typescript\"\n\t\"go.trulyao.dev/mirror/v2/parser\"\n)\n\ntype Language string\n\ntype Tags map[string]string\n\ntype Address struct {\n\tLine1      *string `mirror:\"name:line_1\"`\n\tLine2      *string `mirror:\"name:line_2\"`\n\tStreet     string  `mirror:\"name:street\"`\n\tCity       string  `mirror:\"name:city\"`\n\tState      string  `mirror:\"name:state\"`\n\tPostalCode string  `mirror:\"name:postal_code\"`\n\tCountry    string  `mirror:\"name:country\"`\n}\n\ntype Person struct {\n\tFName     string `mirror:\"name:first_name\"`\n\tLName     string `mirror:\"name:last_name\"`\n\tAge       int    `mirror:\"name:age\"`\n\tAddress   `mirror:\"name:address\"`\n\tLanguages []Language     `mirror:\"name:languages\"`\n\tGrades    map[string]int `mirror:\"name:grades,optional:1\"`\n\tTags      Tags           `mirror:\"name:tags\"`\n\tCreatedAt time.Time      `mirror:\"name:created_at\"`\n\tUpdatedAt *time.Time     `mirror:\"name:updated_at,type:number\"`\n\tDeletedAt *time.Time     `mirror:\"name:deleted_at\"`\n\tIsActive  bool           `mirror:\"name:is_active\"`\n}\n\ntype CreateUserFunc func(p Person) error\n\nfunc main() {\n\tm := mirror.New(config.Config{\n\t\tEnabled:                os.Getenv(\"ENV\") == \"dev\", // only enable mirror in dev\n\t\tFlattenEmbeddedTypes: false,\n\t})\n\n\tm.AddSources(\n\t  Language(\"\"),\n\t  Address{},\n\t  Tags{},\n\t  Person{},\n\t  CreateUserFunc(nil),\n\t)\n\n\ttarget := typescript.DefaultConfig().\n\t\tSetOutputPath(\".\").\n\t\tSetFileName(\"generated.ts\").\n\t\tSetIndentationType(config.IndentTab)\n\n\tm.AddTarget(target)\n\n\tif err := m.GenerateAndSaveAll(); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n```\n\n## Output\n\n```typescript\n/**\n * This file was generated by mirror, do not edit it manually as it will be overwritten.\n *\n * You can find the docs and source code for mirror here: https://github.com/aosasona/mirror\n */\n\ntype Language = string;\n\ntype Address = {\n\tline_1: string | null;\n\tline_2: string | null;\n\tstreet: string;\n\tcity: string;\n\tstate: string;\n\tpostal_code: string;\n\tcountry: string;\n};\n\ntype Tags = Record\u003cstring, string\u003e;\n\ntype Person = {\n\tfirst_name: string;\n\tlast_name: string;\n\tage: number;\n\taddress: Address;\n\tlanguages: Array\u003cstring\u003e;\n\tgrades?: Record\u003cstring, number\u003e;\n\ttags: Record\u003cstring, string\u003e;\n\tcreated_at: string;\n\tupdated_at: number | null;\n\tdeleted_at: string | null;\n\tis_active: boolean;\n};\n\ntype CreateUserFunc = (arg0: Person) =\u003e string;\n```\n\nSee [examples](https://github.com/aosasona/mirror/tree/master/examples) for more options and examples.\n\n## Supported languages\n\n- Typescript\n  \u003e More will be added to the library in the future as required\n\n## Tags\n\nYou can configure the generated types using struct tags; the `json` tag, the `mirror` tag or the legacy `ts` struct tag. You can pass in the following override values via struct field tags:\n\n- name (string)\n- type (string)\n- optional (only `true` or `1` or it is ignored)\n- skip (only `true` or `1`, but can also simply be written like this: `mirror:\"-\"`)\n\n#### Example\n\n```go\ntype Ex struct {\n\tID\tstring `json:\"user_id,omitempty\" mirror:\"type:Uppercase\u003cstring\u003e\"`\n\tName string `mirror:\"name:fname,optional:true\"`\n}\n```\n\nThis will translate into:\n\n```typescript\nexport type Ex = {\n\tuser_id?: Uppercase\u003cstring\u003e | null;\n\tfname?: string;\n};\n```\n\nThese give you more control over what types end up being generated. You don't need to specify these, they are optional, if they are not specified, the default values are inferred from the types themselves.\n\n## Contribution\n\nPRs and issues are welcome :)\n\n## Development\n\n- To run the example:\n\n```sh\njust example\n```\n\n- To run the tests:\n\n```sh\njust test\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faosasona%2Fmirror","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faosasona%2Fmirror","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faosasona%2Fmirror/lists"}