open-index/open-npm huggingface dataset:
npm package: @svton/cli
Description: Svton CLI - Create full-stack applications with NestJS, Next.js, and Taro
Author: SVTON Team
Latest version: 2.2.0

# @svton/cli

> Svton CLI - 使用 NestJS、Next.js 和 Taro 创建全栈应用

[![npm version](https://badge.fury.io/js/@svton/cli.svg)](https://badge.fury.io/js/@svton/cli)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 特性

- 🚀 **全栈模板** - 后端 (NestJS)、管理后台 (Next.js)、移动端 (Taro)
- 📦 **Monorepo 架构** - Turbo + pnpm workspace 预配置
- 🎯 **多种模板** - 按需选择：全栈、仅后端、仅管理后台、仅移动端
- 🛠️ **开发体验** - ESLint、Prettier、TypeScript 预配置
- 🐳 **Docker 支持** - 内置 MySQL 和 Redis 容器配置
- 📚 **类型安全** - 共享类型定义和 API 接口

## 快速开始

```bash
# 推荐方式 (npx)
npx @svton/cli create my-app

# 全局安装后使用
npm install -g @svton/cli
svton create my-app
```

## 使用方法

```bash
svton create <project-name> [options]
svton init <project-name> [options]   # 别名
svton new <project-name> [options]    # 别名
```

### 选项

- `-o, --org <name>` - 组织名称（默认：项目名）
- `--skip-install` - 跳过依赖安装
- `--skip-git` - 跳过 Git 初始化
- `-t, --template <template>` - 使用的模板（full-stack、backend-only、admin-only、mobile-only）
- `-p, --package-manager <pm>` - 包管理器（npm、yarn、pnpm）

### 示例

```bash
# 创建全栈应用
svton create my-app

# 使用自定义组织名
svton create my-app --org my-company

# 创建仅后端项目
svton create my-api --template backend-only

# 跳过依赖安装
svton create my-app --skip-install
```

## 模板

### 全栈模板 (`full-stack`)
完整应用包含：
- **后端**: NestJS + Prisma + MySQL + Redis
- **管理后台**: Next.js + TailwindCSS + shadcn/ui
- **移动端**: Taro + React (微信小程序)
- **共享类型**: TypeScript 类型定义

### 仅后端 (`backend-only`)
- NestJS API 服务器
- Prisma ORM + MySQL
- JWT 认证
- Redis 缓存
- Swagger 文档

### 仅管理后台 (`admin-only`)
- Next.js 15 + App Router
- TailwindCSS + shadcn/ui
- TypeScript + ESLint
- API 客户端集成

### 仅移动端 (`mobile-only`)
- Taro 3.6 框架
- React 18
- 微信小程序支持
- TypeScript + ESLint

## 项目架构

使用 `svton` 创建的项目遵循以下架构：

```
my-app/
├── apps/
│   ├── backend/        # @my-org/backend
│   ├── admin/          # @my-org/admin
│   └── mobile/         # @my-org/mobile
├── packages/
│   └── types/          # @my-org/types
├── package.json
├── pnpm-workspace.yaml
├── turbo.json
└── docker-compose.yml
```

## 创建后的步骤

1. **启动数据库**（全栈/后端模板）：
   ```bash
   docker-compose up -d
   ```

2. **配置环境变量**：
   ```bash
   cp apps/backend/.env.example apps/backend/.env
   # 编辑 .env 文件配置你的设置
   ```

3. **运行数据库迁移**（后端模板）：
   ```bash
   pnpm --filter @my-org/backend prisma:generate
   pnpm --filter @my-org/backend prisma:migrate
   ```

4. **启动开发服务器**：
   ```bash
   pnpm dev
   ```

## 环境要求

- Node.js >= 18.0.0
- npm、yarn 或 pnpm（推荐 pnpm）
- Docker（用于数据库服务）

## 许可证

MIT © [SVTON Team](https://github.com/svton)
npm package: @svton/nestjs-authz
Description: NestJS RBAC authorization module with roles decorator and guard
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-authz

NestJS RBAC 权限模块，提供 `@Roles()` 装饰器和 `RolesGuard`。

## 安装

```bash
pnpm add @svton/nestjs-authz
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { AuthzModule } from '@svton/nestjs-authz';

@Module({
  imports: [
    AuthzModule.forRoot({
      userRoleField: 'role', // 从 req.user.role 读取角色
      enableGlobalGuard: true, // 全局启用 RolesGuard
      allowNoRoles: true, // 没有设置角色要求时放行
    }),
  ],
})
export class AppModule {}
```

### 使用装饰器

```typescript
import { Controller, Get, UseGuards } from '@nestjs/common';
import { Roles, Public, RolesGuard } from '@svton/nestjs-authz';
import { JwtAuthGuard } from './auth/jwt-auth.guard';

@Controller('users')
@UseGuards(JwtAuthGuard, RolesGuard) // 如果没有全局启用
export class UserController {
  // 需要 admin 或 moderator 角色
  @Roles('admin', 'moderator')
  @Get()
  findAll() {
    return [];
  }

  // 只需要 admin 角色
  @Roles('admin')
  @Delete(':id')
  remove(@Param('id') id: string) {
    return { deleted: id };
  }

  // 公开路由，跳过角色检查
  @Public()
  @Get('public')
  publicEndpoint() {
    return { message: 'This is public' };
  }
}
```

### 与 JWT 配合使用

确保 JWT payload 中包含角色信息：

```typescript
// auth.service.ts
@Injectable()
export class AuthService {
  async login(user: User) {
    const payload = {
      sub: user.id,
      email: user.email,
      role: user.role, // 'admin' | 'user' | 'moderator'
    };
    return {
      access_token: this.jwtService.sign(payload),
    };
  }
}

// jwt.strategy.ts
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
  async validate(payload: JwtPayload) {
    return {
      id: payload.sub,
      email: payload.email,
      role: payload.role, // 角色会被附加到 req.user
    };
  }
}
```

## 配置选项

| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| userRoleField | string | 'role' | 用户角色字段（支持嵌套如 'profile.role'） |
| enableGlobalGuard | boolean | false | 是否全局启用 RolesGuard |
| allowNoRoles | boolean | true | 没有设置角色要求时是否放行 |

## 多角色支持

如果用户有多个角色（数组形式），只要有一个角色匹配即可通过：

```typescript
// JWT payload
{
  sub: '123',
  roles: ['user', 'editor'] // 数组形式
}

// 配置
AuthzModule.forRoot({
  userRoleField: 'roles', // 指向数组字段
})

// 使用
@Roles('editor', 'admin') // 用户有 editor 角色，可以访问
@Get('articles')
findAll() {}
```
npm package: @svton/nestjs-cache
Description: NestJS cache decorators with Redis support (@Cacheable, @CacheEvict, @CachePut)
Author: SVTON Team
Latest version: 2.0.0

# @svton/nestjs-cache

NestJS 缓存装饰器模块，基于 Redis，提供 `@Cacheable`、`@CacheEvict`、`@CachePut` 装饰器。

## 安装

```bash
pnpm add @svton/nestjs-cache @svton/nestjs-redis
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { RedisModule } from '@svton/nestjs-redis';
import { CacheModule } from '@svton/nestjs-cache';

@Module({
  imports: [
    RedisModule.forRoot({ host: 'localhost', port: 6379 }),
    CacheModule.forRoot({
      ttl: 3600,      // 默认 TTL (秒)
      prefix: 'app',  // Key 前缀
    }),
  ],
})
export class AppModule {}
```

### @Cacheable - 缓存方法结果

```typescript
import { Cacheable } from '@svton/nestjs-cache';

@Injectable()
export class UserService {
  @Cacheable({ key: 'user:#0', ttl: 3600 })
  async getUser(id: string) {
    return this.userRepo.findById(id);
  }
}
```

### @CacheEvict - 清除缓存

```typescript
import { CacheEvict } from '@svton/nestjs-cache';

@Injectable()
export class UserService {
  @CacheEvict({ key: 'user:#0' })
  async updateUser(id: string, data: UpdateUserDto) {
    return this.userRepo.update(id, data);
  }

  @CacheEvict({ key: 'user:*', allEntries: true })
  async clearAllUserCache() {
    // 清除所有 user:* 缓存
  }
}
```

### @CachePut - 强制更新缓存

```typescript
import { CachePut } from '@svton/nestjs-cache';

@Injectable()
export class UserService {
  @CachePut({ key: 'user:#0', ttl: 3600 })
  async refreshUser(id: string) {
    return this.userRepo.findById(id);
  }
}
```

## Key 表达式

- `#0`, `#1` - 方法参数位置
- `#id`, `#userId` - 从 request.params/body/query 获取

## License

MIT
npm package: @svton/nestjs-config-schema
Description: NestJS config validation with Zod/Joi schema support
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-config-schema

为 `@nestjs/config` 提供 Zod schema 验证支持。

## 安装

```bash
pnpm add @svton/nestjs-config-schema zod
```

## 使用

### 定义环境变量 Schema

```typescript
// src/config/env.schema.ts
import { z } from 'zod';

export const envSchema = z.object({
  // 应用配置
  NODE_ENV: z.enum(['development', 'production', 'test']).default('development'),
  PORT: z.coerce.number().default(3000),
  
  // 数据库
  DATABASE_URL: z.string().url(),
  
  // Redis
  REDIS_URL: z.string().url().optional(),
  
  // JWT
  JWT_SECRET: z.string().min(32),
  JWT_EXPIRES_IN: z.string().default('7d'),
  
  // 七牛云
  QINIU_ACCESS_KEY: z.string().optional(),
  QINIU_SECRET_KEY: z.string().optional(),
  QINIU_BUCKET: z.string().optional(),
});

// 导出类型
export type EnvConfig = z.infer<typeof envSchema>;
```

### 在 ConfigModule 中使用

```typescript
// src/app.module.ts
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { createZodValidate } from '@svton/nestjs-config-schema';
import { envSchema } from './config/env.schema';

@Module({
  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      validate: createZodValidate(envSchema),
    }),
  ],
})
export class AppModule {}
```

### 类型安全的配置访问

```typescript
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EnvConfig } from './config/env.schema';

@Injectable()
export class MyService {
  constructor(private config: ConfigService<EnvConfig, true>) {}

  getPort(): number {
    return this.config.get('PORT'); // 类型安全
  }
}
```

## 常用 Zod 转换

```typescript
import { z } from 'zod';

const schema = z.object({
  // 字符串转数字
  PORT: z.coerce.number(),
  
  // 字符串转布尔
  DEBUG: z.string().transform((v) => v === 'true'),
  
  // 带默认值
  NODE_ENV: z.string().default('development'),
  
  // 可选字段
  REDIS_URL: z.string().optional(),
  
  // URL 验证
  DATABASE_URL: z.string().url(),
  
  // 枚举
  LOG_LEVEL: z.enum(['debug', 'info', 'warn', 'error']),
  
  // 最小长度
  JWT_SECRET: z.string().min(32),
  
  // 逗号分隔转数组
  CORS_ORIGINS: z.string().transform((v) => v.split(',')),
});
```

## 错误处理

验证失败时会抛出 `ConfigValidationError`：

```
Config validation failed:
  - DATABASE_URL: Required
  - JWT_SECRET: String must contain at least 32 character(s)
```

## 选项

```typescript
createZodValidate(schema, {
  // 验证失败时是否抛出错误（默认 true）
  throwOnError: true,
  
  // 自定义错误格式化
  formatError: (error) => `Custom error: ${error.message}`,
});
```
npm package: @svton/nestjs-http
Description: NestJS HTTP response/exception standardization module
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-http

NestJS HTTP 响应/异常规范化模块。

## 功能

- 统一响应格式 `{ code, message, data, traceId, timestamp }`
- 全局异常处理
- Prisma 错误自动映射
- 可配置的 traceId 获取

## 安装

```bash
pnpm add @svton/nestjs-http
```

## 使用

```typescript
import { Module } from '@nestjs/common';
import { HttpModule } from '@svton/nestjs-http';

@Module({
  imports: [
    HttpModule.forRoot({
      successCode: 0,
      successMessage: 'success',
      includeTimestamp: true,
      excludePaths: ['/health', '/metrics'],
    }),
  ],
})
export class AppModule {}
```

## 响应格式

### 成功响应

```json
{
  "code": 0,
  "message": "success",
  "data": { ... },
  "traceId": "abc123",
  "timestamp": "2024-01-01T00:00:00.000Z"
}
```

### 错误响应

```json
{
  "code": 404,
  "message": "Record not found",
  "data": null,
  "traceId": "abc123",
  "timestamp": "2024-01-01T00:00:00.000Z"
}
```

## Prisma 错误映射

| Prisma Code | HTTP Status | 说明 |
|-------------|-------------|------|
| P2002 | 409 Conflict | 唯一约束冲突 |
| P2001/P2025 | 404 Not Found | 记录不存在 |
| P2003 | 400 Bad Request | 外键约束失败 |
| P2011 | 400 Bad Request | 必填字段缺失 |
| P1001-P1003 | 503 Service Unavailable | 数据库连接错误 |

## 配置选项

| 选项 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| enableExceptionFilter | boolean | true | 启用全局异常过滤器 |
| enableResponseInterceptor | boolean | true | 启用全局响应拦截器 |
| successCode | number | 0 | 成功响应 code |
| successMessage | string | 'success' | 成功响应消息 |
| includeTimestamp | boolean | true | 包含时间戳 |
| getTraceId | function | - | 自定义 traceId 获取 |
| excludePaths | (string\|RegExp)[] | - | 排除响应包装的路径 |
npm package: @svton/nestjs-object-storage
Description: NestJS object storage module with multi-provider adapter support
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-object-storage

NestJS 对象存储模块，支持多云厂商适配器。

## 安装

```bash
pnpm add @svton/nestjs-object-storage
# 安装对应厂商 adapter
pnpm add @svton/nestjs-object-storage-qiniu-kodo
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ObjectStorageModule } from '@svton/nestjs-object-storage';
import { createQiniuAdapter } from '@svton/nestjs-object-storage-qiniu-kodo';

@Module({
  imports: [
    ObjectStorageModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        defaultBucket: config.get('QINIU_BUCKET'),
        publicBaseUrl: config.get('QINIU_CDN_URL'),
        adapter: createQiniuAdapter({
          accessKey: config.get('QINIU_ACCESS_KEY'),
          secretKey: config.get('QINIU_SECRET_KEY'),
          bucket: config.get('QINIU_BUCKET'),
          region: config.get('QINIU_REGION'),
        }),
      }),
    }),
  ],
})
export class AppModule {}
```

### 服务注入

```typescript
import { Injectable } from '@nestjs/common';
import { InjectObjectStorage, ObjectStorageClient } from '@svton/nestjs-object-storage';

@Injectable()
export class UploadService {
  constructor(
    @InjectObjectStorage() private readonly storage: ObjectStorageClient,
  ) {}

  async getUploadUrl(key: string) {
    return this.storage.presign({
      key,
      method: 'PUT',
      expiresIn: 3600,
    });
  }

  async verifyCallback(input: VerifyCallbackInput) {
    return this.storage.verifyCallback(input);
  }
}
```

## API

### ObjectStorageClient

- `putObject(input)` - 上传对象
- `deleteObject(input)` - 删除对象
- `getPublicUrl(input)` - 获取公开访问 URL
- `presign(input)` - 生成预签名 URL
- `verifyCallback(input)` - 验证回调签名

## 适配器

- `@svton/nestjs-object-storage-qiniu-kodo` - 七牛云
- `@svton/nestjs-object-storage-aliyun-oss` - 阿里云 OSS
- `@svton/nestjs-object-storage-tencent-cos` - 腾讯云 COS
- `@svton/nestjs-object-storage-s3` - AWS S3
npm package: @svton/nestjs-object-storage-qiniu-kodo
Description: Qiniu Kodo adapter for @svton/nestjs-object-storage
Author: SVTON Team
Latest version: 3.0.0

# @svton/nestjs-object-storage-qiniu-kodo

七牛云 Kodo 对象存储适配器，用于 `@svton/nestjs-object-storage`。

## 安装

```bash
pnpm add @svton/nestjs-object-storage @svton/nestjs-object-storage-qiniu-kodo
```

## 使用

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { ObjectStorageModule } from '@svton/nestjs-object-storage';
import { createQiniuAdapter } from '@svton/nestjs-object-storage-qiniu-kodo';

@Module({
  imports: [
    ObjectStorageModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        defaultBucket: config.get('QINIU_BUCKET'),
        publicBaseUrl: config.get('QINIU_CDN_URL'),
        adapter: createQiniuAdapter({
          accessKey: config.get('QINIU_ACCESS_KEY'),
          secretKey: config.get('QINIU_SECRET_KEY'),
          bucket: config.get('QINIU_BUCKET'),
          region: config.get('QINIU_REGION'), // z0/z1/z2/na0/as0/cn-east-2
          publicDomain: config.get('QINIU_CDN_URL'),
        }),
      }),
    }),
  ],
})
export class AppModule {}
```

## 配置选项

| 选项 | 类型 | 必填 | 说明 |
|------|------|------|------|
| accessKey | string | ✅ | 七牛 Access Key |
| secretKey | string | ✅ | 七牛 Secret Key |
| bucket | string | ✅ | 默认 Bucket |
| region | string | ❌ | 区域（z0/z1/z2/na0/as0/cn-east-2） |
| publicDomain | string | ❌ | CDN 域名（用于生成公开 URL） |
| uploadDomain | string | ❌ | 上传域名（默认使用区域配置） |

## 回调验签

```typescript
@Controller('object-storage')
export class ObjectStorageCallbackController {
  constructor(
    @InjectObjectStorage() private readonly storage: ObjectStorageClient,
  ) {}

