@dans98/prismabox
Version:
Typebox generator for prisma schema
111 lines (97 loc) • 2.98 kB
text/typescript
import type { DMMF } from "@prisma/generator-helper";
export type Annotation =
| { type: "HIDDEN" }
| { type: "HIDDEN_INPUT" }
| { type: "OPTIONS"; value: string };
export function isHiddenVariant(
annotation: Annotation,
): annotation is { type: "HIDDEN"; value: number } {
return annotation.type === "HIDDEN";
}
export function isHiddenInputVariant(
annotation: Annotation,
): annotation is { type: "HIDDEN_INPUT"; value: number } {
return annotation.type === "HIDDEN_INPUT";
}
export function isOptionsVariant(
annotation: Annotation,
): annotation is { type: "OPTIONS"; value: string } {
return annotation.type === "OPTIONS";
}
const annotationKeys: { type: Annotation["type"]; keys: string[] }[] = [
{
type: "HIDDEN_INPUT",
keys: [
// we need to use input.hide instead of hide.input because the latter is a substring of input.hidden
// and will falsely match
"@prismabox.input.hide",
"@prismabox.input.hidden",
],
},
{
type: "HIDDEN",
keys: ["@prismabox.hide", "@prismabox.hidden"],
},
{
type: "OPTIONS",
keys: ["@prismabox.options"],
},
];
export function extractAnnotations(
input: DMMF.Model["fields"][number]["documentation"],
): {
annotations: Annotation[];
description: string | undefined;
isHidden: boolean;
isHiddenInput: boolean;
} {
const annotations: Annotation[] = [];
let description = "";
const raw = input ?? "";
for (const line of raw
.split("\n")
.map((l) => l.trim())
.filter((l) => l.length > 0)) {
const annotationKey = annotationKeys.find((key) =>
key.keys.some((k) => line.startsWith(k)),
);
if (annotationKey) {
if (annotationKey.type === "OPTIONS") {
if (!line.startsWith(`${annotationKey.keys[0]}{`)) {
throw new Error(
"Invalid syntax, expected opening { after prismabox.options",
);
}
if (!line.endsWith("}")) {
throw new Error(
"Invalid syntax, expected closing } for prismabox.options",
);
}
annotations.push({
type: "OPTIONS",
value: line.substring(
annotationKey.keys[0].length + 1,
line.length - 1,
),
});
} else {
annotations.push({ type: annotationKey.type });
}
} else {
description += `${line}\n`;
}
}
description = description.trim();
return {
annotations,
description: description.length > 0 ? description : undefined,
isHidden: isHidden(annotations),
isHiddenInput: isHiddenInput(annotations),
};
}
export function isHidden(annotations: Annotation[]): boolean {
return annotations.some((a) => a.type === "HIDDEN");
}
export function isHiddenInput(annotations: Annotation[]): boolean {
return annotations.some((a) => a.type === "HIDDEN_INPUT");
}