@xyd-js/openapi 0.1.0-xyd.11 → 0.1.0-xyd.13

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 (49) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/__fixtures__/-2.complex.openai/input.yaml +39848 -0
  3. package/__fixtures__/-2.complex.openai/output.json +321646 -0
  4. package/__fixtures__/-2.complex.openai/pluginOasOpenai.ts +553 -0
  5. package/__fixtures__/1.basic/input.yaml +226 -0
  6. package/__fixtures__/1.basic/output.json +1919 -0
  7. package/__fixtures__/2.more/input.yaml +76 -0
  8. package/__fixtures__/2.more/output.json +292 -0
  9. package/__fixtures__/3.multiple-responses/input.yaml +48 -0
  10. package/__fixtures__/3.multiple-responses/output.json +266 -0
  11. package/__fixtures__/4.abc/input.yaml +639 -0
  12. package/__fixtures__/4.abc/output.json +3828 -0
  13. package/__fixtures__/5.xdocs.codeLanguages/input.yaml +231 -0
  14. package/__fixtures__/5.xdocs.codeLanguages/output.json +1879 -0
  15. package/__fixtures__/5.xdocs.sidebar/input.yaml +256 -0
  16. package/__fixtures__/5.xdocs.sidebar/output.json +843 -0
  17. package/__fixtures__/6.codeSamples/input.yaml +75 -0
  18. package/__fixtures__/6.codeSamples/output.json +293 -0
  19. package/__tests__/oapSchemaToReferences.test.ts +88 -0
  20. package/__tests__/utils.ts +81 -0
  21. package/dist/index.cjs +1859 -162
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +36 -4
  24. package/dist/index.d.ts +36 -4
  25. package/dist/index.js +1855 -155
  26. package/dist/index.js.map +1 -1
  27. package/index.ts +10 -2
  28. package/package.json +11 -6
  29. package/src/const.ts +5 -1
  30. package/src/converters/oas-componentSchemas.ts +205 -0
  31. package/src/converters/oas-examples.ts +417 -0
  32. package/src/{parameters.ts → converters/oas-parameters.ts} +17 -3
  33. package/src/converters/oas-paths.ts +354 -0
  34. package/src/{requestBody.ts → converters/oas-requestBody.ts} +30 -10
  35. package/src/converters/oas-responses.ts +76 -0
  36. package/src/converters/oas-schema.ts +141 -0
  37. package/src/index.ts +13 -5
  38. package/src/oas-core.ts +579 -0
  39. package/src/types.ts +18 -0
  40. package/src/utils.ts +103 -90
  41. package/src/xdocs/index.ts +18 -0
  42. package/src/xdocs/pluginSidebar.ts +580 -0
  43. package/src/xdocs/types.ts +26 -0
  44. package/vitest.config.ts +7 -0
  45. package/src/examples.ts +0 -116
  46. package/src/paths.ts +0 -103
  47. package/src/properties.ts +0 -37
  48. package/src/responses.ts +0 -38
  49. package/src/schema.ts +0 -62
