npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, πŸ‘‹, I’m Ryan HefnerΒ  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you πŸ™

Β© 2026 – Pkg Stats / Ryan Hefner

@kaze-no-manga/models

v1.0.0

Published

πŸ“˜ Shared TypeScript types, Zod schemas, and GraphQL definitions for Kaze no Manga ecosystem

Readme

@kaze/models

Shared TypeScript types, Zod schemas, and GraphQL definitions for Kaze no Manga

Overview

This package contains all shared data models, type definitions, validation schemas, and GraphQL types used across the Kaze no Manga ecosystem.

Features

  • πŸ“˜ TypeScript Interfaces: Strongly-typed data models
  • βœ… Zod Schemas: Runtime validation and type inference
  • πŸ”· GraphQL Types: Generated from SDL schemas
  • πŸ”„ Type Safety: End-to-end type safety across all services

Installation

npm install @kaze/models

Usage

TypeScript Interfaces

import { Manga, Chapter, User, LibraryEntry } from '@kaze/models'

const manga: Manga = {
  id: '123',
  title: 'One Piece',
  altTitles: ['ワンピース'],
  // ...
}

Zod Schemas

import { mangaSchema, chapterSchema } from '@kaze/models/schemas'

// Validate data
const result = mangaSchema.safeParse(data)
if (result.success) {
  console.log(result.data) // Typed as Manga
} else {
  console.error(result.error)
}

// Type inference
type MangaInput = z.infer<typeof mangaSchema>

GraphQL Types

import { Query, Mutation, MangaResolvers } from '@kaze/models/graphql'

// Use in resolvers
const resolvers: MangaResolvers = {
  Query: {
    getManga: async (_, { id }) => {
      // Return type is automatically typed
    }
  }
}

Core Models

User

interface User {
  id: string                    // Cognito ID
  email: string
  name?: string
  avatar?: string
  preferences: UserPreferences
  createdAt: Date
  updatedAt: Date
}

interface UserPreferences {
  notifications: {
    email: boolean
    push: boolean
    maxPerDay: number
  }
  reader: {
    imageWidth: 'fit' | 'full'
    spacing: number
    theme: 'light' | 'dark' | 'auto'
  }
}

Manga

interface Manga {
  id: string
  title: string
  altTitles: string[]
  description?: string
  coverImage?: string
  status: MangaStatus
  genres: string[]
  authors: string[]
  year?: number
  sources: MangaSource[]
  createdAt: Date
  updatedAt: Date
}

type MangaStatus = 'ongoing' | 'completed' | 'hiatus' | 'cancelled'

interface MangaSource {
  sourceId: string              // Reference to Source entity
  sourceMangaId: string         // ID on the source platform
  url: string
  priority: number              // For automatic source selection
  lastChecked: Date
}

Source

interface Source {
  id: string
  name: string                  // 'MangaPark', 'OmegaScans'
  baseUrl: string
  status: SourceStatus
  priority: number
  createdAt: Date
  updatedAt: Date
}

type SourceStatus = 'active' | 'deprecated' | 'unavailable'

Chapter

interface Chapter {
  id: string
  mangaId: string
  sourceId: string
  number: number                // Supports decimals (5.5, 5.1)
  title?: string
  releaseDate?: Date
  images: ChapterImage[]
  createdAt: Date
  updatedAt: Date
}

interface ChapterImage {
  url: string                   // S3 URL after download
  originalUrl: string           // Original source URL
  page: number
  width?: number
  height?: number
}

Library Entry

interface LibraryEntry {
  userId: string
  mangaId: string
  status: ReadingStatus
  rating?: number               // 1-10
  notes?: string
  currentChapterId?: string
  currentChapterNumber?: number
  lastReadAt?: Date
  addedAt: Date
  updatedAt: Date
}

type ReadingStatus = 'reading' | 'completed' | 'plan_to_read' | 'dropped' | 'on_hold'

Reading History

interface ReadingHistory {
  id: string
  userId: string
  mangaId: string
  chapterId: string
  chapterNumber: number
  completed: boolean
  readAt: Date
}

