UNPKG

oas

Version:

Comprehensive tooling for working with OpenAPI definitions

1,253 lines (1,211 loc) 44.1 kB
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; } var _chunkTDI4MZLIcjs = require('./chunk-TDI4MZLI.cjs'); var _chunkQ2TBKI3Ocjs = require('./chunk-Q2TBKI3O.cjs'); var _chunkXS7VDTTTcjs = require('./chunk-XS7VDTTT.cjs'); var _chunkVSXG73AZcjs = require('./chunk-VSXG73AZ.cjs'); // src/operation/lib/dedupe-common-parameters.ts function dedupeCommonParameters(parameters, commonParameters) { return commonParameters.filter((param) => { return !parameters.find((param2) => { if (param.name && param2.name) { return param.name === param2.name && param.in === param2.in; } else if (_chunkVSXG73AZcjs.isRef.call(void 0, param) && _chunkVSXG73AZcjs.isRef.call(void 0, param2)) { return param.$ref === param2.$ref; } return false; }); }); } // src/samples/index.ts var _jsonschemamergeallof = require('json-schema-merge-allof'); var _jsonschemamergeallof2 = _interopRequireDefault(_jsonschemamergeallof); var _memoizee = require('memoizee'); var _memoizee2 = _interopRequireDefault(_memoizee); // src/samples/utils.ts function usesPolymorphism(schema) { if (schema.oneOf) { return "oneOf"; } else if (schema.anyOf) { return "anyOf"; } else if (schema.allOf) { return "allOf"; } return false; } function objectify(thing) { if (!_chunkQ2TBKI3Ocjs.isObject.call(void 0, thing)) { return {}; } return thing; } function normalizeArray(arr) { if (Array.isArray(arr)) { return arr; } return [arr]; } function isFunc(thing) { return typeof thing === "function"; } function deeplyStripKey(input, keyToStrip, predicate = (obj, key) => true) { if (typeof input !== "object" || Array.isArray(input) || input === null || !keyToStrip) { return input; } const obj = { ...input }; Object.keys(obj).forEach((k) => { if (k === keyToStrip && predicate(obj[k], k)) { delete obj[k]; return; } obj[k] = deeplyStripKey(obj[k], keyToStrip, predicate); }); return obj; } // src/samples/index.ts var sampleDefaults = (genericSample) => { return (schema) => typeof schema.default === typeof genericSample ? schema.default : genericSample; }; var primitives = { string: sampleDefaults("string"), string_email: sampleDefaults("user@example.com"), "string_date-time": sampleDefaults((/* @__PURE__ */ new Date()).toISOString()), string_date: sampleDefaults((/* @__PURE__ */ new Date()).toISOString().substring(0, 10)), "string_YYYY-MM-DD": sampleDefaults((/* @__PURE__ */ new Date()).toISOString().substring(0, 10)), string_uuid: sampleDefaults("3fa85f64-5717-4562-b3fc-2c963f66afa6"), string_hostname: sampleDefaults("example.com"), string_ipv4: sampleDefaults("198.51.100.42"), string_ipv6: sampleDefaults("2001:0db8:5b96:0000:0000:426f:8e17:642a"), number: sampleDefaults(0), number_float: sampleDefaults(0), integer: sampleDefaults(0), boolean: sampleDefaults(true) }; var primitive = (schema) => { schema = objectify(schema); const { format } = schema; let { type } = schema; if (type === "null") { return null; } else if (Array.isArray(type)) { if (type.length === 1) { type = type[0]; } else { if (type.includes("null")) { type = type.filter((t) => t !== "null"); } type = type.shift(); } } const fn = primitives[`${type}_${format}`] || primitives[type]; if (isFunc(fn)) { return fn(schema); } return `Unknown Type: ${schema.type}`; }; function sampleFromSchema(schema, opts = {}) { const objectifySchema = objectify(schema); let { type } = objectifySchema; const hasPolymorphism = usesPolymorphism(objectifySchema); if (hasPolymorphism === "allOf") { try { return sampleFromSchema( _jsonschemamergeallof2.default.call(void 0, objectifySchema, { resolvers: { // Ignore any unrecognized OAS-specific keywords that might be present on the schema // (like `xml`). defaultResolver: _jsonschemamergeallof2.default.options.resolvers.title } }), opts ); } catch (error) { return void 0; } } else if (hasPolymorphism) { const samples = objectifySchema[hasPolymorphism].map((s) => { return sampleFromSchema(s, opts); }); if (samples.length === 1) { return samples[0]; } else if (samples.some((s) => s === null)) { return samples.find((s) => s !== null); } return samples[0]; } const { example, additionalProperties, properties, items } = objectifySchema; const { includeReadOnly, includeWriteOnly } = opts; if (example !== void 0) { return deeplyStripKey(example, "$$ref", (val) => { return typeof val === "string" && val.indexOf("#") > -1; }); } if (!type) { if (properties || additionalProperties) { type = "object"; } else if (items) { type = "array"; } else { return void 0; } } if (type === "object" || Array.isArray(type) && type.includes("object")) { const props = objectify(properties); const obj = {}; for (const name in props) { if (props[name] && props[name].deprecated) { continue; } if (props[name] && props[name].readOnly && !includeReadOnly) { continue; } if (props[name] && props[name].writeOnly && !includeWriteOnly) { continue; } if (_optionalChain([props, 'access', _2 => _2[name], 'access', _3 => _3.examples, 'optionalAccess', _4 => _4.length])) { obj[name] = props[name].examples[0]; continue; } obj[name] = sampleFromSchema(props[name], opts); } if (additionalProperties === true) { obj.additionalProp = {}; } else if (additionalProperties) { const additionalProps = objectify(additionalProperties); const additionalPropVal = sampleFromSchema(additionalProps, opts); obj.additionalProp = additionalPropVal; } return obj; } if (type === "array" || Array.isArray(type) && type.includes("array")) { if (typeof items === "undefined") { return []; } if (Array.isArray(items.anyOf)) { return items.anyOf.map((i) => sampleFromSchema(i, opts)); } if (Array.isArray(items.oneOf)) { return items.oneOf.map((i) => sampleFromSchema(i, opts)); } return [sampleFromSchema(items, opts)]; } if (schema.enum) { if (schema.default) { return schema.default; } return normalizeArray(schema.enum)[0]; } if (type === "file") { return void 0; } return primitive(schema); } var memo = _memoizee2.default.call(void 0, sampleFromSchema); var samples_default = memo; // src/operation/lib/get-mediatype-examples.ts function getMediaTypeExamples(mediaType, mediaTypeObject, opts = {}) { if (mediaTypeObject.example) { return [ { value: mediaTypeObject.example } ]; } else if (mediaTypeObject.examples) { const { examples } = mediaTypeObject; const multipleExamples = Object.keys(examples).map((key) => { let summary = key; let description; let example = examples[key]; if (example !== null && typeof example === "object") { if ("summary" in example) { summary = example.summary; } if ("description" in example) { description = example.description; } if ("value" in example) { if (example.value !== null && typeof example.value === "object" && "$ref" in example.value) { return false; } example = example.value; } } const ret = { summary, title: key, value: example }; if (description) { ret.description = description; } return ret; }).filter(Boolean); if (multipleExamples.length) { return multipleExamples; } } if (mediaTypeObject.schema) { if (!_chunkQ2TBKI3Ocjs.matches_mimetype_default.xml(mediaType)) { return [ { // eslint-disable-next-line try-catch-failsafe/json-parse value: samples_default(JSON.parse(JSON.stringify(mediaTypeObject.schema)), opts) } ]; } } return []; } // src/operation/lib/get-response-examples.ts function getResponseExamples(operation) { return Object.keys(operation.responses || {}).map((status) => { const response = operation.responses[status]; let onlyHeaders = false; if (_chunkVSXG73AZcjs.isRef.call(void 0, response)) { return false; } const mediaTypes = {}; (response.content ? Object.keys(response.content) : []).forEach((mediaType) => { if (!mediaType) return; const mediaTypeObject = response.content[mediaType]; const examples = getMediaTypeExamples(mediaType, mediaTypeObject, { includeReadOnly: true, includeWriteOnly: false }); if (examples) { mediaTypes[mediaType] = examples; } }); if (response.headers && Object.keys(response.headers).length && !Object.keys(mediaTypes).length) { mediaTypes["*/*"] = []; onlyHeaders = true; } if (!Object.keys(mediaTypes).length) { return false; } return { status, mediaTypes, ...onlyHeaders ? { onlyHeaders } : {} }; }).filter(Boolean); } // src/operation/lib/get-callback-examples.ts function getCallbackExamples(operation) { const ret = []; return ret.concat( ...Object.keys(operation.callbacks || {}).map((identifier) => { const callback = operation.callbacks[identifier]; return [].concat( ...Object.keys(callback).map((expression) => { return Object.keys(callback[expression]).map((method) => { const pathItem = callback[expression]; const example = getResponseExamples(pathItem[method]); if (example.length === 0) return false; return { identifier, expression, method, example }; }); }) ).filter(Boolean); }) ); } // src/operation/lib/get-example-groups.ts var noCorrespondingResponseKey = "NoCorrespondingResponseForCustomCodeSample"; function addMatchingResponseExamples(groups, operation) { operation.getResponseExamples().forEach((example) => { Object.entries(example.mediaTypes || {}).forEach(([mediaType, mediaTypeExamples]) => { mediaTypeExamples.forEach((mediaTypeExample) => { if (mediaTypeExample.title && Object.keys(groups).includes(mediaTypeExample.title)) { groups[mediaTypeExample.title].response = { mediaType, mediaTypeExample, status: example.status }; if (!groups[mediaTypeExample.title].name) { groups[mediaTypeExample.title].name = mediaTypeExample.summary; } } }); }); }); } function getDefaultName(sample, count) { return sample.name && sample.name.length > 0 ? sample.name : `Default${count[sample.language] > 1 ? ` #${count[sample.language]}` : ""}`; } function getExampleGroups(operation) { const namelessCodeSampleCounts = {}; const groups = {}; const codeSamples = _chunkXS7VDTTTcjs.getExtension.call(void 0, "code-samples", operation.api, operation); _optionalChain([codeSamples, 'optionalAccess', _5 => _5.forEach, 'call', _6 => _6((sample, i) => { if (namelessCodeSampleCounts[sample.language]) { namelessCodeSampleCounts[sample.language] += 1; } else { namelessCodeSampleCounts[sample.language] = 1; } const name = getDefaultName(sample, namelessCodeSampleCounts); if (_optionalChain([groups, 'access', _7 => _7[sample.correspondingExample], 'optionalAccess', _8 => _8.customCodeSamples, 'optionalAccess', _9 => _9.length])) { groups[sample.correspondingExample].customCodeSamples.push({ ...sample, name, originalIndex: i }); } else if (sample.correspondingExample) { groups[sample.correspondingExample] = { name, customCodeSamples: [{ ...sample, name, originalIndex: i }] }; } else if (_optionalChain([groups, 'access', _10 => _10[noCorrespondingResponseKey], 'optionalAccess', _11 => _11.customCodeSamples, 'optionalAccess', _12 => _12.length])) { groups[noCorrespondingResponseKey].customCodeSamples.push({ ...sample, name, originalIndex: i }); } else { groups[noCorrespondingResponseKey] = { name, customCodeSamples: [{ ...sample, name, originalIndex: i }] }; } })]); if (Object.keys(groups).length) { addMatchingResponseExamples(groups, operation); return groups; } operation.getParameters().forEach((param) => { Object.entries(param.examples || {}).forEach(([exampleKey, paramExample]) => { groups[exampleKey] = { ...groups[exampleKey], name: _optionalChain([groups, 'access', _13 => _13[exampleKey], 'optionalAccess', _14 => _14.name]) || paramExample.summary, request: { ..._optionalChain([groups, 'access', _15 => _15[exampleKey], 'optionalAccess', _16 => _16.request]), [param.in]: { ..._optionalChain([groups, 'access', _17 => _17[exampleKey], 'optionalAccess', _18 => _18.request, 'optionalAccess', _19 => _19[param.in]]), [param.name]: paramExample.value } } }; }); }); operation.getRequestBodyExamples().forEach((requestExample) => { requestExample.examples.forEach((mediaTypeExample) => { if (mediaTypeExample.title) { const mediaType = requestExample.mediaType === "application/x-www-form-urlencoded" ? "formData" : "body"; groups[mediaTypeExample.title] = { ...groups[mediaTypeExample.title], name: _optionalChain([groups, 'access', _20 => _20[mediaTypeExample.title], 'optionalAccess', _21 => _21.name]) || mediaTypeExample.summary, request: { ..._optionalChain([groups, 'access', _22 => _22[mediaTypeExample.title], 'optionalAccess', _23 => _23.request]), [mediaType]: mediaTypeExample.value } }; } }); }); if (Object.keys(groups).length) { addMatchingResponseExamples(groups, operation); } Object.entries(groups).forEach(([groupId, group]) => { if (group.request && !group.response) { delete groups[groupId]; } }); return groups; } // src/operation/lib/get-requestbody-examples.ts function getRequestBodyExamples(operation) { const requestBody = operation.requestBody; if (!requestBody || !requestBody.content) { return []; } return Object.keys(requestBody.content || {}).map((mediaType) => { const mediaTypeObject = requestBody.content[mediaType]; const examples = getMediaTypeExamples(mediaType, mediaTypeObject, { includeReadOnly: false, includeWriteOnly: true }); if (!examples.length) { return false; } return { mediaType, examples }; }).filter((x) => x !== false); } // src/operation/lib/get-response-as-json-schema.ts var isJSON = _chunkQ2TBKI3Ocjs.matches_mimetype_default.json; function buildHeadersSchema(response, opts) { const headers = response.headers; const headersSchema = { type: "object", properties: {} }; Object.keys(headers).forEach((key) => { if (headers[key] && headers[key].schema) { const header = headers[key]; headersSchema.properties[key] = _chunkQ2TBKI3Ocjs.toJSONSchema.call(void 0, header.schema, { addEnumsToDescriptions: true, transformer: opts.transformer }); if (header.description) { headersSchema.properties[key].description = header.description; } } }); const headersWrapper = { schema: headersSchema, type: "object", label: "Headers" }; if (response.description && headersWrapper.schema) { headersWrapper.description = response.description; } return headersWrapper; } function getResponseAsJSONSchema(operation, api, statusCode, opts) { const response = operation.getResponseByStatusCode(statusCode); const jsonSchema = []; if (!response) { return null; } let hasCircularRefs = false; let hasDiscriminatorMappingRefs = false; function refLogger(ref, type) { if (type === "ref") { hasCircularRefs = true; } else { hasDiscriminatorMappingRefs = true; } } function getPreferredSchema(content) { if (!content) { return null; } const contentTypes = Object.keys(content); if (!contentTypes.length) { return null; } for (let i = 0; i < contentTypes.length; i++) { if (isJSON(contentTypes[i])) { return _chunkQ2TBKI3Ocjs.toJSONSchema.call(void 0, _chunkQ2TBKI3Ocjs.cloneObject.call(void 0, content[contentTypes[i]].schema), { addEnumsToDescriptions: true, refLogger, transformer: opts.transformer }); } } const contentType = contentTypes.shift(); return _chunkQ2TBKI3Ocjs.toJSONSchema.call(void 0, _chunkQ2TBKI3Ocjs.cloneObject.call(void 0, content[contentType].schema), { addEnumsToDescriptions: true, refLogger, transformer: opts.transformer }); } const foundSchema = getPreferredSchema(response.content); if (foundSchema) { const schema = _chunkQ2TBKI3Ocjs.cloneObject.call(void 0, foundSchema); const schemaWrapper = { // If there's no `type` then the root schema is a circular `$ref` that we likely won't be // able to render so instead of generating a JSON Schema with an `undefined` type we should // default to `string` so there's at least *something* the end-user can interact with. type: foundSchema.type || "string", schema: _chunkQ2TBKI3Ocjs.isPrimitive.call(void 0, schema) ? schema : { ...schema, $schema: _chunkQ2TBKI3Ocjs.getSchemaVersionString.call(void 0, schema, api) }, label: "Response body" }; if (response.description && schemaWrapper.schema) { schemaWrapper.description = response.description; } if (api.components && schemaWrapper.schema) { if (hasCircularRefs || hasDiscriminatorMappingRefs && opts.includeDiscriminatorMappingRefs) { schemaWrapper.schema.components = api.components; } } jsonSchema.push(schemaWrapper); } if (response.headers) { jsonSchema.push(buildHeadersSchema(response, opts)); } return jsonSchema.length ? jsonSchema : null; } // src/operation/index.ts var Operation = class { /** * Schema of the operation from the API Definition. */ /** * OpenAPI API Definition that this operation originated from. */ /** * Path that this operation is targeted towards. */ /** * HTTP Method that this operation is targeted towards. */ /** * The primary Content Type that this operation accepts. */ /** * An object with groups of all example definitions (body/header/query/path/response/etc.) */ /** * Request body examples for this operation. */ /** * Response examples for this operation. */ /** * Callback examples for this operation (if it has callbacks). */ /** * Flattened out arrays of both request and response headers that are utilized on this operation. */ constructor(api, path, method, operation) { this.schema = operation; this.api = api; this.path = path; this.method = method; this.contentType = void 0; this.requestBodyExamples = void 0; this.responseExamples = void 0; this.callbackExamples = void 0; this.exampleGroups = void 0; this.headers = { request: [], response: [] }; } getSummary() { if (_optionalChain([this, 'access', _24 => _24.schema, 'optionalAccess', _25 => _25.summary]) && typeof this.schema.summary === "string") { return this.schema.summary; } else if (this.api.paths[this.path].summary && typeof this.api.paths[this.path].summary === "string") { return this.api.paths[this.path].summary; } return void 0; } getDescription() { if (_optionalChain([this, 'access', _26 => _26.schema, 'optionalAccess', _27 => _27.description]) && typeof this.schema.description === "string") { return this.schema.description; } else if (this.api.paths[this.path].description && typeof this.api.paths[this.path].description === "string") { return this.api.paths[this.path].description; } return void 0; } getContentType() { if (this.contentType) { return this.contentType; } let types = []; if (this.schema.requestBody) { if ("$ref" in this.schema.requestBody) { this.schema.requestBody = _chunkTDI4MZLIcjs.findSchemaDefinition.call(void 0, this.schema.requestBody.$ref, this.api); } if ("content" in this.schema.requestBody) { types = Object.keys(this.schema.requestBody.content); } } this.contentType = "application/json"; if (types && types.length) { this.contentType = types[0]; } types.forEach((t) => { if (_chunkQ2TBKI3Ocjs.matches_mimetype_default.json(t)) { this.contentType = t; } }); return this.contentType; } isFormUrlEncoded() { return _chunkQ2TBKI3Ocjs.matches_mimetype_default.formUrlEncoded(this.getContentType()); } isMultipart() { return _chunkQ2TBKI3Ocjs.matches_mimetype_default.multipart(this.getContentType()); } isJson() { return _chunkQ2TBKI3Ocjs.matches_mimetype_default.json(this.getContentType()); } isXml() { return _chunkQ2TBKI3Ocjs.matches_mimetype_default.xml(this.getContentType()); } /** * Checks if the current operation is a webhook or not. * */ isWebhook() { return this instanceof Webhook; } /** * Returns an array of all security requirements associated wtih this operation. If none are * defined at the operation level, the securities for the entire API definition are returned * (with an empty array as a final fallback). * */ getSecurity() { if (!_optionalChain([this, 'access', _28 => _28.api, 'optionalAccess', _29 => _29.components, 'optionalAccess', _30 => _30.securitySchemes]) || !Object.keys(this.api.components.securitySchemes).length) { return []; } return this.schema.security || this.api.security || []; } /** * Retrieve a collection of grouped security schemes. The inner array determines AND-grouped * security schemes, the outer array determines OR-groups. * * @see {@link https://swagger.io/docs/specification/authentication/#multiple} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#security-requirement-object} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#security-requirement-object} * @param filterInvalid Optional flag that, when set to `true`, filters out invalid/nonexistent * security schemes, rather than returning `false`. */ getSecurityWithTypes(filterInvalid = false) { const securityRequirements = this.getSecurity(); return securityRequirements.map((requirement) => { let keys; try { keys = Object.keys(requirement); } catch (e) { return false; } const keysWithTypes = keys.map((key) => { let security; try { security = this.api.components.securitySchemes[key]; } catch (e) { return false; } if (!security) return false; let type = null; if (security.type === "http") { if (security.scheme === "basic") type = "Basic"; else if (security.scheme === "bearer") type = "Bearer"; else type = security.type; } else if (security.type === "oauth2") { type = "OAuth2"; } else if (security.type === "apiKey") { if (security.in === "query") type = "Query"; else if (security.in === "header") type = "Header"; else if (security.in === "cookie") type = "Cookie"; else type = security.type; } else { return false; } return { type, security: { ...security, _key: key, _requirements: requirement[key] } }; }); if (filterInvalid) return keysWithTypes.filter((key) => key !== false); return keysWithTypes; }); } /** * Retrieve an object where the keys are unique scheme types, and the values are arrays * containing each security scheme of that type. * */ prepareSecurity() { const securitiesWithTypes = this.getSecurityWithTypes(); return securitiesWithTypes.reduce( (prev, securities) => { if (!securities) return prev; securities.forEach((security) => { if (!security) return; if (!prev[security.type]) prev[security.type] = []; const exists = prev[security.type].some((sec) => sec._key === security.security._key); if (!exists) { if (_optionalChain([security, 'access', _31 => _31.security, 'optionalAccess', _32 => _32._requirements])) delete security.security._requirements; prev[security.type].push(security.security); } }); return prev; }, {} ); } getHeaders() { const security = this.prepareSecurity(); if (security.Header) { this.headers.request = security.Header.map((h) => { return h.name; }); } if (security.Bearer || security.Basic || security.OAuth2) { this.headers.request.push("Authorization"); } if (security.Cookie) { this.headers.request.push("Cookie"); } if (this.schema.parameters) { this.headers.request = this.headers.request.concat( // Remove the reference object because we will have already dereferenced. this.schema.parameters.map((p) => { if (p.in && p.in === "header") return p.name; return void 0; }).filter((p) => p) ); } if (this.schema.responses) { this.headers.response = Object.keys(this.schema.responses).filter((r) => this.schema.responses[r].headers).map( (r) => ( // Remove the reference object because we will have already dereferenced. Object.keys(this.schema.responses[r].headers) ) ).reduce((a, b) => a.concat(b), []); } if (!this.headers.request.includes("Content-Type") && this.schema.requestBody) { if (this.schema.requestBody.content && Object.keys(this.schema.requestBody.content)) { this.headers.request.push("Content-Type"); } } if (this.schema.responses) { if (Object.keys(this.schema.responses).some( (response) => !!this.schema.responses[response].content )) { if (!this.headers.request.includes("Accept")) this.headers.request.push("Accept"); if (!this.headers.response.includes("Content-Type")) this.headers.response.push("Content-Type"); } } return this.headers; } /** * Determine if the operation has an operation present in its schema. Note that if one is present * in the schema but is an empty string then this will return false. * */ hasOperationId() { return Boolean("operationId" in this.schema && this.schema.operationId.length); } /** * Get an `operationId` for this operation. If one is not present (it's not required by the spec!) * a hash of the path and method will be returned instead. * */ getOperationId(opts = {}) { function sanitize(id) { return id.replace(_optionalChain([opts, 'optionalAccess', _33 => _33.camelCase]) || _optionalChain([opts, 'optionalAccess', _34 => _34.friendlyCase]) ? /[^a-zA-Z0-9_]/g : /[^a-zA-Z0-9]/g, "-").replace(/--+/g, "-").replace(/^-|-$/g, ""); } let operationId; if (this.hasOperationId()) { operationId = this.schema.operationId; } else { operationId = sanitize(this.path).toLowerCase(); } const method = this.method.toLowerCase(); if (_optionalChain([opts, 'optionalAccess', _35 => _35.camelCase]) || _optionalChain([opts, 'optionalAccess', _36 => _36.friendlyCase])) { if (_optionalChain([opts, 'optionalAccess', _37 => _37.friendlyCase])) { operationId = operationId.replaceAll("_", " "); if (!this.hasOperationId()) { operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => ` ${chr}`).split(" ").filter((word, i, arr) => word !== arr[i - 1]).join(" "); } } operationId = operationId.replace(/[^a-zA-Z0-9_]+(.)/g, (_, chr) => chr.toUpperCase()); if (this.hasOperationId()) { operationId = sanitize(operationId); } operationId = operationId.replace(/^[0-9]/g, (match) => `_${match}`); operationId = operationId.charAt(0).toLowerCase() + operationId.slice(1); if (operationId.startsWith(method)) { return operationId; } if (this.hasOperationId()) { return operationId; } operationId = operationId.charAt(0).toUpperCase() + operationId.slice(1); return `${method}${operationId}`; } else if (this.hasOperationId()) { return operationId; } return `${method}_${operationId}`; } /** * Return an array of all tags, and their metadata, that exist on this operation. * */ getTags() { if (!("tags" in this.schema)) { return []; } const oasTagMap = /* @__PURE__ */ new Map(); if ("tags" in this.api) { this.api.tags.forEach((tag) => { oasTagMap.set(tag.name, tag); }); } const oasTags = Object.fromEntries(oasTagMap); const tags = []; if (Array.isArray(this.schema.tags)) { this.schema.tags.forEach((tag) => { if (tag in oasTags) { tags.push(oasTags[tag]); } else { tags.push({ name: tag }); } }); } return tags; } /** * Return is the operation is flagged as `deprecated` or not. * */ isDeprecated() { return "deprecated" in this.schema ? this.schema.deprecated : false; } /** * Determine if the operation has any (non-request body) parameters. * */ hasParameters() { return !!this.getParameters().length; } /** * Return the parameters (non-request body) on the operation. * */ getParameters() { let parameters = _optionalChain([this, 'access', _38 => _38.schema, 'optionalAccess', _39 => _39.parameters]) || []; const commonParams = _optionalChain([this, 'access', _40 => _40.api, 'optionalAccess', _41 => _41.paths, 'optionalAccess', _42 => _42[this.path], 'optionalAccess', _43 => _43.parameters]) || []; if (commonParams.length) { parameters = parameters.concat(dedupeCommonParameters(parameters, commonParams) || []); } return parameters; } /** * Determine if this operation has any required parameters. * */ hasRequiredParameters() { return this.getParameters().some((param) => "required" in param && param.required); } /** * Convert the operation into an array of JSON Schema schemas for each available type of * parameter available on the operation. * */ getParametersAsJSONSchema(opts = {}) { return _chunkQ2TBKI3Ocjs.getParametersAsJSONSchema.call(void 0, this, this.api, { includeDiscriminatorMappingRefs: true, transformer: (s) => s, ...opts }); } /** * Get a single response for this status code, formatted as JSON schema. * * @param statusCode Status code to pull a JSON Schema response for. */ getResponseAsJSONSchema(statusCode, opts = {}) { return getResponseAsJSONSchema(this, this.api, statusCode, { includeDiscriminatorMappingRefs: true, transformer: (s) => s, ...opts }); } /** * Get an array of all valid response status codes for this operation. * */ getResponseStatusCodes() { return this.schema.responses ? Object.keys(this.schema.responses) : []; } /** * Determine if the operation has any request bodies. * */ hasRequestBody() { return !!this.schema.requestBody; } /** * Retrieve the list of all available media types that the operations request body can accept. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#media-type-object} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object} */ getRequestBodyMediaTypes() { if (!this.hasRequestBody()) { return []; } const requestBody = this.schema.requestBody; if (_chunkVSXG73AZcjs.isRef.call(void 0, requestBody)) { return []; } return Object.keys(requestBody.content); } /** * Determine if this operation has a required request body. * */ hasRequiredRequestBody() { if (!this.hasRequestBody()) { return false; } const requestBody = this.schema.requestBody; if (_chunkVSXG73AZcjs.isRef.call(void 0, requestBody)) { return false; } if (requestBody.required) { return true; } return !!this.getParametersAsJSONSchema().filter((js) => ["body", "formData"].includes(js.type)).find((js) => js.schema && Array.isArray(js.schema.required) && js.schema.required.length); } /** * Retrieve a specific request body content schema off this operation. * * If no media type is supplied this will return either the first available JSON-like request * body, or the first available if there are no JSON-like media types present. When this return * comes back it's in the form of an array with the first key being the selected media type, * followed by the media type object in question. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#media-type-object} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#media-type-object} * @param mediaType Specific request body media type to retrieve if present. */ getRequestBody(mediaType) { if (!this.hasRequestBody()) { return false; } const requestBody = this.schema.requestBody; if (_chunkVSXG73AZcjs.isRef.call(void 0, requestBody)) { return false; } if (mediaType) { if (!(mediaType in requestBody.content)) { return false; } return requestBody.content[mediaType]; } let availableMediaType; const mediaTypes = this.getRequestBodyMediaTypes(); mediaTypes.forEach((mt) => { if (!availableMediaType && _chunkQ2TBKI3Ocjs.matches_mimetype_default.json(mt)) { availableMediaType = mt; } }); if (!availableMediaType) { mediaTypes.forEach((mt) => { if (!availableMediaType) { availableMediaType = mt; } }); } if (availableMediaType) { return [ availableMediaType, requestBody.content[availableMediaType], ...requestBody.description ? [requestBody.description] : [] ]; } return false; } /** * Retrieve an array of request body examples that this operation has. * */ getRequestBodyExamples() { const isRequestExampleValueDefined = typeof _optionalChain([this, 'access', _44 => _44.requestBodyExamples, 'optionalAccess', _45 => _45[0], 'optionalAccess', _46 => _46.examples, 'optionalAccess', _47 => _47[0], 'access', _48 => _48.value]) !== "undefined"; if (this.requestBodyExamples && isRequestExampleValueDefined) { return this.requestBodyExamples; } this.requestBodyExamples = getRequestBodyExamples(this.schema); return this.requestBodyExamples; } /** * Return a specific response out of the operation by a given HTTP status code. * * @param statusCode Status code to pull a response object for. */ getResponseByStatusCode(statusCode) { if (!this.schema.responses) { return false; } if (typeof this.schema.responses[statusCode] === "undefined") { return false; } const response = this.schema.responses[statusCode]; if (_chunkVSXG73AZcjs.isRef.call(void 0, response)) { return false; } return response; } /** * Retrieve an array of response examples that this operation has. * */ getResponseExamples() { if (this.responseExamples) { return this.responseExamples; } this.responseExamples = getResponseExamples(this.schema); return this.responseExamples; } /** * Determine if the operation has callbacks. * */ hasCallbacks() { return !!this.schema.callbacks; } /** * Retrieve a specific callback. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#callback-object} * @param identifier Callback identifier to look for. * @param expression Callback expression to look for. * @param method HTTP Method on the callback to look for. */ getCallback(identifier, expression, method) { if (!this.schema.callbacks) return false; const callback = this.schema.callbacks[identifier] ? this.schema.callbacks[identifier][expression] : false; if (!callback || !callback[method]) return false; return new Callback(this.api, expression, method, callback[method], identifier, callback); } /** * Retrieve an array of operations created from each callback. * */ getCallbacks() { const callbackOperations = []; if (!this.hasCallbacks()) return false; Object.keys(this.schema.callbacks).forEach((callback) => { Object.keys(this.schema.callbacks[callback]).forEach((expression) => { const cb = this.schema.callbacks[callback]; if (!_chunkVSXG73AZcjs.isRef.call(void 0, cb)) { const exp = cb[expression]; if (!_chunkVSXG73AZcjs.isRef.call(void 0, exp)) { Object.keys(exp).forEach((method) => { if (!_chunkTDI4MZLIcjs.supportedMethods.includes(method)) return; callbackOperations.push(this.getCallback(callback, expression, method)); }); } } }); }); return callbackOperations; } /** * Retrieve an array of callback examples that this operation has. * */ getCallbackExamples() { if (this.callbackExamples) { return this.callbackExamples; } this.callbackExamples = getCallbackExamples(this.schema); return this.callbackExamples; } /** * Determine if a given a custom specification extension exists within the operation. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions} * @param extension Specification extension to lookup. */ hasExtension(extension) { return Boolean(this.schema && extension in this.schema); } /** * Retrieve a custom specification extension off of the operation. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specification-extensions} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#specification-extensions} * @param extension Specification extension to lookup. * * @deprecated Use `oas.getExtension(extension, operation)` instead. */ getExtension(extension) { return _optionalChain([this, 'access', _49 => _49.schema, 'optionalAccess', _50 => _50[extension]]); } /** * Returns an object with groups of all example definitions (body/header/query/path/response/etc.). * The examples are grouped by their key when defined via the `examples` map. * * Any custom code samples defined via the `x-readme.code-samples` extension are returned, * regardless of if they have a matching response example. * * For standard OAS request parameter (e.g., body/header/query/path/etc.) examples, * they are only present in the return object if they have a corresponding response example * (i.e., a response example with the same key in the `examples` map). */ getExampleGroups() { if (this.exampleGroups) return this.exampleGroups; const groups = getExampleGroups(this); this.exampleGroups = groups; return groups; } }; var Callback = class extends Operation { /** * The identifier that this callback is set to. */ /** * The parent path item object that this Callback exists within. */ constructor(oas, path, method, operation, identifier, parentPathItem) { super(oas, path, method, operation); this.identifier = identifier; this.parentSchema = parentPathItem; } /** * Return the primary identifier for this callback. * * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callback-object} * @see {@link https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#callback-object} */ getIdentifier() { return this.identifier; } getSummary() { if (_optionalChain([this, 'access', _51 => _51.schema, 'optionalAccess', _52 => _52.summary]) && typeof this.schema.summary === "string") { return this.schema.summary; } else if (this.parentSchema.summary && typeof this.parentSchema.summary === "string") { return this.parentSchema.summary; } return void 0; } getDescription() { if (_optionalChain([this, 'access', _53 => _53.schema, 'optionalAccess', _54 => _54.description]) && typeof this.schema.description === "string") { return this.schema.description; } else if (this.parentSchema.description && typeof this.parentSchema.description === "string") { return this.parentSchema.description; } return void 0; } getParameters() { let parameters = _optionalChain([this, 'access', _55 => _55.schema, 'optionalAccess', _56 => _56.parameters]) || []; const commonParams = this.parentSchema.parameters || []; if (commonParams.length) { parameters = parameters.concat(dedupeCommonParameters(parameters, commonParams) || []); } return parameters; } }; var Webhook = class extends Operation { getSummary() { if (_optionalChain([this, 'access', _57 => _57.schema, 'optionalAccess', _58 => _58.summary]) && typeof this.schema.summary === "string") { return this.schema.summary; } else if (this.api.webhooks[this.path].summary && typeof this.api.webhooks[this.path].summary === "string") { return this.api.webhooks[this.path].summary; } return void 0; } getDescription() { if (_optionalChain([this, 'access', _59 => _59.schema, 'optionalAccess', _60 => _60.description]) && typeof this.schema.description === "string") { return this.schema.description; } else if (this.api.webhooks[this.path].description && typeof this.api.webhooks[this.path].description === "string") { return this.api.webhooks[this.path].description; } return void 0; } }; exports.Operation = Operation; exports.Callback = Callback; exports.Webhook = Webhook; /** * Portions of this file have been extracted and modified from Swagger UI. * * @license Apache-2.0 * @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/utils.js} */ /** * This file has been extracted and modified from Swagger UI. * * @license Apache-2.0 * @see {@link https://github.com/swagger-api/swagger-ui/blob/master/src/core/plugins/samples/fn.js} */ //# sourceMappingURL=chunk-4EWSCVWC.cjs.map