ut-tools
Version:
Build and Release management automation package.
183 lines • 6.74 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const isObject_1 = require("./utils/isObject");
const oasSchema_1 = (0, tslib_1.__importDefault)(require("./oasSchema"));
const spectral_core_1 = require("@stoplight/spectral-core");
const spectral_formats_1 = require("@stoplight/spectral-formats");
const json_schema_traverse_1 = (0, tslib_1.__importDefault)(require("json-schema-traverse"));
const MEDIA_VALIDATION_ITEMS = {
2: [
{
field: 'examples',
multiple: true,
keyed: false,
},
],
3: [
{
field: 'example',
multiple: false,
keyed: false,
},
{
field: 'examples',
multiple: true,
keyed: true,
},
],
};
const REQUEST_MEDIA_PATHS = {
2: [],
3: [
['components', 'requestBodies'],
['paths', '*', '*', 'requestBody'],
],
};
const RESPONSE_MEDIA_PATHS = {
2: [['responses'], ['paths', '*', '*', 'responses']],
3: [
['components', 'responses'],
['paths', '*', '*', 'responses'],
],
};
const SCHEMA_VALIDATION_ITEMS = {
2: ['example', 'x-example', 'default'],
3: ['example', 'default'],
};
function hasRequiredProperties(schema) {
return schema.required === undefined || Array.isArray(schema.required);
}
function isSubpath(path, subPaths) {
return subPaths.some(subPath => subPath.every((segment, idx) => segment === '*' || segment === path[idx]));
}
function isMediaRequest(path, oasVersion) {
return isSubpath(path, REQUEST_MEDIA_PATHS[oasVersion]);
}
function isMediaResponse(path, oasVersion) {
return isSubpath(path, RESPONSE_MEDIA_PATHS[oasVersion]);
}
function* getMediaValidationItems(items, targetVal, givenPath, oasVersion) {
for (const { field, keyed, multiple } of items) {
if (!(field in targetVal)) {
continue;
}
const value = targetVal[field];
if (multiple) {
if (!(0, isObject_1.isObject)(value))
continue;
for (const exampleKey of Object.keys(value)) {
const exampleValue = value[exampleKey];
if (oasVersion === 3 && keyed && (!(0, isObject_1.isObject)(exampleValue) || 'externalValue' in exampleValue)) {
continue;
}
const targetPath = [...givenPath, field, exampleKey];
if (keyed) {
targetPath.push('value');
}
yield {
value: keyed && (0, isObject_1.isObject)(exampleValue) ? exampleValue.value : exampleValue,
path: targetPath,
};
}
return;
}
else {
return yield {
value,
path: [...givenPath, field],
};
}
}
}
function* getSchemaValidationItems(fields, targetVal, givenPath) {
for (const field of fields) {
if (!(field in targetVal)) {
continue;
}
yield {
value: targetVal[field],
path: [...givenPath, field],
};
}
}
const KNOWN_TRAVERSE_KEYWORDS = [
...Object.keys(json_schema_traverse_1.default['keywords']),
...Object.keys(json_schema_traverse_1.default['arrayKeywords']),
...Object.keys(json_schema_traverse_1.default['propsKeywords']),
];
function cleanSchema(schema) {
(0, json_schema_traverse_1.default)(schema, { allKeys: true }, ((fragment, jsonPtr, rootSchema, parentJsonPtr, parentKeyword) => {
if (parentKeyword === void 0 || KNOWN_TRAVERSE_KEYWORDS.includes(parentKeyword))
return;
if ('id' in fragment) {
delete fragment.id;
}
if ('$id' in fragment) {
delete fragment.id;
}
}));
}
function relaxRequired(schema, readOnlyProperties, writeOnlyProperties) {
if (readOnlyProperties || writeOnlyProperties)
(0, json_schema_traverse_1.default)(schema, {}, ((fragment, jsonPtr, rootSchema, parentJsonPtr, parentKeyword, parent, propertyName) => {
var _a, _b;
if ((fragment.readOnly === true && readOnlyProperties) || (fragment.writeOnly === true && writeOnlyProperties)) {
if (parentKeyword == 'properties' && parent && hasRequiredProperties(parent)) {
parent.required = (_a = parent.required) === null || _a === void 0 ? void 0 : _a.filter(p => p !== propertyName);
if (((_b = parent.required) === null || _b === void 0 ? void 0 : _b.length) === 0) {
delete parent.required;
}
}
}
}));
}
exports.default = (0, spectral_core_1.createRulesetFunction)({
input: {
type: 'object',
},
options: {
type: 'object',
properties: {
oasVersion: {
enum: [2, 3],
},
schemaField: {
type: 'string',
},
type: {
enum: ['media', 'schema'],
},
},
additionalProperties: false,
},
}, function oasExample(targetVal, opts, context) {
const formats = context.document.formats;
const schemaOpts = {
schema: opts.schemaField === '$' ? targetVal : targetVal[opts.schemaField],
};
let results = void 0;
const validationItems = opts.type === 'schema'
? getSchemaValidationItems(SCHEMA_VALIDATION_ITEMS[opts.oasVersion], targetVal, context.path)
: getMediaValidationItems(MEDIA_VALIDATION_ITEMS[opts.oasVersion], targetVal, context.path, opts.oasVersion);
if ((formats === null || formats === void 0 ? void 0 : formats.has(spectral_formats_1.oas2)) && 'required' in schemaOpts.schema && typeof schemaOpts.schema.required === 'boolean') {
schemaOpts.schema = { ...schemaOpts.schema };
delete schemaOpts.schema.required;
}
schemaOpts.schema = JSON.parse(JSON.stringify(schemaOpts.schema));
cleanSchema(schemaOpts.schema);
relaxRequired(schemaOpts.schema, opts.type === 'media' && isMediaRequest(context.path, opts.oasVersion), opts.type === 'media' && isMediaResponse(context.path, opts.oasVersion));
for (const validationItem of validationItems) {
const result = (0, oasSchema_1.default)(validationItem.value, schemaOpts, {
...context,
path: validationItem.path,
});
if (Array.isArray(result)) {
if (results === void 0)
results = [];
results.push(...result);
}
}
return results;
});
//# sourceMappingURL=oasExample.js.map