  @Post('callback')
  async handleCallback(@Req() req: RawBodyRequest<Request>) {
    const result = await this.storage.verifyCallback({
      method: req.method,
      path: req.path,
      query: req.query as Record<string, string | string[]>,
      headers: req.headers as Record<string, string | string[]>,
      rawBody: req.rawBody!,
    });

    if (!result.isValid) {
      throw new UnauthorizedException('Invalid callback signature');
    }

    // 处理业务逻辑
    return { success: true, key: result.key };
  }
}
```
npm package: @svton/nestjs-queue
Description: NestJS queue module with BullMQ support and simplified API
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-queue

NestJS 队列模块，基于 BullMQ，简化任务队列使用。

## 安装

```bash
pnpm add @svton/nestjs-queue bullmq
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { QueueModule } from '@svton/nestjs-queue';

@Module({
  imports: [
    QueueModule.forRoot({
      connection: {
        host: 'localhost',
        port: 6379,
      },
      prefix: 'queue',
      defaultJobOptions: {
        removeOnComplete: true,
        removeOnFail: false,
      },
    }),
  ],
})
export class AppModule {}
```

### 添加任务

```typescript
import { Injectable } from '@nestjs/common';
import { QueueService } from '@svton/nestjs-queue';

@Injectable()
export class EmailService {
  constructor(private readonly queueService: QueueService) {}

