Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
3 changes: 2 additions & 1 deletion packages/helpers/src/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { getMessageExamples, getOperationMessages } = require('./operations');
const { getServerUrl, getServer } = require('./servers');
const { getClientName, listFiles, getInfo } = require('./utils');
const { getClientName, listFiles, getTitle, getInfo } = require('./utils');
const { getQueryParams } = require('./bindings');

module.exports = {
Expand All @@ -11,5 +11,6 @@ module.exports = {
getQueryParams,
getOperationMessages,
getMessageExamples,
getTitle,
getInfo
};
73 changes: 47 additions & 26 deletions packages/helpers/src/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,48 @@
const { readdir } = require('fs/promises');

/**
* Validate and retrieve the AsyncAPI info object from an AsyncAPI document.
*
* Throws an error if the provided AsyncAPI document has no `info` section.
*
* @param {object} asyncapi - The AsyncAPI document object.
* @returns {object} The validated info object from the AsyncAPI document.
*/
const getInfo = (asyncapi) => {
if (!asyncapi) {
throw new Error('Make sure you pass AsyncAPI document as an argument.');
}
if (!asyncapi.info) {
throw new Error('Provided AsyncAPI document doesn\'t contain Info object.');
}
const info = asyncapi.info();
if (!info) {
throw new Error('AsyncAPI document info object cannot be empty.');
}
return info;
};

/**
* Validate and retrieve the AsyncAPI title parameter in the info object.
*
* Throws an error if the provided AsyncAPI info object lacks a `title` parameter.
*
* @param {object} asyncapi - The AsyncAPI document object.
* @throws {Error} When `title` is `null` or `undefined` or `empty string` .
* @returns {string} The retrieved `title` parameter.
*/
const getTitle = asyncapi => {
const info = getInfo(asyncapi);
if (!info.title) {
throw new Error('Provided AsyncAPI document info field doesn\'t contain title.');
}
const title = info.title();
if (title === '') {
throw new Error('AsyncAPI document title cannot be an empty string.');
}

return title;
};
/**
* Get client name from AsyncAPI info.title or uses a custom name if provided.
*
Expand All @@ -9,11 +52,11 @@ const { readdir } = require('fs/promises');
*
* @returns {string} The formatted client name, either the custom name or a generated name based on the title
*/
const getClientName = (info, appendClientSuffix, customClientName) => {
const getClientName = (asyncapi, appendClientSuffix, customClientName) => {
if (customClientName) {
return customClientName;
}
const title = info.title();
const title = getTitle(asyncapi);
const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
.replace(/^./, char => char.toUpperCase())}`; // Make the first letter uppercase
return appendClientSuffix ? `${baseName}Client` : baseName;
Expand All @@ -35,31 +78,9 @@ const listFiles = async (dir) => {
.map(dirE => dirE.name);
};

/**
* Validate and retrieve the AsyncAPI info object from an AsyncAPI document.
*
* Throws an error if the provided AsyncAPI document has no `info` section.
*
* @param {object} asyncapi - The AsyncAPI document object.
* @returns {object} The validated info object from the AsyncAPI document.
*/
const getInfo = (asyncapi) => {
if (!asyncapi) {
throw new Error('Make sure you pass AsyncAPI document as an argument.');
}
if (!asyncapi.info) {
throw new Error('Provided AsyncAPI document doesn\'t contain Info object.');
}
const info = asyncapi.info();
if (!info) {
throw new Error('AsyncAPI document info object cannot be empty.');
}
return info;
};

module.exports = {
getClientName,
listFiles,
getInfo
getInfo,
getTitle
};

50 changes: 43 additions & 7 deletions packages/helpers/test/utils.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const path = require('path');
const { Parser, fromFile } = require('@asyncapi/parser');
const { getClientName, getInfo } = require('@asyncapi/generator-helpers');
const { getClientName, getTitle, getInfo } = require('@asyncapi/generator-helpers');

const parser = new Parser();
const asyncapi_v3_path = path.resolve(__dirname, './__fixtures__/asyncapi-websocket-query.yml');
Expand All @@ -14,33 +14,30 @@ describe('getClientName integration test with AsyncAPI', () => {
});

it('should generate correct client name for the provided AsyncAPI info object without appendClientSuffix', () => {
const info = parsedAsyncAPIDocument.info();
const appendClientSuffix = false;
const customClientName = '';

const clientName = getClientName(info, appendClientSuffix, customClientName);
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);

// Example assertion: Check if the name is formatted correctly
expect(clientName).toBe('GeminiMarketDataWebsocketAPI');
});

it('should generate correct client name for the provided AsyncAPI info object with appendClientSuffix', () => {
const info = parsedAsyncAPIDocument.info();
const appendClientSuffix = true;
const customClientName = '';

const clientName = getClientName(info, appendClientSuffix, customClientName);
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);

// Example assertion: Check if the name is formatted correctly
expect(clientName).toBe('GeminiMarketDataWebsocketAPIClient');
});

it('should return customClientName', () => {
const info = parsedAsyncAPIDocument.info();
const appendClientSuffix = false;
const customClientName = 'GeminiClient';

const clientName = getClientName(info, appendClientSuffix, customClientName);
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);

// Example assertion: Check if the name is formatted correctly
expect(clientName).toBe(customClientName);
Expand Down Expand Up @@ -80,4 +77,43 @@ describe('getInfo integration test with AsyncAPI', () => {
getInfo(null);
}).toThrow('Make sure you pass AsyncAPI document as an argument.');
});
});

describe('getTitle integration test with AsyncAPI', () => {
let parsedAsyncAPIDocument;

beforeAll(async () => {
const parseResult = await fromFile(parser, asyncapi_v3_path).parse();
parsedAsyncAPIDocument = parseResult.document;
});

it('should return the exact title parameter when exists', () => {
const info = parsedAsyncAPIDocument.info();
const expectedTitle = info.title();
const actualTitle = getTitle(parsedAsyncAPIDocument);
expect(actualTitle).toStrictEqual(expectedTitle);
});

it('should throw error when title function does not exist', () => {
const asyncAPIDocWithoutTitle = {
info: () => ({
// info object without title method
})
};
expect(() => {
getTitle(asyncAPIDocWithoutTitle);
}).toThrow('Provided AsyncAPI document info field doesn\'t contain title.');
});

it('should throw error when title is an empty string', () => {
const asyncAPIDocWithEmptyTitle = {
info: () => ({
title: () => ''
})
};

expect(() => {
getTitle(asyncAPIDocWithEmptyTitle);
}).toThrow('AsyncAPI document title cannot be an empty string.');
});
});
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { File } from '@asyncapi/generator-react-sdk';
import { getClientName, getServerUrl, getServer, getInfo } from '@asyncapi/generator-helpers';
import { getClientName, getServerUrl, getServer, getInfo, getTitle } from '@asyncapi/generator-helpers';
import { FileHeaderInfo } from '../components/FileHeaderInfo';
import { Requires } from '../components/Requires';
import { ClientClass } from '../components/ClientClass';

export default function ({ asyncapi, params }) {
const server = getServer(asyncapi.servers(), params.server);
const info = getInfo(asyncapi);
const title = info.title();
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
const title = getTitle(asyncapi);
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
const serverUrl = getServerUrl(server);
return (
// The clientFileName default values can be found and modified under the package.json
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { AvailableOperations } from '../components/AvailableOperations';
export default function({ asyncapi, params }) {
const server = getServer(asyncapi.servers(), params.server);
const info = asyncapi.info();
const clientName = getClientName(info);
const clientName = getClientName(asyncapi);

const operations = asyncapi.operations().all();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { File } from '@asyncapi/generator-react-sdk';
import { getClientName, getServerUrl, getServer, getInfo } from '@asyncapi/generator-helpers';
import { getClientName, getServerUrl, getServer, getInfo, getTitle } from '@asyncapi/generator-helpers';
import { FileHeaderInfo } from '../components/FileHeaderInfo';
import { Requires } from '../components/Requires';
import { ClientClass } from '../components/ClientClass';

export default function ({ asyncapi, params }) {
const server = getServer(asyncapi.servers(), params.server);
const info = getInfo(asyncapi);
const title = info.title();
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
const title = getTitle(asyncapi);
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
const serverUrl = getServerUrl(server);
const sendOperations = asyncapi.operations().filterBySend();
return (
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { File } from '@asyncapi/generator-react-sdk';
import { getClientName, getServerUrl, getServer, getQueryParams, getInfo } from '@asyncapi/generator-helpers';
import { getClientName, getServerUrl, getServer, getQueryParams, getInfo, getTitle } from '@asyncapi/generator-helpers';
import { FileHeaderInfo } from '../components/FileHeaderInfo';
import { Requires } from '../components/Requires';
import { ClientClass } from '../components/ClientClass';

export default function ({ asyncapi, params }) {
const server = getServer(asyncapi.servers(), params.server);
const info = getInfo(asyncapi);
const title = info.title();
const title = getTitle(asyncapi);
const queryParams = getQueryParams(asyncapi.channels());
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
const serverUrl = getServerUrl(server);
return (
// The clientFileName default values can be found and modified under the package.json
Expand Down