diff --git a/app/port/controller/PackageVersionFileController.ts b/app/port/controller/PackageVersionFileController.ts index af277525..60316bab 100644 --- a/app/port/controller/PackageVersionFileController.ts +++ b/app/port/controller/PackageVersionFileController.ts @@ -145,10 +145,20 @@ export class PackageVersionFileController extends AbstractController { } const file = await this.packageVersionFileService.showPackageVersionFile(packageVersion, path); + const hasMeta = typeof meta === 'string'; + if (!file) { + const possibleFile = await this.#searchPossibleEntries(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`); } - const hasMeta = typeof meta === 'string'; + if (hasMeta) { ctx.set('cache-control', META_CACHE_CONTROL); return formatFileItem(file); @@ -161,6 +171,28 @@ export class PackageVersionFileController extends AbstractController { return await this.distRepository.getDistStream(file.dist); } + /** + * 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` + * @param packageVersion + * @param path + * @return + */ + async #searchPossibleEntries(packageVersion: any, path: string) { + const possiblePath = [ `${path}.js`, `${path}.json`, `${path}/index.js` ]; + + const possibleFiles = possiblePath.map(pathItem => this.packageVersionFileService.showPackageVersionFile(packageVersion, pathItem)); + + const files = await Promise.allSettled(possibleFiles); + + for (const file of files) { + if (file.status === 'fulfilled' && file.value) { + return file.value; + } + } + } + async #getPackageVersion(ctx: EggContext, fullname: string, scope: string, name: string, versionSpec: string) { const { blockReason, packageVersion } = await this.packageManagerService.showPackageVersionByVersionOrTag( scope, name, versionSpec);