cnpmcore
Version:
Private NPM Registry for Enterprise
248 lines • 23.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); }
};
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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