@scalar/openapi-to-markdown 1.5.3 → 1.6.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.
Files changed (43) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +27 -1
  3. package/dist/create-markdown-from-openapi.d.ts +5 -2
  4. package/dist/create-markdown-from-openapi.d.ts.map +1 -1
  5. package/dist/create-markdown-from-openapi.js +7 -3
  6. package/dist/document-anchors.d.ts.map +1 -1
  7. package/dist/document-anchors.js +4 -2
  8. package/dist/document-examples.d.ts.map +1 -1
  9. package/dist/document-examples.js +10 -5
  10. package/dist/get-markdown-examples.d.ts.map +1 -1
  11. package/dist/get-markdown-examples.js +48 -24
  12. package/dist/index.d.ts +1 -0
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/load-document.d.ts +8 -1
  15. package/dist/load-document.d.ts.map +1 -1
  16. package/dist/load-document.js +34 -23
  17. package/dist/markdown/index.d.ts +5 -0
  18. package/dist/markdown/index.d.ts.map +1 -0
  19. package/dist/markdown/index.js +4 -0
  20. package/dist/markdown-nodes.d.ts.map +1 -1
  21. package/dist/markdown-nodes.js +1 -0
  22. package/dist/parse-description.d.ts.map +1 -1
  23. package/dist/parse-description.js +36 -18
  24. package/dist/render-document.d.ts.map +1 -1
  25. package/dist/render-document.js +50 -26
  26. package/dist/render-examples.d.ts.map +1 -1
  27. package/dist/render-examples.js +8 -4
  28. package/dist/render-operation-details.d.ts.map +1 -1
  29. package/dist/render-operation-details.js +28 -14
  30. package/dist/render-operation.d.ts.map +1 -1
  31. package/dist/render-operation.js +60 -31
  32. package/dist/render-schema.d.ts.map +1 -1
  33. package/dist/render-schema.js +145 -77
  34. package/dist/render-security.d.ts.map +1 -1
  35. package/dist/render-security.js +12 -6
  36. package/dist/render-tags.d.ts +7 -0
  37. package/dist/render-tags.d.ts.map +1 -0
  38. package/dist/render-tags.js +73 -0
  39. package/dist/restore-boolean-schemas.d.ts.map +1 -1
  40. package/dist/restore-boolean-schemas.js +22 -11
  41. package/dist/select-document.d.ts.map +1 -1
  42. package/dist/select-document.js +5 -1
  43. package/package.json +14 -9
@@ -10,8 +10,9 @@ const clean = (node) => {
10
10
  node.url = safeUrl(node.url);
11
11
  }
