Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: handle JSON #96

Merged
merged 5 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,16 @@ if (!version) {

try {
const asyncapi = fs.readFileSync(asyncapiFile, 'utf-8');
console.log(converter.convert(asyncapi, version, {
let converted = converter.convert(asyncapi, version, {
id: program.id,
}));
});

// JSON case
if (typeof converted === 'object') {
converted = JSON.stringify(converted, undefined, 2);
}

console.log(converted);
} catch (e) {
showErrorAndExit(e);
}
Expand Down
22 changes: 20 additions & 2 deletions lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,34 @@ const yaml = require('js-yaml');
const helpers = module.exports;

helpers.serialize = (text) => {
if (typeof text === 'object') {
return {
isYAML: false,
parsed: text,
};
}

try {
const maybeJSON = JSON.parse(text);
if (typeof maybeJSON === 'object') {
return {
isYAML: false,
parsed: maybeJSON,
};
}

// if `maybeJSON` is object, then we have 100% sure that we operate on JSON,
// but if it's `string` then we have option that it can be YAML but it doesn't have to be
return {
isYAML: true,
parsed: yaml.safeLoad(text)
};
} catch (e) {
try {
// try to parse again YAML, because the text itself may not have a JSON representation and cannot be represented as a JSON object/string
return {
isYAML: false,
parsed: JSON.parse(text)
isYAML: true,
parsed: yaml.safeLoad(text)
};
} catch (err) {
throw new Error('AsyncAPI document must be a valid JSON or YAML document.');
Expand Down
45 changes: 44 additions & 1 deletion test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const assert = require('assert');
const fs = require('fs');
const path = require("path");
const { convert } = require('../lib');
const { serialize } = require('../lib/helpers');

describe('#convert', () => {
it('should not convert to lowest version', () => {
Expand Down Expand Up @@ -193,6 +194,48 @@ describe('#convert', () => {
const result = convert(input, '2.3.0');
assertResults(output, result);
});

it('should convert from 2.0.0 to 2.1.0 (JSON case)', () => {
const input = fs.readFileSync(path.resolve(__dirname, 'input', '2.0.0', 'streetlights.json'), 'utf8');
let output = fs.readFileSync(path.resolve(__dirname, 'output', '2.1.0', 'streetlights.json'), 'utf8');
let result = convert(input, '2.1.0');

output = JSON.stringify(JSON.parse(output));
result = JSON.stringify(JSON.parse(JSON.stringify(result)));
assert.strictEqual(output, result);
});
});

describe('#serialize', () => {
it('should serialize JSON', () => {
const input = '{"foo": "bar"}';
const output = serialize(input);
assert.strictEqual(output.isYAML, false);
assert.deepEqual(output.parsed, {foo: "bar"});
});

it('should serialize YAML', () => {
const input = 'foo: bar';
const output = serialize(input);
assert.strictEqual(output.isYAML, true);
assert.deepEqual(output.parsed, {foo: "bar"});
});

it('should serialize YAML (with JSON syntax)', () => {
const input = '{foo: bar}';
const output = serialize(input);
assert.strictEqual(output.isYAML, true);
assert.deepEqual(output.parsed, {foo: "bar"});
});

it('should throw error', () => {
const input = '%{foo: bar}';
try {
serialize(input);
} catch(e) {
assert.strictEqual(e.message, 'AsyncAPI document must be a valid JSON or YAML document.');
}
});
});

/*
Expand All @@ -205,4 +248,4 @@ function removeLineBreaks(str) {

function assertResults(output, result){
assert.strictEqual(removeLineBreaks(output), removeLineBreaks(result));
}
}
172 changes: 172 additions & 0 deletions test/input/2.0.0/streetlights.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
{
"asyncapi": "2.0.0",
"info": {
"title": "Streetlights API",
"version": "1.0.0",
"description": "The Smartylighting Streetlights API allows you to remotely manage the city lights.\n\n### Check out its awesome features:\n\n* Turn a specific streetlight on/off 🌃\n* Dim a specific streetlight 😎\n* Receive real-time information about environmental lighting conditions 📈\n",
"license": {
"name": "Apache 2.0",
"url": "https://www.apache.org/licenses/LICENSE-2.0"
}
},
"servers": {
"default": {
"url": "api.streetlights.smartylighting.com:{port}",
"description": "Test broker",
"variables": {
"port": {
"description": "Secure connection (TLS) is available through port 8883.",
"default": "1883",
"enum": [
"1883",
"8883"
]
}
},
"protocol": "mqtt",
"security": [
{
"apiKey": []
}
]
}
},
"components": {
"messages": {
"lightMeasured": {
"summary": "Inform about environmental lighting conditions for a particular streetlight.",
"payload": {
"$ref": "#/components/schemas/lightMeasuredPayload"
}
},
"turnOnOff": {
"summary": "Command a particular streetlight to turn the lights on or off.",
"payload": {
"$ref": "#/components/schemas/turnOnOffPayload"
}
},
"dimLight": {
"summary": "Command a particular streetlight to dim the lights.",
"payload": {
"$ref": "#/components/schemas/dimLightPayload"
}
}
},
"schemas": {
"lightMeasuredPayload": {
"type": "object",
"properties": {
"lumens": {
"type": "integer",
"minimum": 0,
"description": "Light intensity measured in lumens."
},
"sentAt": {
"$ref": "#/components/schemas/sentAt"
}
}
},
"turnOnOffPayload": {
"type": "object",
"properties": {
"command": {
"type": "string",
"enum": [
"on",
"off"
],
"description": "Whether to turn on or off the light."
},
"sentAt": {
"$ref": "#/components/schemas/sentAt"
}
}
},
"dimLightPayload": {
"type": "object",
"properties": {
"percentage": {
"type": "integer",
"description": "Percentage to which the light should be dimmed to.",
"minimum": 0,
"maximum": 100
},
"sentAt": {
"$ref": "#/components/schemas/sentAt"
}
}
},
"sentAt": {
"type": "string",
"format": "date-time",
"description": "Date and time when the message was sent."
}
},
"securitySchemes": {
"apiKey": {
"type": "apiKey",
"in": "user",
"description": "Provide your API key as the user and leave the password empty."
}
},
"parameters": {
"streetlightId": {
"name": "streetlightId",
"description": "The ID of the streetlight.",
"schema": {
"type": "string"
}
}
}
},
"channels": {
"smartylighting/streetlights/1/0/event/{streetlightId}/lighting/measured": {
"parameters": {
"streetlightId": {
"$ref": "#/components/parameters/streetlightId"
}
},
"publish": {
"message": {
"$ref": "#/components/messages/lightMeasured"
}
}
},
"smartylighting/streetlights/1/0/action/{streetlightId}/turn/on": {
"parameters": {
"streetlightId": {
"$ref": "#/components/parameters/streetlightId"
}
},
"subscribe": {
"message": {
"$ref": "#/components/messages/turnOnOff"
}
}
},
"smartylighting/streetlights/1/0/action/{streetlightId}/turn/off": {
"parameters": {
"streetlightId": {
"$ref": "#/components/parameters/streetlightId"
}
},
"subscribe": {
"message": {
"$ref": "#/components/messages/turnOnOff"
}
}
},
"smartylighting/streetlights/1/0/action/{streetlightId}/dim": {
"parameters": {
"streetlightId": {
"$ref": "#/components/parameters/streetlightId"
}
},
"subscribe": {
"message": {
"$ref": "#/components/messages/dimLight"
}
}
}
}
}
Loading