  async sendEmail(to: string, subject: string) {
    await this.queueService.addJob('email', 'send', {
      to,
      subject,
    }, {
      delay: 1000,        // 延迟 1 秒
      attempts: 3,        // 重试 3 次
      backoff: {
        type: 'exponential',
        delay: 1000,
      },
    });
  }
}
```

### 处理任务

```typescript
import { Injectable, OnModuleInit } from '@nestjs/common';
import { QueueService, Job } from '@svton/nestjs-queue';

@Injectable()
export class EmailProcessor implements OnModuleInit {
  constructor(private readonly queueService: QueueService) {}

  onModuleInit() {
    this.queueService.registerWorker('email', async (job: Job) => {
      const { to, subject } = job.data;
      // 发送邮件逻辑
      console.log(`Sending email to ${to}: ${subject}`);
    }, 5); // 并发数 5
  }
}
```

### 注入特定队列

```typescript
import { Injectable } from '@nestjs/common';
import { InjectQueue, Queue } from '@svton/nestjs-queue';

@Injectable()
export class EmailService {
  constructor(@InjectQueue('email') private emailQueue: Queue) {}

  async sendEmail(data: EmailData) {
    await this.emailQueue.add('send', data);
  }
}
```

需要先注册队列：

```typescript
QueueModule.registerQueue('email', 'notification')
```

## License

MIT
npm package: @svton/nestjs-rate-limit
Description: NestJS rate limiting module with Redis support (sliding window, token bucket)
Author: SVTON Team
Latest version: 2.0.0

# @svton/nestjs-rate-limit

NestJS 限流模块，基于 Redis，支持滑动窗口、固定窗口、令牌桶算法。

## 安装

```bash
pnpm add @svton/nestjs-rate-limit @svton/nestjs-redis
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { RedisModule } from '@svton/nestjs-redis';
import { RateLimitModule } from '@svton/nestjs-rate-limit';

