UNPKG

cnpmcore

Version:
246 lines 23.3 kB
"use strict"; 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; Object.defineProperty(exports, "__esModule", { value: true }); exports.PackageVersionFileController = void 0; const tegg_1 = require("@eggjs/tegg"); const egg_errors_1 = require("egg-errors"); const node_path_1 = require("node:path"); const AbstractController_1 = require("./AbstractController"); const AdminAccess_1 = require("../middleware/AdminAccess"); const PackageUtil_1 = require("../../common/PackageUtil"); const PackageVersionFileService_1 = require("../../core/service/PackageVersionFileService"); const PackageManagerService_1 = require("../../core/service/PackageManagerService"); const DistRepository_1 = require("../../repository/DistRepository"); const typebox_1 = require("../typebox"); 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_1.AbstractController { constructor() { super(...arguments); _PackageVersionFileController_instances.add(this); } async sync(ctx, fullname, versionSpec) { ctx.tValidate(typebox_1.Spec, `${fullname}@${versionSpec}`); __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_requireUnpkgEnable).call(this); const [scope, name] = (0, PackageUtil_1.getScopeAndName)(fullname); const { packageVersion } = await this.packageManagerService.showPackageVersionByVersionOrTag(scope, name, versionSpec); if (!packageVersion) { throw new egg_errors_1.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(typebox_1.Spec, `${fullname}@${versionSpec}`); ctx.vary(this.config.cnpmcore.cdnVaryHeader); const [scope, name] = (0, PackageUtil_1.getScopeAndName)(fullname); 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 egg_errors_1.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((0, node_path_1.join)(ctx.path, indexFile)); } async raw(ctx, fullname, versionSpec, path, meta) { __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_requireUnpkgEnable).call(this); ctx.tValidate(typebox_1.Spec, `${fullname}@${versionSpec}`); ctx.vary(this.config.cnpmcore.cdnVaryHeader); const [scope, name] = (0, PackageUtil_1.getScopeAndName)(fullname); 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.substring(0, path.length - 1); const files = await __classPrivateFieldGet(this, _PackageVersionFileController_instances, "m", _PackageVersionFileController_listFilesByDirectory).call(this, packageVersion, directory); if (!files) { throw new egg_errors_1.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 egg_errors_1.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); ctx.type = file.contentType; if (file.contentType === 'text/html' || file.contentType === 'text/xml') { ctx.attachment(file.path); } return await this.distRepository.getDistStream(file.dist); } }; exports.PackageVersionFileController = PackageVersionFileController; _PackageVersionFileController_instances = new WeakSet(); _PackageVersionFileController_requireUnpkgEnable = function _PackageVersionFileController_requireUnpkgEnable() { if (!this.config.cnpmcore.enableUnpkg) { throw new egg_errors_1.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 * @return {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 egg_errors_1.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([ (0, tegg_1.Inject)(), __metadata("design:type", PackageManagerService_1.PackageManagerService) ], PackageVersionFileController.prototype, "packageManagerService", void 0); __decorate([ (0, tegg_1.Inject)(), __metadata("design:type", PackageVersionFileService_1.PackageVersionFileService) ], PackageVersionFileController.prototype, "packageVersionFileService", void 0); __decorate([ (0, tegg_1.Inject)(), __metadata("design:type", DistRepository_1.DistRepository) ], PackageVersionFileController.prototype, "distRepository", void 0); __decorate([ (0, tegg_1.HTTPMethod)({ // PUT /:fullname/:versionSpec/files path: `/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/:versionSpec/files`, method: tegg_1.HTTPMethodEnum.PUT, }), (0, tegg_1.Middleware)(AdminAccess_1.AdminAccess), __param(0, (0, tegg_1.Context)()), __param(1, (0, tegg_1.HTTPParam)()), __param(2, (0, tegg_1.HTTPParam)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "sync", null); __decorate([ (0, tegg_1.HTTPMethod)({ // GET /:fullname/:versionSpec/files => /:fullname/:versionSpec/files/${pkg.main} // GET /:fullname/:versionSpec/files?meta // GET /:fullname/:versionSpec/files/ path: `/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/:versionSpec/files`, method: tegg_1.HTTPMethodEnum.GET, }), __param(0, (0, tegg_1.Context)()), __param(1, (0, tegg_1.HTTPParam)()), __param(2, (0, tegg_1.HTTPParam)()), __param(3, (0, tegg_1.HTTPQuery)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "listFiles", null); __decorate([ (0, tegg_1.HTTPMethod)({ // GET /:fullname/:versionSpec/files/:path // GET /:fullname/:versionSpec/files/:path?meta path: `/:fullname(${PackageUtil_1.FULLNAME_REG_STRING})/:versionSpec/files/:path(.+)`, method: tegg_1.HTTPMethodEnum.GET, }), __param(0, (0, tegg_1.Context)()), __param(1, (0, tegg_1.HTTPParam)()), __param(2, (0, tegg_1.HTTPParam)()), __param(3, (0, tegg_1.HTTPParam)()), __param(4, (0, tegg_1.HTTPQuery)()), __metadata("design:type", Function), __metadata("design:paramtypes", [Object, String, String, String, String]), __metadata("design:returntype", Promise) ], PackageVersionFileController.prototype, "raw", null); exports.PackageVersionFileController = PackageVersionFileController = __decorate([ (0, tegg_1.HTTPController)() ], PackageVersionFileController); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiUGFja2FnZVZlcnNpb25GaWxlQ29udHJvbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL2FwcC9wb3J0L2NvbnRyb2xsZXIvUGFja2FnZVZlcnNpb25GaWxlQ29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSxzQ0FVcUI7QUFDckIsMkNBQTJDO0FBQzNDLHlDQUFpQztBQUNqQyw2REFBMEQ7QUFDMUQsMkRBQXdEO0FBQ3hELDBEQUFnRjtBQUNoRiw0RkFBeUY7QUFDekYsb0ZBQWlGO0FBR2pGLG9FQUFpRTtBQUNqRSx3Q0FBa0M7QUFpQmxDLFNBQVMsY0FBYyxDQUFDLElBQXdCO0lBQzlDLE9BQU87UUFDTCxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7UUFDZixJQUFJLEVBQUUsTUFBTTtRQUNaLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztRQUM3QixTQUFTLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1FBQzlCLFlBQVksRUFBRSxJQUFJLENBQUMsS0FBSztRQUN4QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJO0tBQ3JCLENBQUM7QUFDSixDQUFDO0FBRUQsTUFBTSxrQkFBa0IsR0FBRyxrQ0FBa0MsQ0FBQztBQUM5RCxNQUFNLGtCQUFrQixHQUFHLDBCQUEwQixDQUFDO0FBRy9DLElBQU0sNEJBQTRCLEdBQWxDLE1BQU0sNEJBQTZCLFNBQVEsdUNBQWtCO0lBQTdEOzs7SUFvTFAsQ0FBQztJQWhLTyxBQUFOLEtBQUssQ0FBQyxJQUFJLENBQVksR0FBZSxFQUFlLFFBQWdCLEVBQWUsV0FBbUI7UUFDcEcsR0FBRyxDQUFDLFNBQVMsQ0FBQyxjQUFJLEVBQUUsR0FBRyxRQUFRLElBQUksV0FBVyxFQUFFLENBQUMsQ0FBQztRQUNsRCx1QkFBQSxJQUFJLGlHQUFvQixNQUF4QixJQUFJLENBQXNCLENBQUM7UUFDM0IsTUFBTSxDQUFF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