UNPKG

@kubb/oas

Version:
300 lines (294 loc) • 9.51 kB
'use strict'; var utils = require('oas/utils'); var types = require('oas/types'); var remeda = require('remeda'); var openapiCore = require('@redocly/openapi-core'); var OASNormalize = require('oas-normalize'); var swagger2openapi = require('swagger2openapi'); var BaseOas = require('oas'); var jsonpointer = require('jsonpointer'); function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } var OASNormalize__default = /*#__PURE__*/_interopDefault(OASNormalize); var swagger2openapi__default = /*#__PURE__*/_interopDefault(swagger2openapi); var BaseOas__default = /*#__PURE__*/_interopDefault(BaseOas); var jsonpointer__default = /*#__PURE__*/_interopDefault(jsonpointer); // src/types.ts var HttpMethods = { GET: "get", POST: "post", PUT: "put", PATCH: "patch", DELETE: "delete", HEAD: "head", OPTIONS: "options", TRACE: "trace" }; var Oas = class extends BaseOas__default.default { #options = {}; document = void 0; constructor({ oas, user }, options = {}) { if (typeof oas === "string") { oas = JSON.parse(oas); } super(oas, user); this.document = oas; this.#options = options; } get($ref) { const origRef = $ref; $ref = $ref.trim(); if ($ref === "") { return false; } if ($ref.startsWith("#")) { $ref = globalThis.decodeURIComponent($ref.substring(1)); } else { return null; } const current = jsonpointer__default.default.get(this.api, $ref); if (!current) { throw new Error(`Could not find a definition for ${origRef}.`); } return current; } set($ref, value) { $ref = $ref.trim(); if ($ref === "") { return false; } if ($ref.startsWith("#")) { $ref = globalThis.decodeURIComponent($ref.substring(1)); jsonpointer__default.default.set(this.api, $ref, value); } } resolveDiscriminators() { const schemas = this.api.components?.schemas || {}; Object.entries(schemas).forEach(([_key, schemaObject]) => { if ("discriminator" in schemaObject && typeof schemaObject.discriminator !== "string") { const { mapping = {}, propertyName } = schemaObject.discriminator || {}; if (!schemaObject.properties?.[propertyName]) { schemaObject.properties = {}; } schemaObject.properties[propertyName] = { ...schemaObject.properties[propertyName], enum: Object.keys(mapping) }; Object.entries(mapping).forEach(([mappingKey, mappingValue]) => { if (mappingValue) { const childSchema = this.get(mappingValue); if (!childSchema.properties) { childSchema.properties = {}; } const property = childSchema.properties[propertyName]; if (childSchema.properties) { childSchema.properties[propertyName] = { ...childSchema.properties ? childSchema.properties[propertyName] : {}, enum: [...property?.enum?.filter((value) => value !== mappingKey) ?? [], mappingKey] }; childSchema.required = [...childSchema.required ?? [], propertyName]; this.set(mappingValue, childSchema); } } }); } }); } dereferenceWithRef(schema) { if (isReference(schema)) { return { ...schema, ...this.get(schema.$ref), $ref: schema.$ref }; } return schema; } /** * Oas does not have a getResponseBody(contentType) */ #getResponseBodyFactory(responseBody) { function hasResponseBody(res = responseBody) { return !!res; } return (contentType) => { if (!hasResponseBody(responseBody)) { return false; } if (isReference(responseBody)) { return false; } if (!responseBody.content) { return false; } if (contentType) { if (!(contentType in responseBody.content)) { return false; } return responseBody.content[contentType]; } let availablecontentType = void 0; const contentTypes = Object.keys(responseBody.content); contentTypes.forEach((mt) => { if (!availablecontentType && utils.matchesMimeType.json(mt)) { availablecontentType = mt; } }); if (!availablecontentType) { contentTypes.forEach((mt) => { if (!availablecontentType) { availablecontentType = mt; } }); } if (availablecontentType) { return [availablecontentType, responseBody.content[availablecontentType], ...responseBody.description ? [responseBody.description] : []]; } return false; }; } getResponseSchema(operation, statusCode) { if (operation.schema.responses) { Object.keys(operation.schema.responses).forEach((key) => { const schema2 = operation.schema.responses[key]; const $ref = isReference(schema2) ? schema2.$ref : void 0; if (schema2 && $ref) { operation.schema.responses[key] = this.get($ref); } }); } const getResponseBody = this.#getResponseBodyFactory(operation.getResponseByStatusCode(statusCode)); const { contentType } = this.#options; const responseBody = getResponseBody(contentType); if (responseBody === false) { return {}; } const schema = Array.isArray(responseBody) ? responseBody[1].schema : responseBody.schema; if (!schema) { return {}; } return this.dereferenceWithRef(schema); } getRequestSchema(operation) { const { contentType } = this.#options; if (operation.schema.requestBody) { operation.schema.requestBody = this.dereferenceWithRef(operation.schema.requestBody); } const requestBody = operation.getRequestBody(contentType); if (requestBody === false) { return void 0; } const schema = Array.isArray(requestBody) ? requestBody[1].schema : requestBody.schema; if (!schema) { return void 0; } return this.dereferenceWithRef(schema); } getParametersSchema(operation, inKey) { const { contentType = operation.getContentType() } = this.#options; const params = operation.getParameters().map((schema) => { return this.dereferenceWithRef(schema); }).filter((v) => v.in === inKey); if (!params.length) { return null; } return params.reduce( (schema, pathParameters) => { const property = pathParameters.content?.[contentType]?.schema ?? pathParameters.schema; const required = [...schema.required || [], pathParameters.required ? pathParameters.name : void 0].filter(Boolean); return { ...schema, description: schema.description, deprecated: schema.deprecated, example: schema.example, required, properties: { ...schema.properties, [pathParameters.name]: { description: pathParameters.description, ...property } } }; }, { type: "object", required: [], properties: {} } ); } async valdiate() { const oasNormalize = new OASNormalize__default.default(this.api, { enablePaths: true, colorizeErrors: true }); await oasNormalize.validate({ parser: { validate: { errors: { colorize: true } } } }); } }; // src/utils.ts function isOpenApiV2Document(doc) { return doc && remeda.isPlainObject(doc) && !("openapi" in doc); } function isOpenApiV3_1Document(doc) { return doc && remeda.isPlainObject(doc) && "openapi" in doc && doc.openapi.startsWith("3.1"); } function isParameterObject(obj) { return obj && "in" in obj; } function isNullable(schema) { return schema?.nullable ?? schema?.["x-nullable"] ?? false; } function isReference(obj) { return !!obj && types.isRef(obj); } function isRequired(schema) { if (!schema) { return false; } return Array.isArray(schema.required) ? !!schema.required?.length : !!schema.required; } function isOptional(schema) { return !isRequired(schema); } async function parse(pathOrApi, oasClass = Oas) { if (typeof pathOrApi === "string") { const config = await openapiCore.loadConfig(); const bundleResults = await openapiCore.bundle({ ref: pathOrApi, config, base: pathOrApi }); return parse(bundleResults.bundle.parsed); } const oasNormalize = new OASNormalize__default.default(pathOrApi, { enablePaths: true, colorizeErrors: true }); const document = await oasNormalize.load(); if (isOpenApiV2Document(document)) { const { openapi } = await swagger2openapi__default.default.convertObj(document, { anchors: true }); return new oasClass({ oas: openapi }); } return new oasClass({ oas: document }); } Object.defineProperty(exports, "findSchemaDefinition", { enumerable: true, get: function () { return utils.findSchemaDefinition; } }); Object.defineProperty(exports, "matchesMimeType", { enumerable: true, get: function () { return utils.matchesMimeType; } }); exports.HttpMethods = HttpMethods; exports.Oas = Oas; exports.isNullable = isNullable; exports.isOpenApiV3_1Document = isOpenApiV3_1Document; exports.isOptional = isOptional; exports.isParameterObject = isParameterObject; exports.isReference = isReference; exports.isRequired = isRequired; exports.parse = parse; //# sourceMappingURL=index.cjs.map //# sourceMappingURL=index.cjs.map