Notification

interface Notification {
  id: string
  userId: string
  mangaId: string
  chapterId: string
  type: NotificationType
  title: string
  message: string
  read: boolean
  sentAt: Date
  readAt?: Date
}

type NotificationType = 'new_chapter' | 'manga_completed' | 'source_changed'

GraphQL Schema

Queries

type Query {
  # Manga
  searchManga(query: String!): [Manga!]!
  getManga(id: ID!): Manga
  getChapters(mangaId: ID!): [Chapter!]!
  
  # Library
  getLibrary: [LibraryEntry!]!
  getReadingHistory(limit: Int): [ReadingHistory!]!
  
  # User
  getProfile: User!
  getNotifications(unreadOnly: Boolean): [Notification!]!
}

Mutations

type Mutation {
  # Library
  addToLibrary(mangaId: ID!): LibraryEntry!
  updateLibraryEntry(mangaId: ID!, input: LibraryEntryInput!): LibraryEntry!
  removeFromLibrary(mangaId: ID!): Boolean!
  
  # Progress
  updateProgress(mangaId: ID!, chapterId: ID!): LibraryEntry!
  markChapterAsRead(chapterId: ID!): ReadingHistory!
  
  # User
  updatePreferences(input: UserPreferencesInput!): User!
  markNotificationAsRead(id: ID!): Notification!
}

Validation Schemas

All models have corresponding Zod schemas for runtime validation:

import { z } from 'zod'

export const mangaSchema = z.object({
  id: z.string().uuid(),
  title: z.string().min(1).max(500),
  altTitles: z.array(z.string()).default([]),
  description: z.string().max(5000).optional(),
  status: z.enum(['ongoing', 'completed', 'hiatus', 'cancelled']),
  genres: z.array(z.string()),
  authors: z.array(z.string()),
  year: z.number().int().min(1900).max(2100).optional(),
  // ...
})

export const chapterSchema = z.object({
  id: z.string().uuid(),
  mangaId: z.string().uuid(),
  number: z.number().positive(),
  title: z.string().max(500).optional(),
  // ...
})

Code Generation

GraphQL types are automatically generated from SDL schemas:

# Generate TypeScript types from GraphQL schema
npm run codegen

Configuration in codegen.yml:

schema: './src/graphql/schema.graphql'
generates:
  ./src/graphql/types.ts:
    plugins:
      - typescript
      - typescript-resolvers

Package Structure

models/
β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ types/
β”‚   β”‚   β”œβ”€β”€ user.ts
β”‚   β”‚   β”œβ”€β”€ manga.ts
β”‚   β”‚   β”œβ”€β”€ chapter.ts
β”‚   β”‚   β”œβ”€β”€ library.ts
β”‚   β”‚   └── index.ts
β”‚   β”œβ”€β”€ schemas/
β”‚   β”‚   β”œβ”€β”€ user.schema.ts
β”‚   β”‚   β”œβ”€β”€ manga.schema.ts
β”‚   β”‚   β”œβ”€β”€ chapter.schema.ts
β”‚   β”‚   β”œβ”€β”€ library.schema.ts
β”‚   β”‚   └── index.ts
β”‚   β”œβ”€β”€ graphql/
β”‚   β”‚   β”œβ”€β”€ schema.graphql
β”‚   β”‚   β”œβ”€β”€ types.ts (generated)
β”‚   β”‚   └── index.ts
β”‚   └── index.ts
β”œβ”€β”€ codegen.yml
β”œβ”€β”€ package.json
└── README.md

Development

# Install dependencies
npm install

# Generate GraphQL types
npm run codegen

# Build package
npm run build

# Run tests
npm test

# Publish (private)
npm publish

Versioning

This package follows Semantic Versioning:

  • Major: Breaking changes to types or schemas
  • Minor: New types or optional fields
  • Patch: Bug fixes or documentation updates

License

MIT License - see LICENSE for details.


Part of the Kaze no Manga project