-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathplugin-config.ts
More file actions
81 lines (72 loc) · 2.56 KB
/
plugin-config.ts
File metadata and controls
81 lines (72 loc) · 2.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import { z } from 'zod';
import { type Audit, pluginAuditsSchema } from './audit.js';
import { type Group, groupsSchema } from './group.js';
import { createCheck } from './implementation/checks.js';
import {
materialIconSchema,
metaSchema,
packageVersionSchema,
scoreTargetSchema,
slugSchema,
} from './implementation/schemas.js';
import { formatSlugsList, hasMissingStrings } from './implementation/utils.js';
import { runnerConfigSchema, runnerFunctionSchema } from './runner-config.js';
export const pluginContextSchema = z
.record(z.string(), z.unknown())
.optional()
.describe('Plugin-specific context data for helpers');
export type PluginContext = z.infer<typeof pluginContextSchema>;
export const pluginMetaSchema = packageVersionSchema()
.extend(
metaSchema({
titleDescription: 'Descriptive name',
descriptionDescription: 'Description (markdown)',
docsUrlDescription: 'Plugin documentation site',
description: 'Plugin metadata',
}).shape,
)
.extend({
slug: slugSchema.describe('Unique plugin slug within core config'),
icon: materialIconSchema,
});
export type PluginMeta = z.infer<typeof pluginMetaSchema>;
export const pluginScoreTargetSchema = z
.union([
scoreTargetSchema,
z.record(z.string(), scoreTargetSchema.nonoptional()),
])
.describe(
'Score targets that trigger a perfect score. Number for all audits or record { slug: target } for specific audits',
)
.optional();
export type PluginScoreTarget = z.infer<typeof pluginScoreTargetSchema>;
export const pluginDataSchema = z.object({
runner: z.union([runnerConfigSchema, runnerFunctionSchema]),
audits: pluginAuditsSchema,
groups: groupsSchema,
scoreTarget: pluginScoreTargetSchema,
context: pluginContextSchema,
});
export const pluginConfigSchema = pluginMetaSchema
.extend(pluginDataSchema.shape)
.check(createCheck(findMissingSlugsInGroupRefs));
export type PluginConfig = z.infer<typeof pluginConfigSchema>;
// every listed group ref points to an audit within the plugin
export function findMissingSlugsInGroupRefs<
T extends { audits: Audit[]; groups?: Group[] },
>({ audits, groups = [] }: T) {
const missingSlugs = getAuditSlugsFromGroups(audits, groups);
return (
missingSlugs && {
message: `Group references audits which don't exist in this plugin: ${formatSlugsList(
missingSlugs,
)}`,
}
);
}
function getAuditSlugsFromGroups(audits: Audit[], groups: Group[]) {
return hasMissingStrings(
groups.flatMap(({ refs }) => refs.map(({ slug }) => slug)),
audits.map(({ slug }) => slug),
);
}