UNPKG

cnpmcore

Version:

Private NPM Registry for Enterprise

248 lines 23.6 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); } }; var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _PackageVersionFileController_instances, _PackageVersionFileController_requireUnpkgEnable, _PackageVersionFileController_searchPossibleEntries, _PackageVersionFileController_getPackageVersion, _PackageVersionFileController_listFilesByDirectory; import { join } from 'node:path'; import { HTTPContext, Context, HTTPController, HTTPMethod, HTTPMethodEnum, HTTPParam, HTTPQuery, Inject, Middleware, } from 'egg'; import { NotFoundError } from 'egg/errors'; import { ensureContentType } from "../../common/FileUtil.js"; import { FULLNAME_REG_STRING, getScopeAndName } from "../../common/PackageUtil.js"; import { AdminAccess } from "../middleware/AdminAccess.js"; import { Spec } from "../typebox.js"; import { AbstractController } from "./AbstractController.js"; function formatFileItem(file) { return { path: file.path, type: 'file', contentType: file.contentType, integrity: file.dist.integrity, lastModified: file.mtime, size: file.dist.size, }; } const META_CACHE_CONTROL = 'public, s-maxage=600, max-age=60'; const FILE_CACHE_CONTROL = 'public, max-age=31536000'; let PackageVersionFileController = class PackageVersionFileController extends AbstractController { constructor() { super(...arguments); _PackageVersionFileController_instances.add(this); } async sync(ctx, fullname, versionSpec) { ctx.tValidate(Spec, `${fullname}@${versionSpec}`); __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_requireUnpkgEnable).call(this); const [scope, name] = getScopeAndName(fullname); const { packageVersion } = await this.packageManagerService.showPackageVersionByVersionOrTag(scope, name, versionSpec); if (!packageVersion) { throw new NotFoundError(`${fullname}@${versionSpec} not found`); } const files = await this.packageVersionFileService.syncPackageVersionFiles(packageVersion); return files.map((file) => formatFileItem(file)); } async listFiles(ctx, fullname, versionSpec, meta) { __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_requireUnpkgEnable).call(this); ctx.tValidate(Spec, `${fullname}@${versionSpec}`); ctx.vary(this.config.cnpmcore.cdnVaryHeader); ctx.set('cross-origin-resource-policy', 'cross-origin'); const [scope, name] = getScopeAndName(fullname); await this.userRoleManager.checkReadAccess(ctx, scope, name); const packageVersion = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_getPackageVersion).call(this, ctx, fullname, scope, name, versionSpec); ctx.set('cache-control', META_CACHE_CONTROL); const hasMeta = typeof meta === 'string' || ctx.path.endsWith('/files/'); // meta request if (hasMeta) { const files = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_listFilesByDirectory).call(this, packageVersion, '/'); if (!files) { throw new NotFoundError(`${fullname}@${versionSpec}/files not found`); } return files; } const { manifest } = await this.packageManagerService.showPackageVersionManifest(scope, name, versionSpec, false, true); // GET /foo/1.0.0/files => /foo/1.0.0/files/{main} // ignore empty entry exp: @types/node@20.2.5/ const indexFile = manifest?.main || 'index.js'; ctx.redirect(join(ctx.path, indexFile)); } async raw(ctx, fullname, versionSpec, path, meta) { __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_requireUnpkgEnable).call(this); ctx.tValidate(Spec, `${fullname}@${versionSpec}`); ctx.vary(this.config.cnpmcore.cdnVaryHeader); ctx.set('cross-origin-resource-policy', 'cross-origin'); const [scope, name] = getScopeAndName(fullname); await this.userRoleManager.checkReadAccess(ctx, scope, name); // oxlint-disable-next-line no-param-reassign path = `/${path}`; const packageVersion = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_getPackageVersion).call(this, ctx, fullname, scope, name, versionSpec); if (path.endsWith('/')) { const directory = path.slice(0, -1); const files = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_listFilesByDirectory).call(this, packageVersion, directory); if (!files) { throw new NotFoundError(`${fullname}@${versionSpec}/files${directory} not found`); } ctx.set('cache-control', META_CACHE_CONTROL); return files; } await this.packageVersionFileService.checkPackageVersionInUnpkgWhiteList(scope, name, packageVersion.version); const file = await this.packageVersionFileService.showPackageVersionFile(packageVersion, path); const hasMeta = typeof meta === 'string'; if (!file) { const possibleFile = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_searchPossibleEntries).call(this, packageVersion, path); if (possibleFile) { const route = `/${fullname}/${versionSpec}/files${possibleFile.path}${hasMeta ? '?meta' : ''}`; ctx.redirect(route); return; } throw new NotFoundError(`File ${fullname}@${versionSpec}${path} not found`); } if (hasMeta) { ctx.set('cache-control', META_CACHE_CONTROL); return formatFileItem(file); } ctx.set('cache-control', FILE_CACHE_CONTROL); // SRI support: https://github.com/cnpm/cnpmcore/issues/634 if (file.dist.integrity) { ctx.set('x-integrity', file.dist.integrity); } // https://github.com/cnpm/cnpmcore/issues/693#issuecomment-2955268229 ctx.type = ensureContentType(file.contentType); return await this.distRepository.getDistStream(file.dist); } }; _PackageVersionFileController_instances = new WeakSet(); _PackageVersionFileController_requireUnpkgEnable = function _PackageVersionFileController_requireUnpkgEnable() { if (!this.config.cnpmcore.enableUnpkg) { throw new NotFoundError(); } }; _PackageVersionFileController_searchPossibleEntries = /** * compatibility with unpkg * 1. try to match alias entry. e.g. accessing `index.js` or `index.json` using /index * 2. if given path is directory and has `index.js` file, redirect to it. e.g. using `lib` alias to access `lib/index.js` or `lib/index.json` * @param {PackageVersion} packageVersion packageVersion * @param {String} path filepath * @returns {Promise<PackageVersionFile | undefined>} return packageVersionFile or null */ async function _PackageVersionFileController_searchPossibleEntries(packageVersion, path) { const possiblePath = [`${path}.js`, `${path}.json`, `${path}/index.js`, `${path}/index.json`]; for (const pathItem of possiblePath) { const file = await this.packageVersionFileService.showPackageVersionFile(packageVersion, pathItem); if (file) { return file; } } }; _PackageVersionFileController_getPackageVersion = async function _PackageVersionFileController_getPackageVersion(ctx, fullname, scope, name, versionSpec) { const { blockReason, packageVersion } = await this.packageManagerService.showPackageVersionByVersionOrTag(scope, name, versionSpec); if (blockReason) { this.setCDNHeaders(ctx); throw this.createPackageBlockError(blockReason, fullname, versionSpec); } if (!packageVersion) { throw new NotFoundError(`${fullname}@${versionSpec} not found`); } if (packageVersion.version !== versionSpec) { ctx.set('cache-control', META_CACHE_CONTROL); let location = ctx.url.replace(`/${fullname}/${versionSpec}/files`, `/${fullname}/${packageVersion.version}/files`); location = location.replace(`/${fullname}/${encodeURIComponent(versionSpec)}/files`, `/${fullname}/${packageVersion.version}/files`); throw this.createControllerRedirectError(location); } return packageVersion; }; _PackageVersionFileController_listFilesByDirectory = async function _PackageVersionFileController_listFilesByDirectory(packageVersion, directory) { const { files, directories } = await this.packageVersionFileService.listPackageVersionFiles(packageVersion, directory); if (files.length === 0 && directories.length === 0) return null; const info = { path: directory, type: 'directory', files: [], }; for (const file of files) { info.files.push(formatFileItem(file)); } for (const name of directories) { info.files.push({ path: name, type: 'directory', files: [], }); } return info; }; __decorate([ Inject(), __metadata("design:type", Function) ], PackageVersionFileController.prototype, "packageManagerService", void 0); __decorate([ Inject(), __metadata("design:type", Function) ], PackageVersionFileController.prototype, "packageVersionFileService", void 0); __decorate([ Inject(), __metadata("design:type", Function) ], PackageVersionFileController.prototype, "distRepository", void 0); __decorate([ HTTPMethod({ // PUT /:fullname/:versionSpec/files path: `/:fullname(${FULLNAME_REG_STRING})/:versionSpec/files`, method: HTTPMethodEnum.PUT, }), Middleware(AdminAccess), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "sync", null); __decorate([ HTTPMethod({ // GET /:fullname/:versionSpec/files => /:fullname/:versionSpec/files/${pkg.main} // GET /:fullname/:versionSpec/files?meta // GET /:fullname/:versionSpec/files/ path: `/:fullname(${FULLNAME_REG_STRING})/:versionSpec/files`, method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPQuery()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "listFiles", null); __decorate([ HTTPMethod({ // GET /:fullname/:versionSpec/files/:path // GET /:fullname/:versionSpec/files/:path?meta path: `/:fullname(${FULLNAME_REG_STRING})/:versionSpec/files/:path(.+)`, method: HTTPMethodEnum.GET, }), __param(0, HTTPContext()), __param(1, HTTPParam()), __param(2, HTTPParam()), __param(3, HTTPParam()), __param(4, HTTPQuery()), __metadata("design:type", Function), __metadata("design:paramtypes", [Context, String, String, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "raw", null); PackageVersionFileController = __decorate([ HTTPController() ], PackageVersionFileController); export { PackageVersionFileController }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFja2FnZVZlcnNpb25GaWxlQ29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FwcC9wb3J0L2NvbnRyb2xsZXIvUGFja2FnZVZlcnNpb25GaWxlQ29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRWpDLE9BQU8sRUFDTCxXQUFXLEVBQ1gsT0FBTyxFQUNQLGNBQWMsRUFDZCxVQUFVLEVBQ1YsY0FBYyxFQUNkLFNBQVMsRUFDVCxTQUFTLEVBQ1QsTUFBTSxFQUNOLFVBQVUsR0FDWCxNQUFNLEtBQUssQ0FBQztBQUNiLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFM0MsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDN0QsT0FBTyxFQUFFLG1CQUFtQixFQUFFLGVBQWUsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBTW5GLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMzRCxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBaUI3RCxTQUFTLGNBQWMsQ0FBQyxJQUF3QjtJQUM5QyxPQUFPO1FBQ0wsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1FBQ2YsSUFBSSxFQUFFLE1BQU07UUFDWixXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7UUFDN0IsU0FBUyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUztRQUM5QixZQUFZLEVBQUUsSUFBSSxDQUFDLEtBQUs7UUFDeEIsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtLQUNyQixDQUFDO0FBQ0osQ0FBQztBQUVELE1BQU0sa0JBQWtCLEdBQUcsa0NBQWtD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