-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathvalidate-metadata.ts
More file actions
55 lines (45 loc) · 1.77 KB
/
Copy pathvalidate-metadata.ts
File metadata and controls
55 lines (45 loc) · 1.77 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
import Ajv, { ErrorObject } from "ajv";
import addFormats from "ajv-formats";
import * as fs from "fs/promises";
// @ts-expect-error - no types available
import { parse } from "json-source-map";
import * as github from "./github";
import * as messages from "./messages";
import { getSchema } from "./schemas";
import { Entity } from "./validate-fs";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const normalizeErrors = (error: ErrorObject, lineMap: any) => {
const { instancePath, message, params } = error;
const allowedValues = params?.allowedValues ? `: ${params.allowedValues.join(", ")}` : "";
const line = lineMap[instancePath]?.value?.line || 1;
const capMessage = message && message.charAt(0).toUpperCase() + message.slice(1);
return {
line: line + 1,
message: `${capMessage}${allowedValues}`,
};
};
export async function validateMetadata({ entityType, metadata: metadataPath }: Entity) {
if (!metadataPath) {
return;
}
const schema = getSchema(entityType);
const metadataContent = await fs.readFile(metadataPath, "utf8");
const { data: metadata, pointers: lineMap } = parse(metadataContent);
const ajv = new Ajv({ allErrors: true });
addFormats(ajv);
ajv.validate(schema, metadata);
const errors =
ajv.errors?.map((error: ErrorObject) => normalizeErrors(error, lineMap)).filter(Boolean) ||
[];
if (errors.length) {
await github.addReview({
body: messages.invalidInfoJson(),
comments: errors.map(({ message, line }: { message: string; line: number }) => ({
line,
path: metadataPath,
body: message,
})),
});
throw new Error("The `info.json` file is invalid");
}
}