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

@meta-1/nest-types

v0.0.14

Published

Shared type definitions and schemas for Meta-1 applications

Readme

@meta-1/nest-types

共享类型定义和 Zod Schema,用于前后端类型共享和数据验证。

✨ 特性

  • 🛡️ 类型安全 - 完整的 TypeScript 类型定义
  • 数据验证 - 基于 Zod 的 Schema 验证
  • 🔄 共享复用 - 前后端共享类型定义
  • 📝 自动推导 - 从 Schema 自动推导 TypeScript 类型
  • 🎯 类型检查 - 编译时类型检查

📦 安装

npm install @meta-1/nest-types
# 或
pnpm add @meta-1/nest-types
# 或
yarn add @meta-1/nest-types

依赖安装

npm install zod

🚀 快速开始

基础导入

import {
  // AI 相关
  InvokeAgentSchema,
  AiConfigSchema,
  AddDocumentSchema,
  SearchDocumentSchema,
  
  // Assets 相关
  StorageProvider,
  BucketType,
  PresignedUploadUrlRequestSchema,
  PresignedDownloadUrlRequestSchema,
  
  // Common 相关
  PageRequestSchema,
  RestResult,
  PageData,
  
  // Message 相关
  SendCodeSchema,
  
  // Zod 工具
  coerceNumber,
  coerceNumberOptional,
} from '@meta-1/nest-types';

📚 API 文档

AI 相关类型

InvokeAgentSchema

Agent 调用请求 Schema。

import { InvokeAgentSchema, InvokeAgent } from '@meta-1/nest-types';

// 验证数据
const data: InvokeAgent = InvokeAgentSchema.parse({
  message: '你好,请介绍一下自己',
});

// 或使用 safeParse
const result = InvokeAgentSchema.safeParse({
  message: '',
});

if (!result.success) {
  console.error(result.error.errors);
}

类型定义:

  • message: string - 用户输入的消息内容(必填,最小长度 1)

AiConfigSchema

AI 配置 Schema,包含模型配置、向量存储配置、嵌入模型配置等。

import { AiConfigSchema, AiConfig } from '@meta-1/nest-types';

const config: AiConfig = AiConfigSchema.parse({
  model: {
    name: 'gpt-4',
    apiKey: 'your-api-key',
    apiBaseUrl: 'https://api.openai.com',
    temperature: 0.7,
    maxTokens: 2000,
  },
  vectorStore: {
    name: 'qdrant',
    collectionName: 'documents',
    options: {
      url: 'http://localhost:6333',
      apiKey: 'optional-api-key',
    },
  },
  embeddings: {
    name: 'text-embedding-ada-002',
    apiKey: 'your-api-key',
    apiBaseUrl: 'https://api.openai.com',
  },
  textSplitter: {
    chunkSize: 1000,
    chunkOverlap: 100,
  },
  mcp: {
    name: 'mcp-server',
    version: '1.0.0',
  },
});

AddDocumentSchema

添加文档到向量存储的请求 Schema。

import { AddDocumentSchema, AddDocument } from '@meta-1/nest-types';

const document: AddDocument = AddDocumentSchema.parse({
  id: 'doc-001',
  content: '这是文档内容...',
  metadata: {
    title: '文档标题',
    author: '作者名',
  },
});

DeleteDocumentSchema

删除文档请求 Schema。

import { DeleteDocumentSchema, DeleteDocument } from '@meta-1/nest-types';

const request: DeleteDocument = DeleteDocumentSchema.parse({
  documentId: 'doc-001',
});

SearchDocumentSchema

搜索文档请求 Schema。

import { SearchDocumentSchema, SearchDocument } from '@meta-1/nest-types';

const searchRequest: SearchDocument = SearchDocumentSchema.parse({
  message: '查询关键词',
  k: 5, // 可选,默认 4
});

SearchResultSchema

搜索结果 Schema。

import { SearchResultSchema, SearchResult } from '@meta-1/nest-types';

const result: SearchResult = SearchResultSchema.parse({
  id: 'doc-001',
  chunkId: 'chunk-001',
  content: '匹配的文档内容',
  metadata: {
    title: '文档标题',
  },
});

Assets 相关类型

StorageProvider

存储提供商枚举。

import { StorageProvider } from '@meta-1/nest-types';

const provider = StorageProvider.S3; // 's3' | 'oss' | 'minio'

可用值:

  • StorageProvider.S3 - AWS S3
  • StorageProvider.OSS - 阿里云 OSS
  • StorageProvider.MINIO - MinIO

BucketType

桶类型枚举。

import { BucketType } from '@meta-1/nest-types';

const bucketType = BucketType.PRIVATE; // 'private' | 'public'

可用值:

  • BucketType.PRIVATE - 私有桶,需要签名访问
  • BucketType.PUBLIC - 公共桶,可直接访问

PresignedUploadUrlRequestSchema

预签名上传 URL 请求 Schema。

