UNPKG

2.88 kBPlain TextView Raw
1import { Logger } from '@stryker-mutator/api/logging';
2import { commonTokens, tokens } from '@stryker-mutator/api/plugin';
3import { errorToString } from '@stryker-mutator/util';
4import { IRestResponse, RestClient } from 'typed-rest-client/RestClient';
5
6import { PackageInfo } from './package-info.js';
7import { PromptOption } from './prompt-option.js';
8
9import { initializerTokens } from './index.js';
10
11interface NpmSearchResult {
12 total: number;
13 results: Array<{ package: PackageInfo }>;
14}
15
16export interface NpmPackage {
17 name: string;
18 homepage?: string;
19 initStrykerConfig?: Record<string, unknown>;
20}
21
22const getName = (packageName: string) => {
23 return packageName.replace('@stryker-mutator/', '').replace('stryker-', '').split('-')[0];
24};
25
26const mapSearchResultToPromptOption = (searchResults: NpmSearchResult): PromptOption[] =>
27 searchResults.results.map((result) => ({
28 name: getName(result.package.name),
29 pkg: result.package,
30 }));
31
32const handleResult =
33 (from: string) =>
34 <T>(response: IRestResponse<T>): T => {
35 if (response.statusCode === 200 && response.result) {
36 return response.result;
37 } else {
38 throw new Error(`Path ${from} resulted in http status code: ${response.statusCode}.`);
39 }
40 };
41
42export class NpmClient {
43 public static inject = tokens(commonTokens.logger, initializerTokens.restClientNpmSearch, initializerTokens.restClientNpm);
44 constructor(private readonly log: Logger, private readonly searchClient: RestClient, private readonly packageClient: RestClient) {}
45
46 public getTestRunnerOptions(): Promise<PromptOption[]> {
47 return this.search('/v2/search?q=keywords:@stryker-mutator/test-runner-plugin').then(mapSearchResultToPromptOption);
48 }
49
50 public getTestReporterOptions(): Promise<PromptOption[]> {
51 return this.search('/v2/search?q=keywords:@stryker-mutator/reporter-plugin').then(mapSearchResultToPromptOption);
52 }
53
54 public getAdditionalConfig(pkgInfo: PackageInfo): Promise<NpmPackage> {
55 const path = `/${pkgInfo.name}@${pkgInfo.version}/package.json`;
56 return this.packageClient
57 .get<NpmPackage>(path)
58 .then(handleResult(path))
59 .catch((err) => {
60 this.log.warn(
61 `Could not fetch additional initialization config for dependency ${pkgInfo.name}. You might need to configure it manually`,
62 err
63 );
64 return { name: pkgInfo.name };
65 });
66 }
67
68 private search(path: string): Promise<NpmSearchResult> {
69 this.log.debug(`Searching: ${path}`);
70 return this.searchClient
71 .get<NpmSearchResult>(path)
72 .then(handleResult(path))
73 .catch((err) => {
74 this.log.error(`Unable to reach npms.io (for query ${path}). Please check your internet connection.`, errorToString(err));
75 const result: NpmSearchResult = {
76 results: [],
77 total: 0,
78 };
79 return result;
80 });
81 }
82}