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:
MK (fengmk2)
2025-10-28 22:17:01 +08:00
committed by GitHub
parent e1848c71ec
commit 89f1250927
165 changed files with 839 additions and 586 deletions

View File

@@ -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

View File

@@ -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 {

View File

@@ -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:

View File

@@ -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
View 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

View File

@@ -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
View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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 {

View File

@@ -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) {

View File

@@ -1,4 +1,5 @@
import { AccessLevel, SingletonProto } from '@eggjs/tegg';
import { AccessLevel, SingletonProto } from 'egg';
import type { BugVersion } from '../../core/entity/BugVersion.ts';
@SingletonProto({

View File

@@ -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';

View File

@@ -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) {

View File

@@ -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',

View File

@@ -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(

View File

@@ -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,

View File

@@ -1,5 +1,7 @@
import path from 'node:path';
import { SingletonProto } from '@eggjs/tegg';
import { SingletonProto } from 'egg';
import binaries, {
type BinaryName,
type BinaryTaskConfig,

View File

@@ -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,

View File

@@ -1,4 +1,5 @@
import { SingletonProto } from '@eggjs/tegg';
import { SingletonProto } from 'egg';
import { BinaryType } from '../../enum/Binary.ts';
import {
AbstractBinary,

View File

@@ -1,5 +1,7 @@
import path from 'node:path';
import { SingletonProto } from '@eggjs/tegg';
import { SingletonProto } from 'egg';
import {
AbstractBinary,
BinaryAdapter,

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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';

View File

@@ -1,4 +1,5 @@
import { SingletonProto } from '@eggjs/tegg';
import { SingletonProto } from 'egg';
import { BinaryType } from '../../enum/Binary.ts';
import {
AbstractBinary,

View File

@@ -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(

View File

@@ -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',

View File

@@ -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',

View File

@@ -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',

View File

@@ -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());

View File

@@ -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>;
}

View File

@@ -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';

View File

@@ -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;

View File

@@ -1,4 +1,5 @@
import { Event, Inject } from '@eggjs/tegg';
import { Event, Inject } from 'egg';
import {
PACKAGE_BLOCKED,
PACKAGE_MAINTAINER_CHANGED,

View File

@@ -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;

View File

@@ -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()

View File

@@ -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;

View File

@@ -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()

View File

@@ -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';

View File

@@ -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>;

View File

@@ -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 }

View File

@@ -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;

View File

@@ -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';

View File

@@ -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,

View File

@@ -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';

View File

@@ -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,

View File

@@ -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) {

View File

@@ -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';

View File

@@ -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;

View File

@@ -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',

View File

@@ -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';

View File

@@ -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';

View File

@@ -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 }

View File

@@ -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';

View File

@@ -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';

View File

@@ -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

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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';

View File

@@ -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, '');

View File

@@ -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;

View File

@@ -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';

View File

@@ -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 插件引入

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 {

View File

@@ -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

View File

@@ -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;

View File

@@ -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 {

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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
) {

View File

@@ -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
) {

View File

@@ -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,

View File

@@ -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');

View File

@@ -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>
) {

View File

@@ -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'

View File

@@ -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);

View File

@@ -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'

View File

@@ -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);

View File

@@ -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
) {

View File

@@ -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');

View File

@@ -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'

View File

@@ -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']

View File

@@ -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 =

View File

@@ -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
) {

View File

@@ -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;

View File

@@ -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) {

View File

@@ -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 =

View File

@@ -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