@Module({
  imports: [
    RedisModule.forRoot({ host: 'localhost', port: 6379 }),
    RateLimitModule.forRoot({
      algorithm: 'sliding-window', // 'sliding-window' | 'fixed-window' | 'token-bucket'
      windowSec: 60,               // 时间窗口 (秒)
      limit: 100,                  // 窗口内最大请求数
      prefix: 'ratelimit',         // Key 前缀
    }),
  ],
})
export class AppModule {}
```

### @RateLimit - 自定义限流

```typescript
import { Controller, Get, Post } from '@nestjs/common';
import { RateLimit, SkipRateLimit } from '@svton/nestjs-rate-limit';

@Controller('api')
export class ApiController {
  @RateLimit({ limit: 10, windowSec: 60 })
  @Get('data')
  async getData() {}

  @RateLimit({ limit: 5, windowSec: 60, key: 'login' })
  @Post('login')
  async login() {}

  @SkipRateLimit()
  @Get('health')
  async health() {}
}
```

### 响应头

限流信息会自动添加到响应头：

- `X-RateLimit-Limit` - 总限制数
- `X-RateLimit-Remaining` - 剩余请求数
- `X-RateLimit-Reset` - 重置时间 (Unix timestamp)

## 算法说明

| 算法 | 说明 |
|------|------|
| `sliding-window` | 滑动窗口，平滑限流，推荐使用 |
| `fixed-window` | 固定窗口，简单高效，可能有边界突发 |
| `token-bucket` | 令牌桶，允许一定程度的突发流量 |

## License

MIT
npm package: @svton/nestjs-redis
Description: NestJS Redis module with connection management and cache service
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-redis

NestJS Redis 模块，提供连接管理和轻量级缓存服务。

## 安装

```bash
pnpm add @svton/nestjs-redis
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { RedisModule } from '@svton/nestjs-redis';

