Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/bwireman/genus
Type Script and Elixir structs, a monster mash
https://github.com/bwireman/genus
Last synced: 6 days ago
JSON representation
Type Script and Elixir structs, a monster mash
- Host: GitHub
- URL: https://github.com/bwireman/genus
- Owner: bwireman
- License: mit
- Created: 2022-05-15T15:41:20.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2023-03-04T18:45:12.000Z (over 1 year ago)
- Last Synced: 2024-08-01T19:53:02.453Z (3 months ago)
- Language: Elixir
- Size: 95.7 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Genus
Macro for generating Typescript types and Elixir structs
## Installation
```elixir
def deps do
[
{:genus, git: "[email protected]:bwireman/genus.git"}
]
end
```## Usage
```elixir
defmodule User do
# load the `tschema` macro
use Genus
tschema name: "User" do
field(:id, :string, required: true)
field(:email, :string)
field(:active, :bool, default: false)
field(:role, :union, "Role", true, [:enduser, :admin, :superuser], default: :enduser)
end
end
```### Macro Options
- name: Name of the generated TypeScript interface, defaults to the last piece of the module name
- imports: keyword of other imports and import overrides to add to the generated file### Elixir output
```elixir
defmodule User do
@enforce_keys [:id]
defstruct [id: nil, email: nil, active: false, role: :enduser]
end
```### Typescript output
```typescript
// Do Not Modify! This file was generated by Genus from an Elixir struct @ Elixir.User
// https://github.com/bwireman/genusexport type Role = "enduser" | "admin" | "superuser"
export interface User {
id: string
email?: string
active: boolean
role: Role
}export const apply_user = (v: any): User => v
export const build_user = ({ id, email, active, role }: {
id: string
email?: string
active?: boolean
role?: Role
}): User => {
return {
id: id,
email: email || undefined,
active: active || false,
role: role || "enduser",
}
}export const new_user = (id: string) => build_user({ id })
```### Config
```elixir
import Configconfig :genus,
# path directory to save the write TypeScript code to
# defaults to "./ts"
directory: "types",
# indent spacer for generated TypeScript
# defaults to " "
indent: "\t"
```## Types
| Format | Elixir type | TS type |
| -------------------------------------------- | ----------- | ----------- |
| (name, :string) | String.t() | string |
| (name, :integer) | integer() | number |
| (name, :float) | float() | number |
| (name, :bool) | bool() | boolean |
| (name) | any() | any |
| (name, :external, type_name) | any() | type_name |
| (name, :list, type_name) | list() | type_name[] |
| (name, :union, type_name, is_string, values) | any() | type_name |#### Type Options
- type_name `String.t()`: represents the TS type to use
- is_string `bool()`: Should the union be represented as strings in TS
- values `list()`: Values that compose the union## Field Options
#### `default: value` | `required: true|false`
Fields default to being optional and with a `nil` default in Elixir and nullable with a default of `undefined` in TypeScript. If you specify a value that will be the default value in both Elixir and Typescript. You can also specify `required:` and mark the field as required in both the Elixir struct and the generator function