UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

216 lines 16.9 kB
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 path from 'node:path'; import { HTTPContext, Context, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPQuery, Inject, Middleware, HTTPBody, } from 'egg'; import { NotFoundError } from 'egg/errors'; import binaries from "../../../config/binaries.js"; import { AdminAccess } from "../middleware/AdminAccess.js"; import { BinaryNameRule, BinarySubpathRule } from "../typebox.js"; import { AbstractController } from "./AbstractController.js"; let BinarySyncController = class BinarySyncController extends AbstractController { async showBinaryHTML(ctx) { ctx.type = 'html'; return ctx.app.binaryHTML; } async listBinaries() { return Object.entries(binaries).map(([binaryName, binaryConfig]) => { return { name: `${binaryName}/`, category: `${binaryConfig.category}/`, description: binaryConfig.description, distUrl: binaryConfig.distUrl, repoUrl: /^https?:\/\//.test(binaryConfig.repo) ? binaryConfig.repo : `https://github.com/${binaryConfig.repo}`, type: 'dir', url: `${this.config.cnpmcore.registry}/-/binary/${binaryConfig.category}/`, }; }); } async showBinary(ctx, binaryName, subpath, since, limit) { // check binaryName valid try { ctx.tValidate(BinaryNameRule, binaryName); } catch { throw new NotFoundError(`Binary "${binaryName}" not found`); } let limitCount; if (limit) { limitCount = Number(limit); if (Number.isNaN(limitCount)) { throw new NotFoundError(`invalidate limit "${limit}"`); } if (limitCount > 1000) { throw new NotFoundError(`limit should less than 1000, query is "${limit}"`); } } subpath = subpath || '/'; if (subpath === '/') { const items = await this.binarySyncerService.listRootBinaries(binaryName); return this.formatItems(items); } try { ctx.tValidate(BinarySubpathRule, subpath); } catch { throw new NotFoundError(`Binary "${binaryName}/${subpath}" not found`); } subpath = `/${subpath}`; const parsed = path.parse(subpath); const parent = parsed.dir === '/' ? '/' : `${parsed.dir}/`; const name = subpath.endsWith('/') ? `${parsed.base}/` : parsed.base; // 首先查询 binary === category 的情况 let binary = await this.binarySyncerService.findBinary(binaryName, parent, name); if (!binary) { // 查询不到再去查询 mergeCategory 的情况 const category = binaries?.[binaryName]?.category; if (category) { // canvas/v2.6.1/canvas-v2.6.1-node-v57-linux-glibc-x64.tar.gz // -> node-canvas-prebuilt/v2.6.1/node-canvas-prebuilt-v2.6.1-node-v57-linux-glibc-x64.tar.gz binary = await this.binarySyncerService.findBinary(category, parent, name.replace(new RegExp(`^${binaryName}-`), `${category}-`)); } } if (!binary) { throw new NotFoundError(`Binary "${binaryName}${subpath}" not found`); } if (binary.isDir) { let options; if (limitCount && since) { options = { limit: limitCount, since, }; } const items = await this.binarySyncerService.listDirBinaries(binary, options); return this.formatItems(items); } // download file const urlOrStream = await this.binarySyncerService.downloadBinary(binary); if (!urlOrStream) { throw new NotFoundError(`Binary "${binaryName}${subpath}" not found`); } if (typeof urlOrStream === 'string') { ctx.redirect(urlOrStream); return; } ctx.attachment(name); return urlOrStream; } async syncBinary(ctx, binaryName, lastData) { // check binaryName valid try { ctx.tValidate(BinaryNameRule, binaryName); } catch { throw new NotFoundError(`Binary "${binaryName}" not found`); } this.logger.info('SyncBinary: %s, lastData: %j', binaryName, lastData); const task = await this.binarySyncerService.createTask(binaryName, lastData); return { ok: true, taskId: task?.taskId, logPath: task?.logPath, }; } async showBinaryIndex(ctx, binaryName, since, limit) { // check binaryName valid try { ctx.tValidate(BinaryNameRule, binaryName); } catch { throw new NotFoundError(`Binary "${binaryName}" not found`); } return await this.showBinary(ctx, binaryName, '/', since, limit); } formatItems(items) { return items.map((item) => { return { id: item.binaryId, category: item.category, name: item.name, date: item.date, type: item.isDir ? 'dir' : 'file', size: item.isDir ? undefined : item.size, url: `${this.config.cnpmcore.registry}/-/binary/${item.category}${item.parent}${item.name}`, modified: item.updatedAt, }; }); } }; __decorate([ Inject(), __metadata("design:type", Function) ], BinarySyncController.prototype, "binarySyncerService", void 0); __decorate([ HTTPMethod({ path: '/binary.html', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context]), __metadata("design:returntype", Promise) ], BinarySyncController.prototype, "showBinaryHTML", null); __decorate([ HTTPMethod({ path: '/-/binary/', method: HTTPMethodEnum.GET, }), __metadata("design:type", Function), __metadata("design:paramtypes", []), __metadata("design:returntype", Promise) ], BinarySyncController.prototype, "listBinaries", null); __decorate([ HTTPMethod({ path: '/-/binary/:binaryName(@[^/]{1,220}/[^/]{1,220}|[^@/]{1,220})/:subpath(.*)', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPQuery()), __param(4, HTTPQuery()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, String, String]), __metadata("design:returntype", Promise) ], BinarySyncController.prototype, "showBinary", null); __decorate([ HTTPMethod({ path: '/-/binary/:binaryName/sync', method: HTTPMethodEnum.POST, }), Middleware(AdminAccess), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPBody()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, Object]), __metadata("design:returntype", Promise) ], BinarySyncController.prototype, "syncBinary", null); __decorate([ HTTPMethod({ path: '/-/binary/:binaryName(@[^/]{1,220}/[^/]{1,220}|[^@/]{1,220})', method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPQuery()), __param(3, HTTPQuery()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, String]), __metadata("design:returntype", Promise) ], BinarySyncController.prototype, "showBinaryIndex", null); BinarySyncController = __decorate([ HTTPController() ], BinarySyncController); export { BinarySyncController }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQmluYXJ5U3luY0NvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9hcHAvcG9ydC9jb250cm9sbGVyL0JpbmFyeVN5bmNDb250cm9sbGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sSUFBSSxNQUFNLFdBQVcsQ0FBQztBQUU3QixPQUFPLEVBQ0wsV0FBVyxFQUNYLE9BQU8sRUFDUCxjQUFjLEVBQ2QsVUFBVSxFQUNWLGNBQWMsRUFDZCxTQUFTLEVBQ1QsU0FBUyxFQUNULE1BQU0sRUFDTixVQUFVLEVBQ1YsUUFBUSxHQUNULE1BQU0sS0FBSyxDQUFDO0FBQ2IsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLFlBQVksQ0FBQztBQUUzQyxPQUFPLFFBQTZCLE1BQU0sNkJBQTZCLENBQUM7QUFHeEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzNELE9BQU8sRUFBRSxjQUFjLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDbEUsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHdEQsSUFBTSxvQkFBb0IsR0FBMUIsTUFBTSxvQkFBcUIsU0FBUSxrQkFBa0I7SUFRcEQsQUFBTixLQUFLLENBQUMsY0FBYyxDQUFnQixHQUFZO1FBQzlDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDO1FBQ2xCLE9BQU8sR0FBRyxDQUFDLEdBQUcsQ0FBQyxVQUFVLENBQUM7SUFDNUIsQ0FBQztJQU1LLEFBQU4sS0FBSyxDQUFDLFlBQVk7UUFDaEIsT0FBTyxNQUFNLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsVUFBVSxFQUFFLFlBQVksQ0FBQyxFQUFFLEVBQUU7WUFDakUsT0FBTztnQkFDTCxJQUFJLEVBQUUsR0FBRyxVQUFVLEdBQUc7Z0JBQ3RCLFFBQVEsRUFBRSxHQUFH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