cnpmcore
Version:
Private NPM Registry for Enterprise
217 lines • 17.6 kB
JavaScript
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};
import { Context, HTTPBody, HTTPContext, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, Inject, Middleware, } from 'egg';
import { NotFoundError, UnprocessableEntityError } from 'egg/errors';
import { AdminAccess } from "../middleware/AdminAccess.js";
import { AbstractController } from "./AbstractController.js";
let OrgController = class OrgController extends AbstractController {
// PUT /-/org — Admin only
async createOrg(ctx, body) {
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting');
if (!body.name) {
throw new UnprocessableEntityError('name is required');
}
await this.orgService.createOrg({
name: body.name,
description: body.description,
creatorUserId: authorizedUser.userId,
});
return { ok: true };
}
// GET /-/org/:orgName
async showOrg(ctx, orgName) {
await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
return {
name: org.name,
description: org.description,
created: org.createdAt,
};
}
// DELETE /-/org/:orgName — Admin only
async removeOrg(ctx, orgName) {
await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
await this.orgService.removeOrg(org.orgId);
return { ok: true };
}
// GET /-/org/:orgName/member — npm org ls
async listMembers(ctx, orgName) {
await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
const members = await this.orgService.listMembers(org.orgId);
const users = await this.userRepository.findUsersByUserIds(members.map((m) => m.userId));
const userMap = new Map(users.map((u) => [u.userId, u]));
const result = {};
for (const member of members) {
const user = userMap.get(member.userId);
if (user) {
result[user.displayName] = member.role;
}
}
return result;
}
// PUT /-/org/:orgName/member — npm org set
async addMember(ctx, orgName, body) {
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
const isAdmin = await this.userRoleManager.isAdmin(ctx);
await this.orgService.requiredOrgOwnerOrAdmin(org.orgId, authorizedUser.userId, isAdmin);
if (!body.user) {
throw new UnprocessableEntityError('user is required');
}
const targetUser = await this.userRepository.findUserByName(body.user);
if (!targetUser) {
throw new NotFoundError(`User "${body.user}" not found`);
}
await this.orgService.addMember(org.orgId, targetUser.userId, body.role || 'member');
return { ok: true };
}
// DELETE /-/org/:orgName/member/:username — npm org rm
async removeMember(ctx, orgName, username) {
const authorizedUser = await this.userRoleManager.requiredAuthorizedUser(ctx, 'setting');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
const isAdmin = await this.userRoleManager.isAdmin(ctx);
await this.orgService.requiredOrgOwnerOrAdmin(org.orgId, authorizedUser.userId, isAdmin);
const targetUser = await this.userRepository.findUserByName(username);
if (!targetUser) {
throw new NotFoundError(`User "${username}" not found`);
}
await this.orgService.removeMember(org.orgId, targetUser.userId);
return { ok: true };
}
// GET /-/org/:orgName/member/:username/team
async listUserTeams(ctx, orgName, username) {
await this.userRoleManager.requiredAuthorizedUser(ctx, 'read');
const org = await this.orgService.findOrgByName(orgName);
if (!org) {
throw new NotFoundError(`Org "${orgName}" not found`);
}
const targetUser = await this.userRepository.findUserByName(username);
if (!targetUser) {
throw new NotFoundError(`User "${username}" not found`);
}
const teamResults = await this.teamRepository.listTeamsByUserIdAndOrgId(targetUser.userId, org.orgId);
return teamResults.map((t) => ({ name: t.team.name, description: t.team.description, role: t.role }));
}
};
__decorate([
Inject(),
__metadata("design:type", Function)
], OrgController.prototype, "orgService", void 0);
__decorate([
Inject(),
__metadata("design:type", Function)
], OrgController.prototype, "teamRepository", void 0);
__decorate([
HTTPMethod({
path: '/-/org',
method: HTTPMethodEnum.PUT,
}),
Middleware(AdminAccess),
__param(0, HTTPContext()),
__param(1, HTTPBody()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, Object]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "createOrg", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName',
method: HTTPMethodEnum.GET,
}),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "showOrg", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName',
method: HTTPMethodEnum.DELETE,
}),
Middleware(AdminAccess),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "removeOrg", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName/member',
method: HTTPMethodEnum.GET,
}),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "listMembers", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName/member',
method: HTTPMethodEnum.PUT,
}),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__param(2, HTTPBody()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String, Object]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "addMember", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName/member/:username',
method: HTTPMethodEnum.DELETE,
}),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__param(2, HTTPParam()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String, String]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "removeMember", null);
__decorate([
HTTPMethod({
path: '/-/org/:orgName/member/:username/team',
method: HTTPMethodEnum.GET,
}),
__param(0, HTTPContext()),
__param(1, HTTPParam()),
__param(2, HTTPParam()),
__metadata("design:type", Function),
__metadata("design:paramtypes", [Context, String, String]),
__metadata("design:returntype", Promise)
], OrgController.prototype, "listUserTeams", null);
OrgController = __decorate([
HTTPController()
], OrgController);
export { OrgController };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiT3JnQ29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FwcC9wb3J0L2NvbnRyb2xsZXIvT3JnQ29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQ0wsT0FBTyxFQUNQLFFBQVEsRUFDUixXQUFXLEVBQ1gsY0FBYyxFQUNkLFVBQVUsRUFDVixjQUFjLEVBQ2QsU0FBUyxFQUNULE1BQU0sRUFDTixVQUFVLEdBQ1gsTUFBTSxLQUFLLENBQUM7QUFDYixPQUFPLEVBQUUsYUFBYSxFQUFFLHdCQUF3QixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBSXJFLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUd0RCxJQUFNLGFBQWEsR0FBbkIsTUFBTSxhQUFjLFNBQVEsa0JBQWtCO0lBT25ELDBCQUEwQjtJQU1wQixBQUFOLEtBQUssQ0FBQyxTQUFTLENBQWdCLEdBQVksRUFBYyxJQUE0QztRQUNuRyxNQUFNLGNBQWMsR0FBRyxNQUFNLElBQUksQ0FBQyxlQUFlLENBQUMsc0JBQXNCLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQ3pGLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksd0JBQXdCLENBQUMsa0JBQWtCLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQztZQUM5QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDN0IsYUFBYSxFQUFFLGNBQWMsQ0FBQyxNQUFNO1NBQ3JDLENBQUMsQ0FBQztRQUNILE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7SUFDdEIsQ0FBQztJQUVE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