import {
  PresignedUploadUrlRequestSchema,
  PresignedUploadUrlRequestData,
  BucketType,
} from '@meta-1/nest-types';

const request: PresignedUploadUrlRequestData =
  PresignedUploadUrlRequestSchema.parse({
    fileName: 'example.jpg',
    bucketType: BucketType.PRIVATE,
    prefix: 'uploads/2024/',
    headers: {
      'Content-Type': 'image/jpeg',
      'Content-Length': '1024',
    },
  });

PresignedUploadUrlResponseSchema

预签名上传 URL 响应 Schema。

import {
  PresignedUploadUrlResponseSchema,
  PresignedUploadUrlResponseData,
} from '@meta-1/nest-types';

const response: PresignedUploadUrlResponseData =
  PresignedUploadUrlResponseSchema.parse({
    fileName: 'example.jpg',
    signedUrl: 'https://s3.amazonaws.com/bucket/example.jpg?signature=...',
    url: 'https://s3.amazonaws.com/bucket/example.jpg',
    fileKey: 'uploads/2024/example.jpg',
    expiresAt: 1704067200000,
  });

PresignedDownloadUrlRequestSchema

预签名下载 URL 请求 Schema。

import {
  PresignedDownloadUrlRequestSchema,
  PresignedDownloadUrlRequestData,
} from '@meta-1/nest-types';

const request: PresignedDownloadUrlRequestData =
  PresignedDownloadUrlRequestSchema.parse({
    url: 'https://s3.amazonaws.com/bucket/example.jpg',
  });

PresignedDownloadUrlResponseSchema

预签名下载 URL 响应 Schema。

import {
  PresignedDownloadUrlResponseSchema,
  PresignedDownloadUrlResponseData,
} from '@meta-1/nest-types';

const response: PresignedDownloadUrlResponseData =
  PresignedDownloadUrlResponseSchema.parse({
    downloadUrl: 'https://s3.amazonaws.com/bucket/example.jpg?signature=...',
    expiresAt: 1704067200000, // Unix 时间戳(毫秒),公桶为 0
  });

Common 相关类型

PageRequestSchema

分页请求 Schema,自动将查询参数字符串转换为数字。

import { PageRequestSchema, PageRequest } from '@meta-1/nest-types';

// 从查询参数解析(自动转换字符串为数字)
const pageRequest: PageRequest = PageRequestSchema.parse({
  page: '1', // 字符串会自动转换为数字
  size: '20',
  keyword: '搜索关键词',
});

// 或直接使用数字
const pageRequest2: PageRequest = PageRequestSchema.parse({
  page: 1,
  size: 20,
});

类型定义:

  • page: number - 页码(最小 1,默认 1)
  • size: number - 每页数量(最小 1,最大 100,默认 20)
  • keyword: string - 关键词搜索(可选)

PageDataSchema

分页响应 Schema 工厂函数,用于创建特定数据类型的分页响应 Schema。

import { PageDataSchema } from '@meta-1/nest-types';
import { z } from 'zod';

// 定义单个数据项的 Schema
const UserSchema = z.object({
  id: z.string(),
  name: z.string(),
  email: z.string().email(),
});

// 创建分页响应 Schema
const UserPageDataSchema = PageDataSchema(UserSchema);

// 使用
const pageData = UserPageDataSchema.parse({
  total: 100,
  data: [
    { id: '1', name: '用户1', email: '[email protected]' },
    { id: '2', name: '用户2', email: '[email protected]' },
  ],
});

RestResult

REST API 通用响应结果类型。

import { RestResult } from '@meta-1/nest-types';

const successResponse: RestResult<{ id: string; name: string }> = {
  success: true,
  code: 200,
  message: '操作成功',
  data: {
    id: '1',
    name: '示例数据',
  },
};

const errorResponse: RestResult<null> = {
  success: false,
  code: 400,
  message: '请求参数错误',
};

PageData

分页数据类型。

import { PageData } from '@meta-1/nest-types';

const pageData: PageData<{ id: string; name: string }> = {
  total: 100,
  data: [
    { id: '1', name: '项目1' },
    { id: '2', name: '项目2' },
  ],
};

PageResult

分页响应结果类型。

import { PageResult } from '@meta-1/nest-types';

const pageResult: PageResult<{ id: string; name: string }> = {
  success: true,
  code: 200,
  message: '查询成功',
  data: {
    total: 100,
    data: [
      { id: '1', name: '项目1' },
      { id: '2', name: '项目2' },
    ],
  },
};

PageRequest

分页请求参数类型。

import { PageRequest } from '@meta-1/nest-types';

const pageRequest: PageRequest = {
  page: 1,
  size: 20,
  keyword: '搜索关键词',
};

// 扩展额外的查询参数
const extendedPageRequest: PageRequest<{ status: string }> = {
  page: 1,
  size: 20,
  keyword: '搜索关键词',
  status: 'active',
};

Message 相关类型

SendCodeSchema

发送验证码请求 Schema。

import { SendCodeSchema, SendCodeData } from '@meta-1/nest-types';