@Module({
  imports: [
    RedisModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        url: config.get('REDIS_URL'),
        // 或者分开配置
        // host: config.get('REDIS_HOST'),
        // port: config.get('REDIS_PORT'),
        // password: config.get('REDIS_PASSWORD'),
        keyPrefix: 'myapp:',
        defaultTtl: 3600,
      }),
    }),
  ],
})
export class AppModule {}
```

### 使用 Redis 客户端

```typescript
import { Injectable } from '@nestjs/common';
import { InjectRedis, Redis } from '@svton/nestjs-redis';

@Injectable()
export class MyService {
  constructor(@InjectRedis() private readonly redis: Redis) {}

  async doSomething() {
    await this.redis.set('key', 'value');
    const value = await this.redis.get('key');
    return value;
  }
}
```

### 使用 CacheService

```typescript
import { Injectable } from '@nestjs/common';
import { CacheService } from '@svton/nestjs-redis';

@Injectable()
export class UserService {
  constructor(private readonly cache: CacheService) {}

  async getUser(id: string) {
    // 尝试从缓存获取
    const cached = await this.cache.get<User>(`user:${id}`);
    if (cached) return cached;

    // 从数据库获取
    const user = await this.findUserFromDb(id);
    
    // 写入缓存（1小时过期）
    await this.cache.set(`user:${id}`, user, 3600);
    
    return user;
  }
}
```

## CacheService API

| 方法 | 说明 |
|------|------|
| `get<T>(key)` | 获取缓存值（自动 JSON 反序列化） |
| `set(key, value, ttl?)` | 设置缓存值（自动 JSON 序列化） |
| `del(key)` | 删除缓存 |
| `delByPattern(pattern)` | 批量删除（支持通配符） |
| `exists(key)` | 检查 key 是否存在 |
| `expire(key, ttl)` | 设置过期时间 |
| `ttl(key)` | 获取剩余过期时间 |
| `incr(key)` | 自增 |
| `decr(key)` | 自减 |

## 配置选项

| 选项 | 类型 | 说明 |
|------|------|------|
| url | string | Redis 连接 URL |
| host | string | Redis 主机 |
| port | number | Redis 端口 |
| password | string | Redis 密码 |
| db | number | 数据库索引 |
| keyPrefix | string | 缓存 key 前缀 |
| defaultTtl | number | 默认 TTL（秒） |
npm package: @svton/nestjs-sms
Description: NestJS SMS module with multi-provider adapter support
Author: SVTON Team
Latest version: 1.2.0

# @svton/nestjs-sms

NestJS 短信模块，支持多厂商适配器。

## 安装

```bash
pnpm add @svton/nestjs-sms
# 安装对应厂商 adapter
pnpm add @svton/nestjs-sms-aliyun
```

## 使用

### 模块注册

```typescript
import { Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { SmsModule } from '@svton/nestjs-sms';
import { createAliyunSmsAdapter } from '@svton/nestjs-sms-aliyun';

@Module({
  imports: [
    SmsModule.forRootAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: (config: ConfigService) => ({
        defaultSignName: config.get('SMS_SIGN_NAME'),
        adapter: createAliyunSmsAdapter({
          accessKeyId: config.get('ALIYUN_ACCESS_KEY_ID'),
          accessKeySecret: config.get('ALIYUN_ACCESS_KEY_SECRET'),
          signName: config.get('SMS_SIGN_NAME'),
        }),
      }),
    }),
  ],
})
export class AppModule {}
```

### 服务注入

```typescript
import { Injectable } from '@nestjs/common';
import { InjectSms, SmsClient } from '@svton/nestjs-sms';

