docusaurus-plugin-openapi-docs 4.5.0 → 4.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.
- package/README.md +87 -22
- package/lib/index.js +80 -48
- package/lib/markdown/createHeading.js +1 -1
- package/lib/markdown/createRequestHeader.js +5 -3
- package/lib/markdown/createSchema.js +2 -2
- package/lib/markdown/index.js +3 -2
- package/lib/openapi/createSchemaExample.js +16 -2
- package/lib/openapi/createSchemaExample.test.d.ts +1 -0
- package/lib/openapi/createSchemaExample.test.js +48 -0
- package/lib/openapi/openapi.js +38 -17
- package/lib/openapi/openapi.test.js +48 -0
- package/lib/openapi/webhooks.test.d.ts +1 -0
- package/lib/openapi/webhooks.test.js +23 -0
- package/lib/options.js +3 -0
- package/lib/sidebars/index.js +12 -3
- package/lib/types.d.ts +5 -2
- package/package.json +16 -16
- package/src/index.ts +104 -60
- package/src/markdown/createHeading.ts +2 -2
- package/src/markdown/createRequestHeader.ts +9 -11
- package/src/markdown/createSchema.ts +4 -2
- package/src/markdown/index.ts +3 -2
- package/src/openapi/__fixtures__/webhook/openapi.yaml +17 -0
- package/src/openapi/createSchemaExample.test.ts +57 -0
- package/src/openapi/createSchemaExample.ts +26 -2
- package/src/openapi/openapi.test.ts +58 -0
- package/src/openapi/openapi.ts +35 -6
- package/src/openapi/webhooks.test.ts +30 -0
- package/src/options.ts +3 -0
- package/src/plugin-openapi.d.ts +1 -1
- package/src/sidebars/index.ts +15 -3
- package/src/types.ts +5 -2
- package/src/plugin-content-docs-types.d.ts +0 -42
package/src/index.ts
CHANGED
|
@@ -123,9 +123,12 @@ export default function pluginOpenAPIDocs(
|
|
|
123
123
|
markdownGenerators,
|
|
124
124
|
downloadUrl,
|
|
125
125
|
sidebarOptions,
|
|
126
|
+
schemasOnly,
|
|
126
127
|
disableCompression,
|
|
127
128
|
} = options;
|
|
128
129
|
|
|
130
|
+
const isSchemasOnly = schemasOnly === true;
|
|
131
|
+
|
|
129
132
|
// Remove trailing slash before proceeding
|
|
130
133
|
outputDir = outputDir.replace(/\/$/, "");
|
|
131
134
|
|
|
@@ -160,7 +163,7 @@ export default function pluginOpenAPIDocs(
|
|
|
160
163
|
}
|
|
161
164
|
|
|
162
165
|
// TODO: figure out better way to set default
|
|
163
|
-
if (Object.keys(sidebarOptions ?? {}).length > 0) {
|
|
166
|
+
if (!isSchemasOnly && Object.keys(sidebarOptions ?? {}).length > 0) {
|
|
164
167
|
const sidebarSlice = generateSidebarSlice(
|
|
165
168
|
sidebarOptions!,
|
|
166
169
|
options,
|
|
@@ -234,6 +237,9 @@ hide_send_button: true
|
|
|
234
237
|
{{#frontMatter.show_extensions}}
|
|
235
238
|
show_extensions: true
|
|
236
239
|
{{/frontMatter.show_extensions}}
|
|
240
|
+
{{#frontMatter.mask_credentials_disabled}}
|
|
241
|
+
mask_credentials: false
|
|
242
|
+
{{/frontMatter.mask_credentials_disabled}}
|
|
237
243
|
---
|
|
238
244
|
|
|
239
245
|
{{{markdown}}}
|
|
@@ -329,6 +335,9 @@ custom_edit_url: null
|
|
|
329
335
|
}
|
|
330
336
|
const markdown = pageGeneratorByType[item.type](item as any);
|
|
331
337
|
item.markdown = markdown;
|
|
338
|
+
if (isSchemasOnly && item.type !== "schema") {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
332
341
|
if (item.type === "api") {
|
|
333
342
|
// opportunity to compress JSON
|
|
334
343
|
// const serialize = (o: any) => {
|
|
@@ -344,9 +353,18 @@ custom_edit_url: null
|
|
|
344
353
|
.toString("base64"));
|
|
345
354
|
let infoBasePath = `${outputDir}/${item.infoId}`;
|
|
346
355
|
if (docRouteBasePath) {
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
356
|
+
// Safely extract path segment, handling cases where docPath may not be in outputDir
|
|
357
|
+
const outputSegment =
|
|
358
|
+
docPath && outputDir.includes(docPath)
|
|
359
|
+
? (outputDir.split(docPath)[1]?.replace(/^\/+/g, "") ?? "")
|
|
360
|
+
: outputDir
|
|
361
|
+
.slice(outputDir.indexOf("/", 1))
|
|
362
|
+
.replace(/^\/+/g, "");
|
|
363
|
+
infoBasePath =
|
|
364
|
+
`${docRouteBasePath}/${outputSegment}/${item.infoId}`.replace(
|
|
365
|
+
/^\/+/g,
|
|
366
|
+
""
|
|
367
|
+
);
|
|
350
368
|
}
|
|
351
369
|
if (item.infoId) item.infoPath = infoBasePath;
|
|
352
370
|
}
|
|
@@ -482,29 +500,53 @@ custom_edit_url: null
|
|
|
482
500
|
}
|
|
483
501
|
}
|
|
484
502
|
|
|
485
|
-
async function cleanApiDocs(options: APIOptions) {
|
|
503
|
+
async function cleanApiDocs(options: APIOptions, schemasOnly = false) {
|
|
486
504
|
const { outputDir } = options;
|
|
487
505
|
const apiDir = posixPath(path.join(siteDir, outputDir));
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
apiMdxFiles.map((mdx) =>
|
|
497
|
-
fs.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
498
|
-
if (err) {
|
|
499
|
-
console.error(
|
|
500
|
-
chalk.red(`Cleanup failed for "${apiDir}/${mdx}"`),
|
|
501
|
-
chalk.yellow(err)
|
|
502
|
-
);
|
|
503
|
-
} else {
|
|
504
|
-
console.log(chalk.green(`Cleanup succeeded for "${apiDir}/${mdx}"`));
|
|
506
|
+
|
|
507
|
+
// When schemasOnly is true, only clean the schemas directory
|
|
508
|
+
if (!schemasOnly) {
|
|
509
|
+
const apiMdxFiles = await Globby(
|
|
510
|
+
["*.api.mdx", "*.info.mdx", "*.tag.mdx"],
|
|
511
|
+
{
|
|
512
|
+
cwd: path.resolve(apiDir),
|
|
513
|
+
deep: 1,
|
|
505
514
|
}
|
|
506
|
-
|
|
507
|
-
|
|
515
|
+
);
|
|
516
|
+
const sidebarFile = await Globby(["sidebar.js", "sidebar.ts"], {
|
|
517
|
+
cwd: path.resolve(apiDir),
|
|
518
|
+
deep: 1,
|
|
519
|
+
});
|
|
520
|
+
apiMdxFiles.map((mdx) =>
|
|
521
|
+
fs.unlink(`${apiDir}/${mdx}`, (err) => {
|
|
522
|
+
if (err) {
|
|
523
|
+
console.error(
|
|
524
|
+
chalk.red(`Cleanup failed for "${apiDir}/${mdx}"`),
|
|
525
|
+
chalk.yellow(err)
|
|
526
|
+
);
|
|
527
|
+
} else {
|
|
528
|
+
console.log(
|
|
529
|
+
chalk.green(`Cleanup succeeded for "${apiDir}/${mdx}"`)
|
|
530
|
+
);
|
|
531
|
+
}
|
|
532
|
+
})
|
|
533
|
+
);
|
|
534
|
+
|
|
535
|
+
sidebarFile.map((sidebar) =>
|
|
536
|
+
fs.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
537
|
+
if (err) {
|
|
538
|
+
console.error(
|
|
539
|
+
chalk.red(`Cleanup failed for "${apiDir}/${sidebar}"`),
|
|
540
|
+
chalk.yellow(err)
|
|
541
|
+
);
|
|
542
|
+
} else {
|
|
543
|
+
console.log(
|
|
544
|
+
chalk.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`)
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
})
|
|
548
|
+
);
|
|
549
|
+
}
|
|
508
550
|
|
|
509
551
|
try {
|
|
510
552
|
fs.rmSync(`${apiDir}/schemas`, { recursive: true });
|
|
@@ -517,21 +559,6 @@ custom_edit_url: null
|
|
|
517
559
|
);
|
|
518
560
|
}
|
|
519
561
|
}
|
|
520
|
-
|
|
521
|
-
sidebarFile.map((sidebar) =>
|
|
522
|
-
fs.unlink(`${apiDir}/${sidebar}`, (err) => {
|
|
523
|
-
if (err) {
|
|
524
|
-
console.error(
|
|
525
|
-
chalk.red(`Cleanup failed for "${apiDir}/${sidebar}"`),
|
|
526
|
-
chalk.yellow(err)
|
|
527
|
-
);
|
|
528
|
-
} else {
|
|
529
|
-
console.log(
|
|
530
|
-
chalk.green(`Cleanup succeeded for "${apiDir}/${sidebar}"`)
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
})
|
|
534
|
-
);
|
|
535
562
|
}
|
|
536
563
|
|
|
537
564
|
async function generateVersions(versions: object, outputDir: string) {
|
|
@@ -632,7 +659,7 @@ custom_edit_url: null
|
|
|
632
659
|
}
|
|
633
660
|
}
|
|
634
661
|
|
|
635
|
-
async function cleanAllVersions(options: APIOptions) {
|
|
662
|
+
async function cleanAllVersions(options: APIOptions, schemasOnly = false) {
|
|
636
663
|
const parentOptions = Object.assign({}, options);
|
|
637
664
|
|
|
638
665
|
const { versions } = parentOptions as any;
|
|
@@ -640,14 +667,16 @@ custom_edit_url: null
|
|
|
640
667
|
delete parentOptions.versions;
|
|
641
668
|
|
|
642
669
|
if (versions != null && Object.keys(versions).length > 0) {
|
|
643
|
-
|
|
670
|
+
if (!schemasOnly) {
|
|
671
|
+
await cleanVersions(parentOptions.outputDir);
|
|
672
|
+
}
|
|
644
673
|
Object.keys(versions).forEach(async (key) => {
|
|
645
674
|
const versionOptions = versions[key];
|
|
646
675
|
const mergedOptions = {
|
|
647
676
|
...parentOptions,
|
|
648
677
|
...versionOptions,
|
|
649
678
|
};
|
|
650
|
-
await cleanApiDocs(mergedOptions);
|
|
679
|
+
await cleanApiDocs(mergedOptions, schemasOnly);
|
|
651
680
|
});
|
|
652
681
|
}
|
|
653
682
|
}
|
|
@@ -665,10 +694,12 @@ custom_edit_url: null
|
|
|
665
694
|
.arguments("<id>")
|
|
666
695
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
667
696
|
.option("--all-versions", "Generate all versions.")
|
|
697
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
668
698
|
.action(async (id, instance) => {
|
|
669
699
|
const options = instance.opts();
|
|
670
700
|
const pluginId = options.pluginId;
|
|
671
701
|
const allVersions = options.allVersions;
|
|
702
|
+
const schemasOnly = options.schemasOnly;
|
|
672
703
|
const pluginInstances = getPluginInstances(plugins);
|
|
673
704
|
let targetConfig: any;
|
|
674
705
|
let targetDocsPluginId: any;
|
|
@@ -695,6 +726,9 @@ custom_edit_url: null
|
|
|
695
726
|
targetConfig = config;
|
|
696
727
|
}
|
|
697
728
|
|
|
729
|
+
const withSchemaOverride = (apiOptions: APIOptions): APIOptions =>
|
|
730
|
+
schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
731
|
+
|
|
698
732
|
if (id === "all") {
|
|
699
733
|
if (targetConfig[id]) {
|
|
700
734
|
console.error(
|
|
@@ -704,12 +738,10 @@ custom_edit_url: null
|
|
|
704
738
|
);
|
|
705
739
|
} else {
|
|
706
740
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
707
|
-
|
|
741
|
+
const apiOptions = withSchemaOverride(targetConfig[key]);
|
|
742
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
708
743
|
if (allVersions) {
|
|
709
|
-
await generateAllVersions(
|
|
710
|
-
targetConfig[key],
|
|
711
|
-
targetDocsPluginId
|
|
712
|
-
);
|
|
744
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
713
745
|
}
|
|
714
746
|
});
|
|
715
747
|
}
|
|
@@ -718,9 +750,10 @@ custom_edit_url: null
|
|
|
718
750
|
chalk.red(`ID '${id}' does not exist in OpenAPI docs config.`)
|
|
719
751
|
);
|
|
720
752
|
} else {
|
|
721
|
-
|
|
753
|
+
const apiOptions = withSchemaOverride(targetConfig[id]);
|
|
754
|
+
await generateApiDocs(apiOptions, targetDocsPluginId);
|
|
722
755
|
if (allVersions) {
|
|
723
|
-
await generateAllVersions(
|
|
756
|
+
await generateAllVersions(apiOptions, targetDocsPluginId);
|
|
724
757
|
}
|
|
725
758
|
}
|
|
726
759
|
});
|
|
@@ -733,9 +766,11 @@ custom_edit_url: null
|
|
|
733
766
|
.usage("<id:version>")
|
|
734
767
|
.arguments("<id:version>")
|
|
735
768
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
769
|
+
.option("--schemas-only", "Generate only schema docs.")
|
|
736
770
|
.action(async (id, instance) => {
|
|
737
771
|
const options = instance.opts();
|
|
738
772
|
const pluginId = options.pluginId;
|
|
773
|
+
const schemasOnly = options.schemasOnly;
|
|
739
774
|
const pluginInstances = getPluginInstances(plugins);
|
|
740
775
|
let targetConfig: any;
|
|
741
776
|
let targetDocsPluginId: any;
|
|
@@ -764,6 +799,9 @@ custom_edit_url: null
|
|
|
764
799
|
const [parentId, versionId] = id.split(":");
|
|
765
800
|
const parentConfig = Object.assign({}, targetConfig[parentId]);
|
|
766
801
|
|
|
802
|
+
const withSchemaOverride = (apiOptions: APIOptions): APIOptions =>
|
|
803
|
+
schemasOnly ? { ...apiOptions, schemasOnly: true } : apiOptions;
|
|
804
|
+
|
|
767
805
|
const version = parentConfig.version as string;
|
|
768
806
|
const label = parentConfig.label as string;
|
|
769
807
|
const baseUrl = parentConfig.baseUrl as string;
|
|
@@ -793,10 +831,10 @@ custom_edit_url: null
|
|
|
793
831
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
794
832
|
Object.keys(versions).forEach(async (key) => {
|
|
795
833
|
const versionConfig = versions[key];
|
|
796
|
-
const mergedConfig = {
|
|
834
|
+
const mergedConfig = withSchemaOverride({
|
|
797
835
|
...parentConfig,
|
|
798
836
|
...versionConfig,
|
|
799
|
-
};
|
|
837
|
+
});
|
|
800
838
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
801
839
|
});
|
|
802
840
|
}
|
|
@@ -808,10 +846,10 @@ custom_edit_url: null
|
|
|
808
846
|
);
|
|
809
847
|
} else {
|
|
810
848
|
const versionConfig = versions[versionId];
|
|
811
|
-
const mergedConfig = {
|
|
849
|
+
const mergedConfig = withSchemaOverride({
|
|
812
850
|
...parentConfig,
|
|
813
851
|
...versionConfig,
|
|
814
|
-
};
|
|
852
|
+
});
|
|
815
853
|
await generateVersions(mergedVersions, parentConfig.outputDir);
|
|
816
854
|
await generateApiDocs(mergedConfig, targetDocsPluginId);
|
|
817
855
|
}
|
|
@@ -826,10 +864,12 @@ custom_edit_url: null
|
|
|
826
864
|
.arguments("<id>")
|
|
827
865
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
828
866
|
.option("--all-versions", "Clean all versions.")
|
|
867
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
829
868
|
.action(async (id, instance) => {
|
|
830
869
|
const options = instance.opts();
|
|
831
870
|
const pluginId = options.pluginId;
|
|
832
871
|
const allVersions = options.allVersions;
|
|
872
|
+
const schemasOnly = options.schemasOnly;
|
|
833
873
|
const pluginInstances = getPluginInstances(plugins);
|
|
834
874
|
let targetConfig: any;
|
|
835
875
|
if (pluginId) {
|
|
@@ -862,16 +902,16 @@ custom_edit_url: null
|
|
|
862
902
|
);
|
|
863
903
|
} else {
|
|
864
904
|
Object.keys(targetConfig).forEach(async function (key) {
|
|
865
|
-
await cleanApiDocs(targetConfig[key]);
|
|
905
|
+
await cleanApiDocs(targetConfig[key], schemasOnly);
|
|
866
906
|
if (allVersions) {
|
|
867
|
-
await cleanAllVersions(targetConfig[key]);
|
|
907
|
+
await cleanAllVersions(targetConfig[key], schemasOnly);
|
|
868
908
|
}
|
|
869
909
|
});
|
|
870
910
|
}
|
|
871
911
|
} else {
|
|
872
|
-
await cleanApiDocs(targetConfig[id]);
|
|
912
|
+
await cleanApiDocs(targetConfig[id], schemasOnly);
|
|
873
913
|
if (allVersions) {
|
|
874
|
-
await cleanAllVersions(targetConfig[id]);
|
|
914
|
+
await cleanAllVersions(targetConfig[id], schemasOnly);
|
|
875
915
|
}
|
|
876
916
|
}
|
|
877
917
|
});
|
|
@@ -884,9 +924,11 @@ custom_edit_url: null
|
|
|
884
924
|
.usage("<id:version>")
|
|
885
925
|
.arguments("<id:version>")
|
|
886
926
|
.option("-p, --plugin-id <plugin>", "OpenAPI docs plugin ID.")
|
|
927
|
+
.option("--schemas-only", "Clean only schema docs.")
|
|
887
928
|
.action(async (id, instance) => {
|
|
888
929
|
const options = instance.opts();
|
|
889
930
|
const pluginId = options.pluginId;
|
|
931
|
+
const schemasOnly = options.schemasOnly;
|
|
890
932
|
const pluginInstances = getPluginInstances(plugins);
|
|
891
933
|
let targetConfig: any;
|
|
892
934
|
if (pluginId) {
|
|
@@ -922,14 +964,16 @@ custom_edit_url: null
|
|
|
922
964
|
"Can't use id 'all' for OpenAPI docs versions configuration key."
|
|
923
965
|
);
|
|
924
966
|
} else {
|
|
925
|
-
|
|
967
|
+
if (!schemasOnly) {
|
|
968
|
+
await cleanVersions(parentConfig.outputDir);
|
|
969
|
+
}
|
|
926
970
|
Object.keys(versions).forEach(async (key) => {
|
|
927
971
|
const versionConfig = versions[key];
|
|
928
972
|
const mergedConfig = {
|
|
929
973
|
...parentConfig,
|
|
930
974
|
...versionConfig,
|
|
931
975
|
};
|
|
932
|
-
await cleanApiDocs(mergedConfig);
|
|
976
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
933
977
|
});
|
|
934
978
|
}
|
|
935
979
|
} else {
|
|
@@ -938,7 +982,7 @@ custom_edit_url: null
|
|
|
938
982
|
...parentConfig,
|
|
939
983
|
...versionConfig,
|
|
940
984
|
};
|
|
941
|
-
await cleanApiDocs(mergedConfig);
|
|
985
|
+
await cleanApiDocs(mergedConfig, schemasOnly);
|
|
942
986
|
}
|
|
943
987
|
});
|
|
944
988
|
},
|
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
* ========================================================================== */
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { create } from "./utils";
|
|
9
9
|
|
|
10
10
|
export function createHeading(heading: string) {
|
|
11
11
|
return [
|
|
12
12
|
create(
|
|
13
13
|
"Heading",
|
|
14
14
|
{
|
|
15
|
-
children:
|
|
15
|
+
children: heading,
|
|
16
16
|
as: "h1",
|
|
17
17
|
className: "openapi__heading",
|
|
18
18
|
},
|
|
@@ -9,16 +9,14 @@ import { create } from "./utils";
|
|
|
9
9
|
|
|
10
10
|
export function createRequestHeader(header: string) {
|
|
11
11
|
return [
|
|
12
|
-
create(
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
),
|
|
22
|
-
`\n\n`,
|
|
12
|
+
create("Heading", {
|
|
13
|
+
id: header.replace(" ", "-").toLowerCase(),
|
|
14
|
+
as: "h2",
|
|
15
|
+
className: "openapi-tabs__heading",
|
|
16
|
+
children: [
|
|
17
|
+
`<Translate id="theme.openapi.request.title">${header}</Translate>`,
|
|
18
|
+
],
|
|
19
|
+
}),
|
|
20
|
+
"\n\n",
|
|
23
21
|
];
|
|
24
22
|
}
|
|
@@ -375,7 +375,8 @@ function createDetailsNode(
|
|
|
375
375
|
() => [
|
|
376
376
|
create("span", {
|
|
377
377
|
className: "openapi-schema__required",
|
|
378
|
-
children:
|
|
378
|
+
children:
|
|
379
|
+
"<Translate id='theme.openapi.schemaItem.required'>required</Translate>",
|
|
379
380
|
}),
|
|
380
381
|
]
|
|
381
382
|
),
|
|
@@ -530,7 +531,8 @@ function createPropertyDiscriminator(
|
|
|
530
531
|
guard(required, () => [
|
|
531
532
|
create("span", {
|
|
532
533
|
className: "openapi-schema__required",
|
|
533
|
-
children:
|
|
534
|
+
children:
|
|
535
|
+
"<Translate id='theme.openapi.schemaItem.required'>required</Translate>",
|
|
534
536
|
}),
|
|
535
537
|
]),
|
|
536
538
|
],
|
package/src/markdown/index.ts
CHANGED
|
@@ -72,7 +72,8 @@ export function createApiPageMD({
|
|
|
72
72
|
`import StatusCodes from "@theme/StatusCodes";\n`,
|
|
73
73
|
`import OperationTabs from "@theme/OperationTabs";\n`,
|
|
74
74
|
`import TabItem from "@theme/TabItem";\n`,
|
|
75
|
-
`import Heading from "@theme/Heading";\n
|
|
75
|
+
`import Heading from "@theme/Heading";\n`,
|
|
76
|
+
`import Translate from "@docusaurus/Translate";\n\n`,
|
|
76
77
|
createHeading(title),
|
|
77
78
|
createMethodEndpoint(method, path),
|
|
78
79
|
infoPath && createAuthorization(infoPath),
|
|
@@ -134,7 +135,7 @@ export function createSchemaPageMD({ schema }: SchemaPageMetadata) {
|
|
|
134
135
|
return render([
|
|
135
136
|
`import Schema from "@theme/Schema";\n`,
|
|
136
137
|
`import Heading from "@theme/Heading";\n\n`,
|
|
137
|
-
createHeading(title
|
|
138
|
+
createHeading(title),
|
|
138
139
|
createDescription(description),
|
|
139
140
|
create("Schema", {
|
|
140
141
|
schema: schema,
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
openapi: 3.0.3
|
|
2
|
+
info:
|
|
3
|
+
title: Webhook Example
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
paths: {}
|
|
6
|
+
webhooks:
|
|
7
|
+
order.created:
|
|
8
|
+
post:
|
|
9
|
+
requestBody:
|
|
10
|
+
description: example body
|
|
11
|
+
content:
|
|
12
|
+
application/json:
|
|
13
|
+
schema:
|
|
14
|
+
type: object
|
|
15
|
+
responses:
|
|
16
|
+
"200":
|
|
17
|
+
description: OK
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/* ============================================================================
|
|
2
|
+
* Copyright (c) Palo Alto Networks
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
* ========================================================================== */
|
|
7
|
+
|
|
8
|
+
import { sampleFromSchema } from "./createSchemaExample";
|
|
9
|
+
import { SchemaObject } from "./types";
|
|
10
|
+
|
|
11
|
+
describe("sampleFromSchema", () => {
|
|
12
|
+
describe("const support", () => {
|
|
13
|
+
it("should return default string value when const is not present", () => {
|
|
14
|
+
const schema: SchemaObject = {
|
|
15
|
+
type: "string",
|
|
16
|
+
};
|
|
17
|
+
const context = { type: "request" as const };
|
|
18
|
+
|
|
19
|
+
const result = sampleFromSchema(schema, context);
|
|
20
|
+
|
|
21
|
+
expect(result).toBe("string");
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it("should return const value when const is present", () => {
|
|
25
|
+
const schema: SchemaObject = {
|
|
26
|
+
type: "string",
|
|
27
|
+
const: "example",
|
|
28
|
+
};
|
|
29
|
+
const context = { type: "request" as const };
|
|
30
|
+
|
|
31
|
+
const result = sampleFromSchema(schema, context);
|
|
32
|
+
|
|
33
|
+
expect(result).toBe("example");
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it("should handle anyOf with const values", () => {
|
|
37
|
+
const schema: SchemaObject = {
|
|
38
|
+
type: "string",
|
|
39
|
+
anyOf: [
|
|
40
|
+
{
|
|
41
|
+
type: "string",
|
|
42
|
+
const: "dog",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
type: "string",
|
|
46
|
+
const: "cat",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
const context = { type: "request" as const };
|
|
51
|
+
|
|
52
|
+
const result = sampleFromSchema(schema, context);
|
|
53
|
+
|
|
54
|
+
expect(result).toBe("dog");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
});
|
|
@@ -91,7 +91,12 @@ function sampleFromProp(
|
|
|
91
91
|
|
|
92
92
|
// TODO: handle discriminators
|
|
93
93
|
|
|
94
|
-
|
|
94
|
+
// Check for explicit example/examples first (OAS 3.1 support)
|
|
95
|
+
if (prop.example !== undefined) {
|
|
96
|
+
obj[name] = prop.example;
|
|
97
|
+
} else if (prop.examples !== undefined && prop.examples.length > 0) {
|
|
98
|
+
obj[name] = prop.examples[0];
|
|
99
|
+
} else if (prop.oneOf) {
|
|
95
100
|
obj[name] = sampleFromSchema(prop.oneOf[0], context);
|
|
96
101
|
} else if (prop.anyOf) {
|
|
97
102
|
obj[name] = sampleFromSchema(prop.anyOf[0], context);
|
|
@@ -111,12 +116,27 @@ export const sampleFromSchema = (
|
|
|
111
116
|
try {
|
|
112
117
|
// deep copy schema before processing
|
|
113
118
|
let schemaCopy = JSON.parse(JSON.stringify(schema));
|
|
114
|
-
let {
|
|
119
|
+
let {
|
|
120
|
+
type,
|
|
121
|
+
example,
|
|
122
|
+
examples,
|
|
123
|
+
allOf,
|
|
124
|
+
properties,
|
|
125
|
+
items,
|
|
126
|
+
oneOf,
|
|
127
|
+
anyOf,
|
|
128
|
+
const: constant,
|
|
129
|
+
} = schemaCopy;
|
|
115
130
|
|
|
116
131
|
if (example !== undefined) {
|
|
117
132
|
return example;
|
|
118
133
|
}
|
|
119
134
|
|
|
135
|
+
// OAS 3.1 / JSON Schema: examples is an array
|
|
136
|
+
if (examples !== undefined && examples.length > 0) {
|
|
137
|
+
return examples[0];
|
|
138
|
+
}
|
|
139
|
+
|
|
120
140
|
if (oneOf) {
|
|
121
141
|
if (properties) {
|
|
122
142
|
const combinedSchemas = merge(schemaCopy, oneOf[0]);
|
|
@@ -218,6 +238,10 @@ export const sampleFromSchema = (
|
|
|
218
238
|
return undefined;
|
|
219
239
|
}
|
|
220
240
|
|
|
241
|
+
if (constant) {
|
|
242
|
+
return constant;
|
|
243
|
+
}
|
|
244
|
+
|
|
221
245
|
return primitive(schemaCopy);
|
|
222
246
|
} catch (err) {
|
|
223
247
|
console.error(
|
|
@@ -11,6 +11,8 @@ import path from "path";
|
|
|
11
11
|
import { posixPath } from "@docusaurus/utils";
|
|
12
12
|
|
|
13
13
|
import { readOpenapiFiles } from ".";
|
|
14
|
+
import { processOpenapiFile } from "./openapi";
|
|
15
|
+
import type { APIOptions, SidebarOptions } from "../types";
|
|
14
16
|
|
|
15
17
|
// npx jest packages/docusaurus-plugin-openapi/src/openapi/openapi.test.ts --watch
|
|
16
18
|
|
|
@@ -37,4 +39,60 @@ describe("openapi", () => {
|
|
|
37
39
|
).toBeDefined();
|
|
38
40
|
});
|
|
39
41
|
});
|
|
42
|
+
|
|
43
|
+
describe("schemasOnly", () => {
|
|
44
|
+
it("includes schema metadata when showSchemas is disabled", async () => {
|
|
45
|
+
const openapiData = {
|
|
46
|
+
openapi: "3.0.0",
|
|
47
|
+
info: {
|
|
48
|
+
title: "Schema Only",
|
|
49
|
+
version: "1.0.0",
|
|
50
|
+
},
|
|
51
|
+
paths: {
|
|
52
|
+
"/ping": {
|
|
53
|
+
get: {
|
|
54
|
+
summary: "Ping",
|
|
55
|
+
responses: {
|
|
56
|
+
"200": {
|
|
57
|
+
description: "OK",
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
},
|
|
62
|
+
},
|
|
63
|
+
components: {
|
|
64
|
+
schemas: {
|
|
65
|
+
WithoutTags: {
|
|
66
|
+
title: "Without Tags",
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
value: {
|
|
70
|
+
type: "string",
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
const options: APIOptions = {
|
|
79
|
+
specPath: "dummy", // required by the type but unused in this context
|
|
80
|
+
outputDir: "build",
|
|
81
|
+
showSchemas: false,
|
|
82
|
+
schemasOnly: true,
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const sidebarOptions = {} as SidebarOptions;
|
|
86
|
+
|
|
87
|
+
const [items] = await processOpenapiFile(
|
|
88
|
+
openapiData as any,
|
|
89
|
+
options,
|
|
90
|
+
sidebarOptions
|
|
91
|
+
);
|
|
92
|
+
|
|
93
|
+
const schemaItems = items.filter((item) => item.type === "schema");
|
|
94
|
+
expect(schemaItems).toHaveLength(1);
|
|
95
|
+
expect(schemaItems[0].id).toBe("without-tags");
|
|
96
|
+
});
|
|
97
|
+
});
|
|
40
98
|
});
|