@globalart/zod-to-proto 1.0.19 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,12 +1,7 @@
1
- import { ZodObject, ZodTypeAny } from "zod";
1
+ import { ZodObject } from "zod";
2
2
 
3
3
  //#region src/types.d.ts
4
4
 
5
- /**
6
- * Input type for service definitions.
7
- * Can be either an array of service definitions or an object mapping service names to Zod schemas.
8
- */
9
- type ServicesInput = ServiceDefinition[] | Record<string, ZodObject<any>>;
10
5
  /**
11
6
  * Options for converting Zod schemas to protobuf definitions.
12
7
  */
@@ -20,42 +15,12 @@ interface ZodToProtobufOptions {
20
15
  /** Prefix to add to all generated type names */
21
16
  typePrefix?: string;
22
17
  /** Service definitions to include in the protobuf output */
23
- services?: ServicesInput;
18
+ services?: any;
24
19
  /** Whether to skip generating the root message */
25
20
  skipRootMessage?: boolean;
26
21
  }
27
- /**
28
- * Definition of a single service method.
29
- */
30
- interface ServiceMethod {
31
- /** Method name */
32
- name: string;
33
- /** Zod schema for the request message */
34
- request: ZodTypeAny;
35
- /** Zod schema for the response message */
36
- response: ZodTypeAny;
37
- /** Streaming type: "client" for client streaming, "server" for server streaming, "bidirectional" for both */
38
- streaming?: "client" | "server" | "bidirectional";
39
- }
40
- /**
41
- * Definition of a protobuf service containing multiple methods.
42
- */
43
- interface ServiceDefinition {
44
- /** Service name */
45
- name: string;
46
- /** Array of service methods */
47
- methods: ServiceMethod[];
48
- }
49
22
  //#endregion
50
23
  //#region src/zod-to-protobuf.d.ts
51
- /**
52
- * Generates a protobuf definition string for services only (without root message).
53
- * Convenience function that calls zodToProtobuf with an empty schema.
54
- *
55
- * @param options - Options for protobuf generation
56
- * @returns Protobuf definition string
57
- */
58
- declare const zodToProtobufService: (options?: ZodToProtobufOptions) => string;
59
24
  /**
60
25
  * Converts a Zod schema to a protobuf definition string.
61
26
  * Generates messages, enums, and services based on the provided schema and options.
@@ -64,7 +29,7 @@ declare const zodToProtobufService: (options?: ZodToProtobufOptions) => string;
64
29
  * @param options - Options for protobuf generation including package name, root message name, type prefix, and services
65
30
  * @returns Complete protobuf definition string
66
31
  */
67
- declare const zodToProtobuf: (schema?: ZodTypeAny, options?: ZodToProtobufOptions) => string;
32
+ declare const zodToProtobufService: (options?: ZodToProtobufOptions) => string;
68
33
  //#endregion
69
- export { zodToProtobuf, zodToProtobufService };
34
+ export { zodToProtobufService };
70
35
  //# sourceMappingURL=index.d.mts.map
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import * as inflection from "inflection";
2
1
  import { ZodArray, ZodBigInt, ZodBoolean, ZodDate, ZodEnum, ZodMap, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodRecord, ZodSet, ZodString, ZodTuple, ZodType, z } from "zod";
2
+ import * as inflection from "inflection";
3
3
 
4
4
  //#region src/utils.ts
5
5
  /**
@@ -456,16 +456,6 @@ const generateServices = (services, context) => {
456
456
  //#endregion
457
457
  //#region src/zod-to-protobuf.ts
458
458
  /**
459
- * Generates a protobuf definition string for services only (without root message).
460
- * Convenience function that calls zodToProtobuf with an empty schema.
461
- *
462
- * @param options - Options for protobuf generation
463
- * @returns Protobuf definition string
464
- */
465
- const zodToProtobufService = (options = {}) => {
466
- return zodToProtobuf(z.object(), options);
467
- };
468
- /**
469
459
  * Converts a Zod schema to a protobuf definition string.
470
460
  * Generates messages, enums, and services based on the provided schema and options.
471
461
  *
@@ -473,22 +463,10 @@ const zodToProtobufService = (options = {}) => {
473
463
  * @param options - Options for protobuf generation including package name, root message name, type prefix, and services
474
464
  * @returns Complete protobuf definition string
475
465
  */
