{"version":3,"file":"index.mjs","names":["zodObject"],"sources":["../src/utils.ts","../src/traversers.ts","../src/service-generator.ts","../src/zod-to-protobuf.ts"],"sourcesContent":["import { ZodEnum, ZodNumber } from \"zod\";\nimport type { ProtobufField } from \"./types\";\n\n/**\n * Determines the protobuf number type name based on Zod number schema.\n * Returns \"int32\" for integers, \"double\" for floating point numbers.\n *\n * @param value - Zod number schema\n * @returns Protobuf number type name (\"int32\" or \"double\")\n */\nexport const getNumberTypeName = ({ value }: { value: ZodNumber }): string => {\n  return ['float32', 'float64'].includes(value.format ?? '') ? \"double\" : \"int32\";\n};\n\n/**\n * Converts a string to PascalCase format.\n * Handles dot-separated strings by capitalizing each part.\n *\n * @param value - String to convert\n * @returns PascalCase string\n */\nexport const toPascalCase = ({ value }: { value: string }): string => {\n  return value\n    .split(\".\")\n    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n    .join(\"\");\n};\n\n/**\n * Converts a protobuf field definition to its type string representation.\n * Filters out null/empty values and joins the remaining types.\n *\n * @param field - Protobuf field definition\n * @returns Type string for the protobuf field\n */\nexport const protobufFieldToType = ({\n  field,\n}: {\n  field: ProtobufField;\n}): string => {\n  return field.types.filter(Boolean).join(\" \");\n};\n\nexport const getEnumByIndex = (schema: ZodEnum, index: any): any => {\n  return schema.options[index] || null;\n}\n","import * as inflection from \"inflection\";\nimport {\n  ZodArray,\n  ZodBigInt,\n  ZodBoolean,\n  ZodDate,\n  ZodEnum,\n  ZodMap,\n  ZodNullable,\n  ZodNumber,\n  ZodObject,\n  ZodOptional,\n  ZodRecord,\n  ZodSet,\n  ZodString,\n  ZodTuple,\n  ZodType,\n  type ZodTypeAny,\n} from \"zod\";\nimport {\n  ZodArrayDefinition,\n  ZodMapDefinition,\n  ZodRecordDefinition,\n  type ProtobufField,\n} from \"./types\";\nimport { getNumberTypeName, toPascalCase, protobufFieldToType } from \"./utils\";\n\n/**\n * Traverses a Zod array or set schema and converts it to protobuf repeated fields.\n * Handles nested types and generates appropriate field definitions.\n *\n * @param key - Field name\n * @param value - Zod array or set schema\n * @param messages - Map of message names to their protobuf fields\n * @param enums - Map of enum names to their protobuf values\n * @param typePrefix - Optional prefix for type names\n * @param parentKey - Optional parent message name for nested types\n * @returns Array of protobuf field definitions\n */\nexport const traverseArray = ({\n  key,\n  value,\n  messages,\n  enums,\n  typePrefix,\n  parentKey,\n  schemaToMessageName,\n}: {\n  key: string;\n  value: ZodArray<ZodTypeAny> | ZodSet<ZodTypeAny>;\n  messages: Map<string, string[]>;\n  enums: Map<string, string[]>;\n  typePrefix: string | null;\n  parentKey?: string;\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}): ProtobufField[] => {\n  const nestedValue =\n    value instanceof ZodArray\n      ? value.element\n      : value instanceof ZodSet\n        ? (value.def as unknown as ZodArrayDefinition).valueType\n        : (value as ZodArray<ZodTypeAny>).element;\n\n  const singularKey = inflection.singularize(key);\n  const elementFields = traverseKey({\n    key: singularKey,\n    value: nestedValue,\n    messages,\n    enums,\n    isOptional: false,\n    isInArray: true,\n    typePrefix,\n    parentKey: nestedValue instanceof ZodObject ? parentKey : undefined,\n    schemaToMessageName,\n  });\n  return elementFields.map((field) => ({\n    ...field,\n    types: [\"repeated\", ...field.types],\n    name: field.name.replace(singularKey, key),\n  }));\n};\n\n/**\n * Traverses a Zod map schema and converts it to a protobuf map type.\n * Validates that both key and value types are simple types suitable for map keys/values.\n *\n * @param key - Field name\n * @param value - Zod map schema\n * @param messages - Map of message names to their protobuf fields\n * @param enums - Map of enum names to their protobuf values\n * @param typePrefix - Optional prefix for type names\n * @param parentKey - Optional parent message name for nested types\n * @returns Array containing a single protobuf map field definition, or empty array if invalid\n */\nexport const traverseMap = ({\n  key,\n  value,\n  messages,\n  enums,\n  typePrefix,\n  parentKey,\n  schemaToMessageName,\n}: {\n  key: string;\n  value: ZodMap<ZodTypeAny, ZodTypeAny>;\n  messages: Map<string, string[]>;\n  enums: Map<string, string[]>;\n  typePrefix: string | null;\n  parentKey?: string;\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}): ProtobufField[] => {\n  const mapDef = value.def as ZodMapDefinition;\n\n  const keyType = traverseKey({\n    key: inflection.singularize(key),\n    value: mapDef.keyType,\n    messages,\n    enums,\n    isOptional: false,\n    isInArray: true,\n    typePrefix,\n    parentKey,\n    schemaToMessageName,\n  });\n  const valueType = traverseKey({\n    key: inflection.singularize(key),\n    value: mapDef.valueType,\n    messages,\n    enums,\n    isOptional: false,\n    isInArray: true,\n    typePrefix,\n    parentKey,\n    schemaToMessageName,\n  });\n\n  if (!keyType[0] || keyType.length !== 1) {\n    return [];\n  }\n\n  if (!valueType[0] || valueType.length !== 1) {\n    return [];\n  }\n\n  const mapType = `map<${protobufFieldToType({ field: keyType[0] })}, ${protobufFieldToType({ field: valueType[0] })}>`;\n  return [\n    {\n      types: [mapType],\n      name: key,\n    },\n  ];\n};\n\n/**\n * Traverses a Zod record schema and converts it to a protobuf map type.\n * Similar to traverseMap but handles ZodRecord type.\n *\n * @param key - Field name\n * @param value - Zod record schema\n * @param messages - Map of message names to their protobuf fields\n * @param enums - Map of enum names to their protobuf values\n * @param typePrefix - Optional prefix for type names\n * @param parentKey - Optional parent message name for nested types\n * @returns Array containing a single protobuf map field definition, or empty array if invalid\n */\nexport const traverseRecord = ({\n  key,\n  value,\n  messages,\n  enums,\n  typePrefix,\n  parentKey,\n  schemaToMessageName,\n}: {\n  key: string;\n  value: ZodRecord;\n  messages: Map<string, string[]>;\n  enums: Map<string, string[]>;\n  typePrefix: string | null;\n  parentKey?: string;\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}): ProtobufField[] => {\n  const recordDef = value.def as unknown as ZodRecordDefinition;\n\n  const keyType = traverseKey({\n    key: inflection.singularize(key),\n    value: recordDef.keyType,\n    messages,\n    enums,\n    isOptional: false,\n    isInArray: true,\n    typePrefix,\n    parentKey,\n    schemaToMessageName,\n  });\n  const valueType = traverseKey({\n    key: inflection.singularize(key),\n    value: recordDef.valueType,\n    messages,\n    enums,\n    isOptional: false,\n    isInArray: true,\n    typePrefix,\n    parentKey,\n    schemaToMessageName,\n  });\n\n  if (!keyType[0] || keyType.length !== 1) {\n    return [];\n  }\n\n  if (!valueType[0] || valueType.length !== 1) {\n    return [];\n  }\n\n  const mapType = `map<${protobufFieldToType({ field: keyType[0] })}, ${protobufFieldToType({ field: valueType[0] })}>`;\n  return [\n    {\n      types: [mapType],\n      name: key,\n    },\n  ];\n};\n\n/**\n * Traverses a single key-value pair from a Zod schema and converts it to protobuf field definitions.\n * Handles various Zod types including primitives, objects, arrays, maps, enums, tuples, and optional/nullable fields.\n *\n * @param key - Field name\n * @param value - Zod schema value\n * @param messages - Map of message names to their protobuf fields\n * @param enums - Map of enum names to their protobuf values\n * @param isOptional - Whether the field is optional\n * @param isInArray - Whether the field is inside an array\n * @param typePrefix - Optional prefix for type names\n * @param parentKey - Optional parent message name for nested types\n * @returns Array of protobuf field definitions\n */\nexport const traverseKey = ({\n  key,\n  value,\n  messages,\n  enums,\n  isOptional,\n  isInArray,\n  typePrefix,\n  parentKey,\n  schemaToMessageName,\n}: {\n  key: string;\n  value: unknown;\n  messages: Map<string, string[]>;\n  enums: Map<string, string[]>;\n  isOptional: boolean;\n  isInArray: boolean;\n  typePrefix: string | null;\n  parentKey?: string;\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}): ProtobufField[] => {\n  if (!value) {\n    return [];\n  }\n\n  if (value instanceof ZodOptional || value instanceof ZodNullable) {\n    return traverseKey({\n      key,\n      value: value.unwrap(),\n      messages,\n      enums,\n      isOptional: true,\n      isInArray,\n      typePrefix,\n      parentKey,\n      schemaToMessageName,\n    });\n  }\n\n  if (value instanceof ZodArray || value instanceof ZodSet) {\n    return traverseArray({\n      key,\n      value: value as ZodArray<ZodTypeAny> | ZodSet<ZodTypeAny>,\n      messages,\n      enums,\n      typePrefix,\n      parentKey,\n      schemaToMessageName,\n    });\n  }\n\n  if (value instanceof ZodMap) {\n    return traverseMap({\n      key,\n      value: value as ZodMap<ZodTypeAny, ZodTypeAny>,\n      messages,\n      enums,\n      typePrefix,\n      parentKey,\n      schemaToMessageName,\n    });\n  }\n\n  if (value instanceof ZodRecord) {\n    return traverseRecord({\n      key,\n      value: value as ZodRecord,\n      messages,\n      enums,\n      typePrefix,\n      parentKey,\n      schemaToMessageName,\n    });\n  }\n\n  const optional = isOptional && !isInArray ? \"optional\" : null;\n\n  if (value instanceof ZodObject) {\n    const existingName = schemaToMessageName?.get(value as ZodTypeAny);\n    if (existingName !== undefined) {\n      return [\n        {\n          types: [optional, existingName],\n          name: key,\n        },\n      ];\n    }\n    const keyPascal = toPascalCase({ value: key });\n    const shortName = typePrefix ? `${typePrefix}${keyPascal}` : keyPascal;\n    const longName = (() => {\n      let long = keyPascal;\n      if (parentKey) {\n        const isParentAlreadyPascalCase =\n          /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n        long = isParentAlreadyPascalCase\n          ? `${parentKey}${long}`\n          : `${toPascalCase({ value: parentKey })}${long}`;\n      }\n      return typePrefix ? `${typePrefix}${long}` : long;\n    })();\n    let messageName: string;\n    if (!messages.has(shortName) && !enums.has(shortName)) {\n      messageName = shortName;\n    } else if (\n      parentKey &&\n      (parentKey.endsWith(keyPascal) || longName === `${parentKey}${keyPascal}`)\n    ) {\n      const suffix = \"Item\";\n      messageName = !messages.has(shortName + suffix) && !enums.has(shortName + suffix)\n        ? shortName + suffix\n        : longName;\n    } else {\n      messageName = longName;\n    }\n    const nestedMessageFields = traverseSchema({\n      schema: value as ZodTypeAny,\n      messages,\n      enums,\n      typePrefix,\n      parentKey: messageName,\n      schemaToMessageName,\n    });\n    messages.set(messageName, nestedMessageFields);\n    schemaToMessageName?.set(value as ZodTypeAny, messageName);\n    return [\n      {\n        types: [optional, messageName],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodString) {\n    return [\n      {\n        types: [optional, \"string\"],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodNumber) {\n    const typeName = getNumberTypeName({ value });\n    return [\n      {\n        types: [optional, typeName],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodBoolean) {\n    return [\n      {\n        types: [optional, \"bool\"],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodEnum) {\n    const enumFields = value.options\n      .map(\n        (option: string | number, index: number) =>\n          `    ${String(option)} = ${index};`,\n      )\n      .join(\"\\n\");\n    let enumName = toPascalCase({ value: key });\n    if (parentKey) {\n      const isParentAlreadyPascalCase = /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n      if (isParentAlreadyPascalCase) {\n        enumName = `${parentKey}${enumName}`;\n      } else {\n        const parentMessageName = toPascalCase({ value: parentKey });\n        enumName = `${parentMessageName}${enumName}`;\n      }\n    }\n    if (typePrefix) {\n      enumName = `${typePrefix}${enumName}`;\n    }\n    enums.set(enumName, [`enum ${enumName} {\\n${enumFields}\\n}`]);\n    return [\n      {\n        types: [optional, enumName],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodDate) {\n    return [\n      {\n        types: [optional, \"string\"],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodBigInt) {\n    return [\n      {\n        types: [optional, \"int64\"],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodType) {\n    const def = value.def as {\n      type?: string;\n      check?: unknown;\n      fn?: (data: unknown) => boolean;\n    };\n    if (def.type === \"custom\" && def.check === \"custom\" && def.fn) {\n      try {\n        if (\n          (typeof Buffer !== \"undefined\" && def.fn(Buffer.alloc(0))) ||\n          (typeof Uint8Array !== \"undefined\" && def.fn(new Uint8Array(0)))\n        ) {\n          return [\n            {\n              types: [optional, \"bytes\"],\n              name: key,\n            },\n          ];\n        }\n      } catch {}\n    }\n  }\n\n  if (value instanceof ZodTuple) {\n    const tupleFields: ProtobufField[] = (\n      value.def.items as ZodTypeAny[]\n    ).flatMap((item: ZodTypeAny, index: number) => {\n      return traverseKey({\n        key: `${key}_${index}`,\n        value: item,\n        messages,\n        enums,\n        isOptional: false,\n        isInArray,\n        typePrefix,\n        parentKey,\n        schemaToMessageName,\n      });\n    });\n\n    let tupleMessageName = toPascalCase({ value: key });\n    if (parentKey) {\n      const isParentAlreadyPascalCase = /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n      if (isParentAlreadyPascalCase) {\n        tupleMessageName = `${parentKey}${tupleMessageName}`;\n      } else {\n        const parentMessageName = toPascalCase({ value: parentKey });\n        tupleMessageName = `${parentMessageName}${tupleMessageName}`;\n      }\n    }\n    if (typePrefix) {\n      tupleMessageName = `${typePrefix}${tupleMessageName}`;\n    }\n    messages.set(\n      tupleMessageName,\n      tupleFields.map(\n        (field, index) =>\n          `  ${field.types.join(\" \")} ${field.name} = ${index + 1};`,\n      ),\n    );\n    return [\n      {\n        types: [optional, tupleMessageName],\n        name: key,\n      },\n    ];\n  }\n\n  if (value instanceof ZodType) {\n    return [];\n  }\n\n  return [];\n};\n\n/**\n * Traverses a Zod object schema and converts it to protobuf message field definitions.\n * Processes all fields in the schema and generates appropriate protobuf types.\n *\n * @param schema - Zod schema to traverse\n * @param messages - Map of message names to their protobuf fields\n * @param enums - Map of enum names to their protobuf values\n * @param typePrefix - Optional prefix for type names\n * @param parentKey - Optional parent message name for nested types\n * @returns Array of protobuf field definition strings\n */\nexport const traverseSchema = ({\n  schema,\n  messages,\n  enums,\n  typePrefix,\n  parentKey,\n  schemaToMessageName,\n}: {\n  schema: ZodTypeAny;\n  messages: Map<string, string[]>;\n  enums: Map<string, string[]>;\n  typePrefix: string | null;\n  parentKey?: string;\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}): string[] => {\n  if (\n    !schema ||\n    typeof schema !== \"object\" ||\n    !(\"def\" in schema) ||\n    (schema.constructor.name !== \"ZodObject\" &&\n      (schema.def as { type?: string }).type !== \"object\")\n  ) {\n    return [];\n  }\n\n  const zodObject = schema as ZodObject<Record<string, ZodTypeAny>>;\n  const fields = Object.entries(zodObject.shape).flatMap(([key, value]) => {\n    return traverseKey({\n      key,\n      value,\n      messages,\n      enums,\n      isOptional: false,\n      isInArray: false,\n      typePrefix,\n      parentKey,\n      schemaToMessageName,\n    });\n  });\n\n  return fields.map(\n    (field, index) =>\n      `${protobufFieldToType({ field })} ${field.name} = ${index + 1};`,\n  );\n};\n","import { z, ZodObject, type ZodTypeAny } from \"zod\";\nimport type {\n  ServiceDefinition,\n  ServiceMethod,\n  ServicesInput,\n  ZodFunctionDefinition,\n  ZodTupleDefinition,\n} from \"./types\";\nimport { toPascalCase } from \"./utils\";\nimport { traverseSchema } from \"./traversers\";\n\n/**\n * Context for generating protobuf services.\n * Contains accumulated messages, enums, and type prefix.\n */\ninterface ServiceGenerationContext {\n  /** Map of message names to their protobuf fields */\n  messages: Map<string, string[]>;\n  /** Map of enum names to their protobuf values */\n  enums: Map<string, string[]>;\n  /** Prefix for type names or null if prefix is not used */\n  typePrefix: string | null;\n  /** Map of schema instance to message name for deduplication */\n  schemaToMessageName?: WeakMap<ZodTypeAny, string>;\n}\n\n/**\n * Parses a Zod service schema and extracts method definitions.\n * Each method must be a function with one argument (request) and a return value (response).\n *\n * @param name - Service name\n * @param schema - Zod object containing service methods as functions\n * @returns Service definition with extracted methods\n */\nconst parseZodServiceSchema = (\n  name: string,\n  schema: ZodObject<Record<string, ZodTypeAny>>,\n): ServiceDefinition => {\n  const shape = schema.shape as Record<string, ZodTypeAny>;\n  const methods: ServiceMethod[] = [];\n\n  for (const [methodName, methodSchema] of Object.entries(shape)) {\n    const methodDef = (methodSchema as ZodTypeAny).def as ZodFunctionDefinition;\n\n    if (methodDef.type === \"function\") {\n      const inputDef = methodDef.input;\n\n      const args = (inputDef?.def as ZodTupleDefinition)?.items ?? [];\n      const output = methodDef.output as ZodTypeAny;\n\n      if (args.length > 0 && args[0] && output) {\n        const request = args[0];\n        const response = output;\n\n        let streaming: \"client\" | \"server\" | \"bidirectional\" | undefined;\n        const metadata = methodSchema.meta();\n        streaming = metadata?.streaming as\n          | \"client\"\n          | \"server\"\n          | \"bidirectional\"\n          | undefined;\n\n        methods.push({\n          name: methodName,\n          request,\n          response,\n          streaming,\n        });\n      }\n    }\n  }\n\n  return {\n    name,\n    methods,\n  };\n};\n\n/**\n * Normalizes service input data into an array of service definitions.\n * If an array is passed, returns it as is.\n * If an object is passed, converts each key-value pair into a service definition.\n *\n * @param services - Array of service definitions or object with Zod schemas\n * @returns Array of normalized service definitions\n */\nconst normalizeServices = (services: ServicesInput): ServiceDefinition[] => {\n  if (Array.isArray(services)) {\n    return services;\n  }\n\n  return Object.entries(services).map(([name, schema]) =>\n    parseZodServiceSchema(name, schema),\n  );\n};\n\n/**\n * Ensures that the schema is a ZodObject.\n * If the schema is already an object, returns it as is.\n * Otherwise, wraps the schema in an object with a \"data\" field.\n *\n * @param schema - Zod schema of any type\n * @returns ZodObject containing the original schema\n */\nconst ensureZodObject = (\n  schema: ZodTypeAny,\n): ZodObject<Record<string, ZodTypeAny>> => {\n  const schemaType =\n    (schema.def as { type?: string }).type || schema.constructor.name;\n\n  if (schemaType === \"object\" || schema.constructor.name === \"ZodObject\") {\n    return schema as ZodObject<Record<string, ZodTypeAny>>;\n  }\n\n  return z.object({\n    data: schema,\n  });\n};\n\n/**\n * Generates the name for a request message based on the method name.\n *\n * @param methodName - Name of the service method\n * @param typePrefix - Optional prefix for type names\n * @returns Generated request message name in PascalCase\n */\nconst generateRequestMessageName = (\n  methodName: string,\n  typePrefix: string | null,\n): string => {\n  const messageName = toPascalCase({ value: `${methodName}Request` });\n  return typePrefix ? `${typePrefix}${messageName}` : messageName;\n};\n\n/**\n * Generates the name for a response message based on the method name.\n *\n * @param methodName - Name of the service method\n * @param typePrefix - Optional prefix for type names\n * @returns Generated response message name in PascalCase\n */\nconst generateResponseMessageName = (\n  methodName: string,\n  typePrefix: string | null,\n): string => {\n  const messageName = toPascalCase({ value: `${methodName}Response` });\n  return typePrefix ? `${typePrefix}${messageName}` : messageName;\n};\n\n/**\n * Processes a service method by generating request and response message names\n * and traversing their schemas to populate the context with message definitions.\n *\n * @param method - Service method definition\n * @param context - Generation context containing messages, enums, and type prefix\n * @returns Object containing request and response message names\n */\nconst processServiceMethod = (\n  method: ServiceMethod,\n  context: ServiceGenerationContext,\n): { requestName: string; responseName: string } => {\n  const { messages, enums, typePrefix, schemaToMessageName } = context;\n\n  const requestSchema = ensureZodObject(method.request);\n  let requestName = schemaToMessageName?.get(requestSchema);\n  if (requestName === undefined) {\n    requestName = generateRequestMessageName(method.name, typePrefix);\n    const requestFields = traverseSchema({\n      schema: requestSchema,\n      messages,\n      enums,\n      typePrefix,\n      parentKey: requestName,\n      schemaToMessageName,\n    });\n    messages.set(requestName, requestFields);\n    schemaToMessageName?.set(requestSchema, requestName);\n  }\n\n  const responseSchema = ensureZodObject(method.response);\n  let responseName = schemaToMessageName?.get(responseSchema);\n  if (responseName === undefined) {\n    responseName = generateResponseMessageName(method.name, typePrefix);\n    const responseFields = traverseSchema({\n      schema: responseSchema,\n      messages,\n      enums,\n      typePrefix,\n      parentKey: responseName,\n      schemaToMessageName,\n    });\n    messages.set(responseName, responseFields);\n    schemaToMessageName?.set(responseSchema, responseName);\n  }\n\n  return { requestName, responseName };\n};\n\n/**\n * Generates protobuf service definitions from Zod service schemas.\n * Supports streaming methods (client, server, bidirectional).\n *\n * @param services - Service definitions as array or object with Zod schemas\n * @param context - Generation context containing messages, enums, and type prefix\n * @returns Array of protobuf service definition strings\n */\nexport const generateServices = (\n  services: ServicesInput,\n  context: ServiceGenerationContext,\n): string[] => {\n  const normalizedServices = normalizeServices(services);\n\n  return normalizedServices.map((service) => {\n    const methods = service.methods.map((method) => {\n      const { requestName, responseName } = processServiceMethod(\n        method,\n        context,\n      );\n\n      const requestStreaming =\n        method.streaming === \"client\" || method.streaming === \"bidirectional\";\n      const responseStreaming =\n        method.streaming === \"server\" || method.streaming === \"bidirectional\";\n\n      const requestType = requestStreaming\n        ? `stream ${requestName}`\n        : requestName;\n      const responseType = responseStreaming\n        ? `stream ${responseName}`\n        : responseName;\n\n      return `    rpc ${toPascalCase({ value: method.name })}(${requestType}) returns (${responseType});`;\n    });\n\n    return `service ${toPascalCase({ value: service.name })} {\\n${methods.join(\"\\n\")}\\n}`;\n  });\n};\n","import type { ZodTypeAny } from \"zod\";\nimport type { ZodToProtobufOptions } from \"./types\";\nimport { traverseSchema } from \"./traversers\";\nimport { generateServices } from \"./service-generator\";\nimport { z } from \"zod\";\n\n/**\n * Converts a Zod schema to a protobuf definition string.\n * Generates messages, enums, and services based on the provided schema and options.\n *\n * @param schema - Optional Zod schema to convert (if not provided, only services will be generated)\n * @param options - Options for protobuf generation including package name, root message name, type prefix, and services\n * @returns Complete protobuf definition string\n */\nexport const zodToProtobufService = (\n  options: ZodToProtobufOptions = {},\n): string => {\n  const {\n    packageName = \"default\",\n    typePrefix = \"\",\n    services,\n  } = options;\n\n  const messages = new Map<string, string[]>();\n  const enums = new Map<string, string[]>();\n  const schemaToMessageName = new WeakMap<ZodTypeAny, string>();\n\n  const context = {\n    messages,\n    enums,\n    typePrefix: typePrefix || null,\n    schemaToMessageName,\n  };\n\n  const hasServices =\n    services &&\n    (Array.isArray(services)\n      ? services.length > 0\n      : Object.keys(services).length > 0);\n\n  const servicesString = hasServices ? generateServices(services, context) : [];\n\n  const enumsString = Array.from(enums.values()).map((enumDef) =>\n    enumDef.join(\"\\n\"),\n  );\n\n  const messagesString = Array.from(messages.entries()).map(\n    ([name, fields]) =>\n      `message ${name} {\\n${fields.map((field) => `    ${field}`).join(\"\\n\")}\\n}`,\n  );\n\n  const content = [servicesString, enumsString, messagesString]\n    .filter((strings) => !!strings.length)\n    .map((strings) => strings.join(\"\\n\\n\"))\n    .join(\"\\n\\n\");\n\n  let protoDefinition: string = \"\";\n  if (options.warningDeclaration !== false) {\n    protoDefinition += `\n/**\n * This file was automatically generated by zod-to-proto.\n * DO NOT MODIFY IT BY HAND. Instead, modify the source Zod schema.\n */\n`;\n  }\n\n  protoDefinition += `\nsyntax = \"proto3\";\npackage ${packageName};\n\n${content}\n`;\n\n  return protoDefinition.trim();\n};\n"],"mappings":"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"}