parseDef.js 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import { ignoreOverride } from "./Options.js";
  2. import { selectParser } from "./selectParser.js";
  3. import { getRelativePath } from "./getRelativePath.js";
  4. import { parseAnyDef } from "./parsers/any.js";
  5. export function parseDef(def, refs, forceResolution = false) {
  6. const seenItem = refs.seen.get(def);
  7. if (refs.override) {
  8. const overrideResult = refs.override?.(def, refs, seenItem, forceResolution);
  9. if (overrideResult !== ignoreOverride) {
  10. return overrideResult;
  11. }
  12. }
  13. if (seenItem && !forceResolution) {
  14. const seenSchema = get$ref(seenItem, refs);
  15. if (seenSchema !== undefined) {
  16. return seenSchema;
  17. }
  18. }
  19. const newItem = { def, path: refs.currentPath, jsonSchema: undefined };
  20. refs.seen.set(def, newItem);
  21. const jsonSchemaOrGetter = selectParser(def, def.typeName, refs);
  22. // If the return was a function, then the inner definition needs to be extracted before a call to parseDef (recursive)
  23. const jsonSchema = typeof jsonSchemaOrGetter === "function"
  24. ? parseDef(jsonSchemaOrGetter(), refs)
  25. : jsonSchemaOrGetter;
  26. if (jsonSchema) {
  27. addMeta(def, refs, jsonSchema);
  28. }
  29. if (refs.postProcess) {
  30. const postProcessResult = refs.postProcess(jsonSchema, def, refs);
  31. newItem.jsonSchema = jsonSchema;
  32. return postProcessResult;
  33. }
  34. newItem.jsonSchema = jsonSchema;
  35. return jsonSchema;
  36. }
  37. const get$ref = (item, refs) => {
  38. switch (refs.$refStrategy) {
  39. case "root":
  40. return { $ref: item.path.join("/") };
  41. case "relative":
  42. return { $ref: getRelativePath(refs.currentPath, item.path) };
  43. case "none":
  44. case "seen": {
  45. if (item.path.length < refs.currentPath.length &&
  46. item.path.every((value, index) => refs.currentPath[index] === value)) {
  47. console.warn(`Recursive reference detected at ${refs.currentPath.join("/")}! Defaulting to any`);
  48. return parseAnyDef(refs);
  49. }
  50. return refs.$refStrategy === "seen" ? parseAnyDef(refs) : undefined;
  51. }
  52. }
  53. };
  54. const addMeta = (def, refs, jsonSchema) => {
  55. if (def.description) {
  56. jsonSchema.description = def.description;
  57. if (refs.markdownDescription) {
  58. jsonSchema.markdownDescription = def.description;
  59. }
  60. }
  61. return jsonSchema;
  62. };