Skip to content

Commit

Permalink
fix: npm registry adapter.
Browse files Browse the repository at this point in the history
  • Loading branch information
hezhengxu2018 committed Jul 14, 2024
1 parent 7480e60 commit f3ef419
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 27 deletions.
60 changes: 40 additions & 20 deletions app/common/adapter/NPMRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,29 +41,25 @@ export class NPMRegistry {
}

public async getFullManifests(fullname: string, optionalConfig?: {retries?:number, remoteAuthToken?:string}): Promise<RegistryResponse> {
let retries = optionalConfig?.retries || 3;
// set query t=timestamp, make sure CDN cache disable
// cache=0 is sync worker request flag
const url = `${this.registry}/${encodeURIComponent(fullname)}?t=${Date.now()}&cache=0`;
let lastError: any;
while (retries > 0) {
try {
// large package: https://r.cnpmjs.org/%40procore%2Fcore-icons
// https://r.cnpmjs.org/intraactive-sdk-ui 44s
const authorization = this.genAuthorizationHeader(optionalConfig?.remoteAuthToken);
return await this.request('GET', url, undefined, { timeout: 120000, headers: { authorization } });
} catch (err: any) {
if (err.name === 'ResponseTimeoutError') throw err;
lastError = err;
}
retries--;
if (retries > 0) {
// sleep 1s ~ 4s in random
const delay = process.env.NODE_ENV === 'test' ? 1 : 1000 + Math.random() * 4000;
await setTimeout(delay);
}
}
throw lastError;
return await this.getManifest(url, optionalConfig);
}

public async getAbbreviatedManifests(fullname: string, optionalConfig?: {retries?:number, remoteAuthToken?:string}): Promise<RegistryResponse> {
const url = `${this.registry}/${encodeURIComponent(fullname)}?t=${Date.now()}&cache=0`;
return await this.getManifest(url, { ...optionalConfig, isAbbreviated: true });
}

public async getPackageVersionManifest(fullname: string, versionOrTag: string, optionalConfig?: {retries?:number, remoteAuthToken?:string}) {
const url = `${this.registry}/${encodeURIComponent(fullname)}/${versionOrTag}`;
return await this.getManifest(url, optionalConfig);
}

public async getAbbreviatedPackageVersionManifest(fullname: string, versionOrTag: string, optionalConfig?: {retries?:number, remoteAuthToken?:string}) {
const url = `${this.registry}/${encodeURIComponent(fullname)}/${versionOrTag}`;
return await this.getManifest(url, { ...optionalConfig, isAbbreviated: true });
}

// app.put('/:name/sync', sync.sync);
Expand Down Expand Up @@ -113,4 +109,28 @@ export class NPMRegistry {
private genAuthorizationHeader(remoteAuthToken?:string) {
return remoteAuthToken ? `Bearer ${remoteAuthToken}` : '';
}

private async getManifest(url, optionalConfig?: {retries?:number, remoteAuthToken?:string, isAbbreviated?:boolean}) {
let retries = optionalConfig?.retries || 3;
let lastError: any;
while (retries > 0) {
try {
// large package: https://r.cnpmjs.org/%40procore%2Fcore-icons
// https://r.cnpmjs.org/intraactive-sdk-ui 44s
const authorization = this.genAuthorizationHeader(optionalConfig?.remoteAuthToken);
const accept = optionalConfig?.isAbbreviated ? 'application/vnd.npm.install-v1+json' : '';
return await this.request('GET', url, undefined, { timeout: 120000, headers: { authorization, accept } });
} catch (err: any) {
if (err.name === 'ResponseTimeoutError') throw err;
lastError = err;
}
retries--;
if (retries > 0) {
// sleep 1s ~ 4s in random
const delay = process.env.NODE_ENV === 'test' ? 1 : 1000 + Math.random() * 4000;
await setTimeout(delay);
}
}
throw lastError;
}
}
8 changes: 3 additions & 5 deletions app/core/service/ProxyModeService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export class ProxyModeService extends AbstractService {
}

// used by GET /:fullname/:versionOrTag
async getPackageVersionOrTagManifest(fullname: string, versionOrTag: string) {
async getPackageVersionOrTagManifest(fullname: string, versionOrTag: string, isFullManifests: boolean) {
const { data: manifest } = await this.getPackageAbbreviatedManifests(fullname);
const distTags = manifest['dist-tags'] || {};
const version = distTags[versionOrTag] ? distTags[versionOrTag] : versionOrTag;
Expand All @@ -62,8 +62,7 @@ export class ProxyModeService extends AbstractService {
}

// not in NFS
let responseResult;
// const responseResult = await this.npmRegistry.getPackageVersionManifest(fullname, version);
const responseResult = isFullManifests ? await this.npmRegistry.getPackageVersionManifest(fullname, version) : await this.npmRegistry.getAbbreviatedPackageVersionManifest(fullname, version);
if (responseResult.status !== 200) {
throw new HttpError({
status: responseResult.status,
Expand Down Expand Up @@ -115,8 +114,7 @@ export class ProxyModeService extends AbstractService {
if (isFullManifests) {
responseResult = await this.npmRegistry.getFullManifests(fullname);
} else {
responseResult = await this.npmRegistry.getFullManifests(fullname);
// responseResult = await this.npmRegistry.getAbbreviatedManifests(fullname);
responseResult = await this.npmRegistry.getAbbreviatedManifests(fullname);
}
if (responseResult.status !== 200) {
throw new HttpError({
Expand Down
4 changes: 2 additions & 2 deletions app/port/controller/package/ShowPackageVersionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class ShowPackageVersionController extends AbstractController {
let { blockReason, manifest, pkg } = await this.packageManagerService.showPackageVersionManifest(scope, name, versionSpec, isSync, isFullManifests);
if (!pkg) {
if (this.config.cnpmcore.syncMode === SyncMode.proxy) {
manifest = await this.proxyModeService.getPackageVersionOrTagManifest(fullname, versionSpec);
manifest = await this.proxyModeService.getPackageVersionOrTagManifest(fullname, versionSpec, isFullManifests);
} else {
const allowSync = this.getAllowSync(ctx);
throw this.createPackageNotFoundErrorWithRedirect(fullname, undefined, allowSync);
Expand All @@ -51,7 +51,7 @@ export class ShowPackageVersionController extends AbstractController {
}
if (!manifest) {
if (this.config.cnpmcore.syncMode === SyncMode.proxy) {
manifest = await this.proxyModeService.getPackageVersionOrTagManifest(fullname, versionSpec);
manifest = await this.proxyModeService.getPackageVersionOrTagManifest(fullname, versionSpec, isFullManifests);
} else {
throw new NotFoundError(`${fullname}@${versionSpec} not found`);
}
Expand Down

0 comments on commit f3ef419

Please sign in to comment.