@gitbook/react-openapi 1.3.0 → 1.3.2

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 (64) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/OpenAPICodeSample.jsx +7 -4
  3. package/dist/OpenAPIRequestBody.jsx +7 -2
  4. package/dist/OpenAPIRequestBodyHeaderType.d.ts +8 -0
  5. package/dist/OpenAPIRequestBodyHeaderType.jsx +25 -0
  6. package/dist/OpenAPIResponse.d.ts +1 -1
  7. package/dist/OpenAPIResponse.jsx +2 -2
  8. package/dist/OpenAPIResponseExample.jsx +7 -0
  9. package/dist/OpenAPISchema.jsx +1 -39
  10. package/dist/OpenAPISchemaName.jsx +4 -4
  11. package/dist/OpenAPISecurities.jsx +59 -1
  12. package/dist/OpenAPISelect.jsx +1 -0
  13. package/dist/OpenAPISpec.jsx +16 -1
  14. package/dist/OpenAPIWebhookExample.jsx +1 -1
  15. package/dist/code-samples.js +1 -1
  16. package/dist/generateSchemaExample.js +14 -14
  17. package/dist/translations/de.d.ts +1 -0
  18. package/dist/translations/de.js +1 -0
  19. package/dist/translations/en.d.ts +1 -0
  20. package/dist/translations/en.js +1 -0
  21. package/dist/translations/es.d.ts +1 -0
  22. package/dist/translations/es.js +1 -0
  23. package/dist/translations/fr.d.ts +1 -0
  24. package/dist/translations/fr.js +1 -0
  25. package/dist/translations/index.d.ts +9 -0
  26. package/dist/translations/ja.d.ts +1 -0
  27. package/dist/translations/ja.js +1 -0
  28. package/dist/translations/nl.d.ts +1 -0
  29. package/dist/translations/nl.js +1 -0
  30. package/dist/translations/no.d.ts +1 -0
  31. package/dist/translations/no.js +1 -0
  32. package/dist/translations/pt-br.d.ts +1 -0
  33. package/dist/translations/pt-br.js +1 -0
  34. package/dist/translations/zh.d.ts +1 -0
  35. package/dist/translations/zh.js +1 -0
  36. package/dist/tsconfig.build.tsbuildinfo +1 -1
  37. package/dist/utils.d.ts +1 -0
  38. package/dist/utils.js +38 -0
  39. package/package.json +2 -2
  40. package/src/OpenAPICodeSample.tsx +7 -6
  41. package/src/OpenAPIRequestBody.tsx +11 -2
  42. package/src/OpenAPIRequestBodyHeaderType.tsx +36 -0
  43. package/src/OpenAPIResponse.tsx +3 -3
  44. package/src/OpenAPIResponseExample.tsx +10 -1
  45. package/src/OpenAPISchema.tsx +1 -38
  46. package/src/OpenAPISchemaName.tsx +8 -6
  47. package/src/OpenAPISecurities.tsx +111 -7
  48. package/src/OpenAPISelect.tsx +1 -1
  49. package/src/OpenAPISpec.tsx +21 -1
  50. package/src/OpenAPIWebhookExample.tsx +2 -2
  51. package/src/code-samples.test.ts +2 -2
  52. package/src/code-samples.ts +16 -12
  53. package/src/generateSchemaExample.test.ts +20 -0
  54. package/src/generateSchemaExample.ts +1 -1
  55. package/src/translations/de.ts +1 -0
  56. package/src/translations/en.ts +1 -0
  57. package/src/translations/es.ts +1 -0
  58. package/src/translations/fr.ts +1 -0
  59. package/src/translations/ja.ts +1 -0
  60. package/src/translations/nl.ts +1 -0
  61. package/src/translations/no.ts +1 -0
  62. package/src/translations/pt-br.ts +1 -0
  63. package/src/translations/zh.ts +1 -0
  64. package/src/utils.ts +37 -0
package/dist/utils.d.ts CHANGED
@@ -47,3 +47,4 @@ export declare function getStatusCodeClassName(statusCode: number | string): str
47
47
  * 4xx, 5xx: Error
48
48
  */
49
49
  export declare function getStatusCodeDefaultLabel(statusCode: number | string, context: OpenAPIUniversalContext): string;
