refactor: use all in one egg v4 (#855)
required https://github.com/eggjs/egg/pull/5654 --------- Signed-off-by: MK (fengmk2) <fengmk2@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -2,6 +2,6 @@
|
||||
|
||||
node -v && npm -v \
|
||||
&& npm install -g npminstall --registry=https://registry.npmmirror.com \
|
||||
&& NODE_DEBUG=egg-bin*,egg/bin* npminstall -c --foreground-scripts \
|
||||
&& npminstall -c \
|
||||
&& npm run tsc \
|
||||
&& npmupdate -c --production
|
||||
|
||||
3
.github/copilot-instructions.md
vendored
3
.github/copilot-instructions.md
vendored
@@ -424,8 +424,7 @@ These adapters allow cnpmcore to integrate with different cloud providers and en
|
||||
**Example Controller Implementation:**
|
||||
```typescript
|
||||
import { AbstractController } from './AbstractController';
|
||||
import { Inject } from '@eggjs/tegg';
|
||||
import { HTTPController, HTTPMethod, HTTPQuery } from '@eggjs/tegg-controller-plugin';
|
||||
import { HTTPController, HTTPMethod, HTTPQuery, Inject } from 'egg';
|
||||
|
||||
@HTTPController()
|
||||
export class YourController extends AbstractController {
|
||||
|
||||
14
.github/workflows/nodejs.yml
vendored
14
.github/workflows/nodejs.yml
vendored
@@ -14,6 +14,10 @@ jobs:
|
||||
typecheck:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
concurrency:
|
||||
group: typecheck-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
steps:
|
||||
- name: Checkout Git Source
|
||||
uses: actions/checkout@v5
|
||||
@@ -46,6 +50,9 @@ jobs:
|
||||
shardTotal: [3]
|
||||
|
||||
name: test on postgresql (node@${{ matrix.node-version }}, shard@${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
|
||||
concurrency:
|
||||
group: test-postgresql-fs-nfs-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}-${{ matrix.node-version }}-${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
cancel-in-progress: true
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -139,6 +146,9 @@ jobs:
|
||||
shardTotal: [3]
|
||||
|
||||
name: test on mysql (node@${{ matrix.node-version }}, shard@${{ matrix.shardIndex }}/${{ matrix.shardTotal }})
|
||||
concurrency:
|
||||
group: test-mysql57-fs-nfs-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}-${{ matrix.node-version }}-${{ matrix.shardIndex }}/${{ matrix.shardTotal }}
|
||||
cancel-in-progress: true
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
@@ -190,6 +200,10 @@ jobs:
|
||||
node-version: [20, 22]
|
||||
os: [ubuntu-latest]
|
||||
|
||||
concurrency:
|
||||
group: test-mysql57-s3-nfs-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}-${{ matrix.node-version }}
|
||||
cancel-in-progress: true
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
services:
|
||||
|
||||
3
.github/workflows/release-image.yml
vendored
3
.github/workflows/release-image.yml
vendored
@@ -17,6 +17,9 @@ env:
|
||||
jobs:
|
||||
build-and-push-image:
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: build-and-push-image-${{ github.workflow }}-#${{ github.event.pull_request.number || github.head_ref || github.ref }}
|
||||
cancel-in-progress: true
|
||||
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
270
CLAUDE.md
Normal file
270
CLAUDE.md
Normal file
@@ -0,0 +1,270 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
cnpmcore is a TypeScript-based private NPM registry implementation for enterprise use. It's built on the Egg.js framework using Domain-Driven Design (DDD) architecture principles and supports both MySQL and PostgreSQL databases.
|
||||
|
||||
## Essential Commands
|
||||
|
||||
### Development
|
||||
```bash
|
||||
# Start development server (MySQL)
|
||||
npm run dev
|
||||
|
||||
# Start development server (PostgreSQL)
|
||||
npm run dev:postgresql
|
||||
|
||||
# Lint code
|
||||
npm run lint
|
||||
|
||||
# Fix linting issues
|
||||
npm run lint:fix
|
||||
|
||||
# TypeScript type checking
|
||||
npm run typecheck
|
||||
```
|
||||
|
||||
### Testing
|
||||
```bash
|
||||
# Run all tests with MySQL (takes 4+ minutes)
|
||||
npm run test
|
||||
|
||||
# Run all tests with PostgreSQL (takes 4+ minutes)
|
||||
npm run test:postgresql
|
||||
|
||||
# Run single test file (faster iteration, ~12 seconds)
|
||||
npm run test:local test/path/to/file.test.ts
|
||||
|
||||
# Generate coverage report
|
||||
npm run cov
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
```bash
|
||||
# MySQL setup
|
||||
docker compose -f docker-compose.yml up -d
|
||||
CNPMCORE_DATABASE_NAME=cnpmcore bash ./prepare-database-mysql.sh
|
||||
|
||||
# PostgreSQL setup
|
||||
docker compose -f docker-compose-postgres.yml up -d
|
||||
CNPMCORE_DATABASE_NAME=cnpmcore bash ./prepare-database-postgresql.sh
|
||||
```
|
||||
|
||||
### Build
|
||||
```bash
|
||||
# Clean build artifacts
|
||||
npm run clean
|
||||
|
||||
# Development build
|
||||
npm run tsc
|
||||
|
||||
# Production build
|
||||
npm run tsc:prod
|
||||
```
|
||||
|
||||
## Architecture - Domain-Driven Design (DDD)
|
||||
|
||||
The codebase follows strict DDD layering with clear separation of concerns:
|
||||
|
||||
```
|
||||
Controller (app/port/controller/) ← HTTP interface, validation, auth
|
||||
↓ depends on
|
||||
Service (app/core/service/) ← Business logic orchestration
|
||||
↓ depends on
|
||||
Repository (app/repository/) ← Data access layer
|
||||
↓ depends on
|
||||
Model (app/repository/model/) ← ORM/Database mapping
|
||||
|
||||
Entity (app/core/entity/) ← Pure domain models (no dependencies)
|
||||
Common (app/common/) ← Utilities and adapters (all layers)
|
||||
```
|
||||
|
||||
### Layer Responsibilities
|
||||
|
||||
**Controller Layer** (`app/port/controller/`):
|
||||
- Handle HTTP requests/responses
|
||||
- Validate inputs using `@eggjs/typebox-validate`
|
||||
- Authenticate users and verify authorization
|
||||
- Delegate business logic to Services
|
||||
- All controllers extend `AbstractController`
|
||||
|
||||
**Service Layer** (`app/core/service/`):
|
||||
- Implement core business logic
|
||||
- Orchestrate multiple repositories
|
||||
- Publish domain events
|
||||
- Manage transactions
|
||||
|
||||
**Repository Layer** (`app/repository/`):
|
||||
- CRUD operations on Models
|
||||
- Data access and persistence
|
||||
- Query building and optimization
|
||||
- Methods named: `findX`, `saveX`, `removeX`, `listXs`
|
||||
|
||||
**Entity Layer** (`app/core/entity/`):
|
||||
- Pure domain models with business behavior
|
||||
- No infrastructure dependencies
|
||||
- Immutable data structures preferred
|
||||
|
||||
**Model Layer** (`app/repository/model/`):
|
||||
- ORM definitions using Leoric
|
||||
- Database schema mapping
|
||||
- No business logic
|
||||
|
||||
### Infrastructure Adapters (`app/infra/`)
|
||||
Enterprise customization layer for PaaS integration:
|
||||
- **NFSClientAdapter**: File storage (local/S3/OSS)
|
||||
- **QueueAdapter**: Message queue integration
|
||||
- **AuthAdapter**: Authentication system
|
||||
- **BinaryAdapter**: Binary package storage
|
||||
|
||||
## Key Development Patterns
|
||||
|
||||
### Request Validation Trilogy
|
||||
Always validate requests in this exact order:
|
||||
1. **Parameter Validation** - Use `@eggjs/typebox-validate` for type-safe validation
|
||||
2. **Authentication** - Get authorized user with token role verification
|
||||
3. **Authorization** - Check resource-level permissions to prevent privilege escalation
|
||||
|
||||
```typescript
|
||||
// Example controller method
|
||||
async someMethod(@HTTPQuery() params: QueryType) {
|
||||
// 1. Params already validated by @HTTPQuery with typebox
|
||||
// 2. Authenticate
|
||||
const user = await this.userRoleManager.requiredAuthorizedUser(this.ctx, 'publish');
|
||||
// 3. Authorize (if needed)
|
||||
const { pkg } = await this.ensurePublishAccess(this.ctx, fullname);
|
||||
// 4. Execute business logic
|
||||
return await this.service.doSomething(params);
|
||||
}
|
||||
```
|
||||
|
||||
### Repository Method Naming
|
||||
- `findSomething` - Query single entity
|
||||
- `saveSomething` - Create or update entity
|
||||
- `removeSomething` - Delete entity
|
||||
- `listSomethings` - Query multiple entities (plural)
|
||||
|
||||
### Modifying Database Models
|
||||
When changing a Model, update all 3 locations:
|
||||
1. SQL migrations: `sql/mysql/*.sql` AND `sql/postgresql/*.sql`
|
||||
2. ORM Model: `app/repository/model/*.ts`
|
||||
3. Domain Entity: `app/core/entity/*.ts`
|
||||
|
||||
## Code Style
|
||||
|
||||
### Linting
|
||||
- **Linter**: Oxlint (Rust-based, very fast)
|
||||
- **Formatter**: Prettier
|
||||
- **Pre-commit**: Husky + lint-staged (auto-format on commit)
|
||||
|
||||
Style rules:
|
||||
- Single quotes (`'`)
|
||||
- 2-space indentation
|
||||
- 120 character line width
|
||||
- ES5 trailing commas
|
||||
- Max 6 function parameters
|
||||
- No console statements (use logger)
|
||||
|
||||
### TypeScript
|
||||
- Strict TypeScript enabled
|
||||
- Avoid `any` types - use proper typing or `unknown`
|
||||
- ES modules (`import/export`) throughout
|
||||
- Comprehensive type definitions in all files
|
||||
|
||||
### Testing
|
||||
- Test files use `.test.ts` suffix
|
||||
- Tests mirror source structure in `test/` directory
|
||||
- Use `@eggjs/mock` for mocking
|
||||
- Use `assert` from `node:assert/strict`
|
||||
- Test both success and error cases
|
||||
|
||||
Pattern:
|
||||
```typescript
|
||||
describe('test/path/to/SourceFile.test.ts', () => {
|
||||
describe('[HTTP_METHOD /api/path] functionName()', () => {
|
||||
it('should handle expected behavior', async () => {
|
||||
// Test implementation
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
app/
|
||||
├── common/ # Global utilities and adapters
|
||||
│ ├── adapter/ # External service adapters
|
||||
│ └── enum/ # Shared enumerations
|
||||
├── core/ # Business logic layer
|
||||
│ ├── entity/ # Domain models
|
||||
│ ├── event/ # Event handlers
|
||||
│ ├── service/ # Business services
|
||||
│ └── util/ # Internal utilities
|
||||
├── port/ # Interface layer
|
||||
│ ├── controller/ # HTTP controllers
|
||||
│ ├── middleware/ # Middleware
|
||||
│ └── schedule/ # Background jobs
|
||||
├── repository/ # Data access layer
|
||||
│ └── model/ # ORM models
|
||||
└── infra/ # Infrastructure adapters
|
||||
|
||||
config/ # Configuration files
|
||||
sql/ # Database migrations
|
||||
├── mysql/ # MySQL migrations
|
||||
└── postgresql/ # PostgreSQL migrations
|
||||
test/ # Test files (mirrors app/ structure)
|
||||
```
|
||||
|
||||
## Important Configuration
|
||||
|
||||
- `config/config.default.ts` - Main application configuration
|
||||
- `config/database.ts` - Database connection settings
|
||||
- `config/binaries.ts` - Binary package mirror configurations
|
||||
- `.env` - Environment-specific variables (copy from `.env.example`)
|
||||
- `tsconfig.json` - TypeScript settings (target: ES2021 for Leoric compatibility)
|
||||
|
||||
## Development Workflow
|
||||
|
||||
1. **Setup**: Copy `.env.example` to `.env`, start Docker services, initialize database
|
||||
2. **Feature Development**: Follow bottom-up approach (Model → Entity → Repository → Service → Controller)
|
||||
3. **Testing**: Write tests at appropriate layer, run individual tests for fast iteration
|
||||
4. **Validation**: Run linter, typecheck, relevant tests before committing
|
||||
5. **Commit**: Use semantic commit messages (feat/fix/docs/test/chore)
|
||||
|
||||
## Integration as NPM Package
|
||||
|
||||
cnpmcore can be integrated into Egg.js/Tegg applications as an NPM package, allowing enterprises to:
|
||||
- Customize infrastructure adapters (storage, auth, queue)
|
||||
- Override default behavior while receiving updates
|
||||
- Integrate with existing enterprise systems
|
||||
|
||||
See INTEGRATE.md for detailed integration guide.
|
||||
|
||||
## Performance Notes
|
||||
|
||||
Typical command execution times:
|
||||
- Development server startup: ~20 seconds
|
||||
- TypeScript build: ~6 seconds
|
||||
- Full test suite: 4-15 minutes
|
||||
- Single test file: ~12 seconds
|
||||
- Linting: <1 second
|
||||
- Database initialization: <2 seconds
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Node.js: 20.18.0+ or 22.18.0+
|
||||
- Database: MySQL 5.7+ or PostgreSQL 17+
|
||||
- Cache: Redis 6+
|
||||
- Optional: Elasticsearch 8.x
|
||||
|
||||
## Key Services & Controllers
|
||||
|
||||
Core components to understand:
|
||||
- **PackageController**: Package CRUD operations
|
||||
- **PackageManagerService**: Core package management logic
|
||||
- **BinarySyncerService**: Binary package synchronization
|
||||
- **ChangesStreamService**: NPM registry change stream processing
|
||||
- **UserController**: User authentication and profiles
|
||||
199
INTEGRATE.md
199
INTEGRATE.md
@@ -1,14 +1,14 @@
|
||||
# 🥚 如何在 [tegg](https://github.com/eggjs/tegg) 中集成 cnpmcore
|
||||
# 🥚 如何在 [tegg](https://github.com/eggjs/egg/blob/next/tegg) 中集成 cnpmcore
|
||||
|
||||
> 文档中的示例项目可以在 [这里](https://github.com/eggjs/examples/commit/bed580fe053ae573f8b63f6788002ff9c6e7a142) 查看,在开始前请确保已阅读 [DEVELOPER.md](DEVELOPER.md) 中的相关文档,完成本地开发环境搭建。
|
||||
|
||||
在生产环境中,我们也可以直接部署 cnpmcore 系统,实现完整的 Registry 镜像功能。
|
||||
但通常,在企业内部会有一些内部的中间件服务或限制,例如文件存储、缓存服务、登录鉴权流程等。
|
||||
|
||||
除了源码部署、二次开发的方式,我们还提供了 npm 包的方式,便于 [tegg](https://github.com/eggjs/tegg) 应用集成。
|
||||
除了源码部署、二次开发的方式,我们还提供了 npm 包的方式,便于 [tegg](https://github.com/eggjs/egg/blob/next/tegg) 应用集成。
|
||||
这样既可以享受到丰富的自定义扩展能力,又可以享受到 cnpmcore 持续迭代的功能演进。
|
||||
|
||||
下面,让我们以 [tegg](https://github.com/eggjs/tegg) 初始化的应用为例,以 npm 包的方式集成 cnpmcore,并扩展登录功能,以支持企业内 [SSO](https://en.wikipedia.org/wiki/Single_sign-on) 登录。
|
||||
下面,让我们以 [tegg](https://github.com/eggjs/egg/blob/next/tegg) 初始化的应用为例,以 npm 包的方式集成 cnpmcore,并扩展登录功能,以支持企业内 [SSO](https://en.wikipedia.org/wiki/Single_sign-on) 登录。
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
@@ -34,49 +34,36 @@
|
||||
|
||||
### 📦︎ 安装 cnpmcore 修改对应配置
|
||||
|
||||
```shell
|
||||
npm i cnpmcore -S
|
||||
```
|
||||
```shell
|
||||
npm i cnpmcore
|
||||
```
|
||||
|
||||
1. 修改 `ts-config.json` 配置,这是因为 cnpmcore 使用了 [subPath](https://nodejs.org/api/packages.html#subpath-exports)
|
||||
|
||||
```json
|
||||
{
|
||||
"extends": "@eggjs/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"target": "ES2021"
|
||||
}
|
||||
}
|
||||
```
|
||||
```json
|
||||
{
|
||||
"extends": "@eggjs/tsconfig",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "./",
|
||||
"target": "ES2021"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
2. 修改 `config/plugin.ts` 文件,开启 cnpmcore 依赖的一些插件
|
||||
|
||||
```typescript
|
||||
// 开启如下插件
|
||||
{
|
||||
redis: {
|
||||
enable: true,
|
||||
package: '@eggjs/redis',
|
||||
},
|
||||
teggOrm: {
|
||||
enable: true,
|
||||
package: '@eggjs/tegg-orm-plugin',
|
||||
},
|
||||
eventbusModule: {
|
||||
enable: true,
|
||||
package: '@eggjs/tegg-eventbus-plugin',
|
||||
},
|
||||
tracer: {
|
||||
enable: true,
|
||||
package: '@eggjs/tracer',
|
||||
},
|
||||
typeboxValidate: {
|
||||
enable: true,
|
||||
package: '@eggjs/typebox-validate',
|
||||
},
|
||||
}
|
||||
```
|
||||
```typescript
|
||||
import tracerPlugin from '@eggjs/tracer';
|
||||
import typeboxValidatePlugin from '@eggjs/typebox-validate';
|
||||
import redisPlugin from '@eggjs/redis';
|
||||
|
||||
// 开启如下插件
|
||||
export default {
|
||||
...redisPlugin(),
|
||||
...tracerPlugin(),
|
||||
...typeboxValidatePlugin(),
|
||||
}
|
||||
```
|
||||
|
||||
3. 修改 `config.default.ts` 文件,可以直接覆盖默认配置
|
||||
|
||||
@@ -101,63 +88,63 @@ export default () => {
|
||||
|
||||
1. 创建文件夹,用于存放自定义的 infra module,这里以 app/infra 为例
|
||||
|
||||
```shell
|
||||
├── infra
|
||||
│ ├── AuthAdapter.ts
|
||||
│ ├── NFSAdapter.ts
|
||||
│ ├── QueueAdapter.ts
|
||||
│ └── package.json
|
||||
```
|
||||
```shell
|
||||
├── infra
|
||||
│ ├── AuthAdapter.ts
|
||||
│ ├── NFSAdapter.ts
|
||||
│ ├── QueueAdapter.ts
|
||||
│ └── package.json
|
||||
```
|
||||
|
||||
* 添加 `package.json` ,声明 infra 作为一个 eggModule 单元
|
||||
|
||||
```JSON
|
||||
{
|
||||
"name": "infra",
|
||||
"eggModule": {
|
||||
"name": "infra"
|
||||
}
|
||||
}
|
||||
```
|
||||
```JSON
|
||||
{
|
||||
"name": "infra",
|
||||
"eggModule": {
|
||||
"name": "infra"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
* 添加 `XXXAdapter.ts` 在对应的 Adapter 中继承 cnpmcore 默认的 Adapter,以 AuthAdapter 为例
|
||||
|
||||
```typescript
|
||||
import { AccessLevel, SingletonProto } from '@eggjs/tegg';
|
||||
import { AuthAdapter } from 'cnpmcore/infra/AuthAdapter';
|
||||
```typescript
|
||||
import { AccessLevel, SingletonProto } from 'egg';
|
||||
import { AuthAdapter } from 'cnpmcore/infra/AuthAdapter';
|
||||
|
||||
@SingletonProto({
|
||||
name: 'authAdapter',
|
||||
accessLevel: AccessLevel.PUBLIC,
|
||||
})
|
||||
export class MyAuthAdapter extends AuthAdapter {
|
||||
}
|
||||
```
|
||||
@SingletonProto({
|
||||
name: 'authAdapter',
|
||||
accessLevel: AccessLevel.PUBLIC,
|
||||
})
|
||||
export class MyAuthAdapter extends AuthAdapter {
|
||||
}
|
||||
```
|
||||
|
||||
2. 添加 `config/module.json`,将 cnpmcore 作为一个 module 集成进我们新增的 tegg 应用中
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"path": "../app/biz"
|
||||
},
|
||||
{
|
||||
"path": "../app/infra"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/common"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/core"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/port"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/repository"
|
||||
}
|
||||
]
|
||||
```
|
||||
```json
|
||||
[
|
||||
{
|
||||
"path": "../app/biz"
|
||||
},
|
||||
{
|
||||
"path": "../app/infra"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/common"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/core"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/port"
|
||||
},
|
||||
{
|
||||
"package": "cnpmcore/repository"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### ✍🏻 重载 AuthAdapter 实现
|
||||
|
||||
@@ -173,10 +160,10 @@ export default () => {
|
||||
修改 AuthAdapter.ts 文件
|
||||
|
||||
```typescript
|
||||
import { AccessLevel, EggContext, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Context, SingletonProto } from 'egg';
|
||||
import { AuthAdapter } from 'cnpmcore/infra/AuthAdapter';
|
||||
import { randomUUID } from 'crypto';
|
||||
import { AuthUrlResult, userResult } from 'node_modules/cnpmcore/dist/app/common/typing';
|
||||
import { AuthUrlResult, userResult } from 'cnpmcore/dist/app/common/typing';
|
||||
|
||||
const ONE_DAY = 3600 * 24;
|
||||
|
||||
@@ -185,7 +172,7 @@ const ONE_DAY = 3600 * 24;
|
||||
accessLevel: AccessLevel.PUBLIC,
|
||||
})
|
||||
export class MyAuthAdapter extends AuthAdapter {
|
||||
async getAuthUrl(ctx: EggContext): Promise<AuthUrlResult> {
|
||||
async getAuthUrl(ctx: Context): Promise<AuthUrlResult> {
|
||||
const sessionId = randomUUID();
|
||||
await this.redis.setex(sessionId, ONE_DAY, '');
|
||||
return {
|
||||
@@ -208,33 +195,33 @@ export class MyAuthAdapter extends AuthAdapter {
|
||||
修改 HelloController 的实现,实际也可以通过登录中心回调、页面确认等方式实现
|
||||
|
||||
```typescript
|
||||
// 触发回调接口,会自动完成用户创建
|
||||
await this.httpclient.request(`${ctx.origin}/-/v1/login/sso/${name}`, { method: 'POST' });
|
||||
// 触发回调接口,会自动完成用户创建
|
||||
await this.httpclient.request(`${ctx.origin}/-/v1/login/sso/${name}`, { method: 'POST' });
|
||||
```
|
||||
|
||||
## 🎉 功能验证
|
||||
|
||||
1. 在命令行输入 `npm login --registry=http://127.0.0.1:7001`
|
||||
|
||||
```shell
|
||||
npm login --registry=http://127.0.0.1:7001
|
||||
npm notice Log in on http://127.0.0.1:7001/
|
||||
Login at:
|
||||
http://127.0.0.1:7001/hello?name=e44e8c43-211a-4bcd-ae78-c4cbb1a78ae7
|
||||
Press ENTER to open in the browser...
|
||||
```
|
||||
```shell
|
||||
npm login --registry=http://127.0.0.1:7001
|
||||
npm notice Log in on http://127.0.0.1:7001/
|
||||
Login at:
|
||||
http://127.0.0.1:7001/hello?name=e44e8c43-211a-4bcd-ae78-c4cbb1a78ae7
|
||||
Press ENTER to open in the browser...
|
||||
```
|
||||
|
||||
2. 界面提示回车打开浏览器访问登录中心,也就是我们在 getAuthUrl,返回的 loginUrl 配置
|
||||
|
||||
3. 由于我们 mock 了对应实现,界面会直接显示登录成功
|
||||
|
||||
```shell
|
||||
Logged in on http://127.0.0.1:7001/.
|
||||
```
|
||||
```shell
|
||||
Logged in on http://127.0.0.1:7001/.
|
||||
```
|
||||
|
||||
4. 在命令行输入 `npm whoami --registry=http://127.0.0.1:7001` 验证
|
||||
|
||||
```shell
|
||||
npm whoami --registry=http://127.0.0.1:7001
|
||||
hello
|
||||
```
|
||||
```shell
|
||||
npm whoami --registry=http://127.0.0.1:7001
|
||||
hello
|
||||
```
|
||||
|
||||
2
app.ts
2
app.ts
@@ -20,7 +20,7 @@ export default class CnpmcoreAppHook implements ILifecycleBoot {
|
||||
|
||||
configWillLoad() {
|
||||
const app = this.app;
|
||||
// https://github.com/eggjs/tegg/blob/master/plugin/orm/app.ts#L37
|
||||
// https://github.com/eggjs/egg/blob/next/tegg/plugin/orm/src/app.ts#L37
|
||||
// store query sql to log
|
||||
app.config.orm.logger = {
|
||||
...app.config.orm.logger,
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import { Inject } from '@eggjs/tegg';
|
||||
import type { EggAppConfig, EggLogger } from 'egg';
|
||||
import { EggAppConfig, Logger, Inject } from 'egg';
|
||||
|
||||
export abstract class AbstractService {
|
||||
@Inject()
|
||||
protected readonly config: EggAppConfig;
|
||||
@Inject()
|
||||
protected readonly logger: EggLogger;
|
||||
protected readonly logger: Logger;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Readable } from 'node:stream';
|
||||
import { pipeline } from 'node:stream/promises';
|
||||
|
||||
import { fromData, fromStream, type HashLike } from 'ssri';
|
||||
// @ts-expect-error type error
|
||||
// @ts-expect-error no types available
|
||||
import tar from '@fengmk2/tar';
|
||||
|
||||
import type {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { EggContext } from '@eggjs/tegg';
|
||||
import type { Context } from 'egg';
|
||||
|
||||
export function isSyncWorkerRequest(ctx: EggContext) {
|
||||
export function isSyncWorkerRequest(ctx: Context) {
|
||||
// sync request will contain this query params
|
||||
let isSyncWorkerRequest = ctx.query.cache === '0';
|
||||
if (!isSyncWorkerRequest) {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AccessLevel, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, SingletonProto } from 'egg';
|
||||
|
||||
import type { BugVersion } from '../../core/entity/BugVersion.ts';
|
||||
|
||||
@SingletonProto({
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
// FIXME: @eggjs/redis should use ioredis v5
|
||||
// https://github.com/eggjs/redis/issues/35
|
||||
import type { Redis } from 'ioredis';
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { Readable } from 'node:stream';
|
||||
import type { IncomingHttpHeaders } from 'node:http';
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { Pointcut } from '@eggjs/tegg/aop';
|
||||
import type { EggLogger } from 'egg';
|
||||
|
||||
import { AccessLevel, Inject, SingletonProto, Logger } from 'egg';
|
||||
import { Pointcut } from 'egg/aop';
|
||||
|
||||
import { AsyncTimer } from '../aop/AsyncTimer.ts';
|
||||
import type { NFSClient } from '../typing.ts';
|
||||
|
||||
@@ -17,7 +18,7 @@ export class NFSAdapter {
|
||||
private readonly nfsClient: NFSClient;
|
||||
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
|
||||
@Pointcut(AsyncTimer)
|
||||
async uploadBytes(storeKey: string, bytes: Uint8Array) {
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { AccessLevel, ContextProto, Inject } from '@eggjs/tegg';
|
||||
import type {
|
||||
|
||||
import {
|
||||
ContextProto,
|
||||
AccessLevel, Inject,
|
||||
EggAppConfig,
|
||||
EggContextHttpClient,
|
||||
EggLogger,
|
||||
HttpClient,
|
||||
Logger,
|
||||
HttpClientRequestOptions,
|
||||
HttpClientResponse,
|
||||
} from 'egg';
|
||||
|
||||
import type { PackageManifestType } from '../../repository/PackageRepository.ts';
|
||||
import { isTimeoutError } from '../ErrorUtil.ts';
|
||||
|
||||
@@ -22,9 +25,9 @@ export type RegistryResponse = { method: HttpMethod } & HttpClientResponse;
|
||||
})
|
||||
export class NPMRegistry {
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
@Inject()
|
||||
private readonly httpclient: EggContextHttpClient;
|
||||
private readonly httpClient: HttpClient;
|
||||
@Inject()
|
||||
private config: EggAppConfig;
|
||||
private timeout = 10_000;
|
||||
@@ -127,7 +130,7 @@ export class NPMRegistry {
|
||||
params?: object,
|
||||
options?: object
|
||||
): Promise<RegistryResponse> {
|
||||
const res = (await this.httpclient.request(url, {
|
||||
const res = (await this.httpClient.request(url, {
|
||||
method,
|
||||
data: params,
|
||||
dataType: 'json',
|
||||
|
||||
@@ -2,8 +2,10 @@ import {
|
||||
Inject,
|
||||
QualifierImplDecoratorUtil,
|
||||
type ImplDecorator,
|
||||
} from '@eggjs/tegg';
|
||||
import type { EggHttpClient, EggLogger } from 'egg';
|
||||
HttpClient,
|
||||
Logger,
|
||||
} from 'egg';
|
||||
|
||||
import type { BinaryType } from '../../enum/Binary.ts';
|
||||
import type {
|
||||
BinaryName,
|
||||
@@ -30,10 +32,10 @@ export const BINARY_ADAPTER_ATTRIBUTE = Symbol('BINARY_ADAPTER_ATTRIBUTE');
|
||||
|
||||
export abstract class AbstractBinary {
|
||||
@Inject()
|
||||
protected logger: EggLogger;
|
||||
protected logger: Logger;
|
||||
|
||||
@Inject()
|
||||
protected httpclient: EggHttpClient;
|
||||
protected httpclient: HttpClient;
|
||||
|
||||
abstract initFetch(binaryName: BinaryName): Promise<void>;
|
||||
abstract fetch(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { Inject, SingletonProto, EggAppConfig } from 'egg';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import path from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, {
|
||||
type BinaryName,
|
||||
type BinaryTaskConfig,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { basename } from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import path from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import {
|
||||
AbstractBinary,
|
||||
BinaryAdapter,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import { GithubBinary } from './GithubBinary.ts';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { basename } from 'node:path';
|
||||
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName, type BinaryTaskConfig } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import { AbstractBinary, BinaryAdapter, type BinaryItem, type FetchResult } from './AbstractBinary.ts';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { basename } from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { join } from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import util from 'node:util';
|
||||
import path from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import path from 'node:path';
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import binaries, { type BinaryName } from '../../../../config/binaries.ts';
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
import { XMLParser } from 'fast-xml-parser';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { SingletonProto } from 'egg';
|
||||
|
||||
import { BinaryType } from '../../enum/Binary.ts';
|
||||
import {
|
||||
AbstractBinary,
|
||||
|
||||
@@ -2,10 +2,12 @@ import {
|
||||
Inject,
|
||||
QualifierImplDecoratorUtil,
|
||||
type ImplDecorator,
|
||||
} from '@eggjs/tegg';
|
||||
Logger,
|
||||
HttpClient,
|
||||
} from 'egg';
|
||||
|
||||
import type { RegistryType } from '../../../common/enum/Registry.ts';
|
||||
import type { Registry } from '../../../core/entity/Registry.ts';
|
||||
import type { EggHttpClient, EggLogger } from 'egg';
|
||||
|
||||
export const CHANGE_STREAM_ATTRIBUTE = 'CHANGE_STREAM_ATTRIBUTE';
|
||||
export interface ChangesStreamChange {
|
||||
@@ -15,10 +17,10 @@ export interface ChangesStreamChange {
|
||||
|
||||
export abstract class AbstractChangeStream {
|
||||
@Inject()
|
||||
protected logger: EggLogger;
|
||||
protected logger: Logger;
|
||||
|
||||
@Inject()
|
||||
protected httpclient: EggHttpClient;
|
||||
protected httpClient: HttpClient;
|
||||
|
||||
abstract getInitialSince(registry: Registry): Promise<string>;
|
||||
abstract fetchChanges(
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { E500 } from 'egg-errors';
|
||||
import { SingletonProto } from 'egg';
|
||||
import { E500 } from 'egg/errors';
|
||||
|
||||
import { RegistryType } from '../../../common/enum/Registry.ts';
|
||||
import type { Registry } from '../../../core/entity/Registry.ts';
|
||||
import {
|
||||
@@ -12,7 +13,7 @@ import {
|
||||
export class CnpmcoreChangesStream extends AbstractChangeStream {
|
||||
async getInitialSince(registry: Registry): Promise<string> {
|
||||
const db = new URL(registry.changeStream).origin;
|
||||
const { status, data } = await this.httpclient.request(db, {
|
||||
const { status, data } = await this.httpClient.request(db, {
|
||||
followRedirect: true,
|
||||
timeout: 10_000,
|
||||
dataType: 'json',
|
||||
@@ -34,7 +35,7 @@ export class CnpmcoreChangesStream extends AbstractChangeStream {
|
||||
async *fetchChanges(registry: Registry, since: string) {
|
||||
const db = this.getChangesStreamUrl(registry, since);
|
||||
// json mode
|
||||
const { data } = await this.httpclient.request(db, {
|
||||
const { data } = await this.httpClient.request(db, {
|
||||
followRedirect: true,
|
||||
timeout: 30_000,
|
||||
dataType: 'json',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { E500 } from 'egg-errors';
|
||||
import { SingletonProto } from 'egg';
|
||||
import { E500 } from 'egg/errors';
|
||||
|
||||
import { RegistryType } from '../../../common/enum/Registry.ts';
|
||||
import type { Registry } from '../../../core/entity/Registry.ts';
|
||||
import {
|
||||
@@ -44,7 +45,7 @@ export class CnpmjsorgChangesStream extends AbstractChangeStream {
|
||||
}
|
||||
const db = this.getChangesStreamUrl(registry, since, limit);
|
||||
// json mode
|
||||
const res = await this.httpclient.request<FetchResults>(db, {
|
||||
const res = await this.httpClient.request<FetchResults>(db, {
|
||||
followRedirect: true,
|
||||
timeout: 30_000,
|
||||
dataType: 'json',
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { SingletonProto } from '@eggjs/tegg';
|
||||
import { E500 } from 'egg-errors';
|
||||
import { SingletonProto } from 'egg';
|
||||
import { E500 } from 'egg/errors';
|
||||
|
||||
import { RegistryType } from '../../../common/enum/Registry.ts';
|
||||
import type { Registry } from '../../../core/entity/Registry.ts';
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
export class NpmChangesStream extends AbstractChangeStream {
|
||||
async getInitialSince(registry: Registry): Promise<string> {
|
||||
const db = new URL(registry.changeStream).origin;
|
||||
const { status, data } = await this.httpclient.request(db, {
|
||||
const { status, data } = await this.httpClient.request(db, {
|
||||
followRedirect: true,
|
||||
timeout: 10_000,
|
||||
dataType: 'json',
|
||||
@@ -43,7 +43,7 @@ export class NpmChangesStream extends AbstractChangeStream {
|
||||
): AsyncGenerator<ChangesStreamChange> {
|
||||
// https://github.com/orgs/community/discussions/152515
|
||||
const db = this.getChangesStreamUrl(registry, since);
|
||||
const { data, headers } = await this.httpclient.request(db, {
|
||||
const { data, headers } = await this.httpClient.request(db, {
|
||||
timeout: 60_000,
|
||||
headers: {
|
||||
'npm-replication-opt-in': 'true',
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
import { performance } from 'node:perf_hooks';
|
||||
|
||||
import { Advice, type AdviceContext, type IAdvice } from '@eggjs/tegg/aop';
|
||||
import { Inject } from '@eggjs/tegg';
|
||||
import type { EggLogger } from 'egg';
|
||||
import { Advice, type AdviceContext, type IAdvice } from 'egg/aop';
|
||||
import { Inject, Logger } from 'egg';
|
||||
|
||||
const START = Symbol('AsyncTimer#start');
|
||||
const SUCCEED = Symbol('AsyncTimer#succeed');
|
||||
@@ -11,7 +10,7 @@ const SUCCEED = Symbol('AsyncTimer#succeed');
|
||||
@Advice()
|
||||
export class AsyncTimer implements IAdvice {
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
|
||||
async beforeCall(ctx: AdviceContext) {
|
||||
ctx.set(START, performance.now());
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { Readable } from 'node:stream';
|
||||
import type { IncomingHttpHeaders } from 'node:http';
|
||||
import type { EggContext } from '@eggjs/tegg';
|
||||
|
||||
import type { Context } from 'egg';
|
||||
import type { estypes } from '@elastic/elasticsearch';
|
||||
import type { CnpmcoreConfig } from '../port/config.ts';
|
||||
|
||||
@@ -72,7 +73,7 @@ export interface userResult {
|
||||
email: string;
|
||||
}
|
||||
export interface AuthClient {
|
||||
getAuthUrl(ctx: EggContext): Promise<AuthUrlResult>;
|
||||
getAuthUrl(ctx: Context): Promise<AuthUrlResult>;
|
||||
ensureCurrentUser(): Promise<userResult | null>;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os from 'node:os';
|
||||
import path from 'node:path';
|
||||
|
||||
import { InternalServerError } from 'egg-errors';
|
||||
import { InternalServerError } from 'egg/errors';
|
||||
|
||||
import { Entity, type EntityData } from './Entity.ts';
|
||||
import { EntityUtil, type EasyData } from '../util/EntityUtil.ts';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import type { EggLogger } from 'egg';
|
||||
import { Event, Inject, Logger } from 'egg';
|
||||
|
||||
import { PACKAGE_VERSION_ADDED } from './index.ts';
|
||||
import { BUG_VERSIONS } from '../../common/constants.ts';
|
||||
import type { BugVersionService } from '../service/BugVersionService.ts';
|
||||
@@ -10,7 +10,7 @@ export class BugVersionFixHandler {
|
||||
private readonly bugVersionService: BugVersionService;
|
||||
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
|
||||
async handle(fullname: string) {
|
||||
if (fullname !== BUG_VERSIONS) return;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import { Event, Inject } from 'egg';
|
||||
|
||||
import {
|
||||
PACKAGE_BLOCKED,
|
||||
PACKAGE_MAINTAINER_CHANGED,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
|
||||
import { Event, Inject, Config } from 'egg';
|
||||
|
||||
import {
|
||||
type PackageMetaChange,
|
||||
@@ -28,7 +28,7 @@ class ChangesStreamEvent {
|
||||
protected readonly taskService: TaskService;
|
||||
|
||||
@Inject()
|
||||
protected readonly config: EggAppConfig;
|
||||
protected readonly config: Config;
|
||||
|
||||
protected get hookEnable() {
|
||||
return this.config.cnpmcore.hookEnable;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { Config, Event, Inject } from 'egg';
|
||||
|
||||
import { PACKAGE_VERSION_ADDED } from './index.ts';
|
||||
import { getScopeAndName } from '../../common/PackageUtil.ts';
|
||||
import { PackageVersionManifest as PackageVersionManifestEntity } from '../entity/PackageVersionManifest.ts';
|
||||
@@ -8,7 +8,7 @@ import type { DistRepository } from '../../repository/DistRepository.ts';
|
||||
|
||||
class StoreManifestEvent {
|
||||
@Inject()
|
||||
protected readonly config: EggAppConfig;
|
||||
protected readonly config: Config;
|
||||
@Inject()
|
||||
private readonly packageRepository: PackageRepository;
|
||||
@Inject()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// TODO sync event
|
||||
/* eslint-disable @typescript-eslint/no-unused-vars */
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import { Config, Event, Inject } from 'egg';
|
||||
import {
|
||||
PACKAGE_BLOCKED,
|
||||
PACKAGE_MAINTAINER_CHANGED,
|
||||
@@ -22,7 +20,7 @@ class SyncESPackage {
|
||||
protected readonly packageSearchService: PackageSearchService;
|
||||
|
||||
@Inject()
|
||||
protected readonly config: EggAppConfig;
|
||||
protected readonly config: Config;
|
||||
|
||||
protected async syncPackage(fullname: string) {
|
||||
if (!this.config.cnpmcore.enableElasticsearch) return;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import type { EggAppConfig, EggLogger } from 'egg';
|
||||
import { ForbiddenError } from 'egg-errors';
|
||||
import { Event, Inject, Config, Logger } from 'egg';
|
||||
import { ForbiddenError } from 'egg/errors';
|
||||
|
||||
import {
|
||||
PACKAGE_TAG_ADDED,
|
||||
PACKAGE_TAG_CHANGED,
|
||||
@@ -12,9 +12,9 @@ import type { PackageVersionFileService } from '../service/PackageVersionFileSer
|
||||
|
||||
class SyncPackageVersionFileEvent {
|
||||
@Inject()
|
||||
protected readonly config: EggAppConfig;
|
||||
protected readonly config: Config;
|
||||
@Inject()
|
||||
protected readonly logger: EggLogger;
|
||||
protected readonly logger: Logger;
|
||||
@Inject()
|
||||
private readonly packageManagerService: PackageManagerService;
|
||||
@Inject()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Event, Inject } from '@eggjs/tegg';
|
||||
import { Event, Inject } from 'egg';
|
||||
|
||||
import { PACKAGE_ADDED, PACKAGE_VERSION_ADDED } from './index.ts';
|
||||
import type { TotalRepository } from '../../repository/TotalRepository.ts';
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import '@eggjs/tegg';
|
||||
import type { User } from '../entity/User.ts';
|
||||
|
||||
export const PACKAGE_ADDED = 'PACKAGE_ADDED';
|
||||
@@ -23,7 +22,7 @@ export interface PackageMetaChange {
|
||||
deprecateds?: PackageDeprecated[];
|
||||
}
|
||||
|
||||
declare module '@eggjs/tegg' {
|
||||
declare module 'egg' {
|
||||
interface Events {
|
||||
[PACKAGE_ADDED]: (fullname: string) => Promise<void>;
|
||||
[PACKAGE_UNPUBLISHED]: (fullname: string) => Promise<void>;
|
||||
|
||||
@@ -5,8 +5,8 @@ import {
|
||||
Inject,
|
||||
SingletonProto,
|
||||
type EggObjectFactory,
|
||||
} from '@eggjs/tegg';
|
||||
import type { EggHttpClient } from 'egg';
|
||||
HttpClient,
|
||||
} from 'egg';
|
||||
import { sortBy } from 'lodash-es';
|
||||
|
||||
import binaries, {
|
||||
@@ -42,7 +42,7 @@ export class BinarySyncerService extends AbstractService {
|
||||
@Inject()
|
||||
private readonly taskService: TaskService;
|
||||
@Inject()
|
||||
private readonly httpclient: EggHttpClient;
|
||||
private readonly httpClient: HttpClient;
|
||||
@Inject()
|
||||
private readonly nfsAdapter: NFSAdapter;
|
||||
@Inject()
|
||||
@@ -306,7 +306,7 @@ export class BinarySyncerService extends AbstractService {
|
||||
let localFile = '';
|
||||
try {
|
||||
const { tmpfile, headers, timing } = await downloadToTempfile(
|
||||
this.httpclient,
|
||||
this.httpClient,
|
||||
this.config.dataDir,
|
||||
item.sourceUrl,
|
||||
{ ignoreDownloadStatuses: item.ignoreDownloadStatuses }
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { EggLogger } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, Logger } from 'egg';
|
||||
import pMap from 'p-map';
|
||||
import { BugVersion } from '../entity/BugVersion.ts';
|
||||
import type {
|
||||
@@ -23,7 +22,7 @@ export class BugVersionService {
|
||||
private readonly distRepository: DistRepository;
|
||||
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
|
||||
@Inject()
|
||||
private readonly cacheService: CacheService;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
|
||||
import type { CacheAdapter } from '../../common/adapter/CacheAdapter.ts';
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import type { ChangesStreamTaskData } from '../entity/Task.ts';
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
Inject,
|
||||
SingletonProto,
|
||||
type EggObjectFactory,
|
||||
} from '@eggjs/tegg';
|
||||
import { E500 } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { E500 } from 'egg/errors';
|
||||
|
||||
import {
|
||||
RegistryNotMatchError,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import pMap from 'p-map';
|
||||
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
|
||||
import { Inject, ObjectInitType, type ContextEventBus } from '@eggjs/tegg';
|
||||
import { Advice, type IAdvice } from '@eggjs/tegg/aop';
|
||||
import { Inject, ObjectInitType, type ContextEventBus } from 'egg';
|
||||
import { Advice, type IAdvice } from 'egg/aop';
|
||||
|
||||
@Advice({
|
||||
initType: ObjectInitType.CONTEXT,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { EggLogger } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, Logger } from 'egg';
|
||||
import pMap from 'p-map';
|
||||
|
||||
import type { PackageVersionRepository } from '../../repository/PackageVersionRepository.ts';
|
||||
import { PaddingSemVer } from '../entity/PaddingSemVer.ts';
|
||||
|
||||
@@ -12,7 +12,7 @@ export class FixNoPaddingVersionService {
|
||||
private readonly packageVersionRepository: PackageVersionRepository;
|
||||
|
||||
@Inject()
|
||||
private readonly logger: EggLogger;
|
||||
private readonly logger: Logger;
|
||||
|
||||
async fixPaddingVersion(id?: number): Promise<void> {
|
||||
while (true) {
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import {
|
||||
AccessLevel,
|
||||
SingletonProto,
|
||||
} from '@eggjs/tegg';
|
||||
import { NotFoundError, NotImplementedError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { NotFoundError, NotImplementedError } from 'egg/errors';
|
||||
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import { NOT_IMPLEMENTED_PATH } from '../../common/constants.ts';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, Config } from 'egg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg/errors';
|
||||
|
||||
import type { HookRepository } from '../../repository/HookRepository.ts';
|
||||
import { Hook } from '../entity/Hook.ts';
|
||||
import type { HookType } from '../../common/enum/Hook.ts';
|
||||
@@ -33,7 +33,7 @@ export class HookManageService {
|
||||
private readonly hookRepository: HookRepository;
|
||||
|
||||
@Inject()
|
||||
private readonly config: EggAppConfig;
|
||||
private readonly config: Config;
|
||||
|
||||
get hooksLimit() {
|
||||
return this.config.cnpmcore.hooksLimit;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { EggContextHttpClient } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, HttpClient } from 'egg';
|
||||
|
||||
import type { TriggerHookTask } from '../entity/Task.ts';
|
||||
import type { HookEvent } from '../entity/HookEvent.ts';
|
||||
import type { HookRepository } from '../../repository/HookRepository.ts';
|
||||
@@ -30,7 +30,7 @@ export class HookTriggerService {
|
||||
private readonly userRepository: UserRepository;
|
||||
|
||||
@Inject()
|
||||
private readonly httpclient: EggContextHttpClient;
|
||||
private readonly httpClient: HttpClient;
|
||||
|
||||
@Inject()
|
||||
private readonly taskService: TaskService;
|
||||
@@ -80,7 +80,7 @@ export class HookTriggerService {
|
||||
async doExecuteTrigger(hook: Hook, payload: object): Promise<number> {
|
||||
const { digest, payloadStr } = hook.signPayload(payload);
|
||||
const url = new URL(hook.endpoint);
|
||||
const res = await this.httpclient.request(hook.endpoint, {
|
||||
const res = await this.httpClient.request(hook.endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
Inject,
|
||||
SingletonProto,
|
||||
type EventBus,
|
||||
} from '@eggjs/tegg';
|
||||
import { BadRequestError, ForbiddenError, NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { BadRequestError, ForbiddenError, NotFoundError } from 'egg/errors';
|
||||
import type { RequireAtLeastOne } from 'type-fest';
|
||||
import npa from 'npm-package-arg';
|
||||
import semver from 'semver';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import { errors, type estypes } from '@elastic/elasticsearch';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
|
||||
@@ -2,12 +2,11 @@ import os from 'node:os';
|
||||
import { setTimeout } from 'node:timers/promises';
|
||||
import { rm } from 'node:fs/promises';
|
||||
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { Pointcut } from '@eggjs/tegg/aop';
|
||||
import type { EggHttpClient } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, HttpClient } from 'egg';
|
||||
import { Pointcut } from 'egg/aop';
|
||||
import { isEmpty, isEqual } from 'lodash-es';
|
||||
import semver from 'semver';
|
||||
import { BadRequestError } from 'egg-errors';
|
||||
import { BadRequestError } from 'egg/errors';
|
||||
|
||||
import type {
|
||||
NPMRegistry,
|
||||
@@ -83,7 +82,7 @@ export class PackageSyncerService extends AbstractService {
|
||||
@Inject()
|
||||
private readonly cacheService: CacheService;
|
||||
@Inject()
|
||||
private readonly httpclient: EggHttpClient;
|
||||
private readonly httpClient: HttpClient;
|
||||
@Inject()
|
||||
private readonly registryManagerService: RegistryManagerService;
|
||||
@Inject()
|
||||
@@ -978,7 +977,7 @@ export class PackageSyncerService extends AbstractService {
|
||||
let localFile: string;
|
||||
try {
|
||||
const { tmpfile, headers, timing } = await downloadToTempfile(
|
||||
this.httpclient,
|
||||
this.httpClient,
|
||||
this.config.dataDir,
|
||||
tarball,
|
||||
{ remoteAuthToken }
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import fs from 'node:fs/promises';
|
||||
import { basename, dirname, join } from 'node:path';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
// @ts-expect-error type error
|
||||
import tar from '@fengmk2/tar';
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { ConflictError, ForbiddenError } from 'egg-errors';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import { ConflictError, ForbiddenError } from 'egg/errors';
|
||||
import semver from 'semver';
|
||||
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import { calculateIntegrity, getFullname } from '../../common/PackageUtil.ts';
|
||||
import { createTempDir, mimeLookup } from '../../common/FileUtil.ts';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import semver, { Range } from 'semver';
|
||||
import type { AliasResult, Result } from 'npm-package-arg';
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import type {
|
||||
import {
|
||||
Context,
|
||||
EggHttpClient,
|
||||
HttpClient,
|
||||
HttpClientRequestOptions,
|
||||
HttpClientResponse,
|
||||
AccessLevel, Inject, SingletonProto,
|
||||
BackgroundTaskHelper,
|
||||
} from 'egg';
|
||||
import { ForbiddenError } from 'egg-errors';
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { BackgroundTaskHelper } from '@eggjs/tegg-background-task';
|
||||
import { ForbiddenError } from 'egg/errors';
|
||||
import { valid as semverValid } from 'semver';
|
||||
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
@@ -53,7 +53,7 @@ type GetSourceManifestAndCacheReturnType<T> = T extends
|
||||
})
|
||||
export class ProxyCacheService extends AbstractService {
|
||||
@Inject()
|
||||
private readonly httpclient: EggHttpClient;
|
||||
private readonly httpClient: HttpClient;
|
||||
@Inject()
|
||||
private readonly npmRegistry: NPMRegistry;
|
||||
@Inject()
|
||||
@@ -409,7 +409,7 @@ export class ProxyCacheService extends AbstractService {
|
||||
|
||||
const url = `${this.npmRegistry.registry}${ctx.url}`;
|
||||
|
||||
const res = (await this.httpclient.request(url, {
|
||||
const res = (await this.httpClient.request(url, {
|
||||
timing: true,
|
||||
followRedirect: true,
|
||||
// once redirection is also count as a retry
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { E400, NotFoundError } from 'egg-errors';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import { E400, NotFoundError } from 'egg/errors';
|
||||
|
||||
import type { RegistryRepository } from '../../repository/RegistryRepository.ts';
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import { Registry } from '../entity/Registry.ts';
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
|
||||
import type { ScopeRepository } from '../../repository/ScopeRepository.ts';
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import { Scope } from '../entity/Scope.ts';
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
|
||||
import type { NFSAdapter } from '../../common/adapter/NFSAdapter.ts';
|
||||
import { TaskState, TaskType } from '../../common/enum/Task.ts';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import dayjs from 'dayjs';
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import { isEmpty } from 'lodash-es';
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg-errors';
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg/errors';
|
||||
|
||||
import { AbstractService } from '../../common/AbstractService.ts';
|
||||
import { isGranularToken, type Token } from '../entity/Token.ts';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import crypto from 'node:crypto';
|
||||
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg/errors';
|
||||
|
||||
import type { UserRepository } from '../../repository/UserRepository.ts';
|
||||
import { User as UserEntity } from '../entity/User.ts';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import ObjectID from 'bson-objectid';
|
||||
import { E400 } from 'egg-errors';
|
||||
import { E400 } from 'egg/errors';
|
||||
|
||||
import type { EntityData } from '../entity/Entity.ts';
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
import {
|
||||
type EggContext,
|
||||
type Context,
|
||||
AccessLevel,
|
||||
Inject,
|
||||
SingletonProto,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import type { Redis } from 'ioredis';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
|
||||
import type {
|
||||
AuthClient,
|
||||
@@ -34,7 +35,7 @@ export class AuthAdapter implements AuthClient {
|
||||
@Inject()
|
||||
readonly user: SSO_USER;
|
||||
|
||||
async getAuthUrl(ctx: EggContext): Promise<AuthUrlResult> {
|
||||
async getAuthUrl(ctx: Context): Promise<AuthUrlResult> {
|
||||
const sessionId = randomUUID();
|
||||
await this.redis.setex(sessionId, ONE_DAY, '');
|
||||
|
||||
|
||||
@@ -4,8 +4,9 @@ import {
|
||||
Inject,
|
||||
LifecycleInit,
|
||||
SingletonProto,
|
||||
} from '@eggjs/tegg';
|
||||
import type { EggAppConfig, EggLogger } from 'egg';
|
||||
Logger,
|
||||
Config,
|
||||
} from 'egg';
|
||||
import FSClient from 'fs-cnpm';
|
||||
|
||||
import type {
|
||||
@@ -22,10 +23,10 @@ import type {
|
||||
})
|
||||
export class NFSClientAdapter implements NFSClient {
|
||||
@Inject()
|
||||
private logger: EggLogger;
|
||||
private logger: Logger;
|
||||
|
||||
@Inject()
|
||||
private config: EggAppConfig;
|
||||
private config: Config;
|
||||
|
||||
// oxlint-disable-next-line typescript-eslint/no-explicit-any
|
||||
private _client: any;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import { AccessLevel, Inject, SingletonProto } from 'egg';
|
||||
import type { Redis } from 'ioredis';
|
||||
|
||||
import type { QueueAdapter } from '../common/typing.ts';
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { AccessLevel, Inject, SingletonProto } from '@eggjs/tegg';
|
||||
import type { EggAppConfig } from 'egg';
|
||||
import { AccessLevel, Inject, SingletonProto, Config } from 'egg';
|
||||
import type {
|
||||
Client as ElasticsearchClient,
|
||||
estypes,
|
||||
@@ -16,7 +15,7 @@ import type { SearchAdapter } from '../common/typing.ts';
|
||||
})
|
||||
export class ESSearchAdapter implements SearchAdapter {
|
||||
@Inject()
|
||||
private config: EggAppConfig;
|
||||
private config: Config;
|
||||
|
||||
@Inject()
|
||||
private readonly elasticsearch: ElasticsearchClient; // 由 elasticsearch 插件引入
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {
|
||||
type EggContext,
|
||||
Context,
|
||||
AccessLevel,
|
||||
ContextProto,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
import type { EggAppConfig, EggLogger } from 'egg';
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg-errors';
|
||||
Config, Logger,
|
||||
} from 'egg';
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg/errors';
|
||||
|
||||
import type { PackageRepository } from '../repository/PackageRepository.ts';
|
||||
import type { Package as PackageEntity } from '../core/entity/Package.ts';
|
||||
@@ -26,9 +26,9 @@ export class UserRoleManager {
|
||||
@Inject()
|
||||
private readonly packageRepository: PackageRepository;
|
||||
@Inject()
|
||||
private readonly config: EggAppConfig;
|
||||
private readonly config: Config;
|
||||
@Inject()
|
||||
protected logger: EggLogger;
|
||||
protected logger: Logger;
|
||||
@Inject()
|
||||
private readonly registryManagerService: RegistryManagerService;
|
||||
@Inject()
|
||||
@@ -43,7 +43,7 @@ export class UserRoleManager {
|
||||
// 2. has published in current registry
|
||||
// 3. pkg scope is allowed to publish
|
||||
// use AbstractController#ensurePublishAccess ensure pkg exists;
|
||||
public async checkPublishAccess(ctx: EggContext, fullname: string) {
|
||||
public async checkPublishAccess(ctx: Context, fullname: string) {
|
||||
const user = await this.requiredAuthorizedUser(ctx, 'publish');
|
||||
|
||||
// 1. admin has all access
|
||||
@@ -97,7 +97,7 @@ export class UserRoleManager {
|
||||
// host: 'localhost:7001',
|
||||
// connection: 'keep-alive'
|
||||
// }
|
||||
public async getAuthorizedUserAndToken(ctx: EggContext) {
|
||||
public async getAuthorizedUserAndToken(ctx: Context) {
|
||||
if (this.handleAuthorized) {
|
||||
if (!this.currentAuthorizedUser) return null;
|
||||
return {
|
||||
@@ -122,7 +122,7 @@ export class UserRoleManager {
|
||||
return authorizedUserAndToken;
|
||||
}
|
||||
|
||||
public async requiredAuthorizedUser(ctx: EggContext, role: TokenRole) {
|
||||
public async requiredAuthorizedUser(ctx: Context, role: TokenRole) {
|
||||
const authorizedUserAndToken = await this.getAuthorizedUserAndToken(ctx);
|
||||
if (!authorizedUserAndToken) {
|
||||
const authorization = ctx.get('authorization');
|
||||
@@ -201,7 +201,7 @@ export class UserRoleManager {
|
||||
}
|
||||
}
|
||||
|
||||
public async isAdmin(ctx: EggContext) {
|
||||
public async isAdmin(ctx: Context) {
|
||||
const authorizedUserAndToken = await this.getAuthorizedUserAndToken(ctx);
|
||||
if (!authorizedUserAndToken) return false;
|
||||
const { user, token } = authorizedUserAndToken;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { NotFoundError, UnavailableForLegalReasonsError } from 'egg-errors';
|
||||
import { type EggContext, Inject } from '@eggjs/tegg';
|
||||
import type { EggAppConfig, EggLogger } from 'egg';
|
||||
import { NotFoundError, UnavailableForLegalReasonsError } from 'egg/errors';
|
||||
import { type Context, Inject, EggAppConfig, Logger } from 'egg';
|
||||
|
||||
import { MiddlewareController } from '../middleware/index.ts';
|
||||
import type { UserRoleManager } from '../UserRoleManager.ts';
|
||||
@@ -28,7 +27,7 @@ class ControllerRedirectError extends NotFoundError {
|
||||
|
||||
export abstract class AbstractController extends MiddlewareController {
|
||||
@Inject()
|
||||
protected logger: EggLogger;
|
||||
protected logger: Logger;
|
||||
@Inject()
|
||||
protected config: EggAppConfig;
|
||||
@Inject()
|
||||
@@ -53,7 +52,7 @@ export abstract class AbstractController extends MiddlewareController {
|
||||
}
|
||||
|
||||
protected async ensurePublishAccess<C extends boolean>(
|
||||
ctx: EggContext,
|
||||
ctx: Context,
|
||||
fullname: string,
|
||||
checkPkgExist: C = true as C
|
||||
): Promise<{
|
||||
@@ -87,7 +86,7 @@ export abstract class AbstractController extends MiddlewareController {
|
||||
return this.config.cnpmcore.redirectNotFound;
|
||||
}
|
||||
|
||||
protected getAllowSync(ctx: EggContext): boolean {
|
||||
protected getAllowSync(ctx: Context): boolean {
|
||||
let allowSync = false;
|
||||
|
||||
// request not by node, consider it request from web, don't sync
|
||||
@@ -208,7 +207,7 @@ export abstract class AbstractController extends MiddlewareController {
|
||||
}
|
||||
|
||||
protected getAndCheckVersionFromFilename(
|
||||
ctx: EggContext,
|
||||
ctx: Context,
|
||||
fullname: string,
|
||||
filenameWithVersion: string
|
||||
) {
|
||||
@@ -223,7 +222,7 @@ export abstract class AbstractController extends MiddlewareController {
|
||||
return data.version;
|
||||
}
|
||||
|
||||
protected setCDNHeaders(ctx: EggContext) {
|
||||
protected setCDNHeaders(ctx: Context) {
|
||||
const config = this.config.cnpmcore;
|
||||
if (config.enableCDN) {
|
||||
ctx.set('cache-control', config.cdnCacheControlHeader);
|
||||
|
||||
@@ -3,8 +3,8 @@ import {
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
} from '@eggjs/tegg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
@@ -9,9 +9,9 @@ import {
|
||||
Inject,
|
||||
Middleware,
|
||||
HTTPBody,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import path from 'node:path';
|
||||
import { NotFoundError } from 'egg-errors';
|
||||
import { NotFoundError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import type { BinarySyncerService } from '../../core/service/BinarySyncerService.ts';
|
||||
@@ -29,7 +29,7 @@ export class BinarySyncController extends AbstractController {
|
||||
path: '/binary.html',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showBinaryHTML(@Context() ctx: EggContext) {
|
||||
async showBinaryHTML(@HTTPContext() ctx: Context) {
|
||||
ctx.type = 'html';
|
||||
return ctx.app.binaryHTML;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ export class BinarySyncController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showBinary(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() binaryName: BinaryName,
|
||||
@HTTPParam() subpath: string,
|
||||
@HTTPQuery() since: string,
|
||||
@@ -154,7 +154,7 @@ export class BinarySyncController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async syncBinary(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() binaryName: BinaryName,
|
||||
@HTTPBody() lastData?: Record<string, string>
|
||||
) {
|
||||
@@ -181,7 +181,7 @@ export class BinarySyncController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showBinaryIndex(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() binaryName: BinaryName,
|
||||
@HTTPQuery() since: string,
|
||||
@HTTPQuery() limit: string
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import { Type } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
@@ -27,7 +27,7 @@ export class ChangesStreamController extends AbstractController {
|
||||
path: '/_changes',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async listChanges(@Context() ctx: EggContext, @HTTPQuery() since: string) {
|
||||
async listChanges(@HTTPContext() ctx: Context, @HTTPQuery() since: string) {
|
||||
const params = { since: since ? Number(since) : 0 };
|
||||
ctx.tValidate(ChangeRule, params);
|
||||
const limit = 1000;
|
||||
|
||||
@@ -4,8 +4,8 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
import { NotFoundError, UnprocessableEntityError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { NotFoundError, UnprocessableEntityError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import {
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { performance } from 'node:perf_hooks';
|
||||
|
||||
import {
|
||||
type EggContext,
|
||||
Context,
|
||||
type Context,
|
||||
HTTPContext,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import pkg from 'egg/package.json' with { type: 'json' };
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
@@ -103,7 +104,7 @@ export class HomeController extends AbstractController {
|
||||
path: '/-/ping',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async ping(@Context() ctx: EggContext) {
|
||||
async ping(@HTTPContext() ctx: Context) {
|
||||
return {
|
||||
pong: true,
|
||||
use: performance.now() - ctx.performanceStarttime,
|
||||
@@ -115,7 +116,7 @@ export class HomeController extends AbstractController {
|
||||
method: HTTPMethodEnum.POST,
|
||||
priority: Number.NEGATIVE_INFINITY,
|
||||
})
|
||||
async miscPost(@Context() ctx: EggContext) {
|
||||
async miscPost(@HTTPContext() ctx: Context) {
|
||||
await this.homeService.misc(ctx.path);
|
||||
}
|
||||
|
||||
@@ -124,7 +125,7 @@ export class HomeController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
priority: Number.NEGATIVE_INFINITY,
|
||||
})
|
||||
async miscGet(@Context() ctx: EggContext) {
|
||||
async miscGet(@HTTPContext() ctx: Context) {
|
||||
await this.homeService.misc(ctx.path);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
|
||||
import type { HookManageService } from '../../core/service/HookManageService.ts';
|
||||
import type { TaskService } from '../../core/service/TaskService.ts';
|
||||
@@ -47,7 +47,7 @@ export class HookController {
|
||||
method: HTTPMethodEnum.POST,
|
||||
})
|
||||
async createHook(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPBody() req: CreateHookRequest
|
||||
) {
|
||||
ctx.tValidate(CreateHookRequestRule, req);
|
||||
@@ -70,7 +70,7 @@ export class HookController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async updateHook(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() id: string,
|
||||
@HTTPBody() req: UpdateHookRequest
|
||||
) {
|
||||
@@ -98,7 +98,7 @@ export class HookController {
|
||||
path: '/v1/hooks/hook/:id',
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async deleteHook(@Context() ctx: EggContext, @HTTPParam() id: string) {
|
||||
async deleteHook(@HTTPContext() ctx: Context, @HTTPParam() id: string) {
|
||||
const user = await this.userRoleManager.requiredAuthorizedUser(
|
||||
ctx,
|
||||
'setting'
|
||||
@@ -120,7 +120,7 @@ export class HookController {
|
||||
path: '/v1/hooks',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async listHooks(@Context() ctx: EggContext) {
|
||||
async listHooks(@HTTPContext() ctx: Context) {
|
||||
const user = await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
|
||||
const hooks = await this.hookManageService.listHooksByOwnerId(user.userId);
|
||||
const tasks = await this.taskService.findTasks(
|
||||
@@ -141,7 +141,7 @@ export class HookController {
|
||||
path: '/v1/hooks/hook/:id',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async getHook(@Context() ctx: EggContext, @HTTPParam() id: string) {
|
||||
async getHook(@HTTPContext() ctx: Context, @HTTPParam() id: string) {
|
||||
const user = await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
|
||||
const hook = await this.hookManageService.getHookByOwnerId(id, user.userId);
|
||||
let task: TriggerHookTask | null = null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
HTTPParam,
|
||||
Inject,
|
||||
Middleware,
|
||||
} from '@eggjs/tegg';
|
||||
import { ForbiddenError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { ForbiddenError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import { FULLNAME_REG_STRING } from '../../common/PackageUtil.ts';
|
||||
@@ -32,7 +32,7 @@ export class PackageBlockController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async blockPackage(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPBody() data: BlockPackageType
|
||||
) {
|
||||
@@ -74,7 +74,7 @@ export class PackageBlockController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async unblockPackage(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string
|
||||
) {
|
||||
const packageEntity = await this.getPackageEntityByFullname(fullname);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
type EggContext,
|
||||
type BackgroundTaskHelper,
|
||||
HTTPContext,
|
||||
BackgroundTaskHelper,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
HTTPParam,
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { ForbiddenError, NotFoundError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import {
|
||||
@@ -70,7 +70,7 @@ export class PackageSyncController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async createSyncTask(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPBody() data: SyncPackageTaskType
|
||||
) {
|
||||
@@ -204,7 +204,7 @@ export class PackageSyncController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showSyncTaskLog(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() taskId: string
|
||||
) {
|
||||
@@ -239,7 +239,7 @@ export class PackageSyncController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async deprecatedCreateSyncTask(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPQuery() nodeps: string
|
||||
) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -7,8 +7,8 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
import { ForbiddenError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { ForbiddenError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import { FULLNAME_REG_STRING } from '../../common/PackageUtil.ts';
|
||||
@@ -47,7 +47,7 @@ export class PackageTagController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async saveTag(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() tag: string,
|
||||
@HTTPBody() version: string
|
||||
@@ -75,7 +75,7 @@ export class PackageTagController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async removeTag(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() tag: string
|
||||
) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { join } from 'node:path';
|
||||
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
@@ -9,8 +10,8 @@ import {
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
Middleware,
|
||||
} from '@eggjs/tegg';
|
||||
import { NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { NotFoundError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import { AdminAccess } from '../middleware/AdminAccess.ts';
|
||||
@@ -77,7 +78,7 @@ export class PackageVersionFileController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async sync(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() versionSpec: string
|
||||
) {
|
||||
@@ -108,7 +109,7 @@ export class PackageVersionFileController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async listFiles(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() versionSpec: string,
|
||||
@HTTPQuery() meta: string
|
||||
@@ -155,7 +156,7 @@ export class PackageVersionFileController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async raw(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() versionSpec: string,
|
||||
@HTTPParam() path: string,
|
||||
@@ -252,7 +253,7 @@ export class PackageVersionFileController extends AbstractController {
|
||||
}
|
||||
|
||||
async #getPackageVersion(
|
||||
ctx: EggContext,
|
||||
ctx: Context,
|
||||
fullname: string,
|
||||
scope: string,
|
||||
name: string,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
@@ -7,13 +7,13 @@ import {
|
||||
HTTPParam,
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import {
|
||||
ForbiddenError,
|
||||
NotFoundError,
|
||||
NotImplementedError,
|
||||
UnauthorizedError,
|
||||
} from 'egg-errors';
|
||||
} from 'egg/errors';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
import type { ProxyCacheRepository } from '../../repository/ProxyCacheRepository.ts';
|
||||
@@ -140,7 +140,7 @@ export class ProxyCacheController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
path: '/-/proxy-cache',
|
||||
})
|
||||
async truncateProxyCaches(@Context() ctx: EggContext) {
|
||||
async truncateProxyCaches(@HTTPContext() ctx: Context) {
|
||||
const isAdmin = await this.userRoleManager.isAdmin(ctx);
|
||||
if (!isAdmin) {
|
||||
throw new UnauthorizedError('only admin can do this');
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -9,8 +9,8 @@ import {
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
Middleware,
|
||||
} from '@eggjs/tegg';
|
||||
import { NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { NotFoundError } from 'egg/errors';
|
||||
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
@@ -87,7 +87,7 @@ export class RegistryController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async createRegistry(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPBody() registryOptions: Static<typeof RegistryCreateOptions>
|
||||
) {
|
||||
ctx.tValidate(RegistryCreateOptions, registryOptions);
|
||||
@@ -121,7 +121,7 @@ export class RegistryController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async createRegistrySyncTask(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() id: string,
|
||||
@HTTPBody() registryOptions: Static<typeof RegistryCreateSyncOptions>
|
||||
) {
|
||||
@@ -148,7 +148,7 @@ export class RegistryController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async removeRegistry(@Context() ctx: EggContext, @HTTPParam() id: string) {
|
||||
async removeRegistry(@HTTPContext() ctx: Context, @HTTPParam() id: string) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
ctx,
|
||||
'setting'
|
||||
@@ -166,7 +166,7 @@ export class RegistryController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async updateRegistry(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() id: string,
|
||||
@HTTPBody() updateRegistryOptions: Partial<UpdateRegistryCmd>
|
||||
) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import {
|
||||
type EggContext,
|
||||
Context,
|
||||
HTTPContext,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
HTTPParam,
|
||||
Inject,
|
||||
Middleware,
|
||||
} from '@eggjs/tegg';
|
||||
import { E400 } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { E400 } from 'egg/errors';
|
||||
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
@@ -32,7 +32,7 @@ export class ScopeController extends AbstractController {
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async createScope(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPBody() scopeOptions: Static<typeof ScopeCreateOptions>
|
||||
) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
@@ -61,7 +61,7 @@ export class ScopeController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
@Middleware(AdminAccess)
|
||||
async removeScope(@Context() ctx: EggContext, @HTTPParam() id: string) {
|
||||
async removeScope(@HTTPContext() ctx: Context, @HTTPParam() id: string) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
ctx,
|
||||
'setting'
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg-errors';
|
||||
import { ForbiddenError, UnauthorizedError } from 'egg/errors';
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import type { AuthAdapter } from '../../infra/AuthAdapter.ts';
|
||||
@@ -57,7 +57,7 @@ export class TokenController extends AbstractController {
|
||||
method: HTTPMethodEnum.POST,
|
||||
})
|
||||
async createToken(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPBody() tokenOptions: TokenOptions
|
||||
) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
@@ -93,7 +93,7 @@ export class TokenController extends AbstractController {
|
||||
path: '/-/npm/v1/tokens/token/:tokenKey',
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async removeToken(@Context() ctx: EggContext, @HTTPParam() tokenKey: string) {
|
||||
async removeToken(@HTTPContext() ctx: Context, @HTTPParam() tokenKey: string) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
ctx,
|
||||
'setting'
|
||||
@@ -107,7 +107,7 @@ export class TokenController extends AbstractController {
|
||||
path: '/-/npm/v1/tokens',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async listTokens(@Context() ctx: EggContext) {
|
||||
async listTokens(@HTTPContext() ctx: Context) {
|
||||
// {
|
||||
// 'user-agent': 'npm/8.1.2 node/v16.13.1 darwin arm64 workspaces/false',
|
||||
// 'npm-command': 'token',
|
||||
@@ -177,7 +177,7 @@ export class TokenController extends AbstractController {
|
||||
// 2. Optional to submit description, allowScopes, allowPackages information
|
||||
// 3. Need to implement ensureCurrentUser method in AuthAdapter, or pass in this.user
|
||||
async createGranularToken(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPBody() tokenOptions: GranularTokenOptions
|
||||
) {
|
||||
ctx.tValidate(GranularTokenOptionsRule, tokenOptions);
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import {
|
||||
ForbiddenError,
|
||||
NotFoundError,
|
||||
UnauthorizedError,
|
||||
UnprocessableEntityError,
|
||||
} from 'egg-errors';
|
||||
} from 'egg/errors';
|
||||
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import { AbstractController } from './AbstractController.ts';
|
||||
@@ -58,7 +58,7 @@ export class UserController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async loginOrCreateUser(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() username: string,
|
||||
@HTTPBody() user: User
|
||||
) {
|
||||
@@ -132,7 +132,7 @@ export class UserController extends AbstractController {
|
||||
path: '/-/user/token/:token',
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async logout(@Context() ctx: EggContext, @HTTPParam() token: string) {
|
||||
async logout(@HTTPContext() ctx: Context, @HTTPParam() token: string) {
|
||||
const authorizedUserAndToken =
|
||||
await this.userRoleManager.getAuthorizedUserAndToken(ctx);
|
||||
if (!authorizedUserAndToken) return { ok: false };
|
||||
@@ -151,7 +151,7 @@ export class UserController extends AbstractController {
|
||||
path: '/-/user/org.couchdb.user::username',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showUser(@Context() ctx: EggContext, @HTTPParam() username: string) {
|
||||
async showUser(@HTTPContext() ctx: Context, @HTTPParam() username: string) {
|
||||
const user = await this.userService.findUserByNameOrDisplayName(username);
|
||||
if (!user) {
|
||||
throw new NotFoundError(`User "${username}" not found`);
|
||||
@@ -170,7 +170,7 @@ export class UserController extends AbstractController {
|
||||
path: '/-/whoami',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async whoami(@Context() ctx: EggContext) {
|
||||
async whoami(@HTTPContext() ctx: Context) {
|
||||
await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
|
||||
const authorizedRes =
|
||||
await this.userRoleManager.getAuthorizedUserAndToken(ctx);
|
||||
@@ -224,7 +224,7 @@ export class UserController extends AbstractController {
|
||||
path: '/-/npm/v1/user',
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async showProfile(@Context() ctx: EggContext) {
|
||||
async showProfile(@HTTPContext() ctx: Context) {
|
||||
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(
|
||||
ctx,
|
||||
'read'
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import type { FixNoPaddingVersionService } from '../../../core/service/FixNoPaddingVersionService.ts';
|
||||
@@ -21,7 +21,7 @@ export class PaddingVersionController extends AbstractController {
|
||||
path: '/-/admin/npm/fixPaddingVersion',
|
||||
})
|
||||
async fixNoPaddingVersion(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPQuery() id: string
|
||||
) {
|
||||
const isAdmin = await this.userRoleManager.isAdmin(ctx);
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import { PassThrough } from 'node:stream';
|
||||
import { NotFoundError } from 'egg-errors';
|
||||
|
||||
import { NotFoundError } from 'egg/errors';
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import {
|
||||
@@ -41,7 +42,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
path: `/:fullname(${FULLNAME_REG_STRING})/-/:filenameWithVersion.tgz`,
|
||||
method: HTTPMethodEnum.OPTIONS,
|
||||
})
|
||||
async downloadForOptions(@Context() ctx: EggContext) {
|
||||
async downloadForOptions(@HTTPContext() ctx: Context) {
|
||||
ctx.set('access-control-allow-origin', '*');
|
||||
ctx.set('access-control-allow-methods', 'GET,HEAD');
|
||||
ctx.status = 204;
|
||||
@@ -53,7 +54,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async download(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() filenameWithVersion: string
|
||||
) {
|
||||
@@ -132,7 +133,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async deprecatedDownload(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() fullnameWithVersion: string
|
||||
) {
|
||||
@@ -143,7 +144,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
}
|
||||
|
||||
private async getTgzProxyStream(
|
||||
ctx: EggContext,
|
||||
ctx: Context,
|
||||
fullname: string,
|
||||
version: string
|
||||
) {
|
||||
@@ -175,7 +176,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
path: `/:fullname(${FULLNAME_REG_STRING})/-/:scope/:filenameWithVersion.tgz`,
|
||||
method: HTTPMethodEnum.OPTIONS,
|
||||
})
|
||||
async downloadVerdaccioPathStyleorOptions(@Context() ctx: EggContext) {
|
||||
async downloadVerdaccioPathStyleorOptions(@HTTPContext() ctx: Context) {
|
||||
return this.downloadForOptions(ctx);
|
||||
}
|
||||
|
||||
@@ -185,7 +186,7 @@ export class DownloadPackageVersionTarController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async downloadVerdaccioPathStyle(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() filenameWithVersion: string
|
||||
) {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { BadRequestError, ForbiddenError } from 'egg-errors';
|
||||
import { BadRequestError, ForbiddenError } from 'egg/errors';
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import { FULLNAME_REG_STRING } from '../../../common/PackageUtil.ts';
|
||||
@@ -34,7 +34,7 @@ export class RemovePackageVersionController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async removeByTarballUrl(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() filenameWithVersion: string
|
||||
) {
|
||||
@@ -68,7 +68,7 @@ export class RemovePackageVersionController extends AbstractController {
|
||||
method: HTTPMethodEnum.DELETE,
|
||||
})
|
||||
async removeByPkgUri(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string
|
||||
) {
|
||||
const npmCommand = ctx.get('npm-command');
|
||||
|
||||
@@ -4,9 +4,9 @@ import {
|
||||
ConflictError,
|
||||
ForbiddenError,
|
||||
UnprocessableEntityError,
|
||||
} from 'egg-errors';
|
||||
} from 'egg/errors';
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import { checkData, fromData } from 'ssri';
|
||||
import validateNpmPackageName from 'validate-npm-package-name';
|
||||
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||
@@ -110,7 +110,7 @@ export class SavePackageVersionController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async save(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPBody() pkg: FullPackage
|
||||
) {
|
||||
@@ -334,7 +334,7 @@ export class SavePackageVersionController extends AbstractController {
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
private validateNpmCommand(ctx: EggContext) {
|
||||
private validateNpmCommand(ctx: Context) {
|
||||
// forbidden star/unstar request
|
||||
// npm@6: referer: 'star [REDACTED]'
|
||||
// npm@>=7: 'npm-command': 'star'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
@@ -8,9 +8,9 @@ import {
|
||||
HTTPQuery,
|
||||
Inject,
|
||||
Middleware,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||
import { E451 } from 'egg-errors';
|
||||
import { E451 } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import type { SearchQueryOptions } from '../../typebox.ts';
|
||||
@@ -29,7 +29,7 @@ export class SearchPackageController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async search(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPQuery() text: Static<typeof SearchQueryOptions>['text'],
|
||||
@HTTPQuery() from: Static<typeof SearchQueryOptions>['from'],
|
||||
@HTTPQuery() size: Static<typeof SearchQueryOptions>['size']
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import {
|
||||
@@ -36,7 +36,7 @@ export class ShowPackageController extends AbstractController {
|
||||
path: `/:fullname(${FULLNAME_REG_STRING})`,
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async show(@Context() ctx: EggContext, @HTTPParam() fullname: string) {
|
||||
async show(@HTTPContext() ctx: Context, @HTTPParam() fullname: string) {
|
||||
const [scope, name] = getScopeAndName(fullname);
|
||||
const isSync = isSyncWorkerRequest(ctx);
|
||||
const isFullManifests =
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPController,
|
||||
HTTPMethod,
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
import { NotFoundError } from 'egg-errors';
|
||||
} from 'egg';
|
||||
import { NotFoundError } from 'egg/errors';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
import {
|
||||
@@ -34,7 +34,7 @@ export class ShowPackageVersionController extends AbstractController {
|
||||
method: HTTPMethodEnum.GET,
|
||||
})
|
||||
async show(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPParam() versionSpec: string
|
||||
) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { BadRequestError, UnprocessableEntityError } from 'egg-errors';
|
||||
import { BadRequestError, UnprocessableEntityError } from 'egg/errors';
|
||||
import {
|
||||
type EggContext,
|
||||
HTTPContext,
|
||||
Context,
|
||||
HTTPBody,
|
||||
HTTPController,
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
HTTPMethodEnum,
|
||||
HTTPParam,
|
||||
Inject,
|
||||
} from '@eggjs/tegg';
|
||||
} from 'egg';
|
||||
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||
|
||||
import { AbstractController } from '../AbstractController.ts';
|
||||
@@ -39,7 +39,7 @@ export class UpdatePackageController extends AbstractController {
|
||||
method: HTTPMethodEnum.PUT,
|
||||
})
|
||||
async update(
|
||||
@Context() ctx: EggContext,
|
||||
@HTTPContext() ctx: Context,
|
||||
@HTTPParam() fullname: string,
|
||||
@HTTPBody() data: Maintainer
|
||||
) {
|
||||
@@ -83,7 +83,7 @@ export class UpdatePackageController extends AbstractController {
|
||||
return { ok: true };
|
||||
}
|
||||
|
||||
private getNpmCommand(ctx: EggContext) {
|
||||
private getNpmCommand(ctx: Context) {
|
||||
// npm@6: referer: 'xxx [REDACTED]'
|
||||
// npm@>=7: 'npm-command': 'xxx'
|
||||
let npmCommand = ctx.get<string>('npm-command');
|
||||
@@ -94,7 +94,7 @@ export class UpdatePackageController extends AbstractController {
|
||||
return npmCommand;
|
||||
}
|
||||
|
||||
private isNpmCommandValid(ctx: EggContext, expectCommand: string) {
|
||||
private isNpmCommandValid(ctx: Context, expectCommand: string) {
|
||||
const npmCommand = this.getNpmCommand(ctx);
|
||||
|
||||
return npmCommand === expectCommand;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { EggContext, Next } from '@eggjs/tegg';
|
||||
import { ForbiddenError } from 'egg-errors';
|
||||
import type { Context, Next } from 'egg';
|
||||
import { ForbiddenError } from 'egg/errors';
|
||||
|
||||
import { UserRoleManager } from '../UserRoleManager.ts';
|
||||
|
||||
export async function AdminAccess(ctx: EggContext, next: Next) {
|
||||
export async function AdminAccess(ctx: Context, next: Next) {
|
||||
const userRoleManager = await ctx.getEggObject(UserRoleManager);
|
||||
const isAdmin = await userRoleManager.isAdmin(ctx);
|
||||
if (!isAdmin) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import type { EggContext, Next } from '@eggjs/tegg';
|
||||
import type { Context, Next } from 'egg';
|
||||
|
||||
import { UserRoleManager } from '../UserRoleManager.ts';
|
||||
|
||||
export async function AlwaysAuth(ctx: EggContext, next: Next) {
|
||||
export async function AlwaysAuth(ctx: Context, next: Next) {
|
||||
if (ctx.app.config.cnpmcore.alwaysAuth) {
|
||||
// ignore login request: `PUT /-/user/org.couchdb.user::username`
|
||||
const isLoginRequest =
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { EggContext, Next } from '@eggjs/tegg';
|
||||
import type { Context, Next } from 'egg';
|
||||
|
||||
import { PackageSyncerService } from '../../core/service/PackageSyncerService.ts';
|
||||
|
||||
const DEFAULT_SERVER_ERROR_STATUS = 500;
|
||||
|
||||
export async function ErrorHandler(ctx: EggContext, next: Next) {
|
||||
export async function ErrorHandler(ctx: Context, next: Next) {
|
||||
try {
|
||||
await next();
|
||||
} catch (err) {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user