Skip to content

Commit 0d06579

Browse files
committed
fix: refactor types
1 parent d656b23 commit 0d06579

File tree

7 files changed

+87
-32
lines changed

7 files changed

+87
-32
lines changed

packages/plugin-typescript/src/index.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ import { typescriptPlugin } from './lib/typescript-plugin.js';
22

33
export { TYPESCRIPT_PLUGIN_SLUG } from './lib/constants.js';
44

5-
export type { TypescriptPluginOptions } from './lib/types.js';
65
export { getCurrentTsVersion } from './lib/runner/utils.js';
7-
export { getCategoryRefsFromGroups } from './lib/utils.js';
8-
export { typescriptPlugin } from './lib/typescript-plugin.js';
6+
export {
7+
getCategoryRefsFromAudits,
8+
getCategoryRefsFromGroups,
9+
} from './lib/utils.js';
10+
export {
11+
typescriptPlugin,
12+
TypescriptPluginOptions,
13+
} from './lib/typescript-plugin.js';
914
export default typescriptPlugin;
1015
export { getTsDefaultsFilename } from './lib/runner/constants.js';

packages/plugin-typescript/src/lib/runner/runner.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,22 @@ import type {
66
Issue,
77
RunnerFunction,
88
} from '@code-pushup/models';
9-
import type { TypescriptPluginOptions } from '../types.js';
109
import { AUDIT_LOOKUP } from './constants.js';
11-
import { getTypeScriptDiagnostics } from './ts-runner.js';
10+
import {
11+
type DiagnosticsOptions,
12+
getTypeScriptDiagnostics,
13+
} from './ts-runner.js';
1214
import type { CompilerOptionName } from './types.js';
1315
import { getIssueFromDiagnostic, tSCodeToAuditSlug } from './utils.js';
1416