@Injectable()
export class AuthService {
  constructor(@InjectSms() private readonly sms: SmsClient) {}

  async sendVerificationCode(phone: string, code: string) {
    const result = await this.sms.send({
      phone,
      templateId: 'SMS_123456789',
      params: { code },
    });

    if (!result.success) {
      throw new Error(`Failed to send SMS: ${result.message}`);
    }

    return result;
  }
}
```

## API

### SmsClient

```typescript
interface SmsClient {
  send(input: SendSmsInput): Promise<SendSmsOutput>;
}

interface SendSmsInput {
  phone: string | string[];  // 支持批量发送
  templateId: string;
  params?: Record<string, string>;
  signName?: string;  // 可选，覆盖默认签名
}

interface SendSmsOutput {
  success: boolean;
  messageId?: string;
  code?: string;
  message?: string;
  raw?: unknown;
}
```

## 适配器

- `@svton/nestjs-sms-aliyun` - 阿里云短信
- `@svton/nestjs-sms-tencent` - 腾讯云短信
- `@svton/nestjs-sms-huawei` - 华为云短信

## 创建自定义适配器

```typescript
import { SmsAdapter, SmsClient, SendSmsInput, SendSmsOutput } from '@svton/nestjs-sms';

class MySmsClient implements SmsClient {
  async send(input: SendSmsInput): Promise<SendSmsOutput> {
    // 实现发送逻辑
    return { success: true, messageId: 'xxx' };
  }
}

