New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

openapi-enforcer

Package Overview
Dependencies
Maintainers
1
Versions
131
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

openapi-enforcer - npm Package Compare versions

Comparing version 1.10.8 to 1.11.0

test-resources/ref-parser/Bundle1.yml

14

CHANGELOG.md

@@ -10,2 +10,16 @@ # Change Log

## 1.11.0
### Added
- **Definition Bundler**
Created a custom-built bundler that bundles and references nodes in a format that follows the OpenAPI specification.
### Fixed
- **Custom Ref Parser**
The custom ref parser had a bug where is failed to check for null values when processing objects. That has been resolved.
## 1.10.8

@@ -12,0 +26,0 @@

@@ -124,2 +124,18 @@ ---

## Enforcer.bundle
`Enforcer.bundle ( definition ) : Promise <object>`
Resolves all of the `$ref` values in a definition, reorganizes `$ref` values to meet the OpenAPI specification, and returns an object that can be stringified with `JSON.stringify`.
| Parameter | Description | Type | Default |
| --------- | ----------- | ---- | ------- |
| **definition** | A `string` for the file path to the OpenAPI definition or an `object` to bundle. | `string` or `object` | |
**Parameters:**
- *definition* - A `string` for the file path to the OpenAPI definition or an `object` to bundle.
**Returns:** A Promise that resolves to the bundled `object`.
## Enforcer.dereference

@@ -126,0 +142,0 @@

0

docs/template-files/js/main.js

