import { z } from 'astro/zod' const operationCClientSchema = z.enum(['libcurl']) const operationCSharpClientSchema = z.enum(['httpclient']) const operationGoClientSchema = z.enum(['nethttp']) const operationJavaClientSchema = z.enum(['nethttp', 'okhttp']) const operationJavaScriptClientSchema = z.enum(['axios', 'fetch']) const operationKotlinClientSchema = z.enum(['okhttp']) const operationRustClientSchema = z.enum(['reqwest']) const operationShellClientSchema = z.enum(['curl', 'wget']) const operationReferenceSchema = z.discriminatedUnion('target', [ z.object({ target: z.literal('c'), client: operationCClientSchema }), z.object({ target: z.literal('csharp'), client: operationCSharpClientSchema }), z.object({ target: z.literal('go'), client: operationGoClientSchema }), z.object({ target: z.literal('java'), client: operationJavaClientSchema }), z.object({ target: z.literal('javascript'), client: operationJavaScriptClientSchema }), z.object({ target: z.literal('kotlin'), client: operationKotlinClientSchema }), z.object({ target: z.literal('rust'), client: operationRustClientSchema }), z.object({ target: z.literal('shell'), client: operationShellClientSchema }), ]) const operationClientsSchema = z .object({ c: z.array(operationCClientSchema).optional(), csharp: z.array(operationCSharpClientSchema).optional(), go: z.array(operationGoClientSchema).optional(), java: z.array(operationJavaClientSchema).optional(), javascript: z.array(operationJavaScriptClientSchema).optional(), kotlin: z.array(operationKotlinClientSchema).optional(), rust: z.array(operationRustClientSchema).optional(), shell: z.array(operationShellClientSchema).optional(), }) .partial() const defaultOperationClients = { javascript: ['fetch'], shell: ['curl'], } as const satisfies z.input const defaultOperationReference = { target: 'shell', client: 'curl', } as const satisfies z.input const operationConfigSchema = z .object({ /** * Defines the enabled clients for which operation snippets should be generated. */ clients: operationClientsSchema.default(defaultOperationClients), /** * Defines the operation snippet that should be used by default on operation pages among the enabled operation * snippet clients. */ default: operationReferenceSchema.optional(), }) .transform((value, ctx) => { for (const [target, clients] of Object.entries(value.clients)) { if (!clients) continue if (new Set(clients).size !== clients.length) { ctx.addIssue({ code: 'custom', message: 'Operation snippet clients must be unique.', path: ['clients', target], }) return z.NEVER } } if (value.default && !includesOperationReference(value.clients, value.default)) { ctx.addIssue({ code: 'custom', message: 'The default operation snippet client must be one of the enabled operation snippet clients.', path: ['default'], }) return z.NEVER } const defaultReference = getDefaultOperationReference(value.clients, value.default) if (!defaultReference) { ctx.addIssue({ code: 'custom', message: 'At least one operation snippet client must be enabled.', path: ['clients'], }) return z.NEVER } return { clients: Object.entries(value.clients).flatMap(([target, clients]) => (clients ?? []).map((client) => ({ target: target, client }) as SnippetOperationReference), ), default: defaultReference, } }) const defaultOperationConfig = operationConfigSchema.parse({}) const operationSchema = z .union([z.literal(true), z.literal(false), operationConfigSchema]) .transform((value) => (value === true ? defaultOperationConfig : value)) .default(defaultOperationConfig) export const SnippetsSchema = z .object({ /** * Controls whether autogenerated operation snippets are available on operation pages. * Authored `x-codeSamples` are not affected by this option and are always shown when available. */ operation: operationSchema, /** * Controls whether autogenerated request body snippets are available in request body sections for JSON-like and * URL-encoded form request body media types. * Authored request body examples are not affected by this option and are always shown when available. */ requestBody: z.boolean().default(true), /** * Controls whether autogenerated response snippets are available in response sections for JSON-like response media * types. * Authored response examples are not affected by this option and are always shown when available. */ response: z.boolean().default(true), }) .default({ operation: defaultOperationConfig, requestBody: true, response: true }) function includesOperationReference(clients: SnippetOperationClients, reference: SnippetOperationReference): boolean { return clients[reference.target]?.includes(reference.client as never) ?? false } function getDefaultOperationReference( clients: SnippetOperationClients, reference: SnippetOperationReference | undefined, ): SnippetOperationReference | undefined { if (reference) return reference if (includesOperationReference(clients, defaultOperationReference)) return defaultOperationReference for (const [target, targetClients] of Object.entries(clients)) { const [client] = targetClients ?? [] if (client) return { target, client } as SnippetOperationReference } return } type SnippetOperationClients = z.output export type SnippetOperationReference = z.output