{"id":17364847,"url":"https://github.com/tejasq/klar","last_synced_at":"2025-06-27T08:36:09.003Z","repository":{"id":39613828,"uuid":"141340130","full_name":"TejasQ/klar","owner":"TejasQ","description":"A tool to infer and generate static type definitions based on resources returned by backend APIs.","archived":false,"fork":false,"pushed_at":"2023-01-04T07:52:34.000Z","size":13218,"stargazers_count":8,"open_issues_count":16,"forks_count":1,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-25T19:02:44.885Z","etag":null,"topics":["cli","codegen","resources","types"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/TejasQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-07-17T20:28:28.000Z","updated_at":"2023-07-27T12:04:07.000Z","dependencies_parsed_at":"2023-02-02T04:00:47.957Z","dependency_job_id":null,"html_url":"https://github.com/TejasQ/klar","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/TejasQ%2Fklar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejasQ%2Fklar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejasQ%2Fklar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TejasQ%2Fklar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TejasQ","download_url":"https://codeload.github.com/TejasQ/klar/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248991539,"owners_count":21194894,"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":["cli","codegen","resources","types"],"created_at":"2024-10-15T20:43:44.077Z","updated_at":"2025-04-15T01:50:53.916Z","avatar_url":"https://github.com/TejasQ.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# klar\n\nklar reads responses from backend endpoints and generates strongly typed interface definitions that clearly describe the data returned. It outputs [GraphQL Schemas](https://graphql.org/learn/schema/), [TypeScript Definitions](https://www.typescriptlang.org/docs/handbook/declaration-files/introduction.html), and [flow types](https://flow.org/en/).\n\n![Klar Demo](demo.gif)\n\nklar returns interfaces whose members are _always_ scalar values. If a member is a nested object, it continues to recursively define interfaces until final scalar values are available.\n\nIt _could_ be extended to also just describe any old [POJSO](https://en.wikipedia.org/wiki/Plain_old_Java_object).\n\n\u003c!-- START doctoc generated TOC please keep comment here to allow auto update --\u003e\n\u003c!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --\u003e\n\n- [Motivation](#motivation)\n- [Getting Started](#getting-started)\n- [Config File](#config-file)\n- [CLI Configuration](#cli-configuration)\n  - [`--configFile`, `-c`](#--configfile--c)\n  - [`--outDir`, `-o`](#--outdir--o)\n  - [`--dataProp`, `-d`](#--dataprop--d)\n  - [`--graphql`, `-g`](#--graphql--g)\n  - [`--flow`, `-f`](#--flow--f)\n  - [`--prefix`, `-p`](#--prefix--p)\n- [Why klar?](#why-klar)\n- [Next Steps](#next-steps)\n- [Contributing](#contributing)\n\n\u003c!-- END doctoc generated TOC please keep comment here to allow auto update --\u003e\n\n## Motivation\n\nDeveloper experience is something that is important to me. Developer _convenience_ is something I enjoy. I'd like to, _just before_ `yarn start`ing a web application that interacts with some type of backend, fetch the latest, greatest resource type definitions for my project, and then take full advantage of [my editor](https://code.visualstudio.com/)'s incredible [intellisense](https://code.visualstudio.com/docs/editor/intellisense), allowing me to have on-demand autocomplete for the data I'm working with.\n\n## Getting Started\n\nTo get started with klar, you'd need to tell it where your data lives. To do this, you'd need to create a config file. I know zero-config is currently sexy, but this is information that we have no way of inferring.\n\nA `klar.config.js` is a file that points klar in the right direction. Consider,\n\n```js\nmodule.exports = {\n  url: \"https://jsonplaceholder.typicode.com\",\n  resources: {\n    Post: \"/posts\",\n    Comment: \"/comments\",\n    Album: \"/albums\",\n    Photo: \"/photos\",\n    Todo: \"/todos\",\n    User: \"/users\",\n  },\n};\n```\n\nAs soon as your config file is in place, simply `npx klar` in your project, and you'll magically have interface definitions. Alternatively, `yarn add klar -D` will add it as a dependency in your project so it can be attached to a `prestart` script or similar.\n\n## Config File\n\n`klar.config.js` is a barebones file that points klar in the right direction. It does so by giving klar a URL against which to send requests, and a map of resource names and their respective paths as we've already seen in the previous example.\n\nA full illustration of the config options available to you in this file is below.\n\n```js\nmodule.exports = {\n  url: \"https://jsonplaceholder.typicode.com\",\n\n  /**\n   * A function that is applied to the immediately\n   * returned data.\n   */\n\n  resolve: data =\u003e data.iOnlyWantThisKey,\n\n  resources: {\n    Post: \"/posts\",\n\n    // You can also specify resource-level resolvers,\n    Comment: { path: \"/comments\", resolve: data =\u003e data.comment },\n    Album: \"/albums\",\n    Photo: \"/photos\",\n    Todo: \"/todos\",\n    User: \"/users\",\n  },\n\n  /**\n   * Request options that follow the Init spec\n   * of the fetch API: https://developer.mozilla.org/en-US/docs/Web/API/Request/Request\n   */\n  request: {\n    // headers, credentials, etc. go in here.\n  },\n};\n```\n\n## CLI Configuration\n\nAs a CLI tool, klar supports the following configuration options:\n\n### `--configFile`, `-c`\n\nPath to an alternative config file instead of `klar.config.js` that implements an identical exported schema.\n\n### `--outDir`, `-o`\n\nThis option specifies an output folder for your definition files. Current working directory by default.\n\n### `--dataProp`, `-d`\n\nUsually in the GraphQL world, but also quite common: data sometimes lives in a `data` property in a returned response. When this flag is set, it simply unwraps the response and defines interfaces based on the shape of `response.data`.\n\n### `--graphql`, `-g`\n\nOutput GraphQL schema definitions instead of TypeScript files. 🔥\n\n### `--flow`, `-f`\n\nOutput Flow type definitions instead of TypeScript files.\n\n### `--prefix`, `-p`\n\nThis option will prefix interface names with the name of the resource defined in the config file. Consider,\n\n```js\n// klar.config.js\n{\n  resources: {\n    Bae: '/wolf',\n  }\n}\n\n// in terminal,\nklar -p\n\n// Bae.d.ts\ninterface Bae {\n  name: string\n  otherNestedProperty: BaeOtherNestedProperty\n}\n\ninterface BaeOtherNestedProperty {\n  like: boolean\n}\n```\n\nWithout the prefix option, `otherNestedProperty`'s interface definition would have been _un-_ prefixed: `OtherNestedProperty`. This namespacing helps multiple exported interfaces with identical identifiers.\n\n## Why klar?\n\nklar is the German word for \"clear\". I chose to call this project klar because it makes resource types (or object shapes) fairly clear.\n\nTypically, in German culture, when a type of _contract_ is formed, it's usually agreed upon with the phrase _\"Alles klar\"_, or \"all clear\".\n\nI like how the metaphor applies to this use case of clear communication between client and server.\n\n## Next Steps\n\nWhile this tool has already helped me quite a lot, there is room for improvement! Below is a summary of how it can be improved, and areas wherein _you_ can get involved!\n\n1.  Cover klar with tests for what can be tested.\n1.  Find a comfortable way to handle authenticated requests.\n1.  Find a comfortable way to request _specific_ resources without requiring specific IDs: currently, the resource map from the config file expects a path to a resource with a specific ID, which it fetches and whose type information it infers. It would be interesting to see how we proceed when specific IDs are unknown.\n\n## Contributing\n\nStart with an issue. Let's discuss the issue, and then one of us will submit a pull request.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftejasq%2Fklar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftejasq%2Fklar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftejasq%2Fklar/lists"}