class MySmsAdapter implements SmsAdapter {
  readonly name = 'my-sms';

  createClient(): SmsClient {
    return new MySmsClient();
  }
}

export function createMySmsAdapter(): SmsAdapter {
  return new MySmsAdapter();
}
```
npm package: @svtslv/nestjs-ioredis
Description: Nest - modern, fast, powerful node.js web framework (@ioredis)
Author: Sviatoslav H
Latest version: 1.0.2

# NestJS IORedis

<a href="https://www.npmjs.com/package/@svtslv/nestjs-ioredis"><img src="https://img.shields.io/npm/v/@svtslv/nestjs-ioredis.svg" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/package/@svtslv/nestjs-ioredis"><img src="https://img.shields.io/npm/l/@svtslv/nestjs-ioredis.svg" alt="Package License" /></a>

## Table of Contents

- [Description](#description)
- [Installation](#installation)
- [Examples](#examples)
- [License](#license)

## Description
Integrates IORedis with Nest

## Installation

```bash
npm install @svtslv/nestjs-ioredis ioredis
```

```bash
npm install -D @types/ioredis
```

You can also use the interactive CLI

```sh
npx nestjs-modules
```

## Examples

```sh
docker run -p 6379:6379 redis
```

### RedisModule.forRoot(options, connection?)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@svtslv/nestjs-ioredis';
import { AppController } from './app.controller';

@Module({
  imports: [
    RedisModule.forRoot({
      config: { 
        // host: 'localhost',
        // port: 6379,
        url: 'redis://localhost:6379',
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

### RedisModule.forRootAsync(options, connection?)

```ts
import { Module } from '@nestjs/common';
import { RedisModule } from '@svtslv/nestjs-ioredis';
import { AppController } from './app.controller';