@@ -0,0 +1,579 @@
1
+ import {OpenAPIV3} from "openapi-types";
2
+
3
+ import {
4
+ DEFINED_DEFINITION_PROPERTY_TYPE,
5
+ DefinitionProperty,
6
+ DefinitionPropertyMeta
7
+ } from "@xyd-js/uniform";
8
+
9
+ import {OasJSONSchema} from "./types";
10
+ import {BUILT_IN_PROPERTIES} from "./const";
11
+
12
+ export function schemaObjectToUniformDefinitionProperties(
13
+ schemaObject: OpenAPIV3.ReferenceObject | OpenAPIV3.SchemaObject,
14
+ rootProperty?: boolean,
15
+ visitedRefs?: Map<string, DefinitionProperty>
16
+ ): DefinitionProperty[] | DefinitionProperty | null {
17
+ if ('$ref' in schemaObject) {
18
+ console.warn("Reference objects are not supported in schemaObjectToUniformDefinitionProperties");
19
+
20
+ return null
21
+ }
22
+
23
+ const properties: DefinitionProperty[] = [];
24
+
25
+ // Process schema properties
26
+ if ('anyOf' in schemaObject && schemaObject.anyOf) {
27
+ const property = schemaObjectToUniformDefinitionProperty("", schemaObject, false, false, visitedRefs)
28
+
29
+ if (property) {
30
+ if (rootProperty) {
31
+ return property
32
+ }
33
+
34
+ properties.push(property);
35
+ }
36
+ } else if ('oneOf' in schemaObject && schemaObject.oneOf) {
37
+ const property = schemaObjectToUniformDefinitionProperty("", schemaObject, false, false, visitedRefs)
38
+
39
+ if (property) {
40
+ if (rootProperty) {
41
+ return property
42
+ }
43
+
44
+ properties.push(property);
45
+ }
46
+ } else if ('allOf' in schemaObject && schemaObject.allOf) {
47
+ const componentPaths: string[] = []
48
+
49
+ // Handle allOf by merging properties from all schemas
50
+ for (const schema of schemaObject.allOf) {
51
+ if ('$ref' in schema) {
52
+ console.warn("$ref is not supported in allOf schemas");
53
+
54
+ continue; // Skip reference objects
55
+ }
56
+
57
+ const oasSchema = schema as OasJSONSchema;
58
+ if (oasSchema.__internal_getRefPath) {
59
+ const refPath = oasSchema.__internal_getRefPath();
60
+ if (typeof refPath === 'string') {
61
+ componentPaths.push(refPath);
62
+ } else if (Array.isArray(refPath)) {
63
+ componentPaths.push(...refPath);
64
+ } else {
65
+ console.warn("Invalid refPath type in allOf schema", oasSchema);
66
+ }
67
+ }
68
+
69
+ if ('properties' in schema && schema.properties) {
70
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
71
+ if (BUILT_IN_PROPERTIES[propName]) {
72
+ continue;
73
+ }
74
+ if ('$ref' in propSchema) {
75
+ console.warn("$ref is not supported in allOf properties");
76
+
77
+ continue; // Skip reference objects
78
+ }
79
+
80
+ const property = schemaObjectToUniformDefinitionProperty(
81
+ propName,
82
+ propSchema,
83
+ schema.required?.includes(propName),
84
+ propSchema?.type === "array" ? true : false,
85
+ visitedRefs
86
+ );
87
+
88
+ if (property) {
89
+ // Check if property already exists and merge if needed
90
+ const existingPropertyIndex = properties.findIndex(p => p.name === propName);
91
+ if (existingPropertyIndex >= 0) {
92
+ // Merge properties if they exist in multiple schemas
93
+ const existingProperty = properties[existingPropertyIndex];
94
+ properties[existingPropertyIndex] = {
95
+ ...existingProperty,
96
+ ...property,
97
+ description: property.description || existingProperty.description || "",
98
+ meta: [...(existingProperty.meta || []), ...(property.meta || [])],
99
+ };
100
+ } else {
101
+ properties.push(property);
102
+ }
103
+ }
104
+ }
105
+ }
106
+ }
107
+
108
+ const oasSchema = schemaObject as OasJSONSchema;
109
+ oasSchema.__internal_getRefPath = () => componentPaths
110
+ } else if ('properties' in schemaObject && schemaObject.properties) {
111
+ for (const [propName, propSchema] of Object.entries(schemaObject.properties)) {
112
+ if (BUILT_IN_PROPERTIES[propName]) {
113
+ continue;
114
+ }
115
+ if ('$ref' in propSchema) {
116
+ console.warn("$ref is not supported in properties");
117
+
118
+ continue; // Skip reference objects
119
+ }
120
+
121
+ const property = schemaObjectToUniformDefinitionProperty(
122
+ propName,
123
+ propSchema,
124
+ schemaObject.required?.includes(propName),
125
+ propSchema?.type === "array" ? true : false,
126
+ visitedRefs
127
+ );
128
+ if (property) {
129
+ properties.push(property);
130
+ }
131
+ }
132
+ }
133
+
134
+ return properties
135
+ }
136
+
137
+ export function schemaObjectToUniformDefinitionProperty(
138
+ name: string,
139
+ schema: OpenAPIV3.SchemaObject,
140
+ required?: boolean,
141
+ arrayOf?: boolean,
142
+ visitedRefs?: Map<string, DefinitionProperty>,
143
+ parentProperty?: DefinitionProperty
144
+ ): DefinitionProperty | null {
145
+ if (name === "__UNSAFE_refPath") {
146
+ return null
147
+ }
148
+ if (!schema) return null;
149
+
150
+ if (!visitedRefs) {
151
+ visitedRefs = new Map();
152
+ }
153
+ let refPath = ""
154
+ if ("__UNSAFE_refPath" in schema && typeof schema.__UNSAFE_refPath === 'function') {
155
+ refPath = schema.__UNSAFE_refPath();
156
+ const defProp = visitedRefs.get(refPath);
157
+ if (defProp) {
158
+ return JSON.parse(JSON.stringify(defProp)); // Return a deep copy circular json
159
+ }
160
+ }
161
+
162
+ if (parentProperty) {
163
+ visitedRefs.set(refPath, parentProperty);
164
+ }
165
+
166
+ // Handle anyOf case
167
+ if ('anyOf' in schema && schema.anyOf) {
168
+ const componentPaths: string[] = []
169
+ const properties: DefinitionProperty[] = [];
170
+
171
+ for (const variantSchema of schema.anyOf) {
172
+ if ('$ref' in variantSchema) {
173
+ console.warn("$ref is not supported in anyOf schemas");
174
+
175
+ continue; // Skip reference objects
176
+ }
177
+
178
+ const oasSchema = variantSchema as OasJSONSchema;
179
+ if (oasSchema.__internal_getRefPath) {
180
+ const refPath = oasSchema.__internal_getRefPath();
181
+ if (typeof refPath === 'string') {
182
+ componentPaths.push(refPath);
183
+ } else if (Array.isArray(refPath)) {
184
+ componentPaths.push(...refPath);
185
+ } else {
186
+ console.warn("Invalid refPath type in anyOf schema", oasSchema);
187
+ }
188
+ }
189
+
190
+ const property = schemaObjectToUniformDefinitionProperty(name, variantSchema, required, false, visitedRefs);
191
+
192
+ if (property) {
193
+ if (isMergeType(property.type)) {
194
+ properties.push(...property.properties || []);
195
+ } else {
196
+ properties.push({
197
+ ...property,
198
+ name: variantSchema.title || property.name || "",
199
+ });
200
+ }
201
+ }
202
+ }
203
+
204
+ const oasSchema = schema as OasJSONSchema;
205
+ oasSchema.__internal_getRefPath = () => componentPaths
206
+
207
+ const prop = {
208
+ name,
209
+ type: DEFINED_DEFINITION_PROPERTY_TYPE.UNION,
210
+ description: schema.description || "",
211
+ properties
212
+ };
213
+
214
+ if (refPath) {
215
+ visitedRefs.set(refPath, prop);
216
+ }
217
+ return prop
218
+ }
219
+
220
+ const meta = schemaObjectToUniformDefinitionPropertyMeta({
221
+ ...schema,
222
+ required: required ? [name] : undefined,
223
+ }, name)
224
+
225
+ // Handle oneOf case
226
+ if ('oneOf' in schema && schema.oneOf) {
227
+ const componentPaths: string[] = []
228
+ const properties: DefinitionProperty[] = [];
229
+
230
+ for (const variantSchema of schema.oneOf) {
231
+ if ('$ref' in variantSchema) {
232
+ console.warn("$ref is not supported in oneOf schemas");
233
+
234
+ continue; // Skip reference objects
235
+ }
236
+
237
+ const oasSchema = variantSchema as OasJSONSchema;
238
+ if (oasSchema.__internal_getRefPath) {
239
+ const refPath = oasSchema.__internal_getRefPath();
240
+ if (typeof refPath === 'string') {
241
+ componentPaths.push(refPath);
242
+ } else if (Array.isArray(refPath)) {
243
+ componentPaths.push(...refPath);
244
+ } else {
245
+ console.warn("Invalid refPath type in allOf schema", oasSchema);
246
+ }
247
+ }
248
+
249
+ const property = schemaObjectToUniformDefinitionProperty(name, variantSchema, required, false, visitedRefs);
250
+ if (property) {
251
+ // if (isOfType(property.type)) { TODO: in the future?
252
+ // }
253
+ properties.push({
254
+ ...property,
255
+ name: variantSchema.title || property.name || "",
256
+ });
257
+ }
258
+ }
259
+
260
+ const oasSchema = schema as OasJSONSchema;
261
+ oasSchema.__internal_getRefPath = () => componentPaths
262
+
263
+ const prop: DefinitionProperty = {
264
+ name,
265
+ type: DEFINED_DEFINITION_PROPERTY_TYPE.XOR,
266
+ description: schema.description || "",
267
+ properties,
268
+ meta,
269
+ };
270
+
271
+ if (refPath) {
272
+ visitedRefs.set(refPath, prop);
273
+ }
274
+
275
+ return prop
276
+ }
277
+
278
+ // Handle allOf case
279
+ if ('allOf' in schema && schema.allOf) {
280
+ const componentPaths: string[] = []
281
+ const mergedProperty: DefinitionProperty = {
282
+ name,
283
+ type: schema.type || "",
284
+ description: schema.description || "",
285
+ properties: [],
286
+ meta
287
+ };
288
+
289
+ for (const variantSchema of schema.allOf) {
290
+ if ('$ref' in variantSchema) {
291
+ console.warn("$ref is not supported in allOf schemas");
292
+ continue; // Skip reference objects
293
+ }
294
+
295
+ const oasSchema = variantSchema as OasJSONSchema;
296
+ if (oasSchema.__internal_getRefPath) {
297
+ const refPath = oasSchema.__internal_getRefPath();
298
+ if (typeof refPath === 'string') {
299
+ componentPaths.push(refPath);
300
+ } else if (Array.isArray(refPath)) {
301
+ componentPaths.push(...refPath);
302
+ } else {
303
+ console.warn("Invalid refPath type in allOf schema", oasSchema);
304
+ }
305
+ }
306
+
307
+
308
+ if (!mergedProperty.type) {
309
+ if (typeof variantSchema.type === 'string') {
310
+ mergedProperty.type = variantSchema.type || ""
311
+ }
312
+ }
313
+
314
+ if ('properties' in variantSchema && variantSchema.properties) {
315
+ for (const [propName, propSchema] of Object.entries(variantSchema.properties)) {
316
+ if (BUILT_IN_PROPERTIES[propName]) {
317
+ continue;
318
+ }
319
+ if ('$ref' in propSchema) {
320
+ console.warn("$ref is not supported in allOf properties");
321
+ continue; // Skip reference objects
322
+ }
323
+
324
+ const property = schemaObjectToUniformDefinitionProperty(
325
+ propName,
326
+ propSchema,
327
+ variantSchema.required?.includes(propName),
328
+ false,
329
+ visitedRefs
330
+ );
331
+
332
+ if (property && mergedProperty.properties) {
333
+ // Check if property already exists and merge if needed
334
+ const existingPropertyIndex = mergedProperty.properties.findIndex(p => p.name === propName);
335
+ if (existingPropertyIndex >= 0) {
336
+ // Merge properties if they exist in multiple schemas
337
+ const existingProperty = mergedProperty.properties[existingPropertyIndex];
338
+ mergedProperty.properties[existingPropertyIndex] = {
339
+ ...existingProperty,
340
+ ...property,
341
+ description: property.description || existingProperty.description || "",
342
+ meta: [...(existingProperty.meta || []), ...(property.meta || [])],
343
+ };
344
+ } else {
345
+ mergedProperty.properties.push(property);
346
+ }
347
+ }
348
+ }
349
+ } else {
350
+ const property = schemaObjectToUniformDefinitionProperty(
351
+ "",
352
+ variantSchema,
353
+ false,
354
+ false,
355
+ visitedRefs
356
+ );
357
+ if (property) {
358
+ if (isOfType(property.type)) {
359
+ mergedProperty.ofProperty = property
360
+ } else {
361
+ if (!mergedProperty.properties?.length) {
362
+ mergedProperty.properties = []
363
+ }
364
+
365
+ if (mergedProperty.ofProperty) {
366
+ mergedProperty.description = property.description || mergedProperty.ofProperty.description || ""
367
+ } else {
368
+ mergedProperty.properties.push(property);
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ const oasSchema = schema as OasJSONSchema;
376
+ oasSchema.__internal_getRefPath = () => componentPaths;
377
+
378
+ if (refPath) {
379
+ visitedRefs.set(refPath, mergedProperty);
380
+ }
381
+ return mergedProperty;
382
+ }
383
+
384
+ const property: DefinitionProperty = {
385
+ name,
386
+ type: schema.type || "object",
387
+ description: schema.description || "",
388
+ meta,
389
+ };
390
+
391
+ if (schema.enum) {
392
+ const enumProperties = schemaObjectToUniformDefinitionProperties({
393
+ properties: schema.enum.reduce((acc, enumName) => ({
394
+ ...acc,
395
+ [enumName]: {
396
+ type: schema.type,
397
+ }
398
+ }), {})
399
+ })
400
+ if (!Array.isArray(enumProperties)) {
401
+ return property;
402
+ }
403
+
404
+ meta.push({
405
+ name: "enum-type",
406
+ value: schema.type
407
+ })
408
+
409
+ const enumProperty: DefinitionProperty = {
410
+ name,
411
+ type: DEFINED_DEFINITION_PROPERTY_TYPE.ENUM,
412
+ description: schema.description || "",
413
+ meta,
414
+ properties: enumProperties || [],
415
+ };
416
+
417
+ if (refPath) {
418
+ visitedRefs.set(refPath, enumProperty);
419
+ }
420
+
421
+ return enumProperty
422
+ } else {
423
+ if ('properties' in schema && schema.properties) {
424
+ property.properties = [];
425
+
426
+ for (const [propName, propSchema] of Object.entries(schema.properties)) {
427
+ if (BUILT_IN_PROPERTIES[propName]) {
428
+ continue;
429
+ }
430
+ if ('$ref' in propSchema) {
431
+ console.warn("$ref is not supported in properties");
432
+
433
+ continue; // Skip reference objects
434
+ }
435
+
436
+ const nestedProperty = schemaObjectToUniformDefinitionProperty(
437
+ propName,
438
+ propSchema,
439
+ schema.required?.includes(propName),
440
+ propSchema?.type === "array" ? true : false,
441
+ visitedRefs,
442
+ );
443
+
444
+ if (nestedProperty) {
445
+ property.properties.push(nestedProperty);
446
+ }
447
+ }
448
+ }
449
+ // Handle array items
450
+ else if (schema.type === "array" && schema.items && !('$ref' in schema.items)) {
451
+ const arrayProperty: DefinitionProperty = {
452
+ name,
453
+ type: DEFINED_DEFINITION_PROPERTY_TYPE.ARRAY,
454
+ description: schema.description || "",
455
+ meta,
456
+ properties: []
457
+ };
458
+
459
+ const itemsProperty = schemaObjectToUniformDefinitionProperty("", schema.items, required, true, visitedRefs, arrayProperty);
460
+
461
+ if (itemsProperty) {
462
+ if (arrayOf || isOfType(itemsProperty.type) || itemsProperty.ofProperty?.type) {
463
+ arrayProperty.ofProperty = {
464
+ name: "",
465
+ type: itemsProperty.type,
466
+ properties: itemsProperty.properties || [],
467
+ description: itemsProperty.description || "",
468
+ meta: itemsProperty.meta || [],
469
+ ofProperty: itemsProperty.ofProperty || undefined
470
+ }
471
+ } else {
472
+ arrayProperty.properties = [itemsProperty];
473
+ }
474
+ }
475
+ if (refPath) {
476
+ visitedRefs.set(refPath, arrayProperty);
477
+ }
478
+
479
+ return arrayProperty
480
+ }
481
+ }
482
+
483
+ if (arrayOf) {
484
+ const prop = {
485
+ type: property.type,
486
+ name: "",
487
+ description: "",
488
+ ofProperty: property
489
+ }
490
+ if (refPath) {
491
+ visitedRefs.set(refPath, prop);
492
+ }
493
+ }
494
+
495
+
496
+ if (refPath) {
497
+ visitedRefs.set(refPath, property);
498
+ }
499
+ return property;
500
+ }
501
+
502
+ export function schemaObjectToUniformDefinitionPropertyMeta(objProp: OpenAPIV3.SchemaObject | OpenAPIV3.ParameterObject, name: string) {
503
+ const meta: DefinitionPropertyMeta[] = []
504
+ if (!objProp) {
505
+ return meta
506
+ }
507
+
508
+ if (typeof objProp.required === "boolean" && objProp.required) {
509
+ meta.push({
510
+ name: "required",
511
+ value: "true"
512
+ })
513
+ } else if (Array.isArray(objProp.required)) {
514
+ for (const req of objProp.required) {
515
+ if (req === name) {
516
+ meta.push({
517
+ name: "required",
518
+ value: "true"
519
+ })
520
+ }
521
+ }
522
+ }
523
+ if (objProp.deprecated) {
524
+ meta.push({
525
+ name: "deprecated",
526
+ value: "true"
527
+ })
528
+ }
529
+ if ("default" in objProp) {
530
+ meta.push({
531
+ name: "defaults",
532
+ value: objProp.default
533
+ })
534
+ }
535
+ if ("nullable" in objProp) {
536
+ meta.push({
537
+ name: "nullable",
538
+ value: "true"
539
+ })
540
+ }
541
+ if ("example" in objProp) {
542
+ const example = typeof objProp.example === "object" ? JSON.stringify(objProp.example) : objProp.example;
543
+ meta.push({
544
+ name: "example",
545
+ value: example
546
+ })
547
+ }
548
+ if ("examples" in objProp) {
549
+ meta.push({
550
+ name: "examples",
551
+ value: objProp.examples
552
+ })
553
+ }
554
+ if ("maximum" in objProp) {
555
+ meta.push({
556
+ name: "maximum",
557
+ value: objProp.maximum
558
+ })
559
+ }
560
+ if ("minimum" in objProp) {
561
+ meta.push({
562
+ name: "minimum",
563
+ value: objProp.minimum
564
+ })
565
+ }
566
+
567
+ return meta
568
+ }
569
+
570
+ function isMergeType(type: string) {
571
+ return type === DEFINED_DEFINITION_PROPERTY_TYPE.XOR
572
+ || type === DEFINED_DEFINITION_PROPERTY_TYPE.UNION
573
+ }
574
+
575
+ function isOfType(type: string) {
576
+ return type === DEFINED_DEFINITION_PROPERTY_TYPE.XOR
577
+ || type === DEFINED_DEFINITION_PROPERTY_TYPE.UNION
578
+ || type === DEFINED_DEFINITION_PROPERTY_TYPE.ARRAY
579
+ }
package/src/types.ts ADDED
@@ -0,0 +1,18 @@
1
+ import {OpenAPIV3} from "openapi-types";
2
+ import {JSONSchema} from "@apidevtools/json-schema-ref-parser";
3
+
4
+ export interface uniformOasOptions {
5
+ regions?: string[] // Format: 'METHOD /path' e.g. 'GET /users'
6
+ }
7
+
8
+ export interface SelectorMethod {
9
+ oapPath: OpenAPIV3.PathItemObject;
10
+
11
+ path: string;
12
+
13
+ httpMethod: "get" | "put" | "post" | "delete" | "patch";
14
+ }
15
+
16
+ export type OasJSONSchema = JSONSchema & {
17
+ __internal_getRefPath?: () => string | string[];
18
+ }