12
12
  if ('children' in node) {
13
- for (const child of node.children)
13
+ for (const child of node.children) {
14
14
  clean(child);
15
+ }
15
16
  // The filter preserves the parent's existing child types.
16
17
  const previousLength = node.children.length;
17
18
  node.children = node.children.filter((child) => child.type !== 'image' &&
@@ -33,10 +34,12 @@ const clean = (node) => {
33
34
  if (node.children.length !== previousLength) {
34
35
  const first = node.children.at(0);
35
36
  const last = node.children.at(-1);
36
- if (first?.type === 'text')
37
+ if (first?.type === 'text') {
37
38
  first.value = first.value.trimStart();
38
- if (last?.type === 'text')
39
+ }
40
+ if (last?.type === 'text') {
39
41
  last.value = last.value.trimEnd();
42
+ }
40
43
  }
41
44
  }
42
45
  delete node.position;
@@ -47,24 +50,31 @@ const pruneDefinitions = (tree) => {
47
50
  const footnotes = new Set();
48
51
  const definitions = new Map(tree.children.filter((node) => node.type === 'footnoteDefinition').map((node) => [node.identifier, node]));
49
52
  const collect = (node) => {
50
- if (node.type === 'linkReference')
53
+ if (node.type === 'linkReference') {
51
54
  links.add(node.identifier);
52
- if (node.type === 'footnoteReference')
55
+ }
56
+ if (node.type === 'footnoteReference') {
53
57
  footnotes.add(node.identifier);
54
- if ('children' in node)
58
+ }
59
+ if ('children' in node) {
55
60
  node.children.forEach(collect);
61
+ }
56
62
  };
57
63
  tree.children.filter((node) => node.type !== 'footnoteDefinition').forEach(collect);
58
64
  // Set iteration also visits footnotes discovered inside another footnote.
59
- for (const identifier of footnotes)
65
+ for (const identifier of footnotes) {
60
66
  definitions.get(identifier)?.children.forEach(collect);
67
+ }
61
68
  tree.children = tree.children.filter((node) => {
62
- if (node.type === 'definition')
69
+ if (node.type === 'definition') {
63
70
  return links.has(node.identifier);
64
- if (node.type === 'footnoteDefinition')
71
+ }
72
+ if (node.type === 'footnoteDefinition') {
65
73
  return footnotes.has(node.identifier);
66
- if (node.type === 'paragraph')
74
+ }
75
+ if (node.type === 'paragraph') {
67
76
  return node.children.some((child) => child.type !== 'text' || child.value.trim());
77
+ }
68
78
  return true;
69
79
  });
70
80
  };
@@ -78,8 +88,9 @@ export const createDescriptionParser = () => {
78
88
  const cache = new Map();
79
89
  const parse = async (value) => {
80
90
  // Most schema descriptions are one plain sentence. Parsing them costs more than the page's other text.
81
- if (isPlainText(value))
91
+ if (isPlainText(value)) {
82
92
  return [{ type: 'paragraph', children: [{ type: 'text', value: value.trim() }] }];
93
+ }
83
94
  const parsed = parser.parse(value);
84
95
  // Raw HTML and GitHub alerts retain Scalar's existing conversion behavior.
85
96
  const tree = containsHtml(parsed) || /^\s*>\s*\[!(NOTE|TIP|IMPORTANT|WARNING|CAUTION|SUCCESS)\]/im.test(value)
@@ -93,26 +104,31 @@ export const createDescriptionParser = () => {
93
104
  const copy = { ...node };
94
105
  if ('identifier' in copy) {
95
106
  copy.identifier = `${prefix}${copy.identifier}`;
96
- if ('label' in copy)
107
+ if ('label' in copy) {
97
108
  copy.label = copy.identifier;
98
- if ('referenceType' in copy)
109
+ }
110
+ if ('referenceType' in copy) {
99
111
  copy.referenceType = 'full';
112
+ }
100
113
  }
101
- if ('children' in copy)
114
+ if ('children' in copy) {
102
115
  copy.children = copy.children.map((child) => namespace(child, prefix));
116
+ }
103
117
  return copy;
104
118
  };
105
119
  const hasReference = (node) => 'identifier' in node || ('children' in node && node.children.some(hasReference));
106
120
  return () => {
107
121
  const state = { nextId: 0 };
108
122
  return async (value) => {
109
- if (!value)
123
+ if (!value) {
110
124
  return [];
125
+ }
111
126
  const prefix = `description-${state.nextId++}-`;
112
127
  const cached = cache.get(value) ?? parse(value);
113
128
  if (!cache.has(value)) {
114
- if (cache.size >= 8192)
129
+ if (cache.size >= 8192) {
115
130
  cache.clear();
131
+ }
116
132
  cache.set(value, cached);
117
133
  }
118
134
  const nodes = await cached;
@@ -127,10 +143,12 @@ export const expandDescriptions = async (nodes, description) => {
127
143
  const found = [];
128
144
  const collect = (siblings) => {
129
145
  for (const node of siblings) {
130
- if (node.type === 'descriptionPlaceholder')
146
+ if (node.type === 'descriptionPlaceholder') {
131
147
  found.push({ siblings, node });
132
- else if ('children' in node)
148
+ }
149
+ else if ('children' in node) {
133
150
  collect(node.children);
151
+ }
134
152
  }
135
153
  };
136
154
  collect(nodes);
@@ -1 +1 @@
1
- {"version":3,"file":"render-document.d.ts","sourceRoot":"","sources":["../src/render-document.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,8DAA8D,CAAA;AAcrE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AA+C7D,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,QAAO,CAAC,CACzC,QAAQ,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,MAAM,CAAC,CAuPnB,CAAA"}
1
+ {"version":3,"file":"render-document.d.ts","sourceRoot":"","sources":["../src/render-document.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACV,eAAe,EAGhB,MAAM,8DAA8D,CAAA;AAerE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AAwD7D,2FAA2F;AAC3F,eAAO,MAAM,sBAAsB,QAAO,CAAC,CACzC,QAAQ,EAAE,eAAe,EACzB,OAAO,CAAC,EAAE,oBAAoB,KAC3B,OAAO,CAAC,MAAM,CAAC,CAyRnB,CAAA"}
@@ -12,20 +12,24 @@ import { renderExamples } from './render-examples.js';
12
12
  import { formatOperationMethod, renderOperation } from './render-operation.js';
13
13
  import { createSchemaRenderer } from './render-schema.js';
14
14
  import { renderSecurity } from './render-security.js';
15
+ import { getTagSections } from './render-tags.js';
15
16
  const serializer = unified()
16
17
  .use(remarkGfm)
17
18
  .use(remarkStringify, {
18
19
  bullet: '-',
19
20
  join: [
20
21
  (left, right, parent) => {
21
- if (!('spread' in parent))
22
+ if (!('spread' in parent)) {
22
23
  return undefined;
24
+ }
23
25
  // Inside a tight list item, content after a nested list would otherwise continue its last item.
24
- if (left.type === 'list' && right.type !== 'list')
26
+ if (left.type === 'list' && right.type !== 'list') {
25
27
  return 1;
28
+ }
26
29
  // Code blocks in descriptions read better apart from the prose around them.
27
- if (left.type === 'code' || right.type === 'code')
30
+ if (left.type === 'code' || right.type === 'code') {
28
31
  return 1;
32
+ }
29
33
  return undefined;
30
34
  },
31
35
  ],
@@ -43,12 +47,14 @@ const renderShownModel = async (name, view, previous, description) => {
43
47
  ? [strong(text(view.title)), text(' ('), inlineCode(name), text(')')]
44
48
  : [inlineCode(name)];
45
49
  label.push(text(' — shown above'));
46
- if (previous.name !== name)
50
+ if (previous.name !== name) {
47
51
  label.push(text(' as '), inlineCode(previous.name));
52
+ }
48
53
  label.push(text('.'));
49
54
  const blocks = [paragraph(...label)];
50
- if (view.description && view.description !== previous.description)
55
+ if (view.description && view.description !== previous.description) {
51
56
  blocks.push(...(await description(view.description)));
57
+ }
52
58
  return item(...blocks);
53
59
  };
54
60
  /** Build Markdown directly, retaining caches only for this immutable document snapshot. */
@@ -81,8 +87,9 @@ export const createDocumentRenderer = () => {
81
87
  const entries = [];
82
88
  for (const [path, reference] of Object.entries(group.paths ?? {})) {
83
89
  const pathItem = getResolvedPathItem(reference);
84
- if (!pathItem)
90
+ if (!pathItem) {
85
91
  continue;
92
+ }
86
93
  forEachPathItemOperation(reference, (method, operation) => {
87
94
  const label = `${formatOperationMethod(method)} ${path}`;
88
95
  entries.push({
@@ -107,8 +114,9 @@ export const createDocumentRenderer = () => {
107
114
  const nodes = [];
108
115
  const sections = [];
109
116
  const flush = async () => {
110
- if (!nodes.length)
117
+ if (!nodes.length) {
111
118
  return;
119
+ }
112
120
  const children = nodes.splice(0);
113
121
  await expandDescriptions(children, description);
114
122
  sections.push(serializer.stringify({ type: 'root', children }).trimEnd());
@@ -116,63 +124,73 @@ export const createDocumentRenderer = () => {
116
124
  if (!single) {
117
125
  const { info } = document;
118
126
  const metadata = [field('OpenAPI Version', inlineCode(document.openapi))];
119
- if (info.version)
127
+ if (info.version) {
120
128
  metadata.push(field('API Version', inlineCode(info.version)));
121
- if (info.termsOfService)
129
+ }
130
+ if (info.termsOfService) {
122
131
  metadata.push(field('Terms of service', link(info.termsOfService, info.termsOfService)));
132
+ }
123
133
  if (info.contact) {
124
134
  const contact = [text(info.contact.name ?? '')];
125
135
  metadata.push(item(paragraph(strong(text('Contact:')), text(' '), ...contact, ...(info.contact.url ? [text(' '), link(info.contact.url, info.contact.url)] : []), ...(info.contact.email ? [text(' '), link(`mailto:${info.contact.email}`, info.contact.email)] : []))));
126
136
  }
127
- if (info.license)
137
+ if (info.license) {
128
138
  metadata.push(field('License', info.license.url ? link(info.license.url, info.license.name ?? '') : text(info.license.name)));
139
+ }
129
140
  nodes.push(heading(1, text(info.title)), list(metadata), ...(await description(info.description)));
130
141
  if (whole) {
131
142
  const contents = [];
132
143
  for (const group of groups) {
133
- if (!group.entries.length)
144
+ if (!group.entries.length) {
134
145
  continue;
146
+ }
135
147
  contents.push(paragraph(strong(text(group.title))), list(group.entries.map(({ id, label }) => item(paragraph(link(`#${encodeURIComponent(id)}`, label))))));
136
148
  }
137
149
  if (destinations?.size) {
138
150
  contents.push(paragraph(strong(text('Schemas'))), list([...destinations].map(([name, url]) => item(paragraph(link(url, name))))));
139
151
  }
140
- if (contents.length)
152
+ if (contents.length) {
141
153
  nodes.push(heading(2, text('Contents')), ...contents);
154
+ }
142
155
  }
143
156
  if (document.servers?.length || (whole && document.servers !== undefined)) {
144
- if (documentContext?.servers)
157
+ if (documentContext?.servers) {
145
158
  nodes.push(anchor(documentContext.servers));
159
+ }
146
160
  nodes.push(heading(2, text('Servers')));
147
161
  const effectiveServers = document.servers?.length
148
162
  ? document.servers
149
163
  : [{ url: '/' }];
150
164
  const servers = effectiveServers.map((server) => {
151
165
  const nested = [];
152
- if (server.description)
166
+ if (server.description) {
153
167
  nested.push(field('Description', text(server.description)));
168
+ }
154
169
  const variables = Object.entries(server.variables ?? {});
155
- if (variables.length)
170
+ if (variables.length) {
156
171
  nested.push(item(paragraph(strong(text('Variables:'))), list(variables.map(([name, variable]) => item(paragraph(inlineCode(name), text(' (default: '), inlineCode(variable.default), text(')'), ...(whole && variable.enum?.length
157
172
  ? [text(', possible values: '), inlineCode(variable.enum.join(', '))]
158
173
  : []), text(variable.description ? `: ${variable.description}` : '')))))));
174
+ }
159
175
  const entry = field('URL', inlineCode(server.url));
160
- if (nested.length)
176
+ if (nested.length) {
161
177
  entry.children.push(list(nested));
178
+ }
162
179
  return entry;
163
180
  });
164
181
  nodes.push(list(servers));
165
182
  }
166
- if (documentContext?.authentication)
183
+ if (documentContext?.authentication) {
167
184
  nodes.push(anchor(documentContext.authentication));
185
+ }
168
186
  nodes.push(...(await renderSecurity(document.security, document.components?.securitySchemes, description, 2)));
169
187
  if (document.tags?.length) {
170
188
  nodes.push(heading(2, text('Tags')));
171
- for (const tag of document.tags) {
172
- const title = /^3\.2\./.test(openapiVersion) ? (tag.summary ?? tag.name) : tag.name;
189
+ for (const { tag, title } of getTagSections(document.tags, openapiVersion)) {
173
190
  nodes.push(heading(3, text(title)), ...(await description(tag.description)));
174
- if (tag.externalDocs)
191
+ if (tag.externalDocs) {
175
192
  nodes.push(paragraph(link(tag.externalDocs.url, tag.externalDocs.description ?? tag.externalDocs.url)));
193
+ }
176
194
  }
177
195
  }
178
196
  await flush();
@@ -180,12 +198,14 @@ export const createDocumentRenderer = () => {
180
198
  for (const group of groups) {
181
199
  let hasOperations = false;
182
200
  for (const { path, pathItem, method, operation, id } of group.entries) {
183
- if (!hasOperations && !single)
201
+ if (!hasOperations && !single) {
184
202
  nodes.push(heading(2, text(group.title)));
203
+ }
185
204
  hasOperations = true;
186
205
  schemas.beginSection();
187
- if (id)
206
+ if (id) {
188
207
  nodes.push(anchor(id));
208
+ }
189
209
  nodes.push(...(await renderOperation(document, path, method, pathItem, operation, group.webhook, {
190
210
  description,
191
211
  schemas,
@@ -201,11 +221,13 @@ export const createDocumentRenderer = () => {
201
221
  const renderModel = async (name, schema, level) => {
202
222
  const view = schemas.view(schema);
203
223
  const summary = schemas.summarize(schema);
204
- if (whole)
224
+ if (whole) {
205
225
  nodes.push(anchor(anchors.get('schema', name)));
226
+ }
206
227
  nodes.push(heading(level, text(view.title ?? name)));
207
- if (summary.length)
228
+ if (summary.length) {
208
229
  nodes.push(paragraph(strong(text('Type:')), text('\u00a0'), ...summary));
230
+ }
209
231
  nodes.push(...(await description(view.description)), ...schemas.render(schema, 0, [], { hideDetails: true, name }));
210
232
  if (view.type === 'object' || hasAuthoredExamples(view)) {
211
233
  // A model page's own schema is bounded, so it gets a generated example even in linked mode.
@@ -224,13 +246,15 @@ export const createDocumentRenderer = () => {
224
246
  await renderModel(selected[0], selected[1], 1);
225
247
  }
226
248
  const dependencies = models.filter(([name]) => name !== options.model);
227
- if (dependencies.length)
249
+ if (dependencies.length) {
228
250
  nodes.push(heading(2, text('Schemas')));
251
+ }
229
252
  // Models the page already expanded cost one line each, grouped into a single list.
230
253
  const shownAbove = [];
231
254
  const flushShownAbove = () => {
232
- if (shownAbove.length)
255
+ if (shownAbove.length) {
233
256
  nodes.push(list(shownAbove.splice(0)));
257
+ }
234
258
  };
235
259
  for (const [name, schema] of dependencies) {
236
260
  schemas.beginSection();
@@ -1 +1 @@
1
- {"version":3,"file":"render-examples.d.ts","sourceRoot":"","sources":["../src/render-examples.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,OAAO,CAAA;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,yBAAyB,CAAA;AAEjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,+EAA+E;AAC/E,eAAO,MAAM,cAAc,GACzB,QAAQ,aAAa,EACrB,aAAa,iBAAiB,EAC9B,kBAA8B,EAC9B,OAAO,MAAM,GAAG,OAAO,EACvB,uBAAwB,EAExB,6BAAqC,EACrC,+BAIG;IACD,yFAAyF;IACzF,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oFAAoF;IACpF,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CACvB,KACL,OAAO,CAAC,WAAW,EAAE,CA8EvB,CAAA"}
1
+ {"version":3,"file":"render-examples.d.ts","sourceRoot":"","sources":["../src/render-examples.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAQ,WAAW,EAAE,MAAM,OAAO,CAAA;AAG9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAC3D,OAAO,EAAE,KAAK,aAAa,EAAuB,MAAM,yBAAyB,CAAA;AAEjF,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,+EAA+E;AAC/E,eAAO,MAAM,cAAc,GACzB,QAAQ,aAAa,EACrB,aAAa,iBAAiB,EAC9B,kBAA8B,EAC9B,OAAO,MAAM,GAAG,OAAO,EACvB,uBAAwB,EAExB,6BAAqC,EACrC,+BAIG;IACD,yFAAyF;IACzF,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,gFAAgF;IAChF,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,oFAAoF;IACpF,QAAQ,CAAC,EAAE,gBAAgB,CAAA;CACvB,KACL,OAAO,CAAC,WAAW,EAAE,CAgFvB,CAAA"}
@@ -10,11 +10,13 @@ schemaOpenapiVersion = openapiVersion, { linked = false, quiet = linked, example
10
10
  const nodes = [];
11
11
  const values = (examples?.get ?? getMarkdownExamples)(source, mediaType, mode, openapiVersion, schemaOpenapiVersion, linked);
12
12
  for (const example of values) {
13
- if ('omitted' in example && quiet)
13
+ if ('omitted' in example && quiet) {
14
14
  continue;
15
+ }
15
16
  const start = nodes.length;
16
17
  const generated = examples && example.generated;
17
- nodes.push(paragraph(strong(text(generated ? 'Generated example:' : example.name ? `Example: ${example.name}` : 'Example:'))));
18
+ const exampleLabel = example.name ? `Example: ${example.name}` : 'Example:';
19
+ nodes.push(paragraph(strong(text(generated ? 'Generated example:' : exampleLabel))));
18
20
  const addCode = (code) => {
19
21
  if (generated) {
20
22
  const scope = JSON.stringify([mediaType, mode, openapiVersion, schemaOpenapiVersion, code.lang]);
@@ -31,8 +33,9 @@ schemaOpenapiVersion = openapiVersion, { linked = false, quiet = linked, example
31
33
  nodes.push(paragraph(emphasis(text('Generated example omitted because it is too large.'))));
32
34
  continue;
33
35
  }
34
- if (example.summary)
36
+ if (example.summary) {
35
37
  nodes.push(paragraph(text(example.summary)));
38
+ }
36
39
  nodes.push(...(await description(example.description)));
37
40
  if ('error' in example) {
38
41
  nodes.push(paragraph(text(example.error)));
@@ -43,9 +46,10 @@ schemaOpenapiVersion = openapiVersion, { linked = false, quiet = linked, example
43
46
  continue;
44
47
  }
45
48
  if ('serializedValue' in example) {
49
+ const textLanguage = mediaType.includes('json') ? 'json' : 'text';
46
50
  addCode({
47
51
  type: 'code',
48
- lang: isXmlMediaType(mediaType) ? 'xml' : mediaType.includes('json') ? 'json' : 'text',
52
+ lang: isXmlMediaType(mediaType) ? 'xml' : textLanguage,
49
53
  value: example.serializedValue,
50
54
  });
51
55
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"render-operation-details.d.ts","sourceRoot":"","sources":["../src/render-operation-details.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAA;AAClH,OAAO,KAAK,EAAY,WAAW,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,wFAAwF;AACxF,eAAO,MAAM,aAAa,GACxB,SAAS,cAAc,CAAC,SAAS,CAAC,EAClC,aAAa,iBAAiB,EAC9B,SAAS,cAAc,EACvB,gBAAgB,MAAM,EACtB,6BAAqC,EACrC,WAAW,gBAAgB,KAC1B,OAAO,CAAC,WAAW,EAAE,CAuCvB,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,GACzB,UAAU,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,SAAS,EACpD,WAAW,MAAM,EACjB,aAAa,iBAAiB,EAC9B,SAAS,cAAc,EACvB,gBAAgB,MAAM,EACtB,6BAAqC,EACrC,WAAW,gBAAgB,KAC1B,OAAO,CAAC,WAAW,EAAE,CA8BvB,CAAA;AAID,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,CAAC,OAAO,CAAC,EAC9B,aAAa,iBAAiB,KAC7B,OAAO,CAAC,WAAW,EAAE,CA2BvB,CAAA"}
1
+ {"version":3,"file":"render-operation-details.d.ts","sourceRoot":"","sources":["../src/render-operation-details.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,8DAA8D,CAAA;AAClH,OAAO,KAAK,EAAY,WAAW,EAAE,MAAM,OAAO,CAAA;AAElD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAE5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAErD,wFAAwF;AACxF,eAAO,MAAM,aAAa,GACxB,SAAS,cAAc,CAAC,SAAS,CAAC,EAClC,aAAa,iBAAiB,EAC9B,SAAS,cAAc,EACvB,gBAAgB,MAAM,EACtB,6BAAqC,EACrC,WAAW,gBAAgB,KAC1B,OAAO,CAAC,WAAW,EAAE,CA8CvB,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,cAAc,GACzB,UAAU,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,GAAG,SAAS,EACpD,WAAW,MAAM,EACjB,aAAa,iBAAiB,EAC9B,SAAS,cAAc,EACvB,gBAAgB,MAAM,EACtB,6BAAqC,EACrC,WAAW,gBAAgB,KAC1B,OAAO,CAAC,WAAW,EAAE,CAqCvB,CAAA;AAID,mFAAmF;AACnF,eAAO,MAAM,mBAAmB,GAC9B,OAAO,cAAc,CAAC,OAAO,CAAC,EAC9B,aAAa,iBAAiB,KAC7B,OAAO,CAAC,WAAW,EAAE,CAoCvB,CAAA"}
@@ -6,24 +6,28 @@ export const renderHeaders = async (headers, description, schemas, openapiVersio
6
6
  const entries = [];
7
7
  for (const [name, reference] of Object.entries(headers ?? {})) {
8
8
  // OpenAPI reserves Content-Type for the media type map / encoding field.
9
- if (name.toLowerCase() === 'content-type')
9
+ if (name.toLowerCase() === 'content-type') {
10
10
  continue;
11
- if (!getResolvedRef(reference))
11
+ }
12
+ if (!getResolvedRef(reference)) {
12
13
  continue;
14
+ }
13
15
  const header = getResolvedRef(reference, mergeSiblingReferences);
14
16
  const blocks = [
15
17
  paragraph(strong(inlineCode(name)), text(header.required ? ' (required)' : '')),
16
18
  ...(await description(header.description)),
17
19
  ];
18
- if ('schema' in header && header.schema !== undefined)
20
+ if ('schema' in header && header.schema !== undefined) {
19
21
  blocks.push(...schemas.render(header.schema));
22
+ }
20
23
  if ('example' in header || 'examples' in header) {
21
24
  blocks.push(...(await renderExamples({ example: header.example, examples: header.examples }, description, 'application/json', undefined, openapiVersion, schemaOpenapiVersion, { linked: schemas.linked, examples })));
22
25
  }
23
26
  for (const [mediaType, content] of Object.entries('content' in header ? (header.content ?? {}) : {})) {
24
27
  blocks.push(paragraph(strong(text('Content-Type:')), text(` ${mediaType}`)));
25
- if (content.schema !== undefined)
28
+ if (content.schema !== undefined) {
26
29
  blocks.push(...schemas.render(content.schema));
30
+ }
27
31
  blocks.push(...(await renderExamples(content, description, mediaType, undefined, openapiVersion, schemaOpenapiVersion, {
28
32
  linked: schemas.linked,
29
33
  examples,
@@ -36,8 +40,9 @@ export const renderHeaders = async (headers, description, schemas, openapiVersio
36
40
  /** Preserve explicit encoding settings, including false flags and part headers. */
37
41
  export const renderEncoding = async (encoding, mediaType, description, schemas, openapiVersion, schemaOpenapiVersion = openapiVersion, examples) => {
38
42
  const multipart = mediaType.startsWith('multipart/');
39
- if (!multipart && mediaType !== 'application/x-www-form-urlencoded')
43
+ if (!multipart && mediaType !== 'application/x-www-form-urlencoded') {
40
44
  return [];
45
+ }
41
46
  const entries = [];
42
47
  for (const [name, entry] of Object.entries(encoding ?? {})) {
43
48
  const fields = [];
@@ -47,14 +52,17 @@ export const renderEncoding = async (encoding, mediaType, description, schemas,
47
52
  ['explode', 'Explode'],
48
53
  ['allowReserved', 'Allow reserved'],
49
54
  ]) {
50
- if (entry[key] !== undefined)
55
+ if (entry[key] !== undefined) {
51
56
  fields.push(item(paragraph(text(`${label}: `), inlineCode(entry[key]))));
57
+ }
52
58
  }
53
59
  const blocks = [paragraph(strong(inlineCode(name)))];
54
- if (fields.length)
60
+ if (fields.length) {
55
61
  blocks.push(list(fields));
56
- if (multipart)
62
+ }
63
+ if (multipart) {
57
64
  blocks.push(...(await renderHeaders(entry.headers, description, schemas, openapiVersion, schemaOpenapiVersion, examples)));
65
+ }
58
66
  entries.push(item(...blocks));
59
67
  }
60
68
  return entries.length ? [paragraph(strong(text('Encoding:'))), list(entries)] : [];
@@ -64,24 +72,30 @@ const formatValue = (value) => (typeof value === 'string' ? value : (JSON.string
64
72
  export const renderResponseLinks = async (links, description) => {
65
73
  const entries = [];
66
74
  for (const [name, reference] of Object.entries(links ?? {})) {
67
- if (!getResolvedRef(reference))
75
+ if (!getResolvedRef(reference)) {
68
76
  continue;
77
+ }
69
78
  const link = getResolvedRef(reference, mergeSiblingReferences);
70
79
  const blocks = [
71
80
  paragraph(strong(text(name))),
72
81
  ...(await description(link.description)),
73
82
  ];
74
- if (link.operationId)
83
+ if (link.operationId) {
75
84
  blocks.push(paragraph(strong(text('Operation ID:')), text(' '), inlineCode(link.operationId)));
76
- if (link.operationRef)
85
+ }
86
+ if (link.operationRef) {
77
87
  blocks.push(paragraph(strong(text('Operation reference:')), text(' '), inlineCode(link.operationRef)));
88
+ }
78
89
  const parameters = Object.entries(link.parameters ?? {});
79
- if (parameters.length)
90
+ if (parameters.length) {
80
91
  blocks.push(list(parameters.map(([name, value]) => item(paragraph(strong(text(`${name}:`)), text(' '), inlineCode(formatValue(value)))))));
81
- if (link.requestBody !== undefined)
92
+ }
93
+ if (link.requestBody !== undefined) {
82
94
  blocks.push(paragraph(strong(text('Request body:')), text(' '), inlineCode(formatValue(link.requestBody))));
83
- if (link.server)
95
+ }
96
+ if (link.server) {
84
97
  blocks.push(paragraph(strong(text('Server:')), text(' '), inlineCode(link.server.url)));
98
+ }
85
99
  entries.push(item(...blocks));
86
100
  }
87
101
  return entries.length ? [paragraph(strong(text('Links:'))), list(entries)] : [];
@@ -1 +1 @@
1
- {"version":3,"file":"render-operation.d.ts","sourceRoot":"","sources":["../src/render-operation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAEf,cAAc,EAGf,MAAM,8DAA8D,CAAA;AACrE,OAAO,KAAK,EAAsC,WAAW,EAAE,MAAM,OAAO,CAAA;AAE5E,OAAO,EAAU,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAG5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGrD,oEAAoE;AACpE,KAAK,aAAa,GAAG;IACnB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,OAAO,EAAE,cAAc,CAAA;IACvB,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC,CAAA;AAoCD,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,KAAG,MACkC,CAAA;AAEzF,iFAAiF;AACjF,eAAO,MAAM,eAAe,GAC1B,UAAU,eAAe,EACzB,MAAM,MAAM,EACZ,QAAQ,MAAM,EACd,UAAU,cAAc,EACxB,WAAW,eAAe,EAC1B,SAAS,OAAO,EAChB,4DAAgE,aAAa,KAC5E,OAAO,CAAC,WAAW,EAAE,CAiLvB,CAAA"}
1
+ {"version":3,"file":"render-operation.d.ts","sourceRoot":"","sources":["../src/render-operation.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EAEf,cAAc,EAGf,MAAM,8DAA8D,CAAA;AACrE,OAAO,KAAK,EAAsC,WAAW,EAAE,MAAM,OAAO,CAAA;AAE5E,OAAO,EAAU,KAAK,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AACvE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAE3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AAG5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAGrD,oEAAoE;AACpE,KAAK,aAAa,GAAG;IACnB,WAAW,EAAE,iBAAiB,CAAA;IAC9B,OAAO,EAAE,cAAc,CAAA;IACvB,QAAQ,CAAC,EAAE,gBAAgB,CAAA;IAC3B,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,wFAAwF;IACxF,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,qEAAqE;AACrE,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IACjD,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC,CAAA;AA8CD,yEAAyE;AACzE,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM,KAAG,MACkC,CAAA;AAEzF,iFAAiF;AACjF,eAAO,MAAM,eAAe,GAC1B,UAAU,eAAe,EACzB,MAAM,MAAM,EACZ,QAAQ,MAAM,EACd,UAAU,cAAc,EACxB,WAAW,eAAe,EAC1B,SAAS,OAAO,EAChB,4DAAgE,aAAa,KAC5E,OAAO,CAAC,WAAW,EAAE,CAwMvB,CAAA"}