{"id":18799575,"url":"https://github.com/l2silver/erschema","last_synced_at":"2026-01-02T20:30:15.621Z","repository":{"id":57159934,"uuid":"84622773","full_name":"l2silver/erschema","owner":"l2silver","description":null,"archived":false,"fork":false,"pushed_at":"2017-12-29T05:28:18.000Z","size":60,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-29T09:44:08.913Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/l2silver.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-03-11T04:07:01.000Z","updated_at":"2018-02-11T18:26:30.000Z","dependencies_parsed_at":"2022-08-26T16:41:03.855Z","dependency_job_id":null,"html_url":"https://github.com/l2silver/erschema","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l2silver%2Ferschema","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l2silver%2Ferschema/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l2silver%2Ferschema/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/l2silver%2Ferschema/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/l2silver","download_url":"https://codeload.github.com/l2silver/erschema/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239727883,"owners_count":19687263,"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":[],"created_at":"2024-11-07T22:15:47.329Z","updated_at":"2026-01-02T20:30:15.561Z","avatar_url":"https://github.com/l2silver.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# erschema\n\n[![Build Status](https://travis-ci.org/l2silver/erschema.svg?branch=master)](https://travis-ci.org/l2silver/erschema)\n\nA normalizer that uses plain objects for schema definitions so that they can be reused with other libraries\n\n## Setup\n\n```npm i erschema```\n\n## Usage\n\n```\nimport normalize, {validateSchema, relationshipTypes} from 'erschema'\n\nconst users = {\n  idFunc: (ent)=\u003eent.id,\n  modifier: ({name, ...otherProps})=\u003e({name})\n  premodifier: (ent)=\u003e({\n    ...ent,\n    closeFriends: ent.friends.filter(f=\u003ef.name === 'Harry')\n  }),\n  relationships: [{\n    entityName: 'users',\n    name: 'friends',\n    type: relationshipTypes.MANY,\n  },{\n    entityName: 'users',\n    name: 'closeFriends',\n    type: relationshipTypes.ONE,\n  }]\n}\n\nconst schema = {\n  users,\n}\n\nconst data = [{\n  id: 1,\n  name: 'Loyd',\n  friends: [{\n    id: 2,\n    name: 'Harry'\n  }]\n}]\n\nvalidateSchema(schema)\n\nconst {entities, relationships} = normalize(data, 'users', schema);\nconsole.log(entities)\n/*\n{\n  [1]: {\n    name: 'Loyd'\n  },\n  [2]: {\n    name: 'Harry'\n  }\n}\n*/\n\nconsole.log(relationships)\n/*\n{\n users: {\n  friends: {\n    [1]: [2],\n  },\n  closeFriends: {\n    [1]: 2\n  }\n }\n}\n```\n\n## Why Another Normalizer?\n\nI really liked the [normalizr](https://github.com/paularmstrong/normalizr) project by Dan Abramov and Paul Armstrong, but I felt like if I was going to all the trouble of creating a schema for my data, I'd like to be able to do as much as possible with the schema. I also wanted to extract the relationships from the entities into a completely separate structure.\n\nFor example:\n* I could use the schema to easily construct the shape of the redux store\n* I could listen for delete actions for a certain entityType, and know to search specific relationships for that id and scrub them\n\n## Flowtype\n\ntype $ONE = 1;\ntype $MANY = 2;\ntype $id = string | number;\ntype $relationships = Array\u003c{\n  entityName: string,\n  name?: string,\n  alias?: string,\n  type: $ONE | $MANY\n}\u003e\n\ntype $schema = {\n  modifier?: (ent)=\u003eent,\n  premodifier?: (ent)=\u003eent,\n  idFunc?: (ent)=\u003estring | $id,\n  nameFunc?: (ent)=\u003estring,\n  relationships: $relationships,\n}\n\ntype $schemaName = string;\n\ntype $schemas = {[key: $schemaName]: $schema}\n\n### premodifier\nRuns right before a single entity is about to be processed.\n\n* If you wanted to split an array of related entities into two separate relationships, you could run the premodifier to do so\n\n### modifier\nRuns right after an entity is processed\n\n* Good for cleaning up and removing unneccessary object properties\n\n### idFunc\nUsed to retrieve the id of an entity\n\n* default is (ent)=\u003eent.id\n\n### nameFunc\nUsed to change the entityName of the entity after its schema has been retrieved\n\n* default is (ent)=\u003eent.id\n\n\n### relationships\nAn array of relationshipSchemas used to build relationships\n\n#### entityName\nThe entityName of the related entity. This is the only required field.\n\n#### name\nThe name of the relationship. For example, friends is the name of the relationship above, but the entityName of the relationship is users\n\n#### alias\nWhen a relationship is stored as a different property.\n\n#### type\nIs the relationship ONE-TO-ONE or ONE-TO-MANY\n\n## In production\n\nI currently use derivatives of this approach for a number of my professional and side projects. My own specific versions are quite sophisticated, usually involving actions, selectors, and reducers, and are heavily alloyed with immutablejs, but feel free to design your own system.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl2silver%2Ferschema","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fl2silver%2Ferschema","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fl2silver%2Ferschema/lists"}