record.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. import { ZodFirstPartyTypeKind, } from "zod";
  2. import { parseDef } from "../parseDef.js";
  3. import { parseStringDef } from "./string.js";
  4. import { parseBrandedDef } from "./branded.js";
  5. export function parseRecordDef(def, refs) {
  6. if (refs.target === "openAi") {
  7. console.warn("Warning: OpenAI may not support records in schemas! Try an array of key-value pairs instead.");
  8. }
  9. if (refs.target === "openApi3" &&
  10. def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) {
  11. return {
  12. type: "object",
  13. required: def.keyType._def.values,
  14. properties: def.keyType._def.values.reduce((acc, key) => ({
  15. ...acc,
  16. [key]: parseDef(def.valueType._def, {
  17. ...refs,
  18. currentPath: [...refs.currentPath, "properties", key],
  19. }) ?? {},
  20. }), {}),
  21. additionalProperties: refs.rejectedAdditionalProperties,
  22. };
  23. }
  24. const schema = {
  25. type: "object",
  26. additionalProperties: parseDef(def.valueType._def, {
  27. ...refs,
  28. currentPath: [...refs.currentPath, "additionalProperties"],
  29. }) ?? refs.allowedAdditionalProperties,
  30. };
  31. if (refs.target === "openApi3") {
  32. return schema;
  33. }
  34. if (def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodString &&
  35. def.keyType._def.checks?.length) {
  36. const { type, ...keyType } = parseStringDef(def.keyType._def, refs);
  37. return {
  38. ...schema,
  39. propertyNames: keyType,
  40. };
  41. }
  42. else if (def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodEnum) {
  43. return {
  44. ...schema,
  45. propertyNames: {
  46. enum: def.keyType._def.values,
  47. },
  48. };
  49. }
  50. else if (def.keyType?._def.typeName === ZodFirstPartyTypeKind.ZodBranded &&
  51. def.keyType._def.type._def.typeName === ZodFirstPartyTypeKind.ZodString &&
  52. def.keyType._def.type._def.checks?.length) {
  53. const { type, ...keyType } = parseBrandedDef(def.keyType._def, refs);
  54. return {
  55. ...schema,
  56. propertyNames: keyType,
  57. };
  58. }
  59. return schema;
  60. }