@Module({
  imports: [
    RedisModule.forRootAsync({
      useFactory: () => ({
        config: { 
          // host: 'localhost',
          // port: 6379,
          url: 'redis://localhost:6379',
        },
      }),
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

### InjectRedis(connection?)

```ts
import { Controller, Get, } from '@nestjs/common';
import { InjectRedis, Redis } from '@svtslv/nestjs-ioredis';

@Controller()
export class AppController {
  constructor(
    @InjectRedis() private readonly redis: Redis,
  ) {}

  @Get()
  async getHello() {
    await this.redis.set('key', 'Redis data!');
    const redisData = await this.redis.get("key");
    return { redisData };
  }
}
```

## License

MIT
npm package: @svtslv/nestjs-minio
Description: Nest - modern, fast, powerful node.js web framework (@minio)
Author: Sviatoslav H
Latest version: 1.0.1

# NestJS Minio

<a href="https://www.npmjs.com/package/@svtslv/nestjs-minio"><img src="https://img.shields.io/npm/v/@svtslv/nestjs-minio" alt="NPM Version" /></a>
<a href="https://www.npmjs.com/package/@svtslv/nestjs-minio"><img src="https://img.shields.io/npm/l/@svtslv/nestjs-minio" alt="Package License" /></a>

## Table of Contents

- [Description](#description)
- [Installation](#installation)
- [Examples](#examples)
- [License](#license)

## Description
Integrates Minio with Nest

## Installation

```bash
npm install @svtslv/minio minio
```

```bash
npm install -D @types/minio
```

You can also use the interactive CLI

```sh
npx nestjs-modules
```

## Examples

```bash
docker run \
-p 9000:9000 \
-e MINIO_ACCESS_KEY=minio \
-e MINIO_SECRET_KEY=password \
minio/minio server /data
```

### MinioModule.forRoot(options, connection?)

```ts
import { Module } from '@nestjs/common';
import { MinioModule } from '@svtslv/nestjs-minio';
import { AppController } from './app.controller';

@Module({
  imports: [
    MinioModule.forRoot({
      config: {
        // url: 'http://minio:password@localhost:9000',
        accessKey: 'minio',
        secretKey: 'password',
        endPoint: 'localhost',
        port: 9000,
        useSSL: false,
      },
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

### MinioModule.forRootAsync(options, connection?)

```ts
import { Module } from '@nestjs/common';
import { MinioModule } from '@svtslv/nestjs-minio';
import { AppController } from './app.controller';

@Module({
  imports: [
    MinioModule.forRootAsync({
      useFactory: () => ({
        config: {
          // url: 'http://minio:password@localhost:9000',
          accessKey: 'minio',
          secretKey: 'password',
          endPoint: 'localhost',
          port: 9000,
          useSSL: false,
        },
      }),
    }),
  ],
  controllers: [AppController],
})
export class AppModule {}
```

### InjectMinioClient(connection?)

```ts
import { Controller, Get, } from '@nestjs/common';
import { InjectMinioClient, MinioClient } from '@svtslv/nestjs-minio';

@Controller()
export class AppController {
  constructor(
    @InjectMinioClient() private readonly minioClient: MinioClient,
  ) {}

  @Get()
  async getHello() {
    if(!await this.minioClient.bucketExists('bucket2')) {
      await this.minioClient.makeBucket('bucket2', '');
    }

    return await this.minioClient.listBuckets()
  }
}
```

## License

MIT