refactor: use tegg and egg v4 beta (#836)
🦀 for https://github.com/eggjs/egg/issues/3644
This commit is contained in:
@@ -13,7 +13,10 @@
|
|||||||
"no-console": "warn",
|
"no-console": "warn",
|
||||||
"import/no-anonymous-default-export": "error",
|
"import/no-anonymous-default-export": "error",
|
||||||
"no-unassigned-import": "allow",
|
"no-unassigned-import": "allow",
|
||||||
"new-cap": "allow"
|
"new-cap": "allow",
|
||||||
|
"class-methods-use-this": "allow",
|
||||||
|
"import/no-named-export": "allow",
|
||||||
|
"unicorn/no-array-sort": "allow"
|
||||||
},
|
},
|
||||||
"ignorePatterns": ["index.d.ts"]
|
"ignorePatterns": ["index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,6 @@
|
|||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
|
"printWidth": 120,
|
||||||
"arrowParens": "avoid"
|
"arrowParens": "avoid"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ private async getPackageEntity(scope: string, name: string) {
|
|||||||
|
|
||||||
#### 1、请求参数校验
|
#### 1、请求参数校验
|
||||||
|
|
||||||
使用 [egg-typebox-validate](https://github.com/xiekw2010/egg-typebox-validate) 来做请求参数校验,只需要定义一次参数类型和规则,就能同时拥有参数校验和类型定义。
|
使用 [@eggjs/typebox-validate](https://github.com/eggjs/egg/tree/next/plugins/typebox-validate) 来做请求参数校验,只需要定义一次参数类型和规则,就能同时拥有参数校验和类型定义。
|
||||||
详细使用方式可以参考 [PR#12](https://github.com/cnpm/cnpmcore/pull/12)。
|
详细使用方式可以参考 [PR#12](https://github.com/cnpm/cnpmcore/pull/12)。
|
||||||
|
|
||||||
使用方式请直接参考 `app/port/typebox.ts` 代码。
|
使用方式请直接参考 `app/port/typebox.ts` 代码。
|
||||||
|
|||||||
@@ -73,7 +73,7 @@
|
|||||||
},
|
},
|
||||||
typeboxValidate: {
|
typeboxValidate: {
|
||||||
enable: true,
|
enable: true,
|
||||||
package: 'egg-typebox-validate',
|
package: '@eggjs/typebox-validate',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
1
app.ts
1
app.ts
@@ -1,6 +1,7 @@
|
|||||||
import path from 'node:path';
|
import path from 'node:path';
|
||||||
import { readFile } from 'node:fs/promises';
|
import { readFile } from 'node:fs/promises';
|
||||||
import type { Application, ILifecycleBoot } from 'egg';
|
import type { Application, ILifecycleBoot } from 'egg';
|
||||||
|
|
||||||
import { ChangesStreamService } from './app/core/service/ChangesStreamService.js';
|
import { ChangesStreamService } from './app/core/service/ChangesStreamService.js';
|
||||||
|
|
||||||
declare module 'egg' {
|
declare module 'egg' {
|
||||||
|
|||||||
@@ -77,8 +77,6 @@ export interface AuthClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
declare module 'egg' {
|
declare module 'egg' {
|
||||||
// oxlint-disable-next-line prefer-ts-expect-error ban-ts-comment
|
|
||||||
// @ts-ignore
|
|
||||||
interface EggAppConfig {
|
interface EggAppConfig {
|
||||||
cnpmcore: CnpmcoreConfig;
|
cnpmcore: CnpmcoreConfig;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -140,16 +140,20 @@ export class UserRoleManager {
|
|||||||
`Read-only Token "${token.tokenMark}" can't publish`
|
`Read-only Token "${token.tokenMark}" can't publish`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const userAgent: string = ctx.get('user-agent');
|
||||||
// only support npm >= 7.0.0 allow publish action
|
// only support npm >= 7.0.0 allow publish action
|
||||||
// user-agent: "npm/6.14.12 node/v10.24.1 darwin x64"
|
// user-agent: "npm/6.14.12 node/v10.24.1 darwin x64"
|
||||||
const m = /\bnpm\/(\d{1,5})\./.exec(ctx.get('user-agent'));
|
// pnpm: "pnpm/10.17.0 npm/? node/v20.19.5 darwin arm64"
|
||||||
if (!m) {
|
const isPnpm = userAgent.startsWith('pnpm/');
|
||||||
|
const m = /\bnpm\/(\d{1,5})\./.exec(userAgent);
|
||||||
|
if (m) {
|
||||||
|
const major = Number.parseInt(m[1]);
|
||||||
|
if (major < 7) {
|
||||||
|
throw new ForbiddenError('Only allow npm@>=7.0.0 client to access');
|
||||||
|
}
|
||||||
|
} else if (!isPnpm) {
|
||||||
throw new ForbiddenError('Only allow npm client to access');
|
throw new ForbiddenError('Only allow npm client to access');
|
||||||
}
|
}
|
||||||
const major = Number.parseInt(m[1]);
|
|
||||||
if (major < 7) {
|
|
||||||
throw new ForbiddenError('Only allow npm@>=7.0.0 client to access');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (role === 'setting') {
|
if (role === 'setting') {
|
||||||
if (token.isReadonly) {
|
if (token.isReadonly) {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
HTTPQuery,
|
HTTPQuery,
|
||||||
Inject,
|
Inject,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { Type } from 'egg-typebox-validate/typebox';
|
import { Type } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
import type { ChangeRepository } from '../../repository/ChangeRepository.js';
|
import type { ChangeRepository } from '../../repository/ChangeRepository.js';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
|
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
import type { ProxyCacheRepository } from '../../repository/ProxyCacheRepository.js';
|
import type { ProxyCacheRepository } from '../../repository/ProxyCacheRepository.js';
|
||||||
import type { Static } from 'egg-typebox-validate/typebox';
|
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||||
import type { QueryPageOptions } from '../typebox.js';
|
import type { QueryPageOptions } from '../typebox.js';
|
||||||
import { FULLNAME_REG_STRING } from '../../common/PackageUtil.js';
|
import { FULLNAME_REG_STRING } from '../../common/PackageUtil.js';
|
||||||
import type { ProxyCacheService } from '../../core/service/ProxyCacheService.js';
|
import type { ProxyCacheService } from '../../core/service/ProxyCacheService.js';
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import {
|
|||||||
Middleware,
|
Middleware,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { NotFoundError } from 'egg-errors';
|
import { NotFoundError } from 'egg-errors';
|
||||||
import type { Static } from 'egg-typebox-validate/typebox';
|
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
import type {
|
import type {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import {
|
|||||||
Middleware,
|
Middleware,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { E400 } from 'egg-errors';
|
import { E400 } from 'egg-errors';
|
||||||
import type { Static } from 'egg-typebox-validate/typebox';
|
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
import { AdminAccess } from '../middleware/AdminAccess.js';
|
import { AdminAccess } from '../middleware/AdminAccess.js';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
HTTPParam,
|
HTTPParam,
|
||||||
Inject,
|
Inject,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import type { AuthAdapter } from '../../infra/AuthAdapter.js';
|
import type { AuthAdapter } from '../../infra/AuthAdapter.js';
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
UnauthorizedError,
|
UnauthorizedError,
|
||||||
UnprocessableEntityError,
|
UnprocessableEntityError,
|
||||||
} from 'egg-errors';
|
} from 'egg-errors';
|
||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from './AbstractController.js';
|
import { AbstractController } from './AbstractController.js';
|
||||||
import { LoginResultCode } from '../../common/enum/User.js';
|
import { LoginResultCode } from '../../common/enum/User.js';
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ import {
|
|||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { checkData, fromData } from 'ssri';
|
import { checkData, fromData } from 'ssri';
|
||||||
import validateNpmPackageName from 'validate-npm-package-name';
|
import validateNpmPackageName from 'validate-npm-package-name';
|
||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from '../AbstractController.js';
|
import { AbstractController } from '../AbstractController.js';
|
||||||
import {
|
import {
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
Middleware,
|
Middleware,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import type { Static } from 'egg-typebox-validate/typebox';
|
import type { Static } from '@eggjs/typebox-validate/typebox';
|
||||||
import { E451 } from 'egg-errors';
|
import { E451 } from 'egg-errors';
|
||||||
|
|
||||||
import { AbstractController } from '../AbstractController.js';
|
import { AbstractController } from '../AbstractController.js';
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
HTTPParam,
|
HTTPParam,
|
||||||
Inject,
|
Inject,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
|
|
||||||
import { AbstractController } from '../AbstractController.js';
|
import { AbstractController } from '../AbstractController.js';
|
||||||
import { FULLNAME_REG_STRING } from '../../../common/PackageUtil.js';
|
import { FULLNAME_REG_STRING } from '../../../common/PackageUtil.js';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
import npa from 'npm-package-arg';
|
import npa from 'npm-package-arg';
|
||||||
import { uniq } from 'lodash-es';
|
import { uniq } from 'lodash-es';
|
||||||
import type { Ajv } from 'egg-typebox-validate';
|
import type { Ajv } from '@eggjs/typebox-validate';
|
||||||
|
|
||||||
import { RegistryType } from '../common/enum/Registry.js';
|
import { RegistryType } from '../common/enum/Registry.js';
|
||||||
import { HookType } from '../common/enum/Hook.js';
|
import { HookType } from '../common/enum/Hook.js';
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import {
|
|||||||
Inject,
|
Inject,
|
||||||
} from '@eggjs/tegg';
|
} from '@eggjs/tegg';
|
||||||
import type { EggAppConfig, EggLogger } from 'egg';
|
import type { EggAppConfig, EggLogger } from 'egg';
|
||||||
import { Type, type Static } from 'egg-typebox-validate/typebox';
|
import '@eggjs/typebox-validate';
|
||||||
|
import { Type, type Static } from '@eggjs/typebox-validate/typebox';
|
||||||
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
import { ForbiddenError, NotFoundError } from 'egg-errors';
|
||||||
import { createHash } from 'node:crypto';
|
import { createHash } from 'node:crypto';
|
||||||
import base64url from 'base64url';
|
import base64url from 'base64url';
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import assert from 'node:assert/strict';
|
import assert from 'node:assert/strict';
|
||||||
import { randomUUID } from 'node:crypto';
|
import { randomUUID } from 'node:crypto';
|
||||||
import { join } from 'node:path';
|
import { join } from 'node:path';
|
||||||
import type { Context, EggAppConfig, PowerPartial } from 'egg';
|
|
||||||
|
import type { Context, EggAppConfig, PartialEggConfig } from 'egg';
|
||||||
import OSSClient from 'oss-cnpm';
|
import OSSClient from 'oss-cnpm';
|
||||||
import S3Client from 's3-cnpmcore';
|
import S3Client from 's3-cnpmcore';
|
||||||
import { env } from 'read-env-value';
|
import { env } from 'read-env-value';
|
||||||
@@ -84,9 +85,9 @@ export interface NFSConfig {
|
|||||||
removeBeforeUpload: boolean;
|
removeBeforeUpload: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Config = PowerPartial<EggAppConfig> & { nfs: NFSConfig };
|
export type Config = PartialEggConfig & { nfs: NFSConfig };
|
||||||
|
|
||||||
export default function startConfig(appInfo: EggAppConfig) {
|
export default function startConfig(appInfo: EggAppConfig): Config {
|
||||||
const config = {} as Config;
|
const config = {} as Config;
|
||||||
|
|
||||||
config.keys = env('CNPMCORE_EGG_KEYS', 'string', randomUUID());
|
config.keys = env('CNPMCORE_EGG_KEYS', 'string', randomUUID());
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { database } from './database.js';
|
|||||||
// @ts-expect-error has no construct signatures
|
// @ts-expect-error has no construct signatures
|
||||||
export const mockES = new Mock();
|
export const mockES = new Mock();
|
||||||
|
|
||||||
export default function startConfig(appInfo: EggAppConfig) {
|
export default function startConfig(appInfo: EggAppConfig): PowerPartial<EggAppConfig> {
|
||||||
const config = {} as PowerPartial<EggAppConfig>;
|
const config = {} as PowerPartial<EggAppConfig>;
|
||||||
config.dataDir = join(appInfo.root, '.cnpmcore_unittest');
|
config.dataDir = join(appInfo.root, '.cnpmcore_unittest');
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ const plugin: EggPlugin = {
|
|||||||
},
|
},
|
||||||
typeboxValidate: {
|
typeboxValidate: {
|
||||||
enable: true,
|
enable: true,
|
||||||
package: 'egg-typebox-validate',
|
package: '@eggjs/typebox-validate',
|
||||||
},
|
},
|
||||||
redis: {
|
redis: {
|
||||||
enable: true,
|
enable: true,
|
||||||
|
|||||||
28
package.json
28
package.json
@@ -41,24 +41,25 @@
|
|||||||
"dev:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin dev",
|
"dev:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin dev",
|
||||||
"lint": "oxlint",
|
"lint": "oxlint",
|
||||||
"lint:fix": "npm run lint -- --fix",
|
"lint:fix": "npm run lint -- --fix",
|
||||||
"test:postgresql": "npm run lint:fix && npm run test:local:postgresql",
|
"typecheck": "tsc --noEmit",
|
||||||
|
"test:postgresql": "npm run lint && npm run test:local:postgresql",
|
||||||
"pretest:local:postgresql": "bash prepare-database-postgresql.sh",
|
"pretest:local:postgresql": "bash prepare-database-postgresql.sh",
|
||||||
"test:local:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin test",
|
"test:local:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin test",
|
||||||
"pretest": "npm run clean",
|
"pretest": "npm run clean",
|
||||||
"test": "npm run lint:fix && npm run test:local",
|
"test": "npm run lint && npm run typecheck && npm run test:local",
|
||||||
"pretest:local": "bash prepare-database-mysql.sh",
|
"pretest:local": "bash prepare-database-mysql.sh",
|
||||||
"test:local": "egg-bin test",
|
"test:local": "egg-bin test",
|
||||||
"pret": "bash prepare-database-mysql.sh",
|
"pret": "bash prepare-database-mysql.sh",
|
||||||
"t": "npm run lint:fix && egg-bin test --changed",
|
"t": "npm run lint && egg-bin test --changed",
|
||||||
"precov": "bash prepare-database-mysql.sh",
|
"precov": "bash prepare-database-mysql.sh",
|
||||||
"cov": "egg-bin cov",
|
"cov": "egg-bin cov",
|
||||||
"precov:postgresql": "bash prepare-database-postgresql.sh",
|
"precov:postgresql": "bash prepare-database-postgresql.sh",
|
||||||
"cov:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin cov",
|
"cov:postgresql": "CNPMCORE_DATABASE_TYPE=PostgreSQL egg-bin cov",
|
||||||
"preci": "npm run clean && npm run lint",
|
"preci": "npm run clean && npm run lint && npm run typecheck",
|
||||||
"ci": "npm run cov ",
|
"ci": "npm run cov ",
|
||||||
"postci": "npm run tsc:prod && npm run clean",
|
"postci": "npm run tsc:prod && npm run clean",
|
||||||
"ci:postgresql": "npm run lint && npm run cov:postgresql && npm run tsc:prod && npm run clean",
|
"ci:postgresql": "npm run lint && npm run cov:postgresql && npm run tsc:prod && npm run clean",
|
||||||
"clean": "tsc -b --clean && rm -rf dist",
|
"clean": "tsc -b --clean && rm -rf dist *.tsbuildinfo",
|
||||||
"tsc": "npm run clean && tsc -p ./tsconfig.json",
|
"tsc": "npm run clean && tsc -p ./tsconfig.json",
|
||||||
"tsc:prod": "npm run clean && tsc -p ./tsconfig.prod.json",
|
"tsc:prod": "npm run clean && tsc -p ./tsconfig.prod.json",
|
||||||
"prepublishOnly": "npm run tsc:prod",
|
"prepublishOnly": "npm run tsc:prod",
|
||||||
@@ -88,7 +89,7 @@
|
|||||||
"mocha": "11.6.0"
|
"mocha": "11.6.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@eggjs/redis": "^3.0.0",
|
"@eggjs/redis": "beta",
|
||||||
"@eggjs/scripts": "^4.0.0",
|
"@eggjs/scripts": "^4.0.0",
|
||||||
"@eggjs/tegg": "beta",
|
"@eggjs/tegg": "beta",
|
||||||
"@eggjs/tegg-aop-plugin": "beta",
|
"@eggjs/tegg-aop-plugin": "beta",
|
||||||
@@ -99,7 +100,8 @@
|
|||||||
"@eggjs/tegg-orm-plugin": "beta",
|
"@eggjs/tegg-orm-plugin": "beta",
|
||||||
"@eggjs/tegg-plugin": "beta",
|
"@eggjs/tegg-plugin": "beta",
|
||||||
"@eggjs/tegg-schedule-plugin": "beta",
|
"@eggjs/tegg-schedule-plugin": "beta",
|
||||||
"@eggjs/tracer": "^3.0.0",
|
"@eggjs/tracer": "beta",
|
||||||
|
"@eggjs/typebox-validate": "beta",
|
||||||
"@elastic/elasticsearch": "^8.8.1",
|
"@elastic/elasticsearch": "^8.8.1",
|
||||||
"@fengmk2/tar": "^6.2.0",
|
"@fengmk2/tar": "^6.2.0",
|
||||||
"@node-rs/crc32": "^1.2.2",
|
"@node-rs/crc32": "^1.2.2",
|
||||||
@@ -108,11 +110,10 @@
|
|||||||
"base64url": "^3.0.1",
|
"base64url": "^3.0.1",
|
||||||
"bson-objectid": "^2.0.4",
|
"bson-objectid": "^2.0.4",
|
||||||
"dayjs": "^1.10.7",
|
"dayjs": "^1.10.7",
|
||||||
"egg": "^4.0.8",
|
"egg": "beta",
|
||||||
"egg-cors": "^3.0.0",
|
"egg-cors": "^3.0.0",
|
||||||
"egg-errors": "^2.3.0",
|
"egg-errors": "^2.3.0",
|
||||||
"egg-status": "^1.0.0",
|
"egg-status": "^1.0.0",
|
||||||
"egg-typebox-validate": "^3.0.0",
|
|
||||||
"egg-view-nunjucks": "^2.3.0",
|
"egg-view-nunjucks": "^2.3.0",
|
||||||
"eggjs-elasticsearch": "^0.0.6",
|
"eggjs-elasticsearch": "^0.0.6",
|
||||||
"fast-xml-parser": "^5.0.9",
|
"fast-xml-parser": "^5.0.9",
|
||||||
@@ -138,10 +139,10 @@
|
|||||||
"s3-cnpmcore": "^1.1.2"
|
"s3-cnpmcore": "^1.1.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@eggjs/bin": "^7.1.0",
|
"@eggjs/bin": "beta",
|
||||||
"@eggjs/mock": "^6.0.7",
|
"@eggjs/mock": "beta",
|
||||||
"@eggjs/oxlint-config": "^1.0.0",
|
"@eggjs/oxlint-config": "^1.0.0",
|
||||||
"@eggjs/tsconfig": "^2.0.0",
|
"@eggjs/tsconfig": "beta",
|
||||||
"@elastic/elasticsearch-mock": "^2.0.0",
|
"@elastic/elasticsearch-mock": "^2.0.0",
|
||||||
"@simplewebauthn/typescript-types": "^7.0.0",
|
"@simplewebauthn/typescript-types": "^7.0.0",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
@@ -159,6 +160,7 @@
|
|||||||
"husky": "^9.1.7",
|
"husky": "^9.1.7",
|
||||||
"lint-staged": "^15.5.0",
|
"lint-staged": "^15.5.0",
|
||||||
"oxlint": "^1.11.0",
|
"oxlint": "^1.11.0",
|
||||||
|
"oxlint-tsgolint": "^0.2.0",
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"typescript": "5"
|
"typescript": "5"
|
||||||
},
|
},
|
||||||
@@ -169,7 +171,7 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/cnpm/cnpmcore#readme",
|
"homepage": "https://github.com/cnpm/cnpmcore#readme",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 20.18.0"
|
"node": "^20.18.0 || >=22.18.0"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"*": "prettier --write --ignore-unknown --cache",
|
"*": "prettier --write --ignore-unknown --cache",
|
||||||
|
|||||||
@@ -263,6 +263,24 @@ describe('test/port/controller/package/UpdatePackageController.test.ts', () => {
|
|||||||
assert.deepEqual(res.body, { ok: true });
|
assert.deepEqual(res.body, { ok: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should support pnpm client', async () => {
|
||||||
|
const user = await TestUtil.createUser();
|
||||||
|
mock(app.config.cnpmcore, 'admins', { [user.name]: user.email });
|
||||||
|
const res = await app
|
||||||
|
.httpRequest()
|
||||||
|
.put(`/${scopedName}/-rev/${rev}`)
|
||||||
|
.set('authorization', user.authorization)
|
||||||
|
.set('user-agent', 'pnpm/7.3.1 npm/?')
|
||||||
|
.set('npm-command', 'owner')
|
||||||
|
.send({
|
||||||
|
_id: rev,
|
||||||
|
_rev: rev,
|
||||||
|
maintainers: [{ name: user.name, email: user.email }],
|
||||||
|
});
|
||||||
|
assert.deepEqual(res.body, { ok: true });
|
||||||
|
assert.equal(res.statusCode, 200);
|
||||||
|
});
|
||||||
|
|
||||||
it('should 403 when npm client invalid', async () => {
|
it('should 403 when npm client invalid', async () => {
|
||||||
const user = await TestUtil.createUser();
|
const user = await TestUtil.createUser();
|
||||||
let res = await app
|
let res = await app
|
||||||
@@ -474,6 +492,24 @@ describe('test/port/controller/package/UpdatePackageController.test.ts', () => {
|
|||||||
})
|
})
|
||||||
.expect(200);
|
.expect(200);
|
||||||
assert.equal(res.body.ok, true);
|
assert.equal(res.body.ok, true);
|
||||||
|
|
||||||
|
// should valid with pnpm10 and npm=?
|
||||||
|
res = await app
|
||||||
|
.httpRequest()
|
||||||
|
.put(`/${scopedName}/-rev/${rev}`)
|
||||||
|
.set('authorization', publisher.authorization)
|
||||||
|
.set('user-agent', 'pnpm/10.0.0 npm/?')
|
||||||
|
.set('npm-command', 'owner')
|
||||||
|
.send({
|
||||||
|
_id: rev,
|
||||||
|
_rev: rev,
|
||||||
|
maintainers: [
|
||||||
|
{ name: user.name, email: user.email },
|
||||||
|
{ name: publisher.name, email: publisher.email },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
.expect(200);
|
||||||
|
assert.equal(res.body.ok, true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"target": "ES2021",
|
"target": "ES2021",
|
||||||
"resolveJsonModule": true,
|
"resolveJsonModule": true,
|
||||||
"useUnknownInCatchVariables": false,
|
"useUnknownInCatchVariables": false,
|
||||||
"declaration": false
|
"declaration": false,
|
||||||
},
|
"erasableSyntaxOnly": false
|
||||||
"exclude": ["test"]
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user