const request: SendCodeData = SendCodeSchema.parse({
  email: '[email protected]',
  action: 'register',
});

类型定义:

  • email: string - 邮箱地址(必填,需符合邮箱格式)
  • action: string - 操作类型(必填)

Zod 工具函数

coerceNumber

自定义的数字转换函数,将空字符串、null、undefined 转换为 undefined。

import { coerceNumber } from '@meta-1/nest-types';
import { z } from 'zod';

const NumberSchema = z.object({
  value: coerceNumber(),
});

// 空字符串、null、undefined 都会转换为 undefined
NumberSchema.parse({ value: '' }); // { value: undefined }
NumberSchema.parse({ value: null }); // { value: undefined }
NumberSchema.parse({ value: '123' }); // { value: 123 }

coerceNumberOptional

可选的数字转换函数。

import { coerceNumberOptional } from '@meta-1/nest-types';
import { z } from 'zod';

const OptionalNumberSchema = z.object({
  value: coerceNumberOptional(),
});

OptionalNumberSchema.parse({ value: '' }); // { value: undefined }
OptionalNumberSchema.parse({ value: '123' }); // { value: 123 }
OptionalNumberSchema.parse({}); // { value: undefined }

💡 使用示例

后端使用(NestJS)

DTO 验证

import { Controller, Post, Body, Query } from '@nestjs/common';
import {
  SendCodeSchema,
  SendCodeData,
  PageRequestSchema,
  PageRequest,
} from '@meta-1/nest-types';

@Controller('mail')
export class MailController {
  @Post('send-code')
  async sendCode(@Body() dto: SendCodeData) {
    // 验证数据
    const validatedData = SendCodeSchema.parse(dto);
    return await this.mailService.sendCode(validatedData);
  }

  @Get('list')
  async list(@Query() query: PageRequest) {
    // 自动转换查询参数
    const pageRequest = PageRequestSchema.parse(query);
    return await this.mailService.list(pageRequest);
  }
}

使用 nestjs-zod 集成

import { createZodDto } from 'nestjs-zod';
import { SendCodeSchema } from '@meta-1/nest-types';

export class SendCodeDto extends createZodDto(SendCodeSchema) {}

@Controller('mail')
export class MailController {
  @Post('send-code')
  async sendCode(@Body() dto: SendCodeDto) {
    // 自动验证
    return await this.mailService.sendCode(dto);
  }
}

前端使用(Next.js/React)

表单验证

import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { SendCodeSchema, SendCodeData } from '@meta-1/nest-types';

export function SendCodeForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<SendCodeData>({
    resolver: zodResolver(SendCodeSchema),
  });

  const onSubmit = async (data: SendCodeData) => {
    await fetch('/api/mail/send-code', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(data),
    });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register('email')} type="email" />
      {errors.email && <span>{errors.email.message}</span>}

      <input {...register('action')} />
      {errors.action && <span>{errors.action.message}</span>}

      <button type="submit">发送验证码</button>
    </form>
  );
}

API 调用

import {
  PresignedUploadUrlRequestSchema,
  PresignedUploadUrlRequestData,
  BucketType,
} from '@meta-1/nest-types';

async function uploadFile(file: File) {
  // 验证请求数据
  const requestData: PresignedUploadUrlRequestData =
    PresignedUploadUrlRequestSchema.parse({
      fileName: file.name,
      bucketType: BucketType.PRIVATE,
      headers: {
        'Content-Type': file.type,
        'Content-Length': file.size.toString(),
      },
    });

  // 获取预签名 URL
  const response = await fetch('/api/assets/presigned-upload-url', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(requestData),
  });

  const { signedUrl, url } = await response.json();

  // 使用预签名 URL 上传文件
  await fetch(signedUrl, {
    method: 'PUT',
    body: file,
    headers: requestData.headers,
  });

  return url;
}

分页查询

import { PageRequestSchema, PageRequest } from '@meta-1/nest-types';

async function fetchUsers(page: number, size: number, keyword?: string) {
  const params: PageRequest = PageRequestSchema.parse({
    page: page.toString(), // 从 URL 查询参数来的字符串
    size: size.toString(),
    keyword,
  });

  const queryString = new URLSearchParams({
    page: params.page.toString(),
    size: params.size.toString(),
    ...(params.keyword && { keyword: params.keyword }),
  });

  const response = await fetch(`/api/users?${queryString}`);
  return response.json();
}

📖 最佳实践

  1. 类型安全 - 始终使用 Schema 验证数据,确保类型安全
  2. 前后端共享 - 确保前后端使用相同的 Schema 定义
  3. 错误处理 - 使用 safeParse() 进行验证,优雅处理错误
  4. 边界验证 - 在数据进入系统的边界进行验证(API 入口、表单提交等)
  5. 类型推导 - 使用 z.infer<typeof Schema> 自动推导类型,避免重复定义

📄 许可证

MIT

🤝 贡献

欢迎贡献!请随时提交 Pull Request。