MCPcopy Create free account
hub / github.com/ariesclark/tanu.js

github.com/ariesclark/tanu.js @main

Chat with this repo
repository ↗ · DeepWiki ↗ · + Follow
65 symbols 145 edges 30 files 4 documented · 6% updated 2y ago★ 1341 open issues

Browse by type

Functions 55 Types & classes 10
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Tanu 🦝

A simplified abstraction of the TypeScript Compiler API for defining and generating source files.

npm GitHub issues GitHub Repo stars

Why?

I've always hated the fact that the majority of packages generate TypeScript files from a ridiculously long template literal string, It's not type safe or even readable at all, and I saw a cool tweet.

Yes Matt, It does exist now.

What does Tanu mean? 🦝

Tanuki (a cute animal) but I removed the last two characters cause tanuki was already taken on npm, and sounded cool enough for me. Naming things is hard, okay?

How do I use this?

const User = t.interface("User", {
  id: t.number(),
  email: t.string(),
  name: t.optional({
    first: t.string(),
    last: t.string(),
  }),
});

const MemberRole = t.enum("MemberRole", [
  "DEFAULT",
  "PRIVILEGED",
  "ADMINISTRATOR",
]);

const Member = t.interface("Member", {
  user: User,
  role: MemberRole,
});

const Organization = t.interface("Organization", {
  name: t.comment(t.string(), [
    "The organization name.",
    "@see https://example.com/organization-name",
  ]),
  description: t.optional(t.string()),
  members: t.array(Member),
});

const result = await t.generate([User, MemberRole, Member, Organization]);
console.log(result);
// the generated result.

export interface User {
  id: number;
  email: string;
  name?:
    | {
        first: string;
        last: string;
      }
    | undefined;
}
export enum MemberRole {
  DEFAULT,
  PRIVILEGED,
  ADMINISTRATOR,
}
export interface Member {
  user: User;
  role: MemberRole;
}
export interface Organization {
  /**
   * The organization name.
   * @see https://example.com/organization-name
   */
  name: string;
  description?: string | undefined;
  members: Array<Member>;
}

What about interfaces that reference themselves, or cross-reference each other?

Passing in a callback to the t.interface method will lazily populate the interface with its returned values. This will ensure that you can self-reference or cross-reference the interface, and it will be available by generation.

import { t } from "tanu.js";

const User = t.interface("User", () => ({
  users: t.array(User),
  posts: t.array(Post),
  authoredComments: t.array(Comment),
}));

const Post = t.interface("Post", () => ({
  author: User,
  text: t.string(),
  images: t.array(t.string()),
  postComments: t.array(Comment),
}));

const Comment = t.interface("Comment", {
  author: User,
  post: Post,
  text: t.string(),
});

const CommentReply = t.type("CommentReply", () => ({
  parent: CommentReply,
  author: User,
  post: Post,
  text: t.string(),
}));

const result = await t.generate([User, Post, Comment, CommentReply]);
console.log(result);
// the generated result

export interface User {
  users: Array<User>;
  posts: Array<Post>;
  authoredComments: Array<Comment>;
}
export interface Post {
  author: User;
  text: string;
  images: Array<string>;
  postComments: Array<Comment>;
}
export interface Comment {
  author: User;
  post: Post;
  text: string;
}
export type CommentReply = {
  parent: CommentReply;
  author: User;
  post: Post;
  text: string;
};

Extension points exported contracts — how you extend this code

browse all types & interfaces →

Core symbols most depended-on inside this repo

browse all functions →

Shape

Function 55
Interface 9
Enum 1

Languages

TypeScript100%

Modules by API surface

src/type/primitives/index.ts10 symbols
src/runtime/utils.ts7 symbols
src/type/utils.ts6 symbols
src/type/index.ts5 symbols
src/runtime/statements.ts5 symbols
src/example.out.ts5 symbols
src/utils.ts4 symbols
src/generate.ts4 symbols
src/type/declarations/module.ts3 symbols
src/runtime/index.ts3 symbols
src/type/declarations/type.ts2 symbols
src/type/declarations/interface.ts2 symbols

For agents

$ claude mcp add tanu.js \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page