Skip to content

Commit 056f0ed

Browse files
ItshMohderberg
andauthored
chore: add the getTitle helper (#1568)
Co-authored-by: ItshMoh <mohan.kumar.min22@itbhu.ac.in> Co-authored-by: Lukasz Gornicki <lpgornicki@gmail.com>
1 parent 767455d commit 056f0ed

File tree

7 files changed

+101
-42
lines changed

7 files changed

+101
-42
lines changed

packages/helpers/src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const { getMessageExamples, getOperationMessages } = require('./operations');
22
const { getServerUrl, getServer } = require('./servers');
3-
const { getClientName, listFiles, getInfo, toSnakeCase } = require('./utils');
3+
const { getClientName, listFiles, getInfo, toSnakeCase, getTitle} = require('./utils');
44
const { getQueryParams } = require('./bindings');
55

66
module.exports = {
@@ -11,6 +11,7 @@ module.exports = {
1111
getQueryParams,
1212
getOperationMessages,
1313
getMessageExamples,
14+
getTitle,
1415
getInfo,
1516
toSnakeCase
1617
};

packages/helpers/src/utils.js

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,48 @@
11
const { readdir } = require('fs/promises');
22

3+
/**
4+
* Validate and retrieve the AsyncAPI info object from an AsyncAPI document.
5+
*
6+
* Throws an error if the provided AsyncAPI document has no `info` section.
7+
*
8+
* @param {object} asyncapi - The AsyncAPI document object.
9+
* @returns {object} The validated info object from the AsyncAPI document.
10+
*/
11+
const getInfo = (asyncapi) => {
12+
if (!asyncapi) {
13+
throw new Error('Make sure you pass AsyncAPI document as an argument.');
14+
}
15+
if (!asyncapi.info) {
16+
throw new Error('Provided AsyncAPI document doesn\'t contain Info object.');
17+
}
18+
const info = asyncapi.info();
19+
if (!info) {
20+
throw new Error('AsyncAPI document info object cannot be empty.');
21+
}
22+
return info;
23+
};
24+
25+
/**
26+
* Validate and retrieve the AsyncAPI title parameter in the info object.
27+
*
28+
* Throws an error if the provided AsyncAPI info object lacks a `title` parameter.
29+
*
30+
* @param {object} asyncapi - The AsyncAPI document object.
31+
* @throws {Error} When `title` is `null` or `undefined` or `empty string` .
32+
* @returns {string} The retrieved `title` parameter.
33+
*/
34+
const getTitle = asyncapi => {
35+
const info = getInfo(asyncapi);
36+
if (!info.title) {
37+
throw new Error('Provided AsyncAPI document info field doesn\'t contain title.');
38+
}
39+
const title = info.title();
40+
if (title === '') {
41+
throw new Error('AsyncAPI document title cannot be an empty string.');
42+
}
43+
44+
return title;
45+
};
346
/**
447
* Get client name from AsyncAPI info.title or uses a custom name if provided.
548
*
@@ -9,11 +52,11 @@ const { readdir } = require('fs/promises');
952
*
1053
* @returns {string} The formatted client name, either the custom name or a generated name based on the title
1154
*/
12-
const getClientName = (info, appendClientSuffix, customClientName) => {
55+
const getClientName = (asyncapi, appendClientSuffix, customClientName) => {
1356
if (customClientName) {
1457
return customClientName;
1558
}
16-
const title = info.title();
59+
const title = getTitle(asyncapi);
1760
const baseName = `${title.replace(/\s+/g, '') // Remove all spaces
1861
.replace(/^./, char => char.toUpperCase())}`; // Make the first letter uppercase
1962
return appendClientSuffix ? `${baseName}Client` : baseName;
@@ -35,28 +78,6 @@ const listFiles = async (dir) => {
3578
.map(dirE => dirE.name);
3679
};
3780

38-
/**
39-
* Validate and retrieve the AsyncAPI info object from an AsyncAPI document.
40-
*
41-
* Throws an error if the provided AsyncAPI document has no `info` section.
42-
*
43-
* @param {object} asyncapi - The AsyncAPI document object.
44-
* @returns {object} The validated info object from the AsyncAPI document.
45-
*/
46-
const getInfo = (asyncapi) => {
47-
if (!asyncapi) {
48-
throw new Error('Make sure you pass AsyncAPI document as an argument.');
49-
}
50-
if (!asyncapi.info) {
51-
throw new Error('Provided AsyncAPI document doesn\'t contain Info object.');
52-
}
53-
const info = asyncapi.info();
54-
if (!info) {
55-
throw new Error('AsyncAPI document info object cannot be empty.');
56-
}
57-
return info;
58-
};
59-
6081
/**
6182
* Convert a camelCase or PascalCase string to snake_case.
6283
* If the string is already in snake_case, it will be returned unchanged.
@@ -75,6 +96,7 @@ const toSnakeCase = (inputStr) => {
7596
module.exports = {
7697
getClientName,
7798
listFiles,
99+
getTitle,
78100
getInfo,
79101
toSnakeCase
80102
};

packages/helpers/test/utils.test.js

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const path = require('path');
22
const { Parser, fromFile } = require('@asyncapi/parser');
3-
const { getClientName, getInfo, toSnakeCase } = require('@asyncapi/generator-helpers');
3+
const { getClientName, getInfo, getTitle, toSnakeCase } = require('@asyncapi/generator-helpers');
44

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

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

21-
const clientName = getClientName(info, appendClientSuffix, customClientName);
20+
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);
2221

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

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

32-
const clientName = getClientName(info, appendClientSuffix, customClientName);
30+
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);
3331

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

3836
it('should return customClientName', () => {
39-
const info = parsedAsyncAPIDocument.info();
4037
const appendClientSuffix = false;
4138
const customClientName = 'GeminiClient';
4239

43-
const clientName = getClientName(info, appendClientSuffix, customClientName);
40+
const clientName = getClientName(parsedAsyncAPIDocument, appendClientSuffix, customClientName);
4441

4542
// Example assertion: Check if the name is formatted correctly
4643
expect(clientName).toBe(customClientName);
@@ -82,6 +79,45 @@ describe('getInfo integration test with AsyncAPI', () => {
8279
});
8380
});
8481

82+
describe('getTitle integration test with AsyncAPI', () => {
83+
let parsedAsyncAPIDocument;
84+
85+
beforeAll(async () => {
86+
const parseResult = await fromFile(parser, asyncapi_v3_path).parse();
87+
parsedAsyncAPIDocument = parseResult.document;
88+
});
89+
90+
it('should return the exact title parameter when exists', () => {
91+
const info = parsedAsyncAPIDocument.info();
92+
const expectedTitle = info.title();
93+
const actualTitle = getTitle(parsedAsyncAPIDocument);
94+
expect(actualTitle).toStrictEqual(expectedTitle);
95+
});
96+
97+
it('should throw error when title function does not exist', () => {
98+
const asyncAPIDocWithoutTitle = {
99+
info: () => ({
100+
// info object without title method
101+
})
102+
};
103+
expect(() => {
104+
getTitle(asyncAPIDocWithoutTitle);
105+
}).toThrow('Provided AsyncAPI document info field doesn\'t contain title.');
106+
});
107+
108+
it('should throw error when title is an empty string', () => {
109+
const asyncAPIDocWithEmptyTitle = {
110+
info: () => ({
111+
title: () => ''
112+
})
113+
};
114+
115+
expect(() => {
116+
getTitle(asyncAPIDocWithEmptyTitle);
117+
}).toThrow('AsyncAPI document title cannot be an empty string.');
118+
});
119+
});
120+
85121
describe('toSnakeCase integration test with AsyncAPI', () => {
86122
let parsedAsyncAPIDocument, operations;
87123

packages/templates/clients/websocket/dart/template/client.dart.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { File } from '@asyncapi/generator-react-sdk';
2-
import { getClientName, getServerUrl, getServer, getInfo } from '@asyncapi/generator-helpers';
2+
import { getClientName, getServerUrl, getServer, getInfo, getTitle } from '@asyncapi/generator-helpers';
33
import { FileHeaderInfo } from '../components/FileHeaderInfo';
44
import { Requires } from '../components/Requires';
55
import { ClientClass } from '../components/ClientClass';
66

77
export default function ({ asyncapi, params }) {
88
const server = getServer(asyncapi.servers(), params.server);
99
const info = getInfo(asyncapi);
10-
const title = info.title();
11-
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
10+
const title = getTitle(asyncapi);
11+
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
1212
const serverUrl = getServerUrl(server);
1313
return (
1414
// The clientFileName default values can be found and modified under the package.json

packages/templates/clients/websocket/javascript/template/README.md.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { AvailableOperations } from '../components/AvailableOperations';
55
export default function({ asyncapi, params }) {
66
const server = getServer(asyncapi.servers(), params.server);
77
const info = asyncapi.info();
8-
const clientName = getClientName(info);
8+
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
99

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

packages/templates/clients/websocket/javascript/template/client.js.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import { File } from '@asyncapi/generator-react-sdk';
2-
import { getClientName, getServerUrl, getServer, getInfo } from '@asyncapi/generator-helpers';
2+
import { getClientName, getServerUrl, getServer, getInfo, getTitle } from '@asyncapi/generator-helpers';
33
import { FileHeaderInfo } from '../components/FileHeaderInfo';
44
import { Requires } from '../components/Requires';
55
import { ClientClass } from '../components/ClientClass';
66

77
export default function ({ asyncapi, params }) {
88
const server = getServer(asyncapi.servers(), params.server);
99
const info = getInfo(asyncapi);
10-
const title = info.title();
11-
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
10+
const title = getTitle(asyncapi);
11+
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
1212
const serverUrl = getServerUrl(server);
1313
const sendOperations = asyncapi.operations().filterBySend();
1414
return (

packages/templates/clients/websocket/python/template/client.py.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
import { File } from '@asyncapi/generator-react-sdk';
2-
import { getClientName, getServerUrl, getServer, getQueryParams, getInfo } from '@asyncapi/generator-helpers';
2+
import { getClientName, getServerUrl, getServer, getQueryParams, getInfo, getTitle } from '@asyncapi/generator-helpers';
33
import { FileHeaderInfo } from '../components/FileHeaderInfo';
44
import { Requires } from '../components/Requires';
55
import { ClientClass } from '../components/ClientClass';
66

77
export default function ({ asyncapi, params }) {
88
const server = getServer(asyncapi.servers(), params.server);
99
const info = getInfo(asyncapi);
10-
const title = info.title();
10+
const title = getTitle(asyncapi);
1111
const queryParams = getQueryParams(asyncapi.channels());
12-
const clientName = getClientName(info, params.appendClientSuffix, params.customClientName);
12+
const clientName = getClientName(asyncapi, params.appendClientSuffix, params.customClientName);
1313
const serverUrl = getServerUrl(server);
1414
const operations = asyncapi.operations();
1515
return (

0 commit comments

Comments
 (0)