oas
Version:
Comprehensive tooling for working with OpenAPI definitions
1,253 lines (1,211 loc) • 44.1 kB
JavaScript
"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