diff --git a/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV2.ts b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV2.ts new file mode 100644 index 000000000..eac44722c --- /dev/null +++ b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV2.ts @@ -0,0 +1,184 @@ +import { OpenAPIV2 } from "openapi-types" +import * as O from "fp-ts/Option" +import { pipe, flow } from "fp-ts/function" +import * as A from "fp-ts/Array" + +type PrimitiveSchemaType = "string" | "integer" | "number" | "boolean" + +type SchemaType = "array" | "object" | PrimitiveSchemaType + +type PrimitiveRequestBodyExampleType = number | string | boolean + +type RequestBodyExampleType = + | { [name: string]: RequestBodyExampleType } + | Array + | PrimitiveRequestBodyExampleType + +const getPrimitiveTypePlaceholder = ( + schemaType: PrimitiveSchemaType +): PrimitiveRequestBodyExampleType => { + switch (schemaType) { + case "string": + return "string" + case "integer": + case "number": + return 1 + case "boolean": + return true + } +} + +const getSchemaTypeFromSchemaObject = ( + schema: OpenAPIV2.SchemaObject +): O.Option => + pipe( + schema.type, + O.fromNullable, + O.map( + (schemaType) => + (Array.isArray(schemaType) ? schemaType[0] : schemaType) as SchemaType + ) + ) + +const isSchemaTypePrimitive = ( + schemaType: string +): schemaType is PrimitiveSchemaType => + ["string", "integer", "number", "boolean"].includes(schemaType) + +const isSchemaTypeArray = (schemaType: string): schemaType is "array" => + schemaType === "array" + +const isSchemaTypeObject = (schemaType: string): schemaType is "object" => + schemaType === "object" + +const getSampleEnumValueOrPlaceholder = ( + schema: OpenAPIV2.SchemaObject +): RequestBodyExampleType => { + const enumValue = pipe( + schema.enum, + O.fromNullable, + O.map((enums) => enums[0] as RequestBodyExampleType) + ) + + if (O.isSome(enumValue)) return enumValue.value + + return pipe( + schema, + getSchemaTypeFromSchemaObject, + O.filter(isSchemaTypePrimitive), + O.map(getPrimitiveTypePlaceholder), + O.getOrElseW(() => "") + ) +} + +const generateExampleArrayFromOpenAPIV2ItemsObject = ( + items: OpenAPIV2.ItemsObject +): RequestBodyExampleType => { + // ItemsObject can not hold type "object" + // https://swagger.io/specification/v2/#itemsObject + + // TODO : Handle array of objects + // https://stackoverflow.com/questions/60490974/how-to-define-an-array-of-objects-in-openapi-2-0 + + const primitivePlaceholder = pipe( + items, + O.fromPredicate( + flow((items) => items.type as SchemaType, isSchemaTypePrimitive) + ), + O.map(getSampleEnumValueOrPlaceholder) + ) + + if (O.isSome(primitivePlaceholder)) + return Array.of(primitivePlaceholder.value, primitivePlaceholder.value) + + // If the type is not primitive, it is "array" + // items property is required if type is array + return Array.of( + generateExampleArrayFromOpenAPIV2ItemsObject( + items.items as OpenAPIV2.ItemsObject + ) + ) +} + +const generateRequestBodyExampleFromOpenAPIV2BodySchema = ( + schema: OpenAPIV2.SchemaObject +): RequestBodyExampleType => { + if (schema.example) return schema.example as RequestBodyExampleType + + const primitiveTypeExample = pipe( + schema, + O.fromPredicate( + flow( + getSchemaTypeFromSchemaObject, + O.map(isSchemaTypePrimitive), + O.getOrElseW(() => false) // No schema type found in the schema object, assume non-primitive + ) + ), + O.map(getSampleEnumValueOrPlaceholder) // Use enum or placeholder to populate primitive field + ) + + if (O.isSome(primitiveTypeExample)) return primitiveTypeExample.value + + const arrayTypeExample = pipe( + schema, + O.fromPredicate( + flow( + getSchemaTypeFromSchemaObject, + O.map(isSchemaTypeArray), + O.getOrElseW(() => false) // No schema type found in the schema object, assume type to be different from array + ) + ), + O.map((schema) => schema.items as OpenAPIV2.ItemsObject), + O.map(generateExampleArrayFromOpenAPIV2ItemsObject) + ) + + if (O.isSome(arrayTypeExample)) return arrayTypeExample.value + + return pipe( + schema, + O.fromPredicate( + flow( + getSchemaTypeFromSchemaObject, + O.map(isSchemaTypeObject), + O.getOrElseW(() => false) + ) + ), + O.chain((schema) => + pipe( + schema.properties, + O.fromNullable, + O.map( + (properties) => + Object.entries(properties) as [string, OpenAPIV2.SchemaObject][] + ) + ) + ), + O.getOrElseW(() => [] as [string, OpenAPIV2.SchemaObject][]), + A.reduce( + {} as { [name: string]: RequestBodyExampleType }, + (aggregatedExample, property) => { + const example = generateRequestBodyExampleFromOpenAPIV2BodySchema( + property[1] + ) + aggregatedExample[property[0]] = example + return aggregatedExample + } + ) + ) +} + +export const generateRequestBodyExampleFromOpenAPIV2Body = ( + op: OpenAPIV2.OperationObject +): string => + pipe( + (op.parameters ?? []) as OpenAPIV2.Parameter[], + A.findFirst((param) => param.in === "body"), + O.map( + flow( + (parameter) => parameter.schema, + generateRequestBodyExampleFromOpenAPIV2BodySchema + ) + ), + O.getOrElse(() => "" as RequestBodyExampleType), + (requestBodyExample) => JSON.stringify(requestBodyExample, null, "\t") // Using a tab character mimics standard pretty-print appearance + ) diff --git a/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV3.ts b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV3.ts index b94c9edf3..19432ec3f 100644 --- a/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV3.ts +++ b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV3.ts @@ -3,60 +3,106 @@ import { pipe } from "fp-ts/function" import * as A from "fp-ts/Array" import * as O from "fp-ts/Option" -type SchemaType = OpenAPIV3.ArraySchemaObjectType | OpenAPIV3.NonArraySchemaObjectType +type SchemaType = + | OpenAPIV3.ArraySchemaObjectType + | OpenAPIV3.NonArraySchemaObjectType type PrimitiveSchemaType = Exclude type PrimitiveRequestBodyExampleType = string | number | boolean | null -type RequestBodyExampleType = PrimitiveRequestBodyExampleType | Array | { [name: string]: RequestBodyExampleType } - -const isSchemaTypePrimitive = (schemaType: SchemaType) : schemaType is PrimitiveSchemaType => !["array", "object"].includes(schemaType) +type RequestBodyExampleType = + | PrimitiveRequestBodyExampleType + | Array + | { [name: string]: RequestBodyExampleType } -const getPrimitiveTypePlaceholder = (primitiveType: PrimitiveSchemaType) : PrimitiveRequestBodyExampleType => { - switch(primitiveType) { - case "number": return 0.0 - case "integer": return 0 - case "string": return "string" - case "boolean": return true - } +const isSchemaTypePrimitive = ( + schemaType: SchemaType +): schemaType is PrimitiveSchemaType => + !["array", "object"].includes(schemaType) + +const getPrimitiveTypePlaceholder = ( + primitiveType: PrimitiveSchemaType +): PrimitiveRequestBodyExampleType => { + switch (primitiveType) { + case "number": + return 0.0 + case "integer": + return 0 + case "string": + return "string" + case "boolean": + return true + } } // Use carefully, call only when type is primitive // TODO(agarwal): Use Enum values, if any -const generatePrimitiveRequestBodyExample = (schemaObject: OpenAPIV3.NonArraySchemaObject) : RequestBodyExampleType => - getPrimitiveTypePlaceholder(schemaObject.type as PrimitiveSchemaType) +const generatePrimitiveRequestBodyExample = ( + schemaObject: OpenAPIV3.NonArraySchemaObject +): RequestBodyExampleType => + getPrimitiveTypePlaceholder(schemaObject.type as PrimitiveSchemaType) // Use carefully, call only when type is object -const generateObjectRequestBodyExample = (schemaObject: OpenAPIV3.NonArraySchemaObject) : RequestBodyExampleType => - pipe( - schemaObject.properties, - O.fromNullable, - O.map((properties) => Object.entries(properties) as [string, OpenAPIV3.SchemaObject][]), - O.getOrElseW(() => [] as [string, OpenAPIV3.SchemaObject][]), - A.reduce( - {} as {[name: string]: RequestBodyExampleType}, - (aggregatedExample, property) => { - aggregatedExample[property[0]] = generateRequestBodyExampleFromSchemaObject(property[1]) - return aggregatedExample - } - ) +const generateObjectRequestBodyExample = ( + schemaObject: OpenAPIV3.NonArraySchemaObject +): RequestBodyExampleType => + pipe( + schemaObject.properties, + O.fromNullable, + O.map( + (properties) => + Object.entries(properties) as [string, OpenAPIV3.SchemaObject][] + ), + O.getOrElseW(() => [] as [string, OpenAPIV3.SchemaObject][]), + A.reduce( + {} as { [name: string]: RequestBodyExampleType }, + (aggregatedExample, property) => { + aggregatedExample[property[0]] = + generateRequestBodyExampleFromSchemaObject(property[1]) + return aggregatedExample + } ) + ) -const generateArrayRequestBodyExample = (schemaObject: OpenAPIV3.ArraySchemaObject) : RequestBodyExampleType => - Array.of(generateRequestBodyExampleFromSchemaObject(schemaObject.items as OpenAPIV3.SchemaObject)) +const generateArrayRequestBodyExample = ( + schemaObject: OpenAPIV3.ArraySchemaObject +): RequestBodyExampleType => + Array.of( + generateRequestBodyExampleFromSchemaObject( + schemaObject.items as OpenAPIV3.SchemaObject + ) + ) -const generateRequestBodyExampleFromSchemaObject = (schemaObject: OpenAPIV3.SchemaObject) : RequestBodyExampleType => { - // TODO: Handle schema objects with oneof or anyof - if(schemaObject.example) return schemaObject.example as RequestBodyExampleType - if(!schemaObject.type) return "" - if(isSchemaTypePrimitive(schemaObject.type)) return generatePrimitiveRequestBodyExample(schemaObject as OpenAPIV3.NonArraySchemaObject) - if(schemaObject.type === "object") return generateObjectRequestBodyExample(schemaObject as OpenAPIV3.NonArraySchemaObject) - return generateArrayRequestBodyExample(schemaObject as OpenAPIV3.ArraySchemaObject) +const generateRequestBodyExampleFromSchemaObject = ( + schemaObject: OpenAPIV3.SchemaObject +): RequestBodyExampleType => { + // TODO: Handle schema objects with oneof or anyof + if (schemaObject.example) + return schemaObject.example as RequestBodyExampleType + if (!schemaObject.type) return "" + if (isSchemaTypePrimitive(schemaObject.type)) + return generatePrimitiveRequestBodyExample( + schemaObject as OpenAPIV3.NonArraySchemaObject + ) + if (schemaObject.type === "object") + return generateObjectRequestBodyExample( + schemaObject as OpenAPIV3.NonArraySchemaObject + ) + return generateArrayRequestBodyExample( + schemaObject as OpenAPIV3.ArraySchemaObject + ) } -export const generateRequestBodyExampleFromMediaObject = (mediaObject: OpenAPIV3.MediaTypeObject) : RequestBodyExampleType => { - if(mediaObject.example) return mediaObject.example as RequestBodyExampleType - if(mediaObject.examples) return mediaObject.examples[0] as RequestBodyExampleType - return mediaObject.schema ? generateRequestBodyExampleFromSchemaObject(mediaObject.schema as OpenAPIV3.SchemaObject) : "" -} \ No newline at end of file +export const generateRequestBodyExampleFromMediaObject = ( + mediaObject: OpenAPIV3.MediaTypeObject +): RequestBodyExampleType => { + if (mediaObject.example) return mediaObject.example as RequestBodyExampleType + if (mediaObject.examples) + return mediaObject.examples[0] as RequestBodyExampleType + return mediaObject.schema + ? generateRequestBodyExampleFromSchemaObject( + mediaObject.schema as OpenAPIV3.SchemaObject + ) + : "" +} diff --git a/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV31.ts b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV31.ts index f918d49be..0a71f1d57 100644 --- a/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV31.ts +++ b/packages/hoppscotch-app/helpers/import-export/import/openapi/exampleV31.ts @@ -3,82 +3,133 @@ import { pipe } from "fp-ts/function" import * as O from "fp-ts/Option" import * as A from "fp-ts/Array" -type MixedArraySchemaType = (OpenAPIV31.ArraySchemaObjectType | OpenAPIV31.NonArraySchemaObjectType)[] +type MixedArraySchemaType = ( + | OpenAPIV31.ArraySchemaObjectType + | OpenAPIV31.NonArraySchemaObjectType +)[] -type SchemaType = OpenAPIV31.ArraySchemaObjectType | OpenAPIV31.NonArraySchemaObjectType | MixedArraySchemaType +type SchemaType = + | OpenAPIV31.ArraySchemaObjectType + | OpenAPIV31.NonArraySchemaObjectType + | MixedArraySchemaType -type PrimitiveSchemaType = Exclude +type PrimitiveSchemaType = Exclude< + OpenAPIV31.NonArraySchemaObjectType, + "object" +> type PrimitiveRequestBodyExampleType = string | number | boolean | null -type RequestBodyExampleType = PrimitiveRequestBodyExampleType | Array | { [name: string]: RequestBodyExampleType } +type RequestBodyExampleType = + | PrimitiveRequestBodyExampleType + | Array + | { [name: string]: RequestBodyExampleType } -const isSchemaTypePrimitive = (schemaType: SchemaType) : schemaType is PrimitiveSchemaType => !Array.isArray(schemaType) && !["array", "object"].includes(schemaType) +const isSchemaTypePrimitive = ( + schemaType: SchemaType +): schemaType is PrimitiveSchemaType => + !Array.isArray(schemaType) && !["array", "object"].includes(schemaType) -const getPrimitiveTypePlaceholder = (primitiveType: PrimitiveSchemaType) : PrimitiveRequestBodyExampleType => { - switch(primitiveType) { - case "number": return 0.0 - case "integer": return 0 - case "string": return "string" - case "boolean": return true - } - return null +const getPrimitiveTypePlaceholder = ( + primitiveType: PrimitiveSchemaType +): PrimitiveRequestBodyExampleType => { + switch (primitiveType) { + case "number": + return 0.0 + case "integer": + return 0 + case "string": + return "string" + case "boolean": + return true + } + return null } // Use carefully, the schema type should necessarily be primitive // TODO(agarwal): Use Enum values, if any -const generatePrimitiveRequestBodyExample = (schemaObject: OpenAPIV31.NonArraySchemaObject) : RequestBodyExampleType => - getPrimitiveTypePlaceholder(schemaObject.type as PrimitiveSchemaType) +const generatePrimitiveRequestBodyExample = ( + schemaObject: OpenAPIV31.NonArraySchemaObject +): RequestBodyExampleType => + getPrimitiveTypePlaceholder(schemaObject.type as PrimitiveSchemaType) // Use carefully, the schema type should necessarily be object -const generateObjectRequestBodyExample = (schemaObject: OpenAPIV31.NonArraySchemaObject) : RequestBodyExampleType => - pipe( - schemaObject.properties, - O.fromNullable, - O.map((properties) => Object.entries(properties) as [string, OpenAPIV31.SchemaObject][]), - O.getOrElseW(() => [] as [string, OpenAPIV31.SchemaObject][]), - A.reduce( - {} as {[name: string]: RequestBodyExampleType}, - (aggregatedExample, property) => { - aggregatedExample[property[0]] = generateRequestBodyExampleFromSchemaObject(property[1]) - return aggregatedExample - } - ) +const generateObjectRequestBodyExample = ( + schemaObject: OpenAPIV31.NonArraySchemaObject +): RequestBodyExampleType => + pipe( + schemaObject.properties, + O.fromNullable, + O.map( + (properties) => + Object.entries(properties) as [string, OpenAPIV31.SchemaObject][] + ), + O.getOrElseW(() => [] as [string, OpenAPIV31.SchemaObject][]), + A.reduce( + {} as { [name: string]: RequestBodyExampleType }, + (aggregatedExample, property) => { + aggregatedExample[property[0]] = + generateRequestBodyExampleFromSchemaObject(property[1]) + return aggregatedExample + } ) + ) // Use carefully, the schema type should necessarily be mixed array -const generateMixedArrayRequestBodyEcample = (schemaObject: OpenAPIV31.SchemaObject) : RequestBodyExampleType => - pipe( - schemaObject, - schemaObject => schemaObject.type as MixedArraySchemaType, - A.reduce( - [] as Array, - (aggregatedExample, itemType) => { - // TODO: Figure out how to include non-primitive types as well - if(isSchemaTypePrimitive(itemType)) { - aggregatedExample.push(getPrimitiveTypePlaceholder(itemType)) - } - return aggregatedExample - } - ) +const generateMixedArrayRequestBodyEcample = ( + schemaObject: OpenAPIV31.SchemaObject +): RequestBodyExampleType => + pipe( + schemaObject, + (schemaObject) => schemaObject.type as MixedArraySchemaType, + A.reduce( + [] as Array, + (aggregatedExample, itemType) => { + // TODO: Figure out how to include non-primitive types as well + if (isSchemaTypePrimitive(itemType)) { + aggregatedExample.push(getPrimitiveTypePlaceholder(itemType)) + } + return aggregatedExample + } ) + ) -const generateArrayRequestBodyExample = (schemaObject: OpenAPIV31.ArraySchemaObject) : RequestBodyExampleType => - Array.of(generateRequestBodyExampleFromSchemaObject(schemaObject.items as OpenAPIV31.SchemaObject)) +const generateArrayRequestBodyExample = ( + schemaObject: OpenAPIV31.ArraySchemaObject +): RequestBodyExampleType => + Array.of( + generateRequestBodyExampleFromSchemaObject( + schemaObject.items as OpenAPIV31.SchemaObject + ) + ) -const generateRequestBodyExampleFromSchemaObject = (schemaObject: OpenAPIV31.SchemaObject) : RequestBodyExampleType => { - // TODO: Handle schema objects with oneof or anyof - if(schemaObject.example) return schemaObject.example as RequestBodyExampleType - if(schemaObject.examples) return schemaObject.examples[0] as RequestBodyExampleType - if(!schemaObject.type) return "" - if(isSchemaTypePrimitive(schemaObject.type)) return generatePrimitiveRequestBodyExample(schemaObject as OpenAPIV31.NonArraySchemaObject) - if(schemaObject.type === "object") return generateObjectRequestBodyExample(schemaObject) - if(schemaObject.type === "array") return generateArrayRequestBodyExample(schemaObject) - return generateMixedArrayRequestBodyEcample(schemaObject) +const generateRequestBodyExampleFromSchemaObject = ( + schemaObject: OpenAPIV31.SchemaObject +): RequestBodyExampleType => { + // TODO: Handle schema objects with oneof or anyof + if (schemaObject.example) + return schemaObject.example as RequestBodyExampleType + if (schemaObject.examples) + return schemaObject.examples[0] as RequestBodyExampleType + if (!schemaObject.type) return "" + if (isSchemaTypePrimitive(schemaObject.type)) + return generatePrimitiveRequestBodyExample( + schemaObject as OpenAPIV31.NonArraySchemaObject + ) + if (schemaObject.type === "object") + return generateObjectRequestBodyExample(schemaObject) + if (schemaObject.type === "array") + return generateArrayRequestBodyExample(schemaObject) + return generateMixedArrayRequestBodyEcample(schemaObject) } -export const generateRequestBodyExampleFromMediaObject = (mediaObject: OpenAPIV31.MediaTypeObject) : RequestBodyExampleType => { - if(mediaObject.example) return mediaObject.example as RequestBodyExampleType - if(mediaObject.examples) return mediaObject.examples[0] as RequestBodyExampleType - return mediaObject.schema ? generateRequestBodyExampleFromSchemaObject(mediaObject.schema) : "" -} \ No newline at end of file +export const generateRequestBodyExampleFromMediaObject = ( + mediaObject: OpenAPIV31.MediaTypeObject +): RequestBodyExampleType => { + if (mediaObject.example) return mediaObject.example as RequestBodyExampleType + if (mediaObject.examples) + return mediaObject.examples[0] as RequestBodyExampleType + return mediaObject.schema + ? generateRequestBodyExampleFromSchemaObject(mediaObject.schema) + : "" +} diff --git a/packages/hoppscotch-app/helpers/import-export/import/openapi/index.ts b/packages/hoppscotch-app/helpers/import-export/import/openapi/index.ts index 328ae3414..1ce452edd 100644 --- a/packages/hoppscotch-app/helpers/import-export/import/openapi/index.ts +++ b/packages/hoppscotch-app/helpers/import-export/import/openapi/index.ts @@ -28,6 +28,7 @@ import { step } from "../../steps" import { defineImporter, IMPORTER_INVALID_FILE_FORMAT } from "../" import { generateRequestBodyExampleFromMediaObject as generateExampleV31 } from "./exampleV31" import { generateRequestBodyExampleFromMediaObject as generateExampleV3 } from "./exampleV3" +import { generateRequestBodyExampleFromOpenAPIV2Body } from "./exampleV2" const OPENAPI_DEREF_ERROR = "openapi/deref_error" as const @@ -183,190 +184,6 @@ const parseOpenAPIV3BodyFormData = ( } } -type PrimitiveSchemaType = "string" | "integer" | "number" | "boolean" - -type SchemaType = "array" | "object" | PrimitiveSchemaType - -type PrimitiveRequestBodyExampleType = number | string | boolean - -type RequestBodyExampleType = - | { [name: string]: RequestBodyExampleType } - | Array - | PrimitiveRequestBodyExampleType - -const getPrimitiveTypePlaceholder = ( - schemaType: PrimitiveSchemaType -): PrimitiveRequestBodyExampleType => { - switch (schemaType) { - case "string": - return "string" - case "integer": - case "number": - return 1 - case "boolean": - return true - } -} - -const getSchemaTypeFromSchemaObject = ( - schema: OpenAPIV2.SchemaObject -): O.Option => - pipe( - schema.type, - O.fromNullable, - O.map( - (schemaType) => - (Array.isArray(schemaType) ? schemaType[0] : schemaType) as SchemaType - ) - ) - -const isSchemaTypePrimitive = ( - schemaType: string -): schemaType is PrimitiveSchemaType => - ["string", "integer", "number", "boolean"].includes(schemaType) - -const isSchemaTypeArray = (schemaType: string): schemaType is "array" => - schemaType === "array" - -const isSchemaTypeObject = (schemaType: string): schemaType is "object" => - schemaType === "object" - -const getSampleEnumValueOrPlaceholder = ( - schema: OpenAPIV2.SchemaObject -): RequestBodyExampleType => { - const enumValue = pipe( - schema.enum, - O.fromNullable, - O.map((enums) => enums[0] as RequestBodyExampleType) - ) - - if (O.isSome(enumValue)) return enumValue.value - - return pipe( - schema, - getSchemaTypeFromSchemaObject, - O.filter(isSchemaTypePrimitive), - O.map(getPrimitiveTypePlaceholder), - O.getOrElseW(() => "") - ) -} - -const generateExampleArrayFromOpenAPIV2ItemsObject = ( - items: OpenAPIV2.ItemsObject -): RequestBodyExampleType => { - // ItemsObject can not hold type "object" - // https://swagger.io/specification/v2/#itemsObject - - // TODO : Handle array of objects - // https://stackoverflow.com/questions/60490974/how-to-define-an-array-of-objects-in-openapi-2-0 - - const primitivePlaceholder = pipe( - items, - O.fromPredicate( - flow((items) => items.type as SchemaType, isSchemaTypePrimitive) - ), - O.map(getSampleEnumValueOrPlaceholder) - ) - - if (O.isSome(primitivePlaceholder)) - return Array.of(primitivePlaceholder.value, primitivePlaceholder.value) - - // If the type is not primitive, it is "array" - // items property is required if type is array - return Array.of( - generateExampleArrayFromOpenAPIV2ItemsObject( - items.items as OpenAPIV2.ItemsObject - ) - ) -} - -const generateRequestBodyExampleFromOpenAPIV2BodySchema = ( - schema: OpenAPIV2.SchemaObject -): RequestBodyExampleType => { - if (schema.example) return schema.example as RequestBodyExampleType - - const primitiveTypeExample = pipe( - schema, - O.fromPredicate( - flow( - getSchemaTypeFromSchemaObject, - O.map(isSchemaTypePrimitive), - O.getOrElseW(() => false) // No schema type found in the schema object, assume non-primitive - ) - ), - O.map(getSampleEnumValueOrPlaceholder) // Use enum or placeholder to populate primitive field - ) - - if (O.isSome(primitiveTypeExample)) return primitiveTypeExample.value - - const arrayTypeExample = pipe( - schema, - O.fromPredicate( - flow( - getSchemaTypeFromSchemaObject, - O.map(isSchemaTypeArray), - O.getOrElseW(() => false) // No schema type found in the schema object, assume type to be different from array - ) - ), - O.map((schema) => schema.items as OpenAPIV2.ItemsObject), - O.map(generateExampleArrayFromOpenAPIV2ItemsObject) - ) - - if (O.isSome(arrayTypeExample)) return arrayTypeExample.value - - return pipe( - schema, - O.fromPredicate( - flow( - getSchemaTypeFromSchemaObject, - O.map(isSchemaTypeObject), - O.getOrElseW(() => false) - ) - ), - O.chain((schema) => - pipe( - schema.properties, - O.fromNullable, - O.map( - (properties) => - Object.entries(properties) as [string, OpenAPIV2.SchemaObject][] - ) - ) - ), - O.getOrElseW(() => [] as [string, OpenAPIV2.SchemaObject][]), - A.reduce( - {} as { [name: string]: RequestBodyExampleType }, - (aggregatedExample, property) => { - const example = generateRequestBodyExampleFromOpenAPIV2BodySchema( - property[1] - ) - aggregatedExample[property[0]] = example - return aggregatedExample - } - ) - ) -} - -const getSchemaFromOpenAPIV2Parameter = ( - parameter: OpenAPIV2.Parameter -): OpenAPIV2.SchemaObject => parameter.schema - -const generateRequestBodyExampleFromOpenAPIV2Body = ( - op: OpenAPIV2.OperationObject -): string => - pipe( - (op.parameters ?? []) as OpenAPIV2.Parameter[], - A.findFirst((param) => param.in === "body"), - O.map( - flow( - getSchemaFromOpenAPIV2Parameter, - generateRequestBodyExampleFromOpenAPIV2BodySchema - ) - ), - O.getOrElse(() => "" as RequestBodyExampleType), - (requestBodyExample) => JSON.stringify(requestBodyExample, null, "\t") // Using a tab character mimics standard pretty-print appearance - ) - const parseOpenAPIV3Body = ( op: OpenAPIV3.OperationObject | OpenAPIV31.OperationObject, isV31Request: boolean