{"id":20290617,"url":"https://github.com/notdodo/goflat","last_synced_at":"2025-04-11T11:02:18.144Z","repository":{"id":57704958,"uuid":"498743132","full_name":"notdodo/goflat","owner":"notdodo","description":"Flatten complex JSON structures to a one-dimensional map (JSON key/value).","archived":false,"fork":false,"pushed_at":"2025-01-16T20:16:36.000Z","size":97,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-25T07:23:40.628Z","etag":null,"topics":["flattener","golang","json"],"latest_commit_sha":null,"homepage":"https://github.com/notdodo/goflat","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/notdodo.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":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-06-01T13:15:36.000Z","updated_at":"2025-01-16T20:16:36.000Z","dependencies_parsed_at":"2022-08-24T10:40:38.244Z","dependency_job_id":"70764a33-6798-4edc-9e7e-b9d1d46d0d11","html_url":"https://github.com/notdodo/goflat","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notdodo%2Fgoflat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notdodo%2Fgoflat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notdodo%2Fgoflat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/notdodo%2Fgoflat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/notdodo","download_url":"https://codeload.github.com/notdodo/goflat/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248381716,"owners_count":21094525,"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","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":["flattener","golang","json"],"created_at":"2024-11-14T15:08:29.534Z","updated_at":"2025-04-11T11:02:18.101Z","avatar_url":"https://github.com/notdodo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# goflat\n\n[![Golang CI](https://github.com/notdodo/goflat/actions/workflows/go-ci.yml/badge.svg)](https://github.com/notdodo/goflat/actions/workflows/go-ci.yml)\n\nFlatten complex JSON structures to a one-dimensional map (JSON key/value) that can be converted to a `map[string]interface{}`.\n\n`goflat` supports the flattening of:\n\n- Structs\n- JSON strings\n- Maps\n\n## Examples\n\n### Using a basic JSON structure\n\n```golang\npackage main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\n\t\"github.com/notdodo/goflat\"\n)\n\nfunc main() {\n\tflattened, err := goflat.FlatJSON(`{\"a\": \"3\", \"b\": {\"c\":true, \"a\": \"\", \"e\": null}}`, goflat.FlattenerConfig{\n\t\tSeparator: \".\",\n\t\tOmitEmpty: false,\n\t\tOmitNil:   false,\n\t})\n\tif err != nil {\n\t\tlog.Fatalln(err)\n\t}\n\n\tfmt.Println(flattened)\n}\n```\n\nOutput is: `{\"a\":\"3\",\"b.a\":\"\",\"b.c\":true,\"b.e\":null}`; the sub-structure is returned as a single JSON object.\n\nTo also remove the `null` you can pass the struct:\n\n```golang\nFlattenerConfig{\n\t\tPrefix:    \"\",\n\t\tSeparator: \".\",\n\t\tOmitEmpty: false,\n\t\tOmitNil:   true,\n\t\tSortKeys:  false,\n}\n```\n\n### Arrays\n\nWhen dealing with arrays and recursive structures the library will handle the depth using indexes:\n\nInput: `[{\"a\": \"3\"}, {\"b\": \"3\", \"C\": [{\"c\": 10}, {\"d\": 11}]}]`\n\nOutput: `{\"0.a\":\"3\",\"1.C.0.c\":10,\"1.C.1.d\":11,\"1.b\":\"3\"}`\n\n### Complex JSON strings\n\nIn case of complex JSON structures with array, sub-structures, arrays of sub-structures, etc the previous statement remains valid but in case of multiple array the indexes are always appended in the last part.\n\nFor example:\n\n```json\n[\n  {\n    \"UserId\": \"AIDARRRRRRRRRRRR\",\n    \"UserName\": \"s3-operator\",\n    \"InlinePolicies\": [\n      {\n        \"PolicyName\": \"policy-s3-operator\",\n        \"Statement\": [\n          {\n            \"Effect\": \"Allow\",\n            \"Action\": [\"s3:ListAllMyBuckets\"],\n            \"Resource\": [\"arn:aws:s3:::*\"]\n          },\n          {\n            \"Effect\": \"Allow\",\n            \"Action\": [\"s3:ListBucket\", \"s3:GetBucketLocation\"],\n            \"Resource\": [\"arn:aws:s3:::personal-s3-bucket/*\"]\n          },\n          {\n            \"Effect\": \"Allow\",\n            \"Action\": [\n              \"s3:PutObject\",\n              \"s3:GetObject\",\n              \"s3:AbortMultipartUpload\",\n              \"s3:ListMultipartUploadParts\",\n              \"s3:ListBucketMultipartUploads\"\n            ],\n            \"Resource\": [\"arn:aws:s3:::personal-s3-bucket/*\"]\n          }\n        ]\n      }\n    ]\n  }\n]\n```\n\nIn this case the output is\n\n```json\n{\n  \"0.InlinePolicies.0.Statement.1.Action.0\": \"s3:ListBucket\",\n  \"0.InlinePolicies.0.Statement.2.Action.4\": \"s3:ListBucketMultipartUploads\",\n  \"0.InlinePolicies.0.Statement.2.Effect\": \"Allow\",\n  \"0.InlinePolicies.0.Statement.1.Action.1\": \"s3:GetBucketLocation\",\n  \"0.InlinePolicies.0.Statement.2.Action.1\": \"s3:GetObject\",\n  \"0.InlinePolicies.0.Statement.2.Action.3\": \"s3:ListMultipartUploadParts\",\n  \"0.UserName\": \"s3-operator\",\n  \"0.InlinePolicies.0.Statement.0.Action.0\": \"s3:ListAllMyBuckets\",\n  \"0.InlinePolicies.0.Statement.1.Resource.0\": \"arn:aws:s3:::personal-s3-bucket/*\",\n  \"0.InlinePolicies.0.Statement.0.Effect\": \"Allow\",\n  \"0.UserId\": \"AIDARRRRRRRRRRRR\",\n  \"0.InlinePolicies.0.Statement.0.Resource.0\": \"arn:aws:s3:::*\",\n  \"0.InlinePolicies.0.Statement.1.Effect\": \"Allow\",\n  \"0.InlinePolicies.0.Statement.2.Action.0\": \"s3:PutObject\",\n  \"0.InlinePolicies.0.Statement.2.Action.2\": \"s3:AbortMultipartUpload\",\n  \"0.InlinePolicies.0.PolicyName\": \"policy-s3-operator\",\n  \"0.InlinePolicies.0.Statement.2.Resource.0\": \"arn:aws:s3:::personal-s3-bucket/*\"\n}\n```\n\nThe `[]map[string]interface{}` can be created using `json.Unmarshal([]byte(myJsonString), \u0026myArrayMapStringInterface)`\n\n### Structs\n\nYou can also use the library to flatten any valid struct simply Marshalling the struct to a JSON string\n\n```golang\npackage main\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\n\t\"github.com/notdodo/goflat\"\n)\n\ntype Sub struct {\n\tA int\n\tB string\n\tC []SubSub\n}\n\ntype SubSub struct {\n\tD int\n}\n\nfunc main() {\n\tstructOne := Sub{\n\t\tA: 3,\n\t\tB: \"hello\",\n\t\tC: []SubSub{\n\t\t\t{D: 10}, {D: 11},\n\t\t},\n\t}\n\n\tflatten := goflat.FlatStruct(structOne)\n\tfmt.Println(flatten)\n\tjsonStr, _ := json.Marshal(flatten)\n\tfmt.Println(string(jsonStr))\n}\n```\n\nThe output is:\n\n```json\nmap[A:3 B:hello C..0:{10} C..1:{11}]\n{\"A\":3,\"B\":\"hello\",\"C..0\":{\"D\":10},\"C..1\":{\"D\":11}}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotdodo%2Fgoflat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnotdodo%2Fgoflat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnotdodo%2Fgoflat/lists"}