import { z } from 'zod'; import { BuiltInGenerationParserRuleConfiguration, builtInGenerationRuleParserConfigurationsUnionSchema, BuiltInParserRuleConfiguration, builtInParserRuleConfigurationsUnionSchema, BuiltInUtilityParserRuleConfiguration, builtInUtilityParserRuleConfigurationsUnionSchema, } from './builtInParsers.js'; export const builtInParserBaseSchema = z .object({ name: z .string({ invalid_type_error: 'Rule name must be a string', }) .optional(), shouldExecuteRemotely: z.boolean().optional(), }) .strict(); export type BuiltInParserBase = z.infer; export type BuiltInParserRule = { parsers: [BuiltInParserRuleConfiguration, ...Array]; } & BuiltInParserBase; export type BuiltInGenerationParserRule = { parsers: [ BuiltInGenerationParserRuleConfiguration, ...Array ]; } & BuiltInParserBase; export type BuiltInUtilityParserRule = { parsers: [BuiltInUtilityParserRuleConfiguration, ...Array]; } & BuiltInParserBase; /** * Assemble built-in parser rule schema for context * @internal * @param accepts */ export function makeBuiltInParserRuleSchema( accepts?: Accepts, ): Accepts extends 'generation' ? z.ZodType : Accepts extends 'utility' ? z.ZodType : z.ZodType { let parsersSchema: z.ZodDiscriminatedUnion<'name', any>; switch (accepts) { case 'generation': parsersSchema = builtInGenerationRuleParserConfigurationsUnionSchema; break; case 'utility': parsersSchema = builtInUtilityParserRuleConfigurationsUnionSchema; break; case 'all': parsersSchema = builtInParserRuleConfigurationsUnionSchema; break; default: throw new Error('Invalid "accepts" value. Must be "generation", "utility" or "all"'); } if (parsersSchema === undefined) { throw new Error('undefined parsersSchema'); } return builtInParserBaseSchema .merge( z .object({ parsers: z .array(parsersSchema, { required_error: 'Parsers array is required', invalid_type_error: 'Parsers must be an array', }) .min(1, { message: 'Parsers array must contain at least one parser', }) .superRefine((data, ctx) => { const outputTypes = Array.from( data.reduce((acc, c) => { if (c.output?.type) { acc.add(c.output?.type); } return acc; }, new Set()), ).sort((a, b) => a.localeCompare(b)); if ( outputTypes.length > 1 && !(outputTypes[0] === 'directory' && outputTypes[1] === 'file') ) { ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Rule is mixing parsers output types: ${outputTypes.join(', ')}`, }); } }), }) .strict(), ) .strict() as any; } export const builtInParserRuleSchema = makeBuiltInParserRuleSchema('all'); export const builtInGenerationParserRuleSchema = makeBuiltInParserRuleSchema('generation'); export const builtInUtilityParserRuleSchema = makeBuiltInParserRuleSchema('utility');