476
- const zodToProtobuf = (schema, options = {}) => {
477
- const { packageName = "default", rootMessageName = "Message", typePrefix = "", services, skipRootMessage = false } = options;
466
+ const zodToProtobufService = (options = {}) => {
467
+ const { packageName = "default", typePrefix = "", services } = options;
478
468
  const messages = /* @__PURE__ */ new Map();
479
469
  const enums = /* @__PURE__ */ new Map();
480
- if (schema && !skipRootMessage) {
481
- const fields = traverseSchema({
482
- schema,
483
- messages,
484
- enums,
485
- typePrefix
486
- });
487
- if (fields.length > 0) {
488
- const rootMessageKey = `${typePrefix}${rootMessageName}`;
489
- messages.set(rootMessageKey, fields);
490
- }
491
- }
492
470
  const context = {
493
471
  messages,
494
472
  enums,
@@ -516,5 +494,5 @@ ${content}
516
494
  };
517
495
 
518
496
  //#endregion
519
- export { zodToProtobuf, zodToProtobufService };
497
+ export { zodToProtobufService };
520
498
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["tupleFields: ProtobufField[]","methods: ServiceMethod[]","streaming: \"client\" | \"server\" | \"bidirectional\" | undefined","protoDefinition: string"],"sources":["../src/utils.ts","../src/traversers.ts","../src/service-generator.ts","../src/zod-to-protobuf.ts"],"sourcesContent":["import { 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 value.isInt ? \"int32\" : \"double\";\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","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}: {\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}): ProtobufField[] => {\n const nestedValue =\n value instanceof ZodArray\n ? value.element\n : value instanceof ZodSet\n ? (value.def as unknown as ZodArrayDefinition).valueType\n : // @ts-expect-error\n (value.def as unknown as ZodArrayDefinition).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 });\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}: {\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}): 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 });\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 });\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}: {\n key: string;\n value: ZodRecord;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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 });\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 });\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}: {\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}): 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 });\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 });\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 });\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 });\n }\n\n const optional = isOptional && !isInArray ? \"optional\" : null;\n\n if (value instanceof ZodObject) {\n let messageName = toPascalCase({ value: key });\n if (parentKey) {\n const isParentAlreadyPascalCase = /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n if (isParentAlreadyPascalCase) {\n messageName = `${parentKey}${messageName}`;\n } else {\n const parentMessageName = toPascalCase({ value: parentKey });\n messageName = `${parentMessageName}${messageName}`;\n }\n }\n if (typePrefix) {\n messageName = `${typePrefix}${messageName}`;\n }\n const nestedMessageFields = traverseSchema({\n schema: value,\n messages,\n enums,\n typePrefix,\n parentKey: messageName,\n });\n messages.set(messageName, nestedMessageFields);\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 });\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}: {\n schema: ZodTypeAny;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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<any>;\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 });\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}\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 } = context;\n\n const requestName = generateRequestMessageName(method.name, typePrefix);\n const responseName = generateResponseMessageName(method.name, typePrefix);\n\n if (!messages.has(requestName)) {\n const requestSchema = ensureZodObject(method.request);\n const requestFields = traverseSchema({\n schema: requestSchema,\n messages,\n enums,\n typePrefix,\n parentKey: requestName,\n });\n messages.set(requestName, requestFields);\n }\n\n if (!messages.has(responseName)) {\n const responseSchema = ensureZodObject(method.response);\n const responseFields = traverseSchema({\n schema: responseSchema,\n messages,\n enums,\n typePrefix,\n parentKey: responseName,\n });\n messages.set(responseName, responseFields);\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 * Generates a protobuf definition string for services only (without root message).\n * Convenience function that calls zodToProtobuf with an empty schema.\n *\n * @param options - Options for protobuf generation\n * @returns Protobuf definition string\n */\nexport const zodToProtobufService = (\n options: ZodToProtobufOptions = {},\n): string => {\n return zodToProtobuf(z.object(), options);\n};\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 zodToProtobuf = (\n schema?: ZodTypeAny,\n options: ZodToProtobufOptions = {},\n): string => {\n const {\n packageName = \"default\",\n rootMessageName = \"Message\",\n typePrefix = \"\",\n services,\n skipRootMessage = false,\n } = options;\n\n const messages = new Map<string, string[]>();\n const enums = new Map<string, string[]>();\n\n if (schema && !skipRootMessage) {\n const fields = traverseSchema({ schema, messages, enums, typePrefix });\n if (fields.length > 0) {\n const rootMessageKey = `${typePrefix}${rootMessageName}`;\n messages.set(rootMessageKey, fields);\n }\n }\n\n const context = {\n messages,\n enums,\n typePrefix: typePrefix || null,\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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"}
1
+ {"version":3,"file":"index.mjs","names":["tupleFields: ProtobufField[]","methods: ServiceMethod[]","streaming: \"client\" | \"server\" | \"bidirectional\" | undefined","protoDefinition: string"],"sources":["../src/utils.ts","../src/traversers.ts","../src/service-generator.ts","../src/zod-to-protobuf.ts"],"sourcesContent":["import { 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 value.isInt ? \"int32\" : \"double\";\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","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}: {\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}): ProtobufField[] => {\n const nestedValue =\n value instanceof ZodArray\n ? value.element\n : value instanceof ZodSet\n ? (value.def as unknown as ZodArrayDefinition).valueType\n : // @ts-expect-error\n (value.def as unknown as ZodArrayDefinition).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 });\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}: {\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}): 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 });\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 });\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}: {\n key: string;\n value: ZodRecord;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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 });\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 });\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}: {\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}): 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 });\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 });\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 });\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 });\n }\n\n const optional = isOptional && !isInArray ? \"optional\" : null;\n\n if (value instanceof ZodObject) {\n let messageName = toPascalCase({ value: key });\n if (parentKey) {\n const isParentAlreadyPascalCase = /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n if (isParentAlreadyPascalCase) {\n messageName = `${parentKey}${messageName}`;\n } else {\n const parentMessageName = toPascalCase({ value: parentKey });\n messageName = `${parentMessageName}${messageName}`;\n }\n }\n if (typePrefix) {\n messageName = `${typePrefix}${messageName}`;\n }\n const nestedMessageFields = traverseSchema({\n schema: value,\n messages,\n enums,\n typePrefix,\n parentKey: messageName,\n });\n messages.set(messageName, nestedMessageFields);\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 });\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}: {\n schema: ZodTypeAny;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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<any>;\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 });\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}\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 } = context;\n\n const requestName = generateRequestMessageName(method.name, typePrefix);\n const responseName = generateResponseMessageName(method.name, typePrefix);\n\n if (!messages.has(requestName)) {\n const requestSchema = ensureZodObject(method.request);\n const requestFields = traverseSchema({\n schema: requestSchema,\n messages,\n enums,\n typePrefix,\n parentKey: requestName,\n });\n messages.set(requestName, requestFields);\n }\n\n if (!messages.has(responseName)) {\n const responseSchema = ensureZodObject(method.response);\n const responseFields = traverseSchema({\n schema: responseSchema,\n messages,\n enums,\n typePrefix,\n parentKey: responseName,\n });\n messages.set(responseName, responseFields);\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\n const context = {\n messages,\n enums,\n typePrefix: typePrefix || null,\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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"}
package/package.json CHANGED
@@ -1,31 +1,19 @@
1
1
  {
2
2
  "name": "@globalart/zod-to-proto",
3
- "version": "1.0.19",
3
+ "version": "2.0.0",
4
4
  "author": {
5
5
  "name": "GlobalArt, Inc"
6
6
  },
7
- "license": "MIT",
8
7
  "type": "module",
8
+ "license": "MIT",
9
9
  "files": [
10
10
  "dist",
11
11
  "README.md",
12
12
  "LICENSE"
13
13
  ],
14
- "main": "./dist/index.cjs",
15
- "module": "./dist/index.mjs",
16
- "types": "./dist/index.d.cts",
17
- "exports": {
18
- ".": {
19
- "import": {
20
- "types": "./dist/index.d.mts",
21
- "default": "./dist/index.mjs"
22
- },
23
- "require": {
24
- "types": "./dist/index.d.cts",
25
- "default": "./dist/index.cjs"
26
- }
27
- }
28
- },
14
+ "main": "dist/index.mjs",
15
+ "module": "dist/index.mjs",
16
+ "types": "dist/index.d.mts",
29
17
  "repository": {
30
18
  "type": "git",
31
19
  "url": "git+https://github.com/GlobalArtInc/ecosystem.git#main"
package/dist/index.cjs DELETED
@@ -1,549 +0,0 @@
1
- //#region rolldown:runtime
2
- var __create = Object.create;
3
- var __defProp = Object.defineProperty;
4
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
- var __getOwnPropNames = Object.getOwnPropertyNames;
6
- var __getProtoOf = Object.getPrototypeOf;
7
- var __hasOwnProp = Object.prototype.hasOwnProperty;
8
- var __copyProps = (to, from, except, desc) => {
9
- if (from && typeof from === "object" || typeof from === "function") {
10
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
- key = keys[i];
12
- if (!__hasOwnProp.call(to, key) && key !== except) {
13
- __defProp(to, key, {
14
- get: ((k) => from[k]).bind(null, key),
15
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
16
- });
17
- }
18
- }
19
- }
20
- return to;
21
- };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
23
- value: mod,
24
- enumerable: true
25
- }) : target, mod));
26
-
27
- //#endregion
28
- let inflection = require("inflection");
29
- inflection = __toESM(inflection);
30
- let zod = require("zod");
31
-
32
- //#region src/utils.ts
33
- /**
34
- * Determines the protobuf number type name based on Zod number schema.
35
- * Returns "int32" for integers, "double" for floating point numbers.
36
- *
37
- * @param value - Zod number schema
38
- * @returns Protobuf number type name ("int32" or "double")
39
- */
40
- const getNumberTypeName = ({ value }) => {
41
- return value.isInt ? "int32" : "double";
42
- };
43
- /**
44
- * Converts a string to PascalCase format.
45
- * Handles dot-separated strings by capitalizing each part.
46
- *
47
- * @param value - String to convert
48
- * @returns PascalCase string
49
- */
50
- const toPascalCase = ({ value }) => {
51
- return value.split(".").map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join("");
52
- };
53
- /**
54
- * Converts a protobuf field definition to its type string representation.
55
- * Filters out null/empty values and joins the remaining types.
56
- *
57
- * @param field - Protobuf field definition
58
- * @returns Type string for the protobuf field
59
- */
60
- const protobufFieldToType = ({ field }) => {
61
- return field.types.filter(Boolean).join(" ");
62
- };
63
-
64
- //#endregion
65
- //#region src/traversers.ts
66
- /**
67
- * Traverses a Zod array or set schema and converts it to protobuf repeated fields.
68
- * Handles nested types and generates appropriate field definitions.
69
- *
70
- * @param key - Field name
71
- * @param value - Zod array or set schema
72
- * @param messages - Map of message names to their protobuf fields
73
- * @param enums - Map of enum names to their protobuf values
74
- * @param typePrefix - Optional prefix for type names
75
- * @param parentKey - Optional parent message name for nested types
76
- * @returns Array of protobuf field definitions
77
- */
78
- const traverseArray = ({ key, value, messages, enums, typePrefix, parentKey }) => {
79
- const nestedValue = value instanceof zod.ZodArray ? value.element : value instanceof zod.ZodSet ? value.def.valueType : value.def.element;
80
- const singularKey = inflection.singularize(key);
81
- return traverseKey({
82
- key: singularKey,
83
- value: nestedValue,
84
- messages,
85
- enums,
86
- isOptional: false,
87
- isInArray: true,
88
- typePrefix,
89
- parentKey: nestedValue instanceof zod.ZodObject ? parentKey : void 0
90
- }).map((field) => ({
91
- ...field,
92
- types: ["repeated", ...field.types],
93
- name: field.name.replace(singularKey, key)
94
- }));
95
- };
96
- /**
97
- * Traverses a Zod map schema and converts it to a protobuf map type.
98
- * Validates that both key and value types are simple types suitable for map keys/values.
99
- *
100
- * @param key - Field name
101
- * @param value - Zod map schema
102
- * @param messages - Map of message names to their protobuf fields
103
- * @param enums - Map of enum names to their protobuf values
104
- * @param typePrefix - Optional prefix for type names
105
- * @param parentKey - Optional parent message name for nested types
106
- * @returns Array containing a single protobuf map field definition, or empty array if invalid
107
- */
108
- const traverseMap = ({ key, value, messages, enums, typePrefix, parentKey }) => {
109
- const mapDef = value.def;
110
- const keyType = traverseKey({
111
- key: inflection.singularize(key),
112
- value: mapDef.keyType,
113
- messages,
114
- enums,
115
- isOptional: false,
116
- isInArray: true,
117
- typePrefix,
118
- parentKey
119
- });
120
- const valueType = traverseKey({
121
- key: inflection.singularize(key),
122
- value: mapDef.valueType,
123
- messages,
124
- enums,
125
- isOptional: false,
126
- isInArray: true,
127
- typePrefix,
128
- parentKey
129
- });
130
- if (!keyType[0] || keyType.length !== 1) return [];
131
- if (!valueType[0] || valueType.length !== 1) return [];
132
- return [{
133
- types: [`map<${protobufFieldToType({ field: keyType[0] })}, ${protobufFieldToType({ field: valueType[0] })}>`],
134
- name: key
135
- }];
136
- };
137
- /**
138
- * Traverses a Zod record schema and converts it to a protobuf map type.
139
- * Similar to traverseMap but handles ZodRecord type.
140
- *
141
- * @param key - Field name
142
- * @param value - Zod record schema
143
- * @param messages - Map of message names to their protobuf fields
144
- * @param enums - Map of enum names to their protobuf values
145
- * @param typePrefix - Optional prefix for type names
146
- * @param parentKey - Optional parent message name for nested types
147
- * @returns Array containing a single protobuf map field definition, or empty array if invalid
148
- */
149
- const traverseRecord = ({ key, value, messages, enums, typePrefix, parentKey }) => {
150
- const recordDef = value.def;
151
- const keyType = traverseKey({
152
- key: inflection.singularize(key),
153
- value: recordDef.keyType,
154
- messages,
155
- enums,
156
- isOptional: false,
157
- isInArray: true,
158
- typePrefix,
159
- parentKey
160
- });
161
- const valueType = traverseKey({
162
- key: inflection.singularize(key),
163
- value: recordDef.valueType,
164
- messages,
165
- enums,
166
- isOptional: false,
167
- isInArray: true,
168
- typePrefix,
169
- parentKey
170
- });
171
- if (!keyType[0] || keyType.length !== 1) return [];
172
- if (!valueType[0] || valueType.length !== 1) return [];
173
- return [{
174
- types: [`map<${protobufFieldToType({ field: keyType[0] })}, ${protobufFieldToType({ field: valueType[0] })}>`],
175
- name: key
176
- }];
177
- };
178
- /**
179
- * Traverses a single key-value pair from a Zod schema and converts it to protobuf field definitions.
180
- * Handles various Zod types including primitives, objects, arrays, maps, enums, tuples, and optional/nullable fields.
181
- *
182
- * @param key - Field name
183
- * @param value - Zod schema value
184
- * @param messages - Map of message names to their protobuf fields
185
- * @param enums - Map of enum names to their protobuf values
186
- * @param isOptional - Whether the field is optional
187
- * @param isInArray - Whether the field is inside an array
188
- * @param typePrefix - Optional prefix for type names
189
- * @param parentKey - Optional parent message name for nested types
190
- * @returns Array of protobuf field definitions
191
- */
192
- const traverseKey = ({ key, value, messages, enums, isOptional, isInArray, typePrefix, parentKey }) => {
193
- if (!value) return [];
194
- if (value instanceof zod.ZodOptional || value instanceof zod.ZodNullable) return traverseKey({
195
- key,
196
- value: value.unwrap(),
197
- messages,
198
- enums,
199
- isOptional: true,
200
- isInArray,
201
- typePrefix,
202
- parentKey
203
- });
204
- if (value instanceof zod.ZodArray || value instanceof zod.ZodSet) return traverseArray({
205
- key,
206
- value,
207
- messages,
208
- enums,
209
- typePrefix,
210
- parentKey
211
- });
212
- if (value instanceof zod.ZodMap) return traverseMap({
213
- key,
214
- value,
215
- messages,
216
- enums,
217
- typePrefix,
218
- parentKey
219
- });
220
- if (value instanceof zod.ZodRecord) return traverseRecord({
221
- key,
222
- value,
223
- messages,
224
- enums,
225
- typePrefix,
226
- parentKey
227
- });
228
- const optional = isOptional && !isInArray ? "optional" : null;
229
- if (value instanceof zod.ZodObject) {
230
- let messageName = toPascalCase({ value: key });
231
- if (parentKey) if (/^[A-Z][a-zA-Z0-9]*$/.test(parentKey)) messageName = `${parentKey}${messageName}`;
232
- else messageName = `${toPascalCase({ value: parentKey })}${messageName}`;
233
- if (typePrefix) messageName = `${typePrefix}${messageName}`;
234
- const nestedMessageFields = traverseSchema({
235
- schema: value,
236
- messages,
237
- enums,
238
- typePrefix,
239
- parentKey: messageName
240
- });
241
- messages.set(messageName, nestedMessageFields);
242
- return [{
243
- types: [optional, messageName],
244
- name: key
245
- }];
246
- }
247
- if (value instanceof zod.ZodString) return [{
248
- types: [optional, "string"],
249
- name: key
250
- }];
251
- if (value instanceof zod.ZodNumber) return [{
252
- types: [optional, getNumberTypeName({ value })],
253
- name: key
254
- }];
255
- if (value instanceof zod.ZodBoolean) return [{
256
- types: [optional, "bool"],
257
- name: key
258
- }];
259
- if (value instanceof zod.ZodEnum) {
260
- const enumFields = value.options.map((option, index) => ` ${String(option)} = ${index};`).join("\n");
261
- let enumName = toPascalCase({ value: key });
262
- if (parentKey) if (/^[A-Z][a-zA-Z0-9]*$/.test(parentKey)) enumName = `${parentKey}${enumName}`;
263
- else enumName = `${toPascalCase({ value: parentKey })}${enumName}`;
264
- if (typePrefix) enumName = `${typePrefix}${enumName}`;
265
- enums.set(enumName, [`enum ${enumName} {\n${enumFields}\n}`]);
266
- return [{
267
- types: [optional, enumName],
268
- name: key
269
- }];
270
- }
271
- if (value instanceof zod.ZodDate) return [{
272
- types: [optional, "string"],
273
- name: key
274
- }];
275
- if (value instanceof zod.ZodBigInt) return [{
276
- types: [optional, "int64"],
277
- name: key
278
- }];
279
- if (value instanceof zod.ZodType) {
280
- const def = value.def;
281
- if (def.type === "custom" && def.check === "custom" && def.fn) try {
282
- if (typeof Buffer !== "undefined" && def.fn(Buffer.alloc(0)) || typeof Uint8Array !== "undefined" && def.fn(new Uint8Array(0))) return [{
283
- types: [optional, "bytes"],
284
- name: key
285
- }];
286
- } catch {}
287
- }
288
- if (value instanceof zod.ZodTuple) {
289
- const tupleFields = value.def.items.flatMap((item, index) => {
290
- return traverseKey({
291
- key: `${key}_${index}`,
292
- value: item,
293
- messages,
294
- enums,
295
- isOptional: false,
296
- isInArray,
297
- typePrefix,
298
- parentKey
299
- });
300
- });
301
- let tupleMessageName = toPascalCase({ value: key });
302
- if (parentKey) if (/^[A-Z][a-zA-Z0-9]*$/.test(parentKey)) tupleMessageName = `${parentKey}${tupleMessageName}`;
303
- else tupleMessageName = `${toPascalCase({ value: parentKey })}${tupleMessageName}`;
304
- if (typePrefix) tupleMessageName = `${typePrefix}${tupleMessageName}`;
305
- messages.set(tupleMessageName, tupleFields.map((field, index) => ` ${field.types.join(" ")} ${field.name} = ${index + 1};`));
306
- return [{
307
- types: [optional, tupleMessageName],
308
- name: key
309
- }];
310
- }
311
- if (value instanceof zod.ZodType) return [];
312
- return [];
313
- };
314
- /**
315
- * Traverses a Zod object schema and converts it to protobuf message field definitions.
316
- * Processes all fields in the schema and generates appropriate protobuf types.
317
- *
318
- * @param schema - Zod schema to traverse
319
- * @param messages - Map of message names to their protobuf fields
320
- * @param enums - Map of enum names to their protobuf values
321
- * @param typePrefix - Optional prefix for type names
322
- * @param parentKey - Optional parent message name for nested types
323
- * @returns Array of protobuf field definition strings
324
- */
325
- const traverseSchema = ({ schema, messages, enums, typePrefix, parentKey }) => {
326
- if (!schema || typeof schema !== "object" || !("def" in schema) || schema.constructor.name !== "ZodObject" && schema.def.type !== "object") return [];
327
- const zodObject = schema;
328
- return Object.entries(zodObject.shape).flatMap(([key, value]) => {
329
- return traverseKey({
330
- key,
331
- value,
332
- messages,
333
- enums,
334
- isOptional: false,
335
- isInArray: false,
336
- typePrefix,
337
- parentKey
338
- });
339
- }).map((field, index) => `${protobufFieldToType({ field })} ${field.name} = ${index + 1};`);
340
- };
341
-
342
- //#endregion
343
- //#region src/service-generator.ts
344
- /**
345
- * Parses a Zod service schema and extracts method definitions.
346
- * Each method must be a function with one argument (request) and a return value (response).
347
- *
348
- * @param name - Service name
349
- * @param schema - Zod object containing service methods as functions
350
- * @returns Service definition with extracted methods
351
- */
352
- const parseZodServiceSchema = (name, schema) => {
353
- const shape = schema.shape;
354
- const methods = [];
355
- for (const [methodName, methodSchema] of Object.entries(shape)) {
356
- const methodDef = methodSchema.def;
357
- if (methodDef.type === "function") {
358
- const args = (methodDef.input?.def)?.items ?? [];
359
- const output = methodDef.output;
360
- if (args.length > 0 && args[0] && output) {
361
- const request = args[0];
362
- const response = output;
363
- let streaming;
364
- streaming = methodSchema.meta()?.streaming;
365
- methods.push({
366
- name: methodName,
367
- request,
368
- response,
369
- streaming
370
- });
371
- }
372
- }
373
- }
374
- return {
375
- name,
376
- methods
377
- };
378
- };
379
- /**
380
- * Normalizes service input data into an array of service definitions.
381
- * If an array is passed, returns it as is.
382
- * If an object is passed, converts each key-value pair into a service definition.
383
- *
384
- * @param services - Array of service definitions or object with Zod schemas
385
- * @returns Array of normalized service definitions
386
- */
387
- const normalizeServices = (services) => {
388
- if (Array.isArray(services)) return services;
389
- return Object.entries(services).map(([name, schema]) => parseZodServiceSchema(name, schema));
390
- };
391
- /**
392
- * Ensures that the schema is a ZodObject.
393
- * If the schema is already an object, returns it as is.
394
- * Otherwise, wraps the schema in an object with a "data" field.
395
- *
396
- * @param schema - Zod schema of any type
397
- * @returns ZodObject containing the original schema
398
- */
399
- const ensureZodObject = (schema) => {
400
- if ((schema.def.type || schema.constructor.name) === "object" || schema.constructor.name === "ZodObject") return schema;
401
- return zod.z.object({ data: schema });
402
- };
403
- /**
404
- * Generates the name for a request message based on the method name.
405
- *
406
- * @param methodName - Name of the service method
407
- * @param typePrefix - Optional prefix for type names
408
- * @returns Generated request message name in PascalCase
409
- */
410
- const generateRequestMessageName = (methodName, typePrefix) => {
411
- const messageName = toPascalCase({ value: `${methodName}Request` });
412
- return typePrefix ? `${typePrefix}${messageName}` : messageName;
413
- };
414
- /**
415
- * Generates the name for a response message based on the method name.
416
- *
417
- * @param methodName - Name of the service method
418
- * @param typePrefix - Optional prefix for type names
419
- * @returns Generated response message name in PascalCase
420
- */
421
- const generateResponseMessageName = (methodName, typePrefix) => {
422
- const messageName = toPascalCase({ value: `${methodName}Response` });
423
- return typePrefix ? `${typePrefix}${messageName}` : messageName;
424
- };
425
- /**
426
- * Processes a service method by generating request and response message names
427
- * and traversing their schemas to populate the context with message definitions.
428
- *
429
- * @param method - Service method definition
430
- * @param context - Generation context containing messages, enums, and type prefix
431
- * @returns Object containing request and response message names
432
- */
433
- const processServiceMethod = (method, context) => {
434
- const { messages, enums, typePrefix } = context;
435
- const requestName = generateRequestMessageName(method.name, typePrefix);
436
- const responseName = generateResponseMessageName(method.name, typePrefix);
437
- if (!messages.has(requestName)) {
438
- const requestFields = traverseSchema({
439
- schema: ensureZodObject(method.request),
440
- messages,
441
- enums,
442
- typePrefix,
443
- parentKey: requestName
444
- });
445
- messages.set(requestName, requestFields);
446
- }
447
- if (!messages.has(responseName)) {
448
- const responseFields = traverseSchema({
449
- schema: ensureZodObject(method.response),
450
- messages,
451
- enums,
452
- typePrefix,
453
- parentKey: responseName
454
- });
455
- messages.set(responseName, responseFields);
456
- }
457
- return {
458
- requestName,
459
- responseName
460
- };
461
- };
462
- /**
463
- * Generates protobuf service definitions from Zod service schemas.
464
- * Supports streaming methods (client, server, bidirectional).
465
- *
466
- * @param services - Service definitions as array or object with Zod schemas
467
- * @param context - Generation context containing messages, enums, and type prefix
468
- * @returns Array of protobuf service definition strings
469
- */
470
- const generateServices = (services, context) => {
471
- return normalizeServices(services).map((service) => {
472
- const methods = service.methods.map((method) => {
473
- const { requestName, responseName } = processServiceMethod(method, context);
474
- const requestStreaming = method.streaming === "client" || method.streaming === "bidirectional";
475
- const responseStreaming = method.streaming === "server" || method.streaming === "bidirectional";
476
- const requestType = requestStreaming ? `stream ${requestName}` : requestName;
477
- const responseType = responseStreaming ? `stream ${responseName}` : responseName;
478
- return ` rpc ${toPascalCase({ value: method.name })}(${requestType}) returns (${responseType});`;
479
- });
480
- return `service ${toPascalCase({ value: service.name })} {\n${methods.join("\n")}\n}`;
481
- });
482
- };
483
-
484
- //#endregion
485
- //#region src/zod-to-protobuf.ts
486
- /**
487
- * Generates a protobuf definition string for services only (without root message).
488
- * Convenience function that calls zodToProtobuf with an empty schema.
489
- *
490
- * @param options - Options for protobuf generation
491
- * @returns Protobuf definition string
492
- */
493
- const zodToProtobufService = (options = {}) => {
494
- return zodToProtobuf(zod.z.object(), options);
495
- };
496
- /**
497
- * Converts a Zod schema to a protobuf definition string.
498
- * Generates messages, enums, and services based on the provided schema and options.
499
- *
500
- * @param schema - Optional Zod schema to convert (if not provided, only services will be generated)
501
- * @param options - Options for protobuf generation including package name, root message name, type prefix, and services
502
- * @returns Complete protobuf definition string
503
- */
504
- const zodToProtobuf = (schema, options = {}) => {
505
- const { packageName = "default", rootMessageName = "Message", typePrefix = "", services, skipRootMessage = false } = options;
506
- const messages = /* @__PURE__ */ new Map();
507
- const enums = /* @__PURE__ */ new Map();
508
- if (schema && !skipRootMessage) {
509
- const fields = traverseSchema({
510
- schema,
511
- messages,
512
- enums,
513
- typePrefix
514
- });
515
- if (fields.length > 0) {
516
- const rootMessageKey = `${typePrefix}${rootMessageName}`;
517
- messages.set(rootMessageKey, fields);
518
- }
519
- }
520
- const context = {
521
- messages,
522
- enums,
523
- typePrefix: typePrefix || null
524
- };
525
- const content = [
526
- services && (Array.isArray(services) ? services.length > 0 : Object.keys(services).length > 0) ? generateServices(services, context) : [],
527
- Array.from(enums.values()).map((enumDef) => enumDef.join("\n")),
528
- Array.from(messages.entries()).map(([name, fields]) => `message ${name} {\n${fields.map((field) => ` ${field}`).join("\n")}\n}`)
529
- ].filter((strings) => !!strings.length).map((strings) => strings.join("\n\n")).join("\n\n");
530
- let protoDefinition = "";
531
- if (options.warningDeclaration !== false) protoDefinition += `
532
- /**
533
- * This file was automatically generated by zod-to-proto.
534
- * DO NOT MODIFY IT BY HAND. Instead, modify the source Zod schema.
535
- */
536
- `;
537
- protoDefinition += `
538
- syntax = "proto3";
539
- package ${packageName};
540
-
541
- ${content}
542
- `;
543
- return protoDefinition.trim();
544
- };
545
-
546
- //#endregion
547
- exports.zodToProtobuf = zodToProtobuf;
548
- exports.zodToProtobufService = zodToProtobufService;
549
- //# sourceMappingURL=index.cjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.cjs","names":["ZodArray","ZodSet","ZodObject","ZodOptional","ZodNullable","ZodMap","ZodRecord","ZodString","ZodNumber","ZodBoolean","ZodEnum","ZodDate","ZodBigInt","ZodType","ZodTuple","tupleFields: ProtobufField[]","methods: ServiceMethod[]","streaming: \"client\" | \"server\" | \"bidirectional\" | undefined","z","z","protoDefinition: string"],"sources":["../src/utils.ts","../src/traversers.ts","../src/service-generator.ts","../src/zod-to-protobuf.ts"],"sourcesContent":["import { 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 value.isInt ? \"int32\" : \"double\";\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","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}: {\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}): ProtobufField[] => {\n const nestedValue =\n value instanceof ZodArray\n ? value.element\n : value instanceof ZodSet\n ? (value.def as unknown as ZodArrayDefinition).valueType\n : // @ts-expect-error\n (value.def as unknown as ZodArrayDefinition).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 });\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}: {\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}): 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 });\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 });\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}: {\n key: string;\n value: ZodRecord;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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 });\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 });\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}: {\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}): 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 });\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 });\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 });\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 });\n }\n\n const optional = isOptional && !isInArray ? \"optional\" : null;\n\n if (value instanceof ZodObject) {\n let messageName = toPascalCase({ value: key });\n if (parentKey) {\n const isParentAlreadyPascalCase = /^[A-Z][a-zA-Z0-9]*$/.test(parentKey);\n if (isParentAlreadyPascalCase) {\n messageName = `${parentKey}${messageName}`;\n } else {\n const parentMessageName = toPascalCase({ value: parentKey });\n messageName = `${parentMessageName}${messageName}`;\n }\n }\n if (typePrefix) {\n messageName = `${typePrefix}${messageName}`;\n }\n const nestedMessageFields = traverseSchema({\n schema: value,\n messages,\n enums,\n typePrefix,\n parentKey: messageName,\n });\n messages.set(messageName, nestedMessageFields);\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 });\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}: {\n schema: ZodTypeAny;\n messages: Map<string, string[]>;\n enums: Map<string, string[]>;\n typePrefix: string | null;\n parentKey?: 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<any>;\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 });\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}\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 } = context;\n\n const requestName = generateRequestMessageName(method.name, typePrefix);\n const responseName = generateResponseMessageName(method.name, typePrefix);\n\n if (!messages.has(requestName)) {\n const requestSchema = ensureZodObject(method.request);\n const requestFields = traverseSchema({\n schema: requestSchema,\n messages,\n enums,\n typePrefix,\n parentKey: requestName,\n });\n messages.set(requestName, requestFields);\n }\n\n if (!messages.has(responseName)) {\n const responseSchema = ensureZodObject(method.response);\n const responseFields = traverseSchema({\n schema: responseSchema,\n messages,\n enums,\n typePrefix,\n parentKey: responseName,\n });\n messages.set(responseName, responseFields);\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 * Generates a protobuf definition string for services only (without root message).\n * Convenience function that calls zodToProtobuf with an empty schema.\n *\n * @param options - Options for protobuf generation\n * @returns Protobuf definition string\n */\nexport const zodToProtobufService = (\n options: ZodToProtobufOptions = {},\n): string => {\n return zodToProtobuf(z.object(), options);\n};\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 zodToProtobuf = (\n schema?: ZodTypeAny,\n options: ZodToProtobufOptions = {},\n): string => {\n const {\n packageName = \"default\",\n rootMessageName = \"Message\",\n typePrefix = \"\",\n services,\n skipRootMessage = false,\n } = options;\n\n const messages = new Map<string, string[]>();\n const enums = new Map<string, string[]>();\n\n if (schema && !skipRootMessage) {\n const fields = traverseSchema({ schema, messages, enums, typePrefix });\n if (fields.length > 0) {\n const rootMessageKey = `${typePrefix}${rootMessageName}`;\n messages.set(rootMessageKey, fields);\n }\n }\n\n const context = {\n messages,\n enums,\n typePrefix: typePrefix || null,\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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"}
package/dist/index.d.cts DELETED
@@ -1,70 +0,0 @@
1
- import { ZodObject, ZodTypeAny } from "zod";
2
-
3
- //#region src/types.d.ts
4
-
5
- /**
6
- * Input type for service definitions.
7
- * Can be either an array of service definitions or an object mapping service names to Zod schemas.
8
- */
9
- type ServicesInput = ServiceDefinition[] | Record<string, ZodObject<any>>;
10
- /**
11
- * Options for converting Zod schemas to protobuf definitions.
12
- */
13
- interface ZodToProtobufOptions {
14
- /** Whether to add the warning declaration to the protobuf definition */
15
- warningDeclaration?: boolean;
16
- /** Package name for the generated protobuf file */
17
- packageName?: string;
18
- /** Name of the root message (default: "Message") */
19
- rootMessageName?: string;
20
- /** Prefix to add to all generated type names */
21
- typePrefix?: string;
22
- /** Service definitions to include in the protobuf output */
23
- services?: ServicesInput;
24
- /** Whether to skip generating the root message */
25
- skipRootMessage?: boolean;
26
- }
27
- /**
28
- * Definition of a single service method.
29
- */
30
- interface ServiceMethod {
31
- /** Method name */
32
- name: string;
33
- /** Zod schema for the request message */
34
- request: ZodTypeAny;
35
- /** Zod schema for the response message */
36
- response: ZodTypeAny;
37
- /** Streaming type: "client" for client streaming, "server" for server streaming, "bidirectional" for both */
38
- streaming?: "client" | "server" | "bidirectional";
39
- }
40
- /**
41
- * Definition of a protobuf service containing multiple methods.
42
- */
43
- interface ServiceDefinition {
44
- /** Service name */
45
- name: string;
46
- /** Array of service methods */
47
- methods: ServiceMethod[];
48
- }
49
- //#endregion
50
- //#region src/zod-to-protobuf.d.ts
51
- /**
52
- * Generates a protobuf definition string for services only (without root message).
53
- * Convenience function that calls zodToProtobuf with an empty schema.
54
- *
55
- * @param options - Options for protobuf generation
56
- * @returns Protobuf definition string
57
- */
58
- declare const zodToProtobufService: (options?: ZodToProtobufOptions) => string;
59
- /**
60
- * Converts a Zod schema to a protobuf definition string.
61
- * Generates messages, enums, and services based on the provided schema and options.
62
- *
63
- * @param schema - Optional Zod schema to convert (if not provided, only services will be generated)
64
- * @param options - Options for protobuf generation including package name, root message name, type prefix, and services
65
- * @returns Complete protobuf definition string
66
- */
67
- declare const zodToProtobuf: (schema?: ZodTypeAny, options?: ZodToProtobufOptions) => string;
68
- //#endregion
69
- export { zodToProtobuf, zodToProtobufService };
70
- //# sourceMappingURL=index.d.cts.map