docusaurus-plugin-openapi-docs 0.0.0-759 → 0.0.0-761
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/lib/markdown/createSchema.js +24 -24
- package/lib/markdown/createSchema.test.js +247 -29
- package/lib/openapi/createRequestExample.js +2 -2
- package/lib/openapi/createResponseExample.js +2 -2
- package/package.json +2 -2
- package/src/markdown/__snapshots__/createSchema.test.ts.snap +146 -1
- package/src/markdown/createSchema.test.ts +290 -34
- package/src/markdown/createSchema.ts +55 -54
- package/src/openapi/createRequestExample.ts +2 -2
- package/src/openapi/createResponseExample.ts +2 -2
|
@@ -523,6 +523,19 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
523
523
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
524
524
|
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
525
525
|
}
|
|
526
|
+
if (schema.properties !== undefined) {
|
|
527
|
+
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
528
|
+
}
|
|
529
|
+
if (schema.additionalProperties !== undefined) {
|
|
530
|
+
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
531
|
+
}
|
|
532
|
+
// array of objects
|
|
533
|
+
if (((_a = schema.items) === null || _a === void 0 ? void 0 : _a.properties) !== undefined) {
|
|
534
|
+
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
535
|
+
}
|
|
536
|
+
if (((_b = schema.items) === null || _b === void 0 ? void 0 : _b.anyOf) !== undefined || ((_c = schema.items) === null || _c === void 0 ? void 0 : _c.oneOf) !== undefined) {
|
|
537
|
+
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
538
|
+
}
|
|
526
539
|
if (schema.allOf !== undefined) {
|
|
527
540
|
const { mergedSchemas } = mergeAllOf(schema.allOf);
|
|
528
541
|
if (SCHEMA_TYPE === "request") {
|
|
@@ -547,7 +560,7 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
547
560
|
return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
|
|
548
561
|
}
|
|
549
562
|
// array of objects
|
|
550
|
-
if (((
|
|
563
|
+
if (((_d = mergedSchemas.items) === null || _d === void 0 ? void 0 : _d.properties) !== undefined) {
|
|
551
564
|
return createDetailsNode(name, mergedSchemaName, mergedSchemas, required, schema.nullable);
|
|
552
565
|
}
|
|
553
566
|
return (0, utils_1.create)("SchemaItem", {
|
|
@@ -559,19 +572,6 @@ function createEdges({ name, schema, required, discriminator, }) {
|
|
|
559
572
|
schema: mergedSchemas,
|
|
560
573
|
});
|
|
561
574
|
}
|
|
562
|
-
if (schema.properties !== undefined) {
|
|
563
|
-
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
564
|
-
}
|
|
565
|
-
if (schema.additionalProperties !== undefined) {
|
|
566
|
-
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
567
|
-
}
|
|
568
|
-
// array of objects
|
|
569
|
-
if (((_b = schema.items) === null || _b === void 0 ? void 0 : _b.properties) !== undefined) {
|
|
570
|
-
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
571
|
-
}
|
|
572
|
-
if (((_c = schema.items) === null || _c === void 0 ? void 0 : _c.anyOf) !== undefined || ((_d = schema.items) === null || _d === void 0 ? void 0 : _d.oneOf) !== undefined) {
|
|
573
|
-
return createDetailsNode(name, schemaName, schema, required, schema.nullable);
|
|
574
|
-
}
|
|
575
575
|
// primitives and array of non-objects
|
|
576
576
|
return (0, utils_1.create)("SchemaItem", {
|
|
577
577
|
collapsible: false,
|
|
@@ -604,16 +604,6 @@ function createNodes(schema, schemaType) {
|
|
|
604
604
|
if (schema.oneOf !== undefined || schema.anyOf !== undefined) {
|
|
605
605
|
nodes.push(createAnyOneOf(schema));
|
|
606
606
|
}
|
|
607
|
-
if (schema.allOf !== undefined) {
|
|
608
|
-
const { mergedSchemas } = mergeAllOf(schema.allOf);
|
|
609
|
-
if (mergedSchemas.oneOf !== undefined ||
|
|
610
|
-
mergedSchemas.anyOf !== undefined) {
|
|
611
|
-
nodes.push(createAnyOneOf(mergedSchemas));
|
|
612
|
-
}
|
|
613
|
-
if (mergedSchemas.properties !== undefined) {
|
|
614
|
-
nodes.push(createProperties(mergedSchemas));
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
607
|
if (schema.properties !== undefined) {
|
|
618
608
|
nodes.push(createProperties(schema));
|
|
619
609
|
}
|
|
@@ -624,6 +614,16 @@ function createNodes(schema, schemaType) {
|
|
|
624
614
|
if (schema.items !== undefined) {
|
|
625
615
|
nodes.push(createItems(schema));
|
|
626
616
|
}
|
|
617
|
+
if (schema.allOf !== undefined) {
|
|
618
|
+
const { mergedSchemas } = mergeAllOf(schema.allOf);
|
|
619
|
+
if (mergedSchemas.oneOf !== undefined ||
|
|
620
|
+
mergedSchemas.anyOf !== undefined) {
|
|
621
|
+
nodes.push(createAnyOneOf(mergedSchemas));
|
|
622
|
+
}
|
|
623
|
+
if (mergedSchemas.properties !== undefined) {
|
|
624
|
+
nodes.push(createProperties(mergedSchemas));
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
627
|
if (nodes.length && nodes.length > 0) {
|
|
628
628
|
return nodes.filter(Boolean).flat();
|
|
629
629
|
}
|
|
@@ -32,44 +32,262 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
32
32
|
const prettier = __importStar(require("prettier"));
|
|
33
33
|
const createSchema_1 = require("./createSchema");
|
|
34
34
|
describe("createNodes", () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
35
|
+
describe("oneOf", () => {
|
|
36
|
+
it("should create readable MODs for oneOf primitive properties", async () => {
|
|
37
|
+
const schema = {
|
|
38
|
+
"x-tags": ["clown"],
|
|
39
|
+
type: "object",
|
|
40
|
+
properties: {
|
|
41
|
+
oneOfProperty: {
|
|
42
|
+
oneOf: [
|
|
43
|
+
{
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
noseLength: {
|
|
47
|
+
type: "number",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
required: ["noseLength"],
|
|
51
|
+
description: "Clown's nose length",
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: "array",
|
|
55
|
+
items: {
|
|
56
|
+
type: "string",
|
|
47
57
|
},
|
|
58
|
+
description: "Array of strings",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
type: "boolean",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
type: "number",
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
type: "string",
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
expect(await Promise.all((0, createSchema_1.createNodes)(schema, "request").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
describe("allOf", () => {
|
|
77
|
+
it("should render same-level properties with allOf", async () => {
|
|
78
|
+
const schema = {
|
|
79
|
+
allOf: [
|
|
80
|
+
{
|
|
81
|
+
type: "object",
|
|
82
|
+
properties: {
|
|
83
|
+
allOfProp1: {
|
|
84
|
+
type: "string",
|
|
85
|
+
},
|
|
86
|
+
allOfProp2: {
|
|
87
|
+
type: "string",
|
|
48
88
|
},
|
|
49
|
-
required: ["noseLength"],
|
|
50
|
-
description: "Clown's nose length",
|
|
51
89
|
},
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
properties: {
|
|
93
|
+
parentProp1: {
|
|
94
|
+
type: "string",
|
|
95
|
+
},
|
|
96
|
+
parentProp2: {
|
|
97
|
+
type: "string",
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
};
|
|
101
|
+
expect(await Promise.all((0, createSchema_1.createNodes)(schema, "response").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
|
|
102
|
+
});
|
|
103
|
+
it("should correctly merge nested properties from multiple allOf schemas", async () => {
|
|
104
|
+
const schema = {
|
|
105
|
+
allOf: [
|
|
106
|
+
{
|
|
107
|
+
type: "object",
|
|
108
|
+
properties: {
|
|
109
|
+
outerProp1: {
|
|
110
|
+
type: "object",
|
|
111
|
+
properties: {
|
|
112
|
+
innerProp1: {
|
|
113
|
+
type: "string",
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
type: "object",
|
|
121
|
+
properties: {
|
|
122
|
+
outerProp2: {
|
|
123
|
+
type: "object",
|
|
124
|
+
properties: {
|
|
125
|
+
innerProp2: {
|
|
126
|
+
type: "number",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
],
|
|
133
|
+
};
|
|
134
|
+
expect(await Promise.all((0, createSchema_1.createNodes)(schema, "response").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
|
|
135
|
+
});
|
|
136
|
+
it("should correctly handle shared required properties across allOf schemas", async () => {
|
|
137
|
+
const schema = {
|
|
138
|
+
allOf: [
|
|
139
|
+
{
|
|
140
|
+
type: "object",
|
|
141
|
+
properties: {
|
|
142
|
+
sharedProp: {
|
|
55
143
|
type: "string",
|
|
56
144
|
},
|
|
57
|
-
description: "Array of strings",
|
|
58
145
|
},
|
|
59
|
-
|
|
60
|
-
|
|
146
|
+
required: ["sharedProp"],
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
type: "object",
|
|
150
|
+
properties: {
|
|
151
|
+
anotherProp: {
|
|
152
|
+
type: "number",
|
|
153
|
+
},
|
|
61
154
|
},
|
|
62
|
-
|
|
63
|
-
|
|
155
|
+
required: ["anotherProp"],
|
|
156
|
+
},
|
|
157
|
+
],
|
|
158
|
+
};
|
|
159
|
+
expect(await Promise.all((0, createSchema_1.createNodes)(schema, "response").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
|
|
160
|
+
});
|
|
161
|
+
// Could not resolve values for path:"properties.conflictingProp.type". They are probably incompatible. Values:
|
|
162
|
+
// "string"
|
|
163
|
+
// "number"
|
|
164
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
165
|
+
// it("should handle conflicting properties in allOf schemas", async () => {
|
|
166
|
+
// const schema: SchemaObject = {
|
|
167
|
+
// allOf: [
|
|
168
|
+
// {
|
|
169
|
+
// type: "object",
|
|
170
|
+
// properties: {
|
|
171
|
+
// conflictingProp: {
|
|
172
|
+
// type: "string",
|
|
173
|
+
// },
|
|
174
|
+
// },
|
|
175
|
+
// },
|
|
176
|
+
// {
|
|
177
|
+
// type: "object",
|
|
178
|
+
// properties: {
|
|
179
|
+
// conflictingProp: {
|
|
180
|
+
// type: "number",
|
|
181
|
+
// },
|
|
182
|
+
// },
|
|
183
|
+
// },
|
|
184
|
+
// ],
|
|
185
|
+
// };
|
|
186
|
+
// expect(
|
|
187
|
+
// await Promise.all(
|
|
188
|
+
// createNodes(schema, "response").map(
|
|
189
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
190
|
+
// )
|
|
191
|
+
// )
|
|
192
|
+
// ).toMatchSnapshot();
|
|
193
|
+
// });
|
|
194
|
+
// Could not resolve values for path:"type". They are probably incompatible. Values:
|
|
195
|
+
// "object"
|
|
196
|
+
// "array"
|
|
197
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
198
|
+
// it("should handle mixed data types in allOf schemas", async () => {
|
|
199
|
+
// const schema: SchemaObject = {
|
|
200
|
+
// allOf: [
|
|
201
|
+
// {
|
|
202
|
+
// type: "object",
|
|
203
|
+
// properties: {
|
|
204
|
+
// mixedTypeProp1: {
|
|
205
|
+
// type: "string",
|
|
206
|
+
// },
|
|
207
|
+
// },
|
|
208
|
+
// },
|
|
209
|
+
// {
|
|
210
|
+
// type: "array",
|
|
211
|
+
// items: {
|
|
212
|
+
// type: "number",
|
|
213
|
+
// },
|
|
214
|
+
// },
|
|
215
|
+
// ],
|
|
216
|
+
// };
|
|
217
|
+
// expect(
|
|
218
|
+
// await Promise.all(
|
|
219
|
+
// createNodes(schema, "response").map(
|
|
220
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
221
|
+
// )
|
|
222
|
+
// )
|
|
223
|
+
// ).toMatchSnapshot();
|
|
224
|
+
// });
|
|
225
|
+
it("should correctly deep merge properties in allOf schemas", async () => {
|
|
226
|
+
const schema = {
|
|
227
|
+
allOf: [
|
|
228
|
+
{
|
|
229
|
+
type: "object",
|
|
230
|
+
properties: {
|
|
231
|
+
deepProp: {
|
|
232
|
+
type: "object",
|
|
233
|
+
properties: {
|
|
234
|
+
innerProp1: {
|
|
235
|
+
type: "string",
|
|
236
|
+
},
|
|
237
|
+
},
|
|
238
|
+
},
|
|
64
239
|
},
|
|
65
|
-
|
|
66
|
-
|
|
240
|
+
},
|
|
241
|
+
{
|
|
242
|
+
type: "object",
|
|
243
|
+
properties: {
|
|
244
|
+
deepProp: {
|
|
245
|
+
type: "object",
|
|
246
|
+
properties: {
|
|
247
|
+
innerProp2: {
|
|
248
|
+
type: "number",
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
},
|
|
67
252
|
},
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
253
|
+
},
|
|
254
|
+
],
|
|
255
|
+
};
|
|
256
|
+
expect(await Promise.all((0, createSchema_1.createNodes)(schema, "response").map(async (md) => await prettier.format(md, { parser: "babel" })))).toMatchSnapshot();
|
|
257
|
+
});
|
|
258
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
259
|
+
// it("should handle discriminator with allOf schemas", async () => {
|
|
260
|
+
// const schema: SchemaObject = {
|
|
261
|
+
// allOf: [
|
|
262
|
+
// {
|
|
263
|
+
// type: "object",
|
|
264
|
+
// discriminator: {
|
|
265
|
+
// propertyName: "type",
|
|
266
|
+
// },
|
|
267
|
+
// properties: {
|
|
268
|
+
// type: {
|
|
269
|
+
// type: "string",
|
|
270
|
+
// },
|
|
271
|
+
// },
|
|
272
|
+
// },
|
|
273
|
+
// {
|
|
274
|
+
// type: "object",
|
|
275
|
+
// properties: {
|
|
276
|
+
// specificProp: {
|
|
277
|
+
// type: "string",
|
|
278
|
+
// },
|
|
279
|
+
// },
|
|
280
|
+
// },
|
|
281
|
+
// ],
|
|
282
|
+
// };
|
|
283
|
+
// expect(
|
|
284
|
+
// await Promise.all(
|
|
285
|
+
// createNodes(schema, "response").map(
|
|
286
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
287
|
+
// )
|
|
288
|
+
// )
|
|
289
|
+
// ).toMatchSnapshot();
|
|
290
|
+
// });
|
|
73
291
|
});
|
|
74
292
|
describe("additionalProperties", () => {
|
|
75
293
|
it.each([
|
|
@@ -17,8 +17,8 @@ const primitives = {
|
|
|
17
17
|
string: {
|
|
18
18
|
default: () => "string",
|
|
19
19
|
email: () => "user@example.com",
|
|
20
|
-
date: () =>
|
|
21
|
-
"date-time": () =>
|
|
20
|
+
date: () => "2024-07-29",
|
|
21
|
+
"date-time": () => "2024-07-29T15:51:28.071Z",
|
|
22
22
|
uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
23
23
|
hostname: () => "example.com",
|
|
24
24
|
ipv4: () => "198.51.100.42",
|
|
@@ -17,8 +17,8 @@ const primitives = {
|
|
|
17
17
|
string: {
|
|
18
18
|
default: () => "string",
|
|
19
19
|
email: () => "user@example.com",
|
|
20
|
-
date: () =>
|
|
21
|
-
"date-time": () =>
|
|
20
|
+
date: () => "2024-07-29",
|
|
21
|
+
"date-time": () => "2024-07-29T15:51:28.071Z",
|
|
22
22
|
uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
23
23
|
hostname: () => "example.com",
|
|
24
24
|
ipv4: () => "198.51.100.42",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "docusaurus-plugin-openapi-docs",
|
|
3
3
|
"description": "OpenAPI plugin for Docusaurus.",
|
|
4
|
-
"version": "0.0.0-
|
|
4
|
+
"version": "0.0.0-761",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"openapi",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
"engines": {
|
|
63
63
|
"node": ">=14"
|
|
64
64
|
},
|
|
65
|
-
"gitHead": "
|
|
65
|
+
"gitHead": "845d09c7416618b6acf56c37a067a4eba93e91c9"
|
|
66
66
|
}
|
|
@@ -223,7 +223,152 @@ Array [
|
|
|
223
223
|
]
|
|
224
224
|
`;
|
|
225
225
|
|
|
226
|
-
exports[`createNodes should
|
|
226
|
+
exports[`createNodes allOf should correctly deep merge properties in allOf schemas 1`] = `
|
|
227
|
+
Array [
|
|
228
|
+
"<SchemaItem collapsible={true} className={\\"schemaItem\\"}>
|
|
229
|
+
<details style={{}} className={\\"openapi-markdown__details\\"}>
|
|
230
|
+
<summary style={{}}>
|
|
231
|
+
<span className={\\"openapi-schema__container\\"}>
|
|
232
|
+
<strong className={\\"openapi-schema__property\\"}>deepProp</strong>
|
|
233
|
+
<span className={\\"openapi-schema__name\\"}>object</span>
|
|
234
|
+
</span>
|
|
235
|
+
</summary>
|
|
236
|
+
<div style={{ marginLeft: \\"1rem\\" }}>
|
|
237
|
+
<SchemaItem
|
|
238
|
+
collapsible={false}
|
|
239
|
+
name={\\"innerProp1\\"}
|
|
240
|
+
required={false}
|
|
241
|
+
schemaName={\\"string\\"}
|
|
242
|
+
qualifierMessage={undefined}
|
|
243
|
+
schema={{ type: \\"string\\" }}
|
|
244
|
+
></SchemaItem>
|
|
245
|
+
<SchemaItem
|
|
246
|
+
collapsible={false}
|
|
247
|
+
name={\\"innerProp2\\"}
|
|
248
|
+
required={false}
|
|
249
|
+
schemaName={\\"number\\"}
|
|
250
|
+
qualifierMessage={undefined}
|
|
251
|
+
schema={{ type: \\"number\\" }}
|
|
252
|
+
></SchemaItem>
|
|
253
|
+
</div>
|
|
254
|
+
</details>
|
|
255
|
+
</SchemaItem>;
|
|
256
|
+
",
|
|
257
|
+
]
|
|
258
|
+
`;
|
|
259
|
+
|
|
260
|
+
exports[`createNodes allOf should correctly handle shared required properties across allOf schemas 1`] = `
|
|
261
|
+
Array [
|
|
262
|
+
"<SchemaItem
|
|
263
|
+
collapsible={false}
|
|
264
|
+
name={\\"sharedProp\\"}
|
|
265
|
+
required={true}
|
|
266
|
+
schemaName={\\"string\\"}
|
|
267
|
+
qualifierMessage={undefined}
|
|
268
|
+
schema={{ type: \\"string\\" }}
|
|
269
|
+
></SchemaItem>;
|
|
270
|
+
",
|
|
271
|
+
"<SchemaItem
|
|
272
|
+
collapsible={false}
|
|
273
|
+
name={\\"anotherProp\\"}
|
|
274
|
+
required={true}
|
|
275
|
+
schemaName={\\"number\\"}
|
|
276
|
+
qualifierMessage={undefined}
|
|
277
|
+
schema={{ type: \\"number\\" }}
|
|
278
|
+
></SchemaItem>;
|
|
279
|
+
",
|
|
280
|
+
]
|
|
281
|
+
`;
|
|
282
|
+
|
|
283
|
+
exports[`createNodes allOf should correctly merge nested properties from multiple allOf schemas 1`] = `
|
|
284
|
+
Array [
|
|
285
|
+
"<SchemaItem collapsible={true} className={\\"schemaItem\\"}>
|
|
286
|
+
<details style={{}} className={\\"openapi-markdown__details\\"}>
|
|
287
|
+
<summary style={{}}>
|
|
288
|
+
<span className={\\"openapi-schema__container\\"}>
|
|
289
|
+
<strong className={\\"openapi-schema__property\\"}>outerProp1</strong>
|
|
290
|
+
<span className={\\"openapi-schema__name\\"}>object</span>
|
|
291
|
+
</span>
|
|
292
|
+
</summary>
|
|
293
|
+
<div style={{ marginLeft: \\"1rem\\" }}>
|
|
294
|
+
<SchemaItem
|
|
295
|
+
collapsible={false}
|
|
296
|
+
name={\\"innerProp1\\"}
|
|
297
|
+
required={false}
|
|
298
|
+
schemaName={\\"string\\"}
|
|
299
|
+
qualifierMessage={undefined}
|
|
300
|
+
schema={{ type: \\"string\\" }}
|
|
301
|
+
></SchemaItem>
|
|
302
|
+
</div>
|
|
303
|
+
</details>
|
|
304
|
+
</SchemaItem>;
|
|
305
|
+
",
|
|
306
|
+
"<SchemaItem collapsible={true} className={\\"schemaItem\\"}>
|
|
307
|
+
<details style={{}} className={\\"openapi-markdown__details\\"}>
|
|
308
|
+
<summary style={{}}>
|
|
309
|
+
<span className={\\"openapi-schema__container\\"}>
|
|
310
|
+
<strong className={\\"openapi-schema__property\\"}>outerProp2</strong>
|
|
311
|
+
<span className={\\"openapi-schema__name\\"}>object</span>
|
|
312
|
+
</span>
|
|
313
|
+
</summary>
|
|
314
|
+
<div style={{ marginLeft: \\"1rem\\" }}>
|
|
315
|
+
<SchemaItem
|
|
316
|
+
collapsible={false}
|
|
317
|
+
name={\\"innerProp2\\"}
|
|
318
|
+
required={false}
|
|
319
|
+
schemaName={\\"number\\"}
|
|
320
|
+
qualifierMessage={undefined}
|
|
321
|
+
schema={{ type: \\"number\\" }}
|
|
322
|
+
></SchemaItem>
|
|
323
|
+
</div>
|
|
324
|
+
</details>
|
|
325
|
+
</SchemaItem>;
|
|
326
|
+
",
|
|
327
|
+
]
|
|
328
|
+
`;
|
|
329
|
+
|
|
330
|
+
exports[`createNodes allOf should render same-level properties with allOf 1`] = `
|
|
331
|
+
Array [
|
|
332
|
+
"<SchemaItem
|
|
333
|
+
collapsible={false}
|
|
334
|
+
name={\\"parentProp1\\"}
|
|
335
|
+
required={false}
|
|
336
|
+
schemaName={\\"string\\"}
|
|
337
|
+
qualifierMessage={undefined}
|
|
338
|
+
schema={{ type: \\"string\\" }}
|
|
339
|
+
></SchemaItem>;
|
|
340
|
+
",
|
|
341
|
+
"<SchemaItem
|
|
342
|
+
collapsible={false}
|
|
343
|
+
name={\\"parentProp2\\"}
|
|
344
|
+
required={false}
|
|
345
|
+
schemaName={\\"string\\"}
|
|
346
|
+
qualifierMessage={undefined}
|
|
347
|
+
schema={{ type: \\"string\\" }}
|
|
348
|
+
></SchemaItem>;
|
|
349
|
+
",
|
|
350
|
+
"<SchemaItem
|
|
351
|
+
collapsible={false}
|
|
352
|
+
name={\\"allOfProp1\\"}
|
|
353
|
+
required={false}
|
|
354
|
+
schemaName={\\"string\\"}
|
|
355
|
+
qualifierMessage={undefined}
|
|
356
|
+
schema={{ type: \\"string\\" }}
|
|
357
|
+
></SchemaItem>;
|
|
358
|
+
",
|
|
359
|
+
"<SchemaItem
|
|
360
|
+
collapsible={false}
|
|
361
|
+
name={\\"allOfProp2\\"}
|
|
362
|
+
required={false}
|
|
363
|
+
schemaName={\\"string\\"}
|
|
364
|
+
qualifierMessage={undefined}
|
|
365
|
+
schema={{ type: \\"string\\" }}
|
|
366
|
+
></SchemaItem>;
|
|
367
|
+
",
|
|
368
|
+
]
|
|
369
|
+
`;
|
|
370
|
+
|
|
371
|
+
exports[`createNodes oneOf should create readable MODs for oneOf primitive properties 1`] = `
|
|
227
372
|
Array [
|
|
228
373
|
"<SchemaItem collapsible={true} className={\\"schemaItem\\"}>
|
|
229
374
|
<details style={{}} className={\\"openapi-markdown__details\\"}>
|
|
@@ -11,50 +11,306 @@ import { createNodes } from "./createSchema";
|
|
|
11
11
|
import { SchemaObject } from "../openapi/types";
|
|
12
12
|
|
|
13
13
|
describe("createNodes", () => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
14
|
+
describe("oneOf", () => {
|
|
15
|
+
it("should create readable MODs for oneOf primitive properties", async () => {
|
|
16
|
+
const schema: SchemaObject = {
|
|
17
|
+
"x-tags": ["clown"],
|
|
18
|
+
type: "object",
|
|
19
|
+
properties: {
|
|
20
|
+
oneOfProperty: {
|
|
21
|
+
oneOf: [
|
|
22
|
+
{
|
|
23
|
+
type: "object",
|
|
24
|
+
properties: {
|
|
25
|
+
noseLength: {
|
|
26
|
+
type: "number",
|
|
27
|
+
},
|
|
26
28
|
},
|
|
29
|
+
required: ["noseLength"],
|
|
30
|
+
description: "Clown's nose length",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
type: "array",
|
|
34
|
+
items: {
|
|
35
|
+
type: "string",
|
|
36
|
+
},
|
|
37
|
+
description: "Array of strings",
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
type: "boolean",
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
type: "number",
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
type: "string",
|
|
47
|
+
},
|
|
48
|
+
],
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
expect(
|
|
53
|
+
await Promise.all(
|
|
54
|
+
createNodes(schema, "request").map(
|
|
55
|
+
async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
56
|
+
)
|
|
57
|
+
)
|
|
58
|
+
).toMatchSnapshot();
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("allOf", () => {
|
|
63
|
+
it("should render same-level properties with allOf", async () => {
|
|
64
|
+
const schema: SchemaObject = {
|
|
65
|
+
allOf: [
|
|
66
|
+
{
|
|
67
|
+
type: "object",
|
|
68
|
+
properties: {
|
|
69
|
+
allOfProp1: {
|
|
70
|
+
type: "string",
|
|
71
|
+
},
|
|
72
|
+
allOfProp2: {
|
|
73
|
+
type: "string",
|
|
27
74
|
},
|
|
28
|
-
required: ["noseLength"],
|
|
29
|
-
description: "Clown's nose length",
|
|
30
75
|
},
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
properties: {
|
|
79
|
+
parentProp1: {
|
|
80
|
+
type: "string",
|
|
81
|
+
},
|
|
82
|
+
parentProp2: {
|
|
83
|
+
type: "string",
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
expect(
|
|
89
|
+
await Promise.all(
|
|
90
|
+
createNodes(schema, "response").map(
|
|
91
|
+
async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
).toMatchSnapshot();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it("should correctly merge nested properties from multiple allOf schemas", async () => {
|
|
98
|
+
const schema: SchemaObject = {
|
|
99
|
+
allOf: [
|
|
100
|
+
{
|
|
101
|
+
type: "object",
|
|
102
|
+
properties: {
|
|
103
|
+
outerProp1: {
|
|
104
|
+
type: "object",
|
|
105
|
+
properties: {
|
|
106
|
+
innerProp1: {
|
|
107
|
+
type: "string",
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
type: "object",
|
|
115
|
+
properties: {
|
|
116
|
+
outerProp2: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {
|
|
119
|
+
innerProp2: {
|
|
120
|
+
type: "number",
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
],
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
expect(
|
|
130
|
+
await Promise.all(
|
|
131
|
+
createNodes(schema, "response").map(
|
|
132
|
+
async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
).toMatchSnapshot();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it("should correctly handle shared required properties across allOf schemas", async () => {
|
|
139
|
+
const schema: SchemaObject = {
|
|
140
|
+
allOf: [
|
|
141
|
+
{
|
|
142
|
+
type: "object",
|
|
143
|
+
properties: {
|
|
144
|
+
sharedProp: {
|
|
34
145
|
type: "string",
|
|
35
146
|
},
|
|
36
|
-
description: "Array of strings",
|
|
37
147
|
},
|
|
38
|
-
|
|
39
|
-
|
|
148
|
+
required: ["sharedProp"],
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
type: "object",
|
|
152
|
+
properties: {
|
|
153
|
+
anotherProp: {
|
|
154
|
+
type: "number",
|
|
155
|
+
},
|
|
40
156
|
},
|
|
41
|
-
|
|
42
|
-
|
|
157
|
+
required: ["anotherProp"],
|
|
158
|
+
},
|
|
159
|
+
],
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
expect(
|
|
163
|
+
await Promise.all(
|
|
164
|
+
createNodes(schema, "response").map(
|
|
165
|
+
async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
166
|
+
)
|
|
167
|
+
)
|
|
168
|
+
).toMatchSnapshot();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Could not resolve values for path:"properties.conflictingProp.type". They are probably incompatible. Values:
|
|
172
|
+
// "string"
|
|
173
|
+
// "number"
|
|
174
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
175
|
+
// it("should handle conflicting properties in allOf schemas", async () => {
|
|
176
|
+
// const schema: SchemaObject = {
|
|
177
|
+
// allOf: [
|
|
178
|
+
// {
|
|
179
|
+
// type: "object",
|
|
180
|
+
// properties: {
|
|
181
|
+
// conflictingProp: {
|
|
182
|
+
// type: "string",
|
|
183
|
+
// },
|
|
184
|
+
// },
|
|
185
|
+
// },
|
|
186
|
+
// {
|
|
187
|
+
// type: "object",
|
|
188
|
+
// properties: {
|
|
189
|
+
// conflictingProp: {
|
|
190
|
+
// type: "number",
|
|
191
|
+
// },
|
|
192
|
+
// },
|
|
193
|
+
// },
|
|
194
|
+
// ],
|
|
195
|
+
// };
|
|
196
|
+
|
|
197
|
+
// expect(
|
|
198
|
+
// await Promise.all(
|
|
199
|
+
// createNodes(schema, "response").map(
|
|
200
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
201
|
+
// )
|
|
202
|
+
// )
|
|
203
|
+
// ).toMatchSnapshot();
|
|
204
|
+
// });
|
|
205
|
+
|
|
206
|
+
// Could not resolve values for path:"type". They are probably incompatible. Values:
|
|
207
|
+
// "object"
|
|
208
|
+
// "array"
|
|
209
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
210
|
+
// it("should handle mixed data types in allOf schemas", async () => {
|
|
211
|
+
// const schema: SchemaObject = {
|
|
212
|
+
// allOf: [
|
|
213
|
+
// {
|
|
214
|
+
// type: "object",
|
|
215
|
+
// properties: {
|
|
216
|
+
// mixedTypeProp1: {
|
|
217
|
+
// type: "string",
|
|
218
|
+
// },
|
|
219
|
+
// },
|
|
220
|
+
// },
|
|
221
|
+
// {
|
|
222
|
+
// type: "array",
|
|
223
|
+
// items: {
|
|
224
|
+
// type: "number",
|
|
225
|
+
// },
|
|
226
|
+
// },
|
|
227
|
+
// ],
|
|
228
|
+
// };
|
|
229
|
+
|
|
230
|
+
// expect(
|
|
231
|
+
// await Promise.all(
|
|
232
|
+
// createNodes(schema, "response").map(
|
|
233
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
234
|
+
// )
|
|
235
|
+
// )
|
|
236
|
+
// ).toMatchSnapshot();
|
|
237
|
+
// });
|
|
238
|
+
|
|
239
|
+
it("should correctly deep merge properties in allOf schemas", async () => {
|
|
240
|
+
const schema: SchemaObject = {
|
|
241
|
+
allOf: [
|
|
242
|
+
{
|
|
243
|
+
type: "object",
|
|
244
|
+
properties: {
|
|
245
|
+
deepProp: {
|
|
246
|
+
type: "object",
|
|
247
|
+
properties: {
|
|
248
|
+
innerProp1: {
|
|
249
|
+
type: "string",
|
|
250
|
+
},
|
|
251
|
+
},
|
|
252
|
+
},
|
|
43
253
|
},
|
|
44
|
-
|
|
45
|
-
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
type: "object",
|
|
257
|
+
properties: {
|
|
258
|
+
deepProp: {
|
|
259
|
+
type: "object",
|
|
260
|
+
properties: {
|
|
261
|
+
innerProp2: {
|
|
262
|
+
type: "number",
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
},
|
|
46
266
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
267
|
+
},
|
|
268
|
+
],
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
expect(
|
|
272
|
+
await Promise.all(
|
|
273
|
+
createNodes(schema, "response").map(
|
|
274
|
+
async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
275
|
+
)
|
|
55
276
|
)
|
|
56
|
-
)
|
|
57
|
-
)
|
|
277
|
+
).toMatchSnapshot();
|
|
278
|
+
});
|
|
279
|
+
|
|
280
|
+
// eslint-disable-next-line jest/no-commented-out-tests
|
|
281
|
+
// it("should handle discriminator with allOf schemas", async () => {
|
|
282
|
+
// const schema: SchemaObject = {
|
|
283
|
+
// allOf: [
|
|
284
|
+
// {
|
|
285
|
+
// type: "object",
|
|
286
|
+
// discriminator: {
|
|
287
|
+
// propertyName: "type",
|
|
288
|
+
// },
|
|
289
|
+
// properties: {
|
|
290
|
+
// type: {
|
|
291
|
+
// type: "string",
|
|
292
|
+
// },
|
|
293
|
+
// },
|
|
294
|
+
// },
|
|
295
|
+
// {
|
|
296
|
+
// type: "object",
|
|
297
|
+
// properties: {
|
|
298
|
+
// specificProp: {
|
|
299
|
+
// type: "string",
|
|
300
|
+
// },
|
|
301
|
+
// },
|
|
302
|
+
// },
|
|
303
|
+
// ],
|
|
304
|
+
// };
|
|
305
|
+
|
|
306
|
+
// expect(
|
|
307
|
+
// await Promise.all(
|
|
308
|
+
// createNodes(schema, "response").map(
|
|
309
|
+
// async (md: any) => await prettier.format(md, { parser: "babel" })
|
|
310
|
+
// )
|
|
311
|
+
// )
|
|
312
|
+
// ).toMatchSnapshot();
|
|
313
|
+
// });
|
|
58
314
|
});
|
|
59
315
|
|
|
60
316
|
describe("additionalProperties", () => {
|
|
@@ -615,6 +615,7 @@ function createEdges({
|
|
|
615
615
|
}
|
|
616
616
|
|
|
617
617
|
const schemaName = getSchemaName(schema);
|
|
618
|
+
|
|
618
619
|
if (discriminator !== undefined && discriminator.propertyName === name) {
|
|
619
620
|
return createPropertyDiscriminator(
|
|
620
621
|
name,
|
|
@@ -635,6 +636,47 @@ function createEdges({
|
|
|
635
636
|
);
|
|
636
637
|
}
|
|
637
638
|
|
|
639
|
+
if (schema.properties !== undefined) {
|
|
640
|
+
return createDetailsNode(
|
|
641
|
+
name,
|
|
642
|
+
schemaName,
|
|
643
|
+
schema,
|
|
644
|
+
required,
|
|
645
|
+
schema.nullable
|
|
646
|
+
);
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
if (schema.additionalProperties !== undefined) {
|
|
650
|
+
return createDetailsNode(
|
|
651
|
+
name,
|
|
652
|
+
schemaName,
|
|
653
|
+
schema,
|
|
654
|
+
required,
|
|
655
|
+
schema.nullable
|
|
656
|
+
);
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
// array of objects
|
|
660
|
+
if (schema.items?.properties !== undefined) {
|
|
661
|
+
return createDetailsNode(
|
|
662
|
+
name,
|
|
663
|
+
schemaName,
|
|
664
|
+
schema,
|
|
665
|
+
required,
|
|
666
|
+
schema.nullable
|
|
667
|
+
);
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
if (schema.items?.anyOf !== undefined || schema.items?.oneOf !== undefined) {
|
|
671
|
+
return createDetailsNode(
|
|
672
|
+
name,
|
|
673
|
+
schemaName,
|
|
674
|
+
schema,
|
|
675
|
+
required,
|
|
676
|
+
schema.nullable
|
|
677
|
+
);
|
|
678
|
+
}
|
|
679
|
+
|
|
638
680
|
if (schema.allOf !== undefined) {
|
|
639
681
|
const { mergedSchemas }: { mergedSchemas: SchemaObject } = mergeAllOf(
|
|
640
682
|
schema.allOf
|
|
@@ -707,47 +749,6 @@ function createEdges({
|
|
|
707
749
|
});
|
|
708
750
|
}
|
|
709
751
|
|
|
710
|
-
if (schema.properties !== undefined) {
|
|
711
|
-
return createDetailsNode(
|
|
712
|
-
name,
|
|
713
|
-
schemaName,
|
|
714
|
-
schema,
|
|
715
|
-
required,
|
|
716
|
-
schema.nullable
|
|
717
|
-
);
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
if (schema.additionalProperties !== undefined) {
|
|
721
|
-
return createDetailsNode(
|
|
722
|
-
name,
|
|
723
|
-
schemaName,
|
|
724
|
-
schema,
|
|
725
|
-
required,
|
|
726
|
-
schema.nullable
|
|
727
|
-
);
|
|
728
|
-
}
|
|
729
|
-
|
|
730
|
-
// array of objects
|
|
731
|
-
if (schema.items?.properties !== undefined) {
|
|
732
|
-
return createDetailsNode(
|
|
733
|
-
name,
|
|
734
|
-
schemaName,
|
|
735
|
-
schema,
|
|
736
|
-
required,
|
|
737
|
-
schema.nullable
|
|
738
|
-
);
|
|
739
|
-
}
|
|
740
|
-
|
|
741
|
-
if (schema.items?.anyOf !== undefined || schema.items?.oneOf !== undefined) {
|
|
742
|
-
return createDetailsNode(
|
|
743
|
-
name,
|
|
744
|
-
schemaName,
|
|
745
|
-
schema,
|
|
746
|
-
required,
|
|
747
|
-
schema.nullable
|
|
748
|
-
);
|
|
749
|
-
}
|
|
750
|
-
|
|
751
752
|
// primitives and array of non-objects
|
|
752
753
|
return create("SchemaItem", {
|
|
753
754
|
collapsible: false,
|
|
@@ -787,6 +788,19 @@ export function createNodes(
|
|
|
787
788
|
nodes.push(createAnyOneOf(schema));
|
|
788
789
|
}
|
|
789
790
|
|
|
791
|
+
if (schema.properties !== undefined) {
|
|
792
|
+
nodes.push(createProperties(schema));
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
if (schema.additionalProperties !== undefined) {
|
|
796
|
+
nodes.push(createAdditionalProperties(schema));
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
// TODO: figure out how to handle array of objects
|
|
800
|
+
if (schema.items !== undefined) {
|
|
801
|
+
nodes.push(createItems(schema));
|
|
802
|
+
}
|
|
803
|
+
|
|
790
804
|
if (schema.allOf !== undefined) {
|
|
791
805
|
const { mergedSchemas } = mergeAllOf(schema.allOf);
|
|
792
806
|
|
|
@@ -802,19 +816,6 @@ export function createNodes(
|
|
|
802
816
|
}
|
|
803
817
|
}
|
|
804
818
|
|
|
805
|
-
if (schema.properties !== undefined) {
|
|
806
|
-
nodes.push(createProperties(schema));
|
|
807
|
-
}
|
|
808
|
-
|
|
809
|
-
if (schema.additionalProperties !== undefined) {
|
|
810
|
-
nodes.push(createAdditionalProperties(schema));
|
|
811
|
-
}
|
|
812
|
-
|
|
813
|
-
// TODO: figure out how to handle array of objects
|
|
814
|
-
if (schema.items !== undefined) {
|
|
815
|
-
nodes.push(createItems(schema));
|
|
816
|
-
}
|
|
817
|
-
|
|
818
819
|
if (nodes.length && nodes.length > 0) {
|
|
819
820
|
return nodes.filter(Boolean).flat();
|
|
820
821
|
}
|
|
@@ -30,8 +30,8 @@ const primitives: Primitives = {
|
|
|
30
30
|
string: {
|
|
31
31
|
default: () => "string",
|
|
32
32
|
email: () => "user@example.com",
|
|
33
|
-
date: () =>
|
|
34
|
-
"date-time": () =>
|
|
33
|
+
date: () => "2024-07-29",
|
|
34
|
+
"date-time": () => "2024-07-29T15:51:28.071Z",
|
|
35
35
|
uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
36
36
|
hostname: () => "example.com",
|
|
37
37
|
ipv4: () => "198.51.100.42",
|
|
@@ -30,8 +30,8 @@ const primitives: Primitives = {
|
|
|
30
30
|
string: {
|
|
31
31
|
default: () => "string",
|
|
32
32
|
email: () => "user@example.com",
|
|
33
|
-
date: () =>
|
|
34
|
-
"date-time": () =>
|
|
33
|
+
date: () => "2024-07-29",
|
|
34
|
+
"date-time": () => "2024-07-29T15:51:28.071Z",
|
|
35
35
|
uuid: () => "3fa85f64-5717-4562-b3fc-2c963f66afa6",
|
|
36
36
|
hostname: () => "example.com",
|
|
37
37
|
ipv4: () => "198.51.100.42",
|