@asyncapi/parser
Advanced tools
Comparing version 0.18.0 to 0.18.1
@@ -5,3 +5,3 @@ const path = require('path'); | ||
const asyncapi = require('@asyncapi/specs'); | ||
const $RefParser = require('json-schema-ref-parser'); | ||
const $RefParser = require('@apidevtools/json-schema-ref-parser'); | ||
const mergePatch = require('tiny-merge-patch').apply; | ||
@@ -88,3 +88,3 @@ const ParserError = require('./errors/parser-error'); | ||
parsedJSON, | ||
refs: findRefs(parsedJSON, err.path, options.path, initialFormat, asyncapiYAMLorJSON), | ||
refs: findRefs(parsedJSON, err.originalPath || err.path, options.path, initialFormat, asyncapiYAMLorJSON), | ||
}); | ||
@@ -91,0 +91,0 @@ } |
@@ -1,2 +0,1 @@ | ||
const path = require('path'); | ||
const YAML = require('js-yaml'); | ||
@@ -108,9 +107,10 @@ const { yamlAST, loc } = require('@fmvilas/pseudo-yaml-ast'); | ||
utils.findRefs = (json, absolutePath, relativeDir, initialFormat, asyncapiYAMLorJSON) => { | ||
const relativePath = path.relative(relativeDir, absolutePath); | ||
utils.findRefs = (json, absolutePath, relativePath, initialFormat, asyncapiYAMLorJSON) => { | ||
let possibleRefUrls = [absolutePath]; | ||
if (absolutePath.startsWith(relativePath)) possibleRefUrls.push(absolutePath.substr(relativePath.length)); | ||
let refs = []; | ||
traverse(json, (key, value, scope) => { | ||
if (key === '$ref' && value === relativePath) { | ||
refs.push({ location: [...scope, '$ref'] }); | ||
if (key === '$ref' && possibleRefUrls.includes(value)) { | ||
refs.push({ location: [...scope.map(tilde), '$ref'] }); | ||
} | ||
@@ -191,3 +191,3 @@ }); | ||
for (let key of location) { | ||
obj = obj[key]; | ||
obj = obj[untilde(key)]; | ||
} | ||
@@ -201,3 +201,3 @@ return obj; | ||
if (!Array.isArray(obj.children)) return; | ||
const child = obj.children.find(c => c && c.type === 'Property' && c.key && c.key.value === key); | ||
const child = obj.children.find(c => c && c.type === 'Property' && c.key && c.key.value === untilde(key)); | ||
if (!child) return; | ||
@@ -217,1 +217,22 @@ obj = child.value; | ||
} | ||
const tilde = (str) => { | ||
return str.replace(/[~\/]{1}/g, (m) => { | ||
switch (m) { | ||
case '/': return '~1' | ||
case '~': return '~0' | ||
} | ||
return m; | ||
}); | ||
}; | ||
const untilde = (str) => { | ||
if (!str.includes('~')) return str; | ||
return str.replace(/~[01]/g, (m) => { | ||
switch (m) { | ||
case '~1': return '/' | ||
case '~0': return '~' | ||
} | ||
return m; | ||
}); | ||
}; |
{ | ||
"name": "@asyncapi/parser", | ||
"version": "0.18.0", | ||
"version": "0.18.1", | ||
"description": "JavaScript AsyncAPI parser.", | ||
@@ -46,7 +46,7 @@ "main": "lib/index.js", | ||
"dependencies": { | ||
"@apidevtools/json-schema-ref-parser": "github:fmvilas/json-schema-ref-parser#add-more-info-about-errors", | ||
"@asyncapi/specs": "^2.7.1", | ||
"@fmvilas/pseudo-yaml-ast": "^0.3.0", | ||
"ajv": "^6.10.1", | ||
"@asyncapi/specs": "^2.7.1", | ||
"js-yaml": "^3.13.1", | ||
"json-schema-ref-parser": "^7.1.0", | ||
"json-to-ast": "^2.1.0", | ||
@@ -53,0 +53,0 @@ "node-fetch": "^2.6.0", |
@@ -211,3 +211,3 @@ const { expect } = require('chai'); | ||
it('should return a map with all the nested schemas', () => { | ||
const doc = JSON.parse(fs.readFileSync(path.resolve(__dirname, "../nested-schemas.json"), 'utf8')); | ||
const doc = JSON.parse(fs.readFileSync(path.resolve(__dirname, "../good/nested-schemas.json"), 'utf8')); | ||
const d = new AsyncAPIDocument(doc); | ||
@@ -214,0 +214,0 @@ const schemas = d.allSchemas(); |
@@ -0,1 +1,2 @@ | ||
const { EOL } = require('os'); | ||
const chai = require('chai'); | ||
@@ -11,7 +12,7 @@ const chaiAsPromised = require("chai-as-promised"); | ||
const invalidYAML = fs.readFileSync(path.resolve(__dirname, "./malformed-asyncapi.yaml"), 'utf8'); | ||
const inputYAML = fs.readFileSync(path.resolve(__dirname, "./asyncapi.yaml"), 'utf8'); | ||
const inputJSON = fs.readFileSync(path.resolve(__dirname, "./asyncapi.json"), 'utf8'); | ||
const invalidAsyncapiYAML = fs.readFileSync(path.resolve(__dirname, "./invalid-asyncapi.yaml"), 'utf8'); | ||
const invalidAsyncpiJSON = fs.readFileSync(path.resolve(__dirname, "./invalid-asyncapi.json"), 'utf8'); | ||
const invalidYAML = fs.readFileSync(path.resolve(__dirname, "./wrong/malformed-asyncapi.yaml"), 'utf8'); | ||
const inputYAML = fs.readFileSync(path.resolve(__dirname, "./good/asyncapi.yaml"), 'utf8'); | ||
const inputJSON = fs.readFileSync(path.resolve(__dirname, "./good/asyncapi.json"), 'utf8'); | ||
const invalidAsyncapiYAML = fs.readFileSync(path.resolve(__dirname, "./wrong/invalid-asyncapi.yaml"), 'utf8'); | ||
const invalidAsyncpiJSON = fs.readFileSync(path.resolve(__dirname, "./wrong/invalid-asyncapi.json"), 'utf8'); | ||
const outputJSON = '{"asyncapi":"2.0.0","info":{"title":"My API","version":"1.0.0"},"channels":{"mychannel":{"publish":{"externalDocs":{"x-extension":true,"url":"https://company.com/docs"},"message":{"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"},"x-parser-original-traits":[{"externalDocs":{"url":"https://company.com/docs"}}]}}},"components":{"messages":{"testMessage":{"payload":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"},"x-some-extension":"some extension","x-parser-original-traits":[{"x-some-extension":"some extension"}],"schemaFormat":"application/vnd.aai.asyncapi;version=2.0.0","x-parser-message-name":"testMessage"}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string","x-parser-schema-id":"<anonymous-schema-1>"},"test":{"type":"object","properties":{"testing":{"type":"string","x-parser-schema-id":"<anonymous-schema-3>"}},"x-parser-schema-id":"<anonymous-schema-2>"}},"x-parser-schema-id":"testSchema"}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}'; | ||
@@ -24,2 +25,4 @@ const invalidYamlOutput = '{"asyncapi":"2.0.0","info":{"version":"1.0.0"},"channels":{"mychannel":{"publish":{"traits":[{"externalDocs":{"url":"https://company.com/docs"}}],"externalDocs":{"x-extension":true,"url":"https://irrelevant.com"},"message":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}}}}}}},"components":{"messages":{"testMessage":{"traits":[{"x-some-extension":"some extension"}],"payload":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}}}}},"schemas":{"testSchema":{"type":"object","properties":{"name":{"type":"string"},"test":{"type":"object","properties":{"testing":{"type":"string"}}}}}},"messageTraits":{"extension":{"x-some-extension":"some extension"}},"operationTraits":{"docs":{"externalDocs":{"url":"https://company.com/docs"}}}}}' | ||
const eolLength = EOL.length; | ||
const checkErrorTypeAndMessage = async (fn, type, message) => { | ||
@@ -45,3 +48,5 @@ try { | ||
describe.only('parse()', function () { | ||
const offset = (offset, line) => (offset + ((eolLength - 1) * (line - 1))) | ||
describe('parse()', function () { | ||
it('should parse YAML', async function () { | ||
@@ -91,6 +96,6 @@ const result = await parser.parse(inputYAML, { path: __filename }); | ||
startColumn: 1, | ||
startOffset: 16, | ||
startOffset: offset(16, 2), | ||
endLine: 3, | ||
endColumn: 19, | ||
endOffset: 40, | ||
endOffset: offset(40, 3), | ||
} | ||
@@ -101,2 +106,25 @@ }]); | ||
}); | ||
it('should fail when asyncapi is not valid (ref with line break) (yaml)', async function () { | ||
try { | ||
await parser.parse(fs.readFileSync(path.resolve(__dirname, "./wrong/invalid-asyncapi-with-ref-with-line-break.yaml"), 'utf8'), { | ||
path: __filename, | ||
}); | ||
} catch (e) { | ||
await expect(e.type).to.equal('https://github.com/asyncapi/parser-js/validation-errors'); | ||
await expect(e.title).to.equal('There were errors validating the AsyncAPI document.'); | ||
await expect(e.validationErrors).to.deep.equal([{ | ||
title: '/channels/smartylighting~1streetlights~11~10~1action~1{streetlightId}~1turn~1off/parameters/streetlightId/$ref should match format \"uri-reference\"', | ||
location: { | ||
jsonPointer: '/channels/smartylighting~1streetlights~11~10~1action~1{streetlightId}~1turn~1off/parameters/streetlightId/$ref', | ||
startLine: 67, | ||
startColumn: 9, | ||
startOffset: offset(1970, 67), | ||
endLine: 68, | ||
endColumn: 46, | ||
endOffset: offset(2024, 68), | ||
} | ||
}]); | ||
} | ||
}); | ||
@@ -115,6 +143,6 @@ it('should fail when asyncapi is not valid (json)', async function () { | ||
startColumn: 11, | ||
startOffset: 33, | ||
startOffset: offset(33, 3), | ||
endLine: 5, | ||
endColumn: 4, | ||
endOffset: 58, | ||
endOffset: offset(58, 5), | ||
} | ||
@@ -161,3 +189,3 @@ }]); | ||
endColumn: 16, | ||
endOffset: 15, | ||
endOffset: offset(15, 1), | ||
}]); | ||
@@ -194,6 +222,6 @@ } | ||
startColumn: 11, | ||
startOffset: 615, | ||
startOffset: offset(615, 30), | ||
endLine: 30, | ||
endColumn: 34, | ||
endOffset: 638, | ||
endOffset: offset(638, 30), | ||
}]); | ||
@@ -211,6 +239,6 @@ } | ||
startColumn: 21, | ||
startOffset: 599, | ||
startOffset: offset(599, 38), | ||
endLine: 38, | ||
endColumn: 38, | ||
endOffset: 616, | ||
endOffset: offset(616, 38), | ||
}]); | ||
@@ -230,2 +258,65 @@ } | ||
it('should offer information about missing HTTP $refs', async function () { | ||
try { | ||
await parser.parse(fs.readFileSync(path.resolve(__dirname, "./wrong/inexisting-http-ref.yaml"), 'utf8'), { | ||
path: 'https://example.com', | ||
resolve: { | ||
file: false | ||
} | ||
}) | ||
} catch (e) { | ||
expect(e.refs).to.deep.equal([{ | ||
jsonPointer: '/channels/mychannel/publish/message/$ref', | ||
startLine: 9, | ||
startColumn: 9, | ||
startOffset: offset(116, 9), | ||
endLine: 9, | ||
endColumn: 68, | ||
endOffset: offset(175, 9), | ||
}]); | ||
} | ||
}); | ||
it('should offer information about missing root $refs', async function () { | ||
try { | ||
await parser.parse(fs.readFileSync(path.resolve(__dirname, "./wrong/inexisting-root-ref.yaml"), 'utf8'), { | ||
path: 'https://example.com', | ||
resolve: { | ||
file: false | ||
} | ||
}) | ||
} catch (e) { | ||
expect(e.refs).to.deep.equal([{ | ||
jsonPointer: '/channels/mychannel/subscribe/message/$ref', | ||
startLine: 9, | ||
startColumn: 9, | ||
startOffset: offset(118, 9), | ||
endLine: 9, | ||
endColumn: 49, | ||
endOffset: offset(158, 9), | ||
}]); | ||
} | ||
}); | ||
it('should offer information about missing local $refs', async function () { | ||
try { | ||
await parser.parse(fs.readFileSync(path.resolve(__dirname, "./wrong/inexisting-local-ref.yaml"), 'utf8'), { | ||
path: 'https://example.com', | ||
resolve: { | ||
file: false | ||
} | ||
}) | ||
} catch (e) { | ||
expect(e.refs).to.deep.equal([{ | ||
jsonPointer: '/channels/mychannel2/publish/message/$ref', | ||
startLine: 9, | ||
startColumn: 9, | ||
startOffset: offset(117, 9), | ||
endLine: 9, | ||
endColumn: 50, | ||
endOffset: offset(158, 9), | ||
}]); | ||
} | ||
}); | ||
it('should throw error if document is invalid YAML', async function () { | ||
@@ -232,0 +323,0 @@ try { |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
GitHub dependency
Supply chain riskContains a dependency which resolves to a GitHub URL. Dependencies fetched from GitHub specifiers are not immutable can be used to inject untrusted code or reduce the likelihood of a reproducible install.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
991088
80
7487
1
+ Added@apidevtools/json-schema-ref-parser@github:fmvilas/json-schema-ref-parser#add-more-info-about-errors
- Removedjson-schema-ref-parser@^7.1.0
- Removedcall-me-maybe@1.0.2(transitive)
- Removedjson-schema-ref-parser@7.1.4(transitive)
- Removedono@6.0.1(transitive)