15-
export type RunnerOptions = TypescriptPluginOptions & {
17+
export type RunnerOptions = DiagnosticsOptions & {
1618
expectedAudits: Pick<Audit, 'slug'>[];
1719
};
1820

1921
export function createRunnerFunction(options: RunnerOptions): RunnerFunction {
22+
const { tsConfigPath, expectedAudits } = options;
2023
return async (): Promise<AuditOutputs> => {
21-
const diagnostics = await getTypeScriptDiagnostics(options.tsConfigPath);
24+
const diagnostics = await getTypeScriptDiagnostics({ tsConfigPath });
2225
const result: Record<
2326
CompilerOptionName,
2427
Pick<AuditReport, 'slug' | 'details'>
@@ -42,11 +45,11 @@ export function createRunnerFunction(options: RunnerOptions): RunnerFunction {
4245
},
4346
{} as unknown as Record<
4447
CompilerOptionName,
45-
Pick<AuditReport, 'slug' | 'details'>
48+
Pick<AuditOutput, 'slug' | 'details'>
4649
>,
4750
);
4851

49-
return options.expectedAudits.map(({ slug }) => {
52+
return expectedAudits.map(({ slug }) => {
5053
const { details } = result[slug as CompilerOptionName] ?? {};
5154

5255
const issues = details?.issues ?? [];

packages/plugin-typescript/src/lib/runner/ts-runner.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
import {
2-
type CompilerOptions,
32
type Diagnostic,
43
createProgram,
54
getPreEmitDiagnostics,
65
} from 'typescript';
76
import { loadTargetConfig, validateDiagnostics } from './utils.js';
87

98
export type DiagnosticsOptions = {
10-
fileNames: string[];
11-
compilerOptions: CompilerOptions;
9+
tsConfigPath: string;
1210
};
13-
14-
export async function getTypeScriptDiagnostics(
15-
tsConfigPath: string,
16-
): Promise<readonly Diagnostic[]> {
11+
export async function getTypeScriptDiagnostics({
12+
tsConfigPath,
13+
}: DiagnosticsOptions): Promise<readonly Diagnostic[]> {
1714
try {
1815
const { fileNames, options } = await loadTargetConfig(tsConfigPath);
1916

packages/plugin-typescript/src/lib/schema.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@ import { z } from 'zod';
22
import { AUDITS, DEFAULT_TS_CONFIG } from './constants.js';
33
import type { AuditSlug } from './types.js';
44

5-
const auditSlugs = AUDITS.map(({ slug }) => slug) as [string, ...string[]];
5+
const auditSlugs = AUDITS.map(({ slug }) => slug) as [
6+
AuditSlug,
7+
...AuditSlug[],
8+
];
69
export const typescriptPluginConfigSchema = z.object({
710
tsConfigPath: z
811
.string({
@@ -18,4 +21,4 @@ export const typescriptPluginConfigSchema = z.object({
1821

1922
export type TypescriptPluginOptions = z.infer<
2023
typeof typescriptPluginConfigSchema
21-
> & { onlyAudits?: (string | AuditSlug)[] | undefined };
24+
>;
Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
1-
import { z } from 'zod';
21
import type { CamelCaseToKebabCase } from '@code-pushup/utils';
32
import type { CompilerOptionName } from './runner/types.js';
4-
import { typescriptPluginConfigSchema } from './schema.js';
53

64
export type AuditSlug = CamelCaseToKebabCase<CompilerOptionName>;
7-
8-
export type TypescriptPluginOptions = z.infer<
9-
typeof typescriptPluginConfigSchema
10-
> & { onlyAudits?: AuditSlug[] | undefined };

packages/plugin-typescript/src/lib/typescript-plugin.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,29 @@ import type { PluginConfig } from '@code-pushup/models';
33
import { DEFAULT_TS_CONFIG, TYPESCRIPT_PLUGIN_SLUG } from './constants.js';
44
import { normalizeCompilerOptions } from './normalize-compiler-options.js';
55
import { createRunnerFunction } from './runner/runner.js';
6-
import type { TypescriptPluginOptions } from './types.js';
6+
import type { DiagnosticsOptions } from './runner/ts-runner.js';
7+
import { typescriptPluginConfigSchema } from './schema.js';
8+
import type { AuditSlug } from './types.js';
79
import { getAudits, getGroups, logSkippedAudits } from './utils.js';
810

911
const packageJson = createRequire(import.meta.url)(
1012
'../../package.json',
1113
) as typeof import('../../package.json');
1214

15+
export type FilterOptions = { onlyAudits?: AuditSlug[] | undefined };
16+
export type TypescriptPluginOptions = Partial<DiagnosticsOptions> &
17+
FilterOptions;
18+
1319
export async function typescriptPlugin(
1420
options?: TypescriptPluginOptions,
1521
): Promise<PluginConfig> {
16-
const { tsConfigPath } = options ?? { tsConfigPath: DEFAULT_TS_CONFIG };
22+
const { tsConfigPath = DEFAULT_TS_CONFIG, onlyAudits } = parseOptions(
23+
options ?? {},
24+
);
1725

1826
const compilerOptions = await normalizeCompilerOptions({ tsConfigPath });
19-
const filteredAudits = getAudits(compilerOptions, options);
20-
const filteredGroups = getGroups(compilerOptions, options);
27+
const filteredAudits = getAudits(compilerOptions, { onlyAudits });
28+
const filteredGroups = getGroups(compilerOptions, { onlyAudits });
2129

2230
logSkippedAudits(filteredAudits);
2331

@@ -37,3 +45,15 @@ export async function typescriptPlugin(
3745
}),
3846
};
3947
}
48+
49+
function parseOptions(
50+
tsPluginOptions: TypescriptPluginOptions,
51+
): TypescriptPluginOptions {
52+
try {
53+
return typescriptPluginConfigSchema.parse(tsPluginOptions);
54+
} catch (error) {
55+
throw new Error(
56+
`Error parsing TypeScript Plugin options: ${(error as Error).message}`,
57+
);
58+
}
59+
}

packages/plugin-typescript/src/lib/utils.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,10 @@ import {
88
TYPESCRIPT_PLUGIN_SLUG,
99
} from './constants.js';
1010
import { normalizeCompilerOptions } from './normalize-compiler-options.js';
11-
import type { TypescriptPluginOptions } from './types.js';
11+
import type {
12+
FilterOptions,
13+
TypescriptPluginOptions,
14+
} from './typescript-plugin.js';
1215

1316
export function filterAuditsBySlug(slugs?: string[]) {
1417
return ({ slug }: { slug: string }) => {
@@ -74,7 +77,7 @@ export function getGroups(
7477

7578
export function getAudits(
7679
definitive: CompilerOptions,
77-
options?: TypescriptPluginOptions,
80+
options?: FilterOptions,
7881
) {
7982
return AUDITS.filter(
8083
filterAuditsByCompilerOptions(definitive, options?.onlyAudits),
@@ -91,11 +94,16 @@ export async function getCategoryRefsFromGroups(
9194
opt?: TypescriptPluginOptions,
9295
): Promise<CategoryRef[]> {
9396
const { tsConfigPath } = opt ?? { tsConfigPath: DEFAULT_TS_CONFIG };
94-
const definitive = await normalizeCompilerOptions({ ...opt, tsConfigPath });
97+
// this line is duplicated in the typescriptPlugin function
98+
// to mitigate multiple file access we cache the result
99+
const compilerOptions = await normalizeCompilerOptions({
100+
...opt,
101+
tsConfigPath,
102+
});
95103
return GROUPS.map(group => ({
96104
...group,
97105
refs: group.refs.filter(
98-
filterAuditsByCompilerOptions(definitive, opt?.onlyAudits),
106+
filterAuditsByCompilerOptions(compilerOptions, opt?.onlyAudits),
99107
),
100108
}))
101109
.filter(group => group.refs.length > 0)
@@ -107,6 +115,31 @@ export async function getCategoryRefsFromGroups(
107115
}));
108116
}
109117

118+
/**
119+
* Retrieve the category references from the audits.
120+
* @param opt TSPluginOptions
121+
* @returns The array of category references
122+
*/
123+
export async function getCategoryRefsFromAudits(
124+
opt?: TypescriptPluginOptions,
125+
): Promise<CategoryRef[]> {
126+
const { tsConfigPath } = opt ?? { tsConfigPath: DEFAULT_TS_CONFIG };
127+
// this line is duplicated in the typescriptPlugin function
128+
// to mitigate multiple file access we cache the result
129+
const compilerOptions = await normalizeCompilerOptions({
130+
...opt,
131+
tsConfigPath,
132+
});
133+
return AUDITS.filter(
134+
filterAuditsByCompilerOptions(compilerOptions, opt?.onlyAudits),
135+
).map(({ slug }) => ({
136+
plugin: TYPESCRIPT_PLUGIN_SLUG,
137+
slug,
138+
weight: 1,
139+
type: 'audit',
140+
}));
141+
}
142+
110143
export function logSkippedAudits(audits: Audit[]) {
111144
const skippedAudits = AUDITS.filter(
112145
audit => !audits.some(filtered => filtered.slug === audit.slug),

0 commit comments

Comments
 (0)