UNPKG

openapi-merge

Version:

A tool to merge numerous OpenAPI files into a single openapi definition.

91 lines (90 loc) 3.52 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.deepEquality = exports.shallowEquality = void 0; const atlassian_openapi_1 = require("atlassian-openapi"); const lodash_1 = __importDefault(require("lodash")); const ts_is_present_1 = require("ts-is-present"); function referenceCount(walker, component) { let count = 0; walker(component, ref => { count++; return ref; }); return count; } function shallowEquality(referenceWalker) { return (x, y) => { if (!lodash_1.default.isEqual(x, y)) { return false; } if (atlassian_openapi_1.SwaggerTypeChecks.isReference(x)) { return false; } return referenceCount(referenceWalker, x) === 0; }; } exports.shallowEquality = shallowEquality; function isSchemaOrThrowError(ref, s) { if (s === undefined) { throw new Error(`Could not resolve reference: ${ref.$ref}`); } return s; } function arraysEquivalent(leftOriginal, rightOriginal) { if (leftOriginal.length !== rightOriginal.length) { return false; } const left = [...leftOriginal].sort(); const right = [...rightOriginal].sort(); for (let index = 0; index < left.length; index++) { if (left[index] !== right[index]) { return false; } } return true; } class ReferenceRecord { constructor() { this.leftRightSeen = {}; } checkAndStore(left, right) { if (this.leftRightSeen[left.$ref] === undefined) { this.leftRightSeen[left.$ref] = {}; } const leftLookup = this.leftRightSeen[left.$ref]; const result = leftLookup[right.$ref] === true ? 'seen-before' : 'new'; leftLookup[right.$ref] = true; return result; } } function deepEquality(xLookup, yLookup) { const refRecord = new ReferenceRecord(); function compare(x, y) { // If both are references then look up the references and compare them for equality if (ts_is_present_1.isPresent(x) && ts_is_present_1.isPresent(y)) { if (atlassian_openapi_1.SwaggerTypeChecks.isReference(x) && atlassian_openapi_1.SwaggerTypeChecks.isReference(y)) { if (refRecord.checkAndStore(x, y) === 'seen-before') { return true; } const xResult = isSchemaOrThrowError(x, xLookup.getSchema(x)); const yResult = isSchemaOrThrowError(y, yLookup.getSchema(y)); return compare(xResult, yResult); } else if (atlassian_openapi_1.SwaggerTypeChecks.isReference(x) || atlassian_openapi_1.SwaggerTypeChecks.isReference(y)) { return false; } else if (typeof x === 'object' && typeof y === 'object') { // If both are objects then they should have all of the same keys and the values of those keys should match if (!arraysEquivalent(Object.keys(x), Object.keys(y))) { return false; } const xKeys = Object.keys(x); return xKeys.every(key => compare(x[key], y[key])); } } // If they are not objects or references then you can just run a direct equality return lodash_1.default.isEqual(x, y); } return compare; } exports.deepEquality = deepEquality;