Skip to content

Commit

Permalink
fix: handle JSON input/output (#96)
Browse files Browse the repository at this point in the history
  • Loading branch information
magicmatatjahu authored Feb 18, 2022
1 parent f9fd48e commit 65d81c8
Show file tree
Hide file tree
Showing 5 changed files with 417 additions and 5 deletions.
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

0 comments on commit 65d81c8

Please sign in to comment.