UNPKG

@autorest/openapi-to-typespec

Version:

Autorest plugin to scaffold a Typespec definition from an OpenAPI document

107 lines (93 loc) 3.71 kB
import { ArraySchema, getAllProperties, isObjectSchema, ObjectSchema, Operation, Schema, SchemaResponse, } from "@autorest/codemodel"; import { isArmIdSchema, isArraySchema, isDictionarySchema, isResponseSchema, isStringSchema } from "../utils/schemas"; // Common-type v2 resource doesn't have systemData export function isResource(schema: ObjectSchema): boolean { let idPropertyFound = false; let typePropertyFound = false; let namePropertyFound = false; for (const property of getAllProperties(schema)) { if (property.flattenedNames) continue; if (property.serializedName === "id" && (isStringSchema(property.schema) || isArmIdSchema(property.schema))) { idPropertyFound = true; } else if (property.serializedName === "type" && isStringSchema(property.schema)) { typePropertyFound = true; } else if (property.serializedName === "name" && isStringSchema(property.schema)) { namePropertyFound = true; } } return idPropertyFound && typePropertyFound && namePropertyFound; } export function isTrackedResource(schema: ObjectSchema): [isTrackedResource: boolean, isOptionalLocation: boolean] { if (!isResource(schema)) return [false, false]; let isLocationFound = false; let isOptionalLocation = false; let isTagsFound = false; for (const property of getAllProperties(schema)) { if (property.flattenedNames) continue; if (property.serializedName === "location" && isStringSchema(property.schema)) { isLocationFound = true; isOptionalLocation = property.required !== true; } else if (property.serializedName === "tags" && isDictionarySchema(property.schema)) { isTagsFound = true; } } return [isLocationFound && isTagsFound, isLocationFound && isTagsFound && isOptionalLocation]; } export function getPagingItemType(operation: Operation, markPaging: boolean = false): string | undefined { const response = operation.responses?.find((r) => isResponseSchema(r)); if (response === undefined) return undefined; let itemName = "value"; if (operation.extensions?.["x-ms-pageable"]?.itemName) { itemName = operation.extensions?.["x-ms-pageable"]?.itemName; } const schemaResponse = response as SchemaResponse; if (isArraySchema(schemaResponse.schema)) { return schemaResponse.schema.elementType.language.default.name; } if (isObjectSchema(schemaResponse.schema)) { const responseSchema = schemaResponse.schema.properties?.find( (p) => p.serializedName === itemName && isArraySchema(p.schema), ); if (!responseSchema) return undefined; markPaging && markPagination(schemaResponse.schema, operation); return (responseSchema.schema as ArraySchema).elementType.language.default.name; } return undefined; } function markPagination(schema: Schema, operation: Operation) { schema.language.default.paging = { ...schema.language.default.paging, isPageable: true, }; if (!isObjectSchema(schema)) return; let itemName = "value"; if (operation.extensions?.["x-ms-pageable"]?.itemName) { itemName = operation.extensions?.["x-ms-pageable"]?.itemName; } let nextLinkName = null; if (operation.extensions?.["x-ms-pageable"]?.nextLinkName) { nextLinkName = operation.extensions?.["x-ms-pageable"]?.nextLinkName; } for (const property of schema.properties ?? []) { if (property.serializedName === nextLinkName) { property.language.default.paging = { ...property.language.default.paging, isNextLink: true, }; } if (property.serializedName === itemName) { property.language.default.paging = { ...property.language.default.paging, isValue: true, }; } } }