50
+ export declare function getSchemaTitle(schema: OpenAPIV3.SchemaObject): string;
package/dist/utils.js CHANGED
@@ -184,3 +184,41 @@ function getStatusCodeCategory(statusCode) {
184
184
  var category = Math.floor(code / 100);
185
185
  return category;
186
186
  }
187
+ export function getSchemaTitle(schema) {
188
+ var _a;
189
+ // Otherwise try to infer a nice title
190
+ var type = 'any';
191
+ if (schema.enum || schema['x-enumDescriptions'] || schema['x-gitbook-enum']) {
192
+ type = "".concat(schema.type, " \u00B7 enum");
193
+ // check array AND schema.items as this is sometimes null despite what the type indicates
194
+ }
195
+ else if (schema.type === 'array' && !!schema.items) {
196
+ type = "".concat(getSchemaTitle(schema.items), "[]");
197
+ }
198
+ else if (Array.isArray(schema.type)) {
199
+ type = schema.type.join(' | ');
200
+ }
201
+ else if (schema.type || schema.properties) {
202
+ type = (_a = schema.type) !== null && _a !== void 0 ? _a : 'object';
203
+ if (schema.format) {
204
+ type += " \u00B7 ".concat(schema.format);
205
+ }
206
+ // Only add the title if it's an object (no need for the title of a string, number, etc.)
207
+ if (type === 'object' && schema.title) {
208
+ type += " \u00B7 ".concat(schema.title.replaceAll(' ', ''));
209
+ }
210
+ }
211
+ if ('anyOf' in schema) {
212
+ type = 'any of';
213
+ }
214
+ else if ('oneOf' in schema) {
215
+ type = 'one of';
216
+ }
217
+ else if ('allOf' in schema) {
218
+ type = 'all of';
219
+ }
220
+ else if ('not' in schema) {
221
+ type = 'not';
222
+ }
223
+ return type;
224
+ }
package/package.json CHANGED
@@ -8,11 +8,11 @@
8
8
  "default": "./dist/index.js"
9
9
  }
10
10
  },
11
- "version": "1.3.0",
11
+ "version": "1.3.2",
12
12
  "sideEffects": false,
13
13
  "dependencies": {
14
14
  "@gitbook/openapi-parser": "workspace:*",
15
- "@scalar/api-client-react": "^1.2.19",
15
+ "@scalar/api-client-react": "^1.3.16",
16
16
  "@scalar/oas-utils": "^0.2.130",
17
17
  "clsx": "^2.1.1",
18
18
  "flatted": "^3.2.9",
@@ -253,15 +253,11 @@ function getCustomCodeSamples(props: {
253
253
  if (customSamples && Array.isArray(customSamples)) {
254
254
  customCodeSamples = customSamples
255
255
  .filter((sample) => {
256
- return (
257
- typeof sample.label === 'string' &&
258
- typeof sample.source === 'string' &&
259
- typeof sample.lang === 'string'
260
- );
256
+ return typeof sample.source === 'string' && typeof sample.lang === 'string';
261
257
  })
262
258
  .map((sample, index) => ({
263
259
  key: `custom-sample-${sample.lang}-${index}`,
264
- label: sample.label,
260
+ label: sample.label || sample.lang,
265
261
  body: context.renderCodeBlock({
266
262
  code: sample.source,
267
263
  syntax: sample.lang,
@@ -312,6 +308,11 @@ function getSecurityHeaders(securities: OpenAPIOperationData['securities']): {
312
308
  [name]: 'YOUR_API_KEY',
313
309
  };
314
310
  }
311
+ case 'oauth2': {
312
+ return {
313
+ Authorization: 'Bearer YOUR_OAUTH2_TOKEN',
314
+ };
315
+ }
315
316
  default: {
316
317
  return {};
317
318
  }
@@ -1,5 +1,6 @@
1
1
  import type { OpenAPIV3 } from '@gitbook/openapi-parser';
2
2
  import { InteractiveSection } from './InteractiveSection';
3
+ import { OpenAPIRequestBodyHeaderType } from './OpenAPIRequestBodyHeaderType';
3
4
  import { OpenAPIRootSchema } from './OpenAPISchemaServer';
4
5
  import type { OpenAPIClientContext } from './context';
5
6
  import { t } from './translate';
@@ -20,11 +21,18 @@ export function OpenAPIRequestBody(props: {
20
21
  return null;
21
22
  }
22
23
 
24
+ const stateKey = createStateKey('request-body-media-type', context.blockKey);
25
+
23
26
  return (
24
27
  <InteractiveSection
25
- header={t(context.translation, 'name' in data ? 'payload' : 'body')}
28
+ header={
29
+ <>
30
+ <span>{t(context.translation, 'name' in data ? 'payload' : 'body')}</span>
31
+ <OpenAPIRequestBodyHeaderType requestBody={requestBody} stateKey={stateKey} />
32
+ </>
33
+ }
26
34
  className="openapi-requestbody"
27
- stateKey={createStateKey('request-body-media-type', context.blockKey)}
35
+ stateKey={stateKey}
28
36
  selectIcon={context.icons.chevronDown}
29
37
  tabs={Object.entries(requestBody.content ?? {}).map(
30
38
  ([contentType, mediaTypeObject]) => {
@@ -35,6 +43,7 @@ export function OpenAPIRequestBody(props: {
35
43
  <OpenAPIRootSchema
36
44
  schema={mediaTypeObject.schema ?? {}}
37
45
  context={context}
46
+ key={contentType}
38
47
  />
39
48
  ),
40
49
  };
@@ -0,0 +1,36 @@
1
+ 'use client';
2
+
3
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
4
+ import { useSelectState } from './OpenAPISelect';
5
+ import { getSchemaTitle } from './utils';
6
+
7
+ /**
8
+ * Display the type of a request body. It only displays the type if the selected content is an array.
9
+ */
10
+ export function OpenAPIRequestBodyHeaderType(props: {
11
+ requestBody: OpenAPIV3.RequestBodyObject;
12
+ stateKey: string;
13
+ }) {
14
+ const { requestBody, stateKey } = props;
15
+ const content = requestBody.content ?? {};
16
+ const state = useSelectState(stateKey, Object.keys(content)[0]);
17
+
18
+ const selectedContentMediaType = Object.entries(content).find(
19
+ ([contentType]) => contentType === state.key
20
+ )?.[1];
21
+
22
+ // If the selected content is not an array, we don't display the type
23
+ if (
24
+ !selectedContentMediaType ||
25
+ !selectedContentMediaType.schema?.type ||
26
+ selectedContentMediaType.schema.type !== 'array'
27
+ ) {
28
+ return null;
29
+ }
30
+
31
+ return (
32
+ <span className="openapi-requestbody-header-type">
33
+ {`${getSchemaTitle(selectedContentMediaType.schema)}`}
34
+ </span>
35
+ );
36
+ }
@@ -11,14 +11,14 @@ import { parameterToProperty, resolveDescription } from './utils';
11
11
  */
12
12
  export function OpenAPIResponse(props: {
13
13
  response: OpenAPIV3.ResponseObject;
14
- mediaType: OpenAPIV3.MediaTypeObject;
14
+ mediaType: OpenAPIV3.MediaTypeObject | null;
15
15
  context: OpenAPIClientContext;
16
16
  }) {
17
17
  const { response, context, mediaType } = props;
18
18
  const headers = Object.entries(response.headers ?? {}).map(
19
19
  ([name, header]) => [name, header ?? {}] as const
20
20
  );
21
- const content = Object.entries(mediaType.schema ?? {});
21
+ const content = Object.entries(mediaType?.schema ?? {});
22
22
 
23
23
  const description = resolveDescription(response);
24
24
 
@@ -62,7 +62,7 @@ export function OpenAPIResponse(props: {
62
62
  />
63
63
  </OpenAPIDisclosure>
64
64
  ) : null}
65
- {mediaType.schema && (
65
+ {mediaType?.schema && (
66
66
  <div className="openapi-responsebody">
67
67
  <OpenAPISchemaProperties
68
68
  id={`response-${context.blockKey}`}
@@ -99,7 +99,7 @@ export function OpenAPIResponseExample(props: {
99
99
  function OpenAPIResponse(props: {
100
100
  context: OpenAPIContext;
101
101
  content: {
102
- [media: string]: OpenAPIV3.MediaTypeObject;
102
+ [media: string]: OpenAPIV3.MediaTypeObject | null;
103
103
  };
104
104
  }) {
105
105
  const { context, content } = props;
@@ -113,6 +113,15 @@ function OpenAPIResponse(props: {
113
113
 
114
114
  const tabs = entries.map((entry) => {
115
115
  const [mediaType, mediaTypeObject] = entry;
116
+
117
+ if (!mediaTypeObject) {
118
+ return {
119
+ key: mediaType,
120
+ label: mediaType,
121
+ body: <OpenAPIEmptyExample context={context} />,
122
+ };
123
+ }
124
+
116
125
  return {
117
126
  key: mediaType,
118
127
  label: mediaType,
@@ -16,7 +16,7 @@ import { retrocycle } from './decycle';
16
16
  import { getDisclosureLabel } from './getDisclosureLabel';
17
17
  import { stringifyOpenAPI } from './stringifyOpenAPI';
18
18
  import { tString } from './translate';
19
- import { checkIsReference, resolveDescription, resolveFirstExample } from './utils';
19
+ import { checkIsReference, getSchemaTitle, resolveDescription, resolveFirstExample } from './utils';
20
20
 
21
21
  type CircularRefsIds = Map<OpenAPIV3.SchemaObject, string>;
22
22
 
@@ -652,40 +652,3 @@ function mergeRequiredFields(
652
652
  new Set([...(latestAncestor?.required || []), ...(schemaOrRef.required || [])])
653
653
  );
654
654
  }
655
-
656
- function getSchemaTitle(schema: OpenAPIV3.SchemaObject): string {
657
- // Otherwise try to infer a nice title
658
- let type = 'any';
659
-
660
- if (schema.enum || schema['x-enumDescriptions'] || schema['x-gitbook-enum']) {
661
- type = `${schema.type} · enum`;
662
- // check array AND schema.items as this is sometimes null despite what the type indicates
663
- } else if (schema.type === 'array' && !!schema.items) {
664
- type = `${getSchemaTitle(schema.items)}[]`;
665
- } else if (Array.isArray(schema.type)) {
666
- type = schema.type.join(' | ');
667
- } else if (schema.type || schema.properties) {
668
- type = schema.type ?? 'object';
669
-
670
- if (schema.format) {
671
- type += ` · ${schema.format}`;
672
- }
673
-
674
- // Only add the title if it's an object (no need for the title of a string, number, etc.)
675
- if (type === 'object' && schema.title) {
676
- type += ` · ${schema.title.replaceAll(' ', '')}`;
677
- }
678
- }
679
-
680
- if ('anyOf' in schema) {
681
- type = 'any of';
682
- } else if ('oneOf' in schema) {
683
- type = 'one of';
684
- } else if ('allOf' in schema) {
685
- type = 'all of';
686
- } else if ('not' in schema) {
687
- type = 'not';
688
- }
689
-
690
- return type;
691
- }
@@ -27,12 +27,14 @@ export function OpenAPISchemaName(props: OpenAPISchemaNameProps) {
27
27
  {propertyName}
28
28
  </span>
29
29
  ) : null}
30
- <span>
31
- {type ? <span className="openapi-schema-type">{type}</span> : null}
32
- {additionalItems ? (
33
- <span className="openapi-schema-type">{additionalItems}</span>
34
- ) : null}
35
- </span>
30
+ {type || additionalItems ? (
31
+ <span>
32
+ {type ? <span className="openapi-schema-type">{type}</span> : null}
33
+ {additionalItems ? (
34
+ <span className="openapi-schema-type">{additionalItems}</span>
35
+ ) : null}
36
+ </span>
37
+ ) : null}
36
38
  {schema?.readOnly ? (
37
39
  <span className="openapi-schema-readonly">
38
40
  {t(context.translation, 'read_only')}
@@ -1,5 +1,7 @@
1
+ import type { OpenAPIV3 } from '@gitbook/openapi-parser';
1
2
  import { InteractiveSection } from './InteractiveSection';
2
3
  import { Markdown } from './Markdown';
4
+ import { OpenAPICopyButton } from './OpenAPICopyButton';
3
5
  import { OpenAPISchemaName } from './OpenAPISchemaName';
4
6
  import type { OpenAPIClientContext } from './context';
5
7
  import { t } from './translate';
@@ -105,13 +107,7 @@ function getLabelForType(security: OpenAPISecurityWithRequired, context: OpenAPI
105
107
  />
106
108
  );
107
109
  case 'oauth2':
108
- return (
109
- <OpenAPISchemaName
110
- context={context}
111
- propertyName="OAuth2"
112
- required={security.required}
113
- />
114
- );
110
+ return <OpenAPISchemaOAuth2Flows context={context} security={security} />;
115
111
  case 'openIdConnect':
116
112
  return (
117
113
  <OpenAPISchemaName
@@ -125,3 +121,111 @@ function getLabelForType(security: OpenAPISecurityWithRequired, context: OpenAPI
125
121
  return security.type;
126
122
  }
127
123
  }
124
+
125
+ function OpenAPISchemaOAuth2Flows(props: {
126
+ context: OpenAPIClientContext;
127
+ security: OpenAPIV3.OAuth2SecurityScheme & { required?: boolean };
128
+ }) {
129
+ const { context, security } = props;
130
+
131
+ const flows = Object.entries(security.flows ?? {});
132
+
133
+ return (
134
+ <div className="openapi-securities-oauth-flows">
135
+ {flows.map(([name, flow], index) => (
136
+ <OpenAPISchemaOAuth2Item
137
+ key={index}
138
+ flow={flow}
139
+ name={name}
140
+ context={context}
141
+ security={security}
142
+ />
143
+ ))}
144
+ </div>
145
+ );
146
+ }
147
+
148
+ function OpenAPISchemaOAuth2Item(props: {
149
+ flow: NonNullable<OpenAPIV3.OAuth2SecurityScheme['flows']>[keyof NonNullable<
150
+ OpenAPIV3.OAuth2SecurityScheme['flows']
151
+ >];
152
+ name: string;
153
+ context: OpenAPIClientContext;
154
+ security: OpenAPIV3.OAuth2SecurityScheme & { required?: boolean };
155
+ }) {
156
+ const { flow, context, security, name } = props;
157
+
158
+ if (!flow) {
159
+ return null;
160
+ }
161
+
162
+ const scopes = Object.entries(flow?.scopes ?? {});
163
+
164
+ return (
165
+ <div>
166
+ <OpenAPISchemaName
167
+ context={context}
168
+ propertyName="OAuth2"
169
+ type={name}
170
+ required={security.required}
171
+ />
172
+ <div className="openapi-securities-oauth-content openapi-markdown">
173
+ {security.description ? <Markdown source={security.description} /> : null}
174
+ {'authorizationUrl' in flow && flow.authorizationUrl ? (
175
+ <span>
176
+ Authorization URL:{' '}
177
+ <OpenAPICopyButton
178
+ value={flow.authorizationUrl}
179
+ context={context}
180
+ className="openapi-securities-url"
181
+ withTooltip
182
+ >
183
+ {flow.authorizationUrl}
184
+ </OpenAPICopyButton>
185
+ </span>
186
+ ) : null}
187
+ {'tokenUrl' in flow && flow.tokenUrl ? (
188
+ <span>
189
+ Token URL:{' '}
190
+ <OpenAPICopyButton
191
+ value={flow.tokenUrl}
192
+ context={context}
193
+ className="openapi-securities-url"
194
+ withTooltip
195
+ >
196
+ {flow.tokenUrl}
197
+ </OpenAPICopyButton>
198
+ </span>
199
+ ) : null}
200
+ {'refreshUrl' in flow && flow.refreshUrl ? (
201
+ <span>
202
+ Refresh URL:{' '}
203
+ <OpenAPICopyButton
204
+ value={flow.refreshUrl}
205
+ context={context}
206
+ className="openapi-securities-url"
207
+ withTooltip
208
+ >
209
+ {flow.refreshUrl}
210
+ </OpenAPICopyButton>
211
+ </span>
212
+ ) : null}
213
+ {scopes.length ? (
214
+ <div>
215
+ {t(context.translation, 'available_scopes')}:{' '}
216
+ <ul>
217
+ {scopes.map(([key, value]) => (
218
+ <li key={key}>
219
+ <OpenAPICopyButton value={key} context={context} withTooltip>
220
+ <code>{key}</code>
221
+ </OpenAPICopyButton>
222
+ : {value}
223
+ </li>
224
+ ))}
225
+ </ul>
226
+ </div>
227
+ ) : null}
228
+ </div>
229
+ </div>
230
+ );
231
+ }
@@ -33,7 +33,7 @@ interface OpenAPISelectProps<T extends OpenAPISelectItem> extends Omit<SelectPro
33
33
  icon?: React.ReactNode;
34
34
  }
35
35
 
36
- export function useSelectState(stateKey = 'select-state', initialKey?: Key) {
36
+ export function useSelectState(stateKey = 'select-state', initialKey: Key = 'default') {
37
37
  const store = useStore(getOrCreateStoreByKey(stateKey, initialKey));
38
38
  return {
39
39
  key: store.key,
@@ -18,7 +18,7 @@ export function OpenAPISpec(props: {
18
18
 
19
19
  const { operation } = data;
20
20
 
21
- const parameters = operation.parameters ?? [];
21
+ const parameters = deduplicateParameters(operation.parameters ?? []);
22
22
  const parameterGroups = groupParameters(parameters, context);
23
23
 
24
24
  const securities = 'securities' in data ? data.securities : [];
@@ -113,3 +113,23 @@ function getParameterGroupName(paramIn: string, context: OpenAPIClientContext):
113
113
  return paramIn;
114
114
  }
115
115
  }
116
+
117
+ /** Deduplicate parameters by name and in.
118
+ * Some specs have both parameters define at path and operation level.
119
+ * We only want to display one of them.
120
+ */
121
+ function deduplicateParameters(parameters: OpenAPI.Parameters): OpenAPI.Parameters {
122
+ const seen = new Set();
123
+
124
+ return parameters.filter((param) => {
125
+ const key = `${param.name}:${param.in}`;
126
+
127
+ if (seen.has(key)) {
128
+ return false;
129
+ }
130
+
131
+ seen.add(key);
132
+
133
+ return true;
134
+ });
135
+ }
@@ -19,9 +19,9 @@ export function OpenAPIWebhookExample(props: {
19
19
  }
20
20
 
21
21
  return Object.entries(
22
- operation.requestBody.content as Record<string, OpenAPIV3.MediaTypeObject>
22
+ operation.requestBody.content as Record<string, OpenAPIV3.MediaTypeObject | null>
23
23
  ).map(([key, value]) => {
24
- const schema = value.schema;
24
+ const schema = value?.schema;
25
25
 
26
26
  if (!schema) {
27
27
  return {
@@ -400,7 +400,7 @@ describe('python code sample generator', () => {
400
400
  const output = generator?.generate(input);
401
401
 
402
402
  expect(output).toBe(
403
- 'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/x-www-form-urlencoded"},\n data={"key":"value"}\n)\n\ndata = response.json()'
403
+ 'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/x-www-form-urlencoded"},\n data={\n "key": "value"\n }\n)\n\ndata = response.json()'
404
404
  );
405
405
  });
406
406
 
@@ -422,7 +422,7 @@ describe('python code sample generator', () => {
422
422
  const output = generator?.generate(input);
423
423
 
424
424
  expect(output).toBe(
425
- 'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/json"},\n data=json.dumps({"key":"value","truethy":True,"falsey":False,"nullish":None})\n)\n\ndata = response.json()'
425
+ 'import requests\n\nresponse = requests.get(\n "https://example.com/path",\n headers={"Content-Type":"application/json"},\n data=json.dumps({\n "key": "value",\n "truethy": True,\n "falsey": False,\n "nullish": None\n })\n)\n\ndata = response.json()'
426
426
  );
427
427
  });
428
428
 
@@ -356,18 +356,22 @@ const BodyGenerators = {
356
356
  // Convert JSON to XML if needed
357
357
  body = JSON.stringify(convertBodyToXML(body));
358
358
  } else {
359
- body = stringifyOpenAPI(body, (_key, value) => {
360
- switch (value) {
361
- case true:
362
- return '$$__TRUE__$$';
363
- case false:
364
- return '$$__FALSE__$$';
365
- case null:
366
- return '$$__NULL__$$';
367
- default:
368
- return value;
369
- }
370
- })
359
+ body = stringifyOpenAPI(
360
+ body,
361
+ (_key, value) => {
362
+ switch (value) {
363
+ case true:
364
+ return '$$__TRUE__$$';
365
+ case false:
366
+ return '$$__FALSE__$$';
367
+ case null:
368
+ return '$$__NULL__$$';
369
+ default:
370
+ return value;
371
+ }
372
+ },
373
+ 2
374
+ )
371
375
  .replaceAll('"$$__TRUE__$$"', 'True')
372
376
  .replaceAll('"$$__FALSE__$$"', 'False')
373
377
  .replaceAll('"$$__NULL__$$"', 'None');
@@ -1017,4 +1017,24 @@ describe('generateSchemaExample', () => {
1017
1017
  },
1018
1018
  });
1019
1019
  });
1020
+
1021
+ it('handles deprecated properties', () => {
1022
+ expect(
1023
+ generateSchemaExample({
1024
+ type: 'object',
1025
+ deprecated: true,
1026
+ })
1027
+ ).toBeUndefined();
1028
+ });
1029
+
1030
+ it('handle nested deprecated properties', () => {
1031
+ expect(
1032
+ generateSchemaExample({
1033
+ type: 'array',
1034
+ items: {
1035
+ deprecated: true,
1036
+ },
1037
+ })
1038
+ ).toBeUndefined();
1039
+ });
1020
1040
  });
@@ -167,7 +167,7 @@ const getExampleFromSchema = (
167
167
  const makeUpRandomData = !!options?.emptyString;
168
168
 
169
169
  // If the property is deprecated we don't show it in examples.
170
- if (schema.deprecated) {
170
+ if (schema.deprecated || (schema.type === 'array' && schema.items?.deprecated)) {
171
171
  return undefined;
172
172
  }
173
173
 
@@ -35,6 +35,7 @@ export const de = {
35
35
  show: 'Zeige ${1}',
36
36
  hide: 'Verstecke ${1}',
37
37
  available_items: 'Verfügbare Elemente',
38
+ available_scopes: 'Verfügbare scopes',
38
39
  properties: 'Eigenschaften',
39
40
  or: 'oder',
40
41
  and: 'und',
@@ -35,6 +35,7 @@ export const en = {
35
35
  show: 'Show ${1}',
36
36
  hide: 'Hide ${1}',
37
37
  available_items: 'Available items',
38
+ available_scopes: 'Available scopes',
38
39
  possible_values: 'Possible values',
39
40
  properties: 'Properties',
40
41
  or: 'or',
@@ -35,6 +35,7 @@ export const es = {
35
35
  show: 'Mostrar ${1}',
36
36
  hide: 'Ocultar ${1}',
37
37
  available_items: 'Elementos disponibles',
38
+ available_scopes: 'Scopes disponibles',
38
39
  properties: 'Propiedades',
39
40
  or: 'o',
40
41
  and: 'y',
@@ -35,6 +35,7 @@ export const fr = {
35
35
  show: 'Afficher ${1}',
36
36
  hide: 'Masquer ${1}',
37
37
  available_items: 'Éléments disponibles',
38
+ available_scopes: 'Scopes disponibles',
38
39
  properties: 'Propriétés',
39
40
  or: 'ou',
40
41
  and: 'et',
@@ -35,6 +35,7 @@ export const ja = {
35
35
  show: '${1}を表示',
36
36
  hide: '${1}を非表示',
37
37
  available_items: '利用可能なアイテム',
38
+ available_scopes: '利用可能なスコープ',
38
39
  properties: 'プロパティ',
39
40
  or: 'または',
40
41
  and: 'かつ',
@@ -35,6 +35,7 @@ export const nl = {
35
35
  show: 'Toon ${1}',
36
36
  hide: 'Verberg ${1}',
37
37
  available_items: 'Beschikbare items',
38
+ available_scopes: 'Beschikbare scopes',
38
39
  properties: 'Eigenschappen',
39
40
  or: 'of',
40
41
  and: 'en',
@@ -35,6 +35,7 @@ export const no = {
35
35
  show: 'Vis ${1}',
36
36
  hide: 'Skjul ${1}',
37
37
  available_items: 'Tilgjengelige elementer',
38
+ available_scopes: 'Tilgjengelige scopes',
38
39
  properties: 'Egenskaper',
39
40
  or: 'eller',
40
41
  and: 'og',
@@ -35,6 +35,7 @@ export const pt_br = {
35
35
  show: 'Mostrar ${1}',
36
36
  hide: 'Ocultar ${1}',
37
37
  available_items: 'Itens disponíveis',
38
+ available_scopes: 'Scopes disponíveis',
38
39
  properties: 'Propriedades',
39
40
  or: 'ou',
40
41
  and: 'e',
@@ -35,6 +35,7 @@ export const zh = {
35
35
  show: '显示${1}',
36
36
  hide: '隐藏${1}',
37
37
  available_items: '可用项',
38
+ available_scopes: '可用范围',
38
39
  properties: '属性',
39
40
  or: '或',
40
41
  and: '和',