@@ -0,0 +0,0 @@ ;(function () {

@@ -92,2 +92,12 @@ /**

Enforcer.bundle = function (definition) {
if (Enforcer.config.useNewRefParser) {
const refParser = new NewRefParser(definition);
return refParser.bundle();
} else {
const refParser = new OldRefParser();
return refParser.bundle(definition);
}
};
Enforcer.dereference = function (definition) {

@@ -94,0 +104,0 @@ if (Enforcer.config.useNewRefParser) {

12

package.json
{
"name": "openapi-enforcer",
"version": "1.10.8",
"version": "1.11.0",
"description": "Library for validating, parsing, and formatting data against open api schemas.",

@@ -48,13 +48,13 @@ "main": "index.js",

"devDependencies": {
"@gi60s/markdown-docs": "0.0.10",
"@gi60s/markdown-docs": "0.1.2",
"chai": "^4.2.0",
"chokidar-cli": "^1.2.2",
"coveralls": "^3.0.2",
"chokidar-cli": "^1.2.3",
"coveralls": "^3.1.0",
"mocha": "^5.2.0",
"nyc": "^14.1.0"
"nyc": "^14.1.1"
},
"dependencies": {
"axios": "^0.19.2",
"json-schema-ref-parser": "^6.0.1"
"json-schema-ref-parser": "^6.1.0"
}
}

@@ -63,5 +63,70 @@ /**

RefParser.prototype.bundle = async function () {
const that = map.get(this);
if (that.bundled) {
const { value, error, warning } = that.bundled;
return new Result(value, error, warning);
}
const exception = new Exception('Unable to bundle definition for one or more reasons');
const [ dereferenced, error ] = await this.dereference();
const bundled = util.copy(dereferenced)
if (error) {
exception.push(error);
} else {
const map = mapNodesAndPaths(bundled, null, '', '#', [])
const duplicates = Array.from(map.keys())
.map(key => {
const data = map.get(key)
return { node: key, refs: data }
})
.filter(v => v.refs.length > 1)
// get the optimal references
const version = getVersion(bundled)
const priorities = version === 2
? ['definitions', 'parameters', 'responses', 'securityDefinitions', 'security', 'tags', 'externalDocs']
: ['components/schemas', 'components/responses', 'components/parameters', 'components/examples', 'components/requestBodies', 'components/headers', 'components/securitySchemes', 'components/links', 'components/callbacks', 'components', 'security', 'servers', 'tags', 'externalDocs']
duplicates.forEach(dup => {
const refs = dup.refs
refs.sort((a, b) => {
const pathA = a.path
const pathB = b.path
let priorityA = priorities.findIndex(p => pathA.startsWith('#/' + p))
let priorityB = priorities.findIndex(p => pathB.startsWith('#/' + p))
if (priorityA === -1) priorityA = Number.MAX_SAFE_INTEGER
if (priorityB === -1) priorityB = Number.MAX_SAFE_INTEGER
if (priorityA < priorityB) {
return -1;
} else if (priorityA > priorityB) {
return 1;
} else {
return pathA.split('/').length < pathB.split('/').length ? -1 : 1;
}
})
dup.ref = refs[0]
})
duplicates.forEach(dup => {
const refs = dup.refs;
const length = refs.length;
for (let i = 1; i < length; i++) {
const ref = refs[i]
ref.parent[ref.key] = dup.ref.path
}
})
}
that.bundled = new Result(bundled, exception);
return that.bundled;
}
RefParser.prototype.dereference = async function () {
const that = map.get(this);
if (that.dereferenced) return that.dereferenced;
if (that.dereferenced) {
const { value, error, warning } = that.dereferenced
return new Result(value, error, warning)
}

@@ -101,3 +166,4 @@ const exception = new Exception('Unable to dereference definition for one or more reasons');

const keys = Object.keys(sourceMap);
for (let i = 0; i < keys.length; i++) {
const length = keys.length;
for (let i = 0; i < length; i++) {
const key = keys[i];

@@ -153,2 +219,48 @@ if (sourceMap[key].includes(node)) return key;

function mapNodesAndPaths (node, parent, key, path, chain, map = new Map()) {
if (node && typeof node === 'object') {
// if we're in an endless loop then exit
if (chain.includes(node)) return
// add to loop watching chain
chain = chain.slice();
chain.push(node);
const data = {
key,
parent,
path
}
// store where this node resides in the tree
const existing = map.get(node);
if (existing) {
existing.push(data);
} else {
map.set(node, [data]);
}
if (Array.isArray(node)) {
node.forEach((n, i) => {
mapNodesAndPaths(n, node, i, path + '/' + i, chain, map);
});
} else {
Object.keys(node).forEach(key => {
mapNodesAndPaths(node[key], node, key, path + '/' + key, chain, map);
});
}
}
return map;
}
function getVersion (spec) {
if (spec) {
if (spec.swagger) return 2;
if (spec.openapi) {
const v = spec.openapi.split('.')[0];
if (/^\d$/.test(v)) return +v;
}
}
}
async function parse (basePath, fullPath, source, value, that, map, chain, exception) {

@@ -168,3 +280,3 @@ // console.log('Parse:\n B: ' + basePath + '\n S: ' + Object.keys(source));

} else if (typeof value === 'object') {
} else if (value && typeof value === 'object') {
if (value.hasOwnProperty('$ref')) {

@@ -171,0 +283,0 @@ const infiniteLoop = chain.includes(value);

@@ -336,2 +336,53 @@ const expect = require('chai').expect;

describe('bundle', () => {
it('can bundle multiple files', async function () {
const parser = new RefParser(path.resolve(resourcesDir, 'Bundle1.yml'));
const [ bundled ] = await parser.bundle();
expect(bundled.b.a).to.equal('#/a');
expect(bundled.c.a).to.equal('#/a');
expect(bundled.c.b).to.equal('#/b');
expect(bundled.d.c).to.equal('#/c/c');
})
// this test proves that bundling will prioritize references
// to follow the OpenAPI specification
it('will smartly reference duplicates', async function () {
const doc = {
openapi: '3.0.0',
info: { title: '', version: '' },
paths: {
'/': {
responses: {
'200': {
description: '',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/x'
}
}
}
}
}
}
},
components: {
schemas: {
x: {
$ref: '#/schemas/x'
}
}
},
schemas: {
x: {
type: 'string'
}
}
}
const parser = new RefParser(doc);
const [ bundled ] = await parser.bundle();
expect(bundled.components.schemas.x).to.deep.equal({ type: 'string' })
});
})
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc