https://github.com/mattkhan/jsonapi-resources-anchor
Easily generate TypeScript schemas, JSON Schemas, or any schema of your choice from cerebris/jsonapi-resources JSONAPI::Resource classes.
https://github.com/mattkhan/jsonapi-resources-anchor
codegen jsonapi-resources rails ruby typescript
Last synced: 16 days ago
JSON representation
Easily generate TypeScript schemas, JSON Schemas, or any schema of your choice from cerebris/jsonapi-resources JSONAPI::Resource classes.
- Host: GitHub
- URL: https://github.com/mattkhan/jsonapi-resources-anchor
- Owner: mattkhan
- License: mit
- Created: 2024-07-08T06:29:29.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2025-02-07T02:55:42.000Z (9 months ago)
- Last Synced: 2025-02-07T03:28:05.520Z (9 months ago)
- Topics: codegen, jsonapi-resources, rails, ruby, typescript
- Language: Ruby
- Homepage:
- Size: 194 KB
- Stars: 4
- Watchers: 3
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
- Security: SECURITY.md
Awesome Lists containing this project
README
# JSON:API Resource Schema Generation: Anchor
[Documentation](https://jsonapi-resources-anchor.up.railway.app/)
Easily generate TypeScript schemas, JSON Schemas, or any schema of your choice
from [cerebris/jsonapi-resources](https://github.com/cerebris/jsonapi-resources)
`JSONAPI::Resource` classes.
Ideally, API schemas have the types of each payload fully specified.
`jsonapi-resources-anchor` provides:
- [Type inference](https://jsonapi-resources-anchor.up.railway.app/docs/Features/type_inference)
via the underlying ActiveRecord model of a resource
- [Type annotation](https://jsonapi-resources-anchor.up.railway.app/docs/Features/type_annotation),
e.g. `attribute :name_length, Anchor::Types::Integer`
- [Configuration](https://jsonapi-resources-anchor.up.railway.app/docs/API/configuration),
e.g. setting the case (camel, snake, etc.) of properties and deriving
TypeScript comments from database comments
- TypeScript and JSON Schema generators via
`Anchor::TypeScript::SchemaGenerator` and
`Anchor::JSONSchema::SchemaGenerator`
See the [example](./spec/example) Rails app for a fully functional app using
`Anchor`.
## Installation
```ruby
gem 'jsonapi-resources-anchor'
```
```sh
bundle install
```
## TypeScript Demo
Given:
ActiveRecord Schema:
```rb
create_table "comments", force: :cascade do |t|
t.string "text", null: false
t.string "commentable_type"
t.bigint "commentable_id"
t.bigint "user_id", null: false
t.bigint "deleted_by_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["commentable_type", "commentable_id"], name: "index_comments_on_commentable"
t.index ["deleted_by_id"], name: "index_comments_on_deleted_by_id"
t.index ["user_id"], name: "index_comments_on_user_id"
end
create_table "posts", force: :cascade do |t|
t.string "description", null: false
t.bigint "user_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_posts_on_user_id"
end
create_table "users", force: :cascade do |t|
t.string "name", null: false
t.integer "integer"
t.decimal "decimal"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "role"
end
```
`JSONAPI::Resource` classes:
```rb
class ApplicationResource < JSONAPI::Resource
abstract
include Anchor::SchemaSerializable
end
class CommentResource < ApplicationResource
attribute :text
attribute :created_at
attribute :updated_at
attribute :inferred_unknown
attribute :type_given, Anchor::Types::String
relationship :user, to: :one
relationship :commentable, Anchor::Types::Relationship.new(resources: [UserResource, PostResource], null: true), polymorphic: true, to: :one
end
class UserResource < ApplicationResource
attribute :name
attribute :role, UserRoleEnum
relationship :comments, to: :many
relationship :posts, to: :many
end
class UserRoleEnum < Anchor::Types::Enum
anchor_schema_name "UserRole"
value :admin, "admin"
value :content_creator, "content_creator"
value :external, "external"
value :guest, "guest"
value :system, "system"
end
class PostResource < ApplicationResource
attribute :description
relationship :user, to: :one
relationship :comment, to: :many
end
class Schema < Anchor::Schema
resource CommentResource
resource UserResource
resource PostResource
enum UserRoleEnum
end
```
`Anchor::TypeScript::SchemaGenerator.call(register: Schema.register)` will
return the schema below in a `String`:
```ts
type Maybe = T | null;
export type Comment = {
id: number;
type: "comments";
text: string;
created_at: string;
updated_at: string;
inferred_unknown: unknown;
type_given: string;
relationships: {
user: User;
commentable: Maybe;
};
};
export type User = {
id: number;
type: "users";
name: string;
role: UserRole;
relationships: {
comments: Array;
posts: Array;
};
};
export type Post = {
id: number;
type: "posts";
description: string;
relationships: {
user: User;
comment: Array;
};
};
export enum UserRole {
Admin = "admin",
ContentCreator = "content_creator",
External = "external",
Guest = "guest",
System = "system",
}
```
#### References
- [@nopelluhh](https://github.com/nopelluhh)
- [ElMassimo/types_from_serializers](https://github.com/ElMassimo/types_from_serializers)
- [rmosolgo/graphql-ruby](https://github.com/rmosolgo/graphql-ruby)
#### Security
[Security Policy](/SECURITY.md)