Skip to content

Commit

Permalink
rewrite handlers, readme, routes
Browse files Browse the repository at this point in the history
  • Loading branch information
kaushik-rishi committed Apr 30, 2024
1 parent 0c1a899 commit dd4bbd5
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 97 deletions.
17 changes: 16 additions & 1 deletion template/README.md.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
import { File } from '@asyncapi/generator-react-sdk';

export default function readmeFile({asyncapi, params}) {
const server = asyncapi.allServers().get(params.server);
const protocol = server.protocol();
const security = server.security();

let hasSecuritySchemeX509 = false;
let securitySchemeType;
if (params.securityScheme && security && security.length > 0) {
const securityReq = security[0].all();
if (securityReq && securityReq.length > 0) {
securitySchemeType = securityReq[0].scheme().type();
}
}

hasSecuritySchemeX509 = (params.securityScheme && (protocol === 'kafka' || protocol === 'kafka-secure') && securitySchemeType === 'X509');

return <File name={'README.md'}>
{`# ${ asyncapi.info().title() }
Expand All @@ -12,7 +27,7 @@ ${ asyncapi.info().description() || '' }
\`\`\`sh
npm i
\`\`\`
${(params.securityScheme && (asyncapi.server(params.server).protocol() === 'kafka' || asyncapi.server(params.server).protocol() === 'kafka-secure') && asyncapi.components().securityScheme(params.securityScheme).type() === 'X509') ? '1. (Optional) For X509 security provide files with all data required to establish secure connection using certificates. Place files like `ca.pem`, `service.cert`, `service.key` in the root of the project or the location that you explicitly specified during generation.' : ''}
${ hasSecuritySchemeX509 ? '1. (Optional) For X509 security provide files with all data required to establish secure connection using certificates. Place files like `ca.pem`, `service.cert`, `service.key` in the root of the project or the location that you explicitly specified during generation.' : ''}
## Import and start
Expand Down
97 changes: 47 additions & 50 deletions template/src/api/handlers/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,43 +8,41 @@ import { File } from '@asyncapi/generator-react-sdk';

const OPTIONS_MESSAGE_HEADERS_STRING = 'options.message.headers';

function publishHandler(channel) {
if (!channel.hasPublish()) {
function receiveHandler(operation) {
if (!operation.isReceive()) {
return '';
}

const lambdaChannel = channel.publish().ext('x-lambda');
const publishOperationId = channel.publish().id();
const publishMessage = channel.publish().message(0);
const operationId = operation.id();
const message = operation.messages().all()[0];
const lambdaChannel = operation.extensions().get('x-lambda');

const exportedHandler = `
/**
* Registers a middleware function for the ${publishOperationId} operation to be executed during request processing.
* Registers a middleware function for the ${operationId} operation to be executed during request processing.
*
* Middleware functions have access to options object that you can use to access the message content and other helper functions
*
* @param {function} middlewareFn - The middleware function to be registered.
* @throws {TypeError} If middlewareFn is not a function.
*/
handler.${convertOpertionIdToMiddlewareFn(
channel.publish().id()
)} = (middlewareFn) => {
handler.${convertOpertionIdToMiddlewareFn(operationId)} = (middlewareFn) => {
if (typeof middlewareFn !== 'function') {
throw new TypeError('middlewareFn must be a function');
}
${publishOperationId}Middlewares.push(middlewareFn);
${operationId}Middlewares.push(middlewareFn);
}
`;

const privateHandlerLogic = `
/**
* ${channel.publish().summary() || ''}
* ${operation.hasSummary() ? operation.summary() : ''}
*
* @param {object} options
* @param {object} options.message
${
publishMessage.headers()
? Object.entries(publishMessage.headers().properties())
message.headers()
? Object.entries(message.headers().properties())
.map(([fieldName, field]) => {
return docline(field, fieldName, OPTIONS_MESSAGE_HEADERS_STRING);
})
Expand All @@ -53,16 +51,16 @@ function publishHandler(channel) {
}
*
${
publishMessage.payload()
? Object.entries(publishMessage.payload().properties())
message.payload()
? Object.entries(message.payload().properties())
.map(([fieldName, field]) => {
return docline(field, fieldName, OPTIONS_MESSAGE_HEADERS_STRING);
})
.join('\n')
: ''
}
*/
handler._${publishOperationId} = async ({message}) => {
handler._${operationId} = async ({message}) => {
${
lambdaChannel
? `
Expand All @@ -74,7 +72,7 @@ function publishHandler(channel) {
.then(res => res.json())
.then(json => console.log(json))
.catch(err => { throw err; });`
: `for (const middleware of ${publishOperationId}Middlewares) {
: `for (const middleware of ${operationId}Middlewares) {
await middleware(message);
}`
}
Expand All @@ -84,50 +82,48 @@ function publishHandler(channel) {
return `
${lambdaChannel ? 'const fetch = require("node-fetch");' : ''}
const ${publishOperationId}Middlewares = [];
const ${operationId}Middlewares = [];
${exportedHandler}
${privateHandlerLogic}
`;
}

function subscribeHandler(channel) {
if (!channel.hasSubscribe()) {
function sendHandler(operation) {
if (!operation.isSend()) {
return '';
}

const subscribeOperationId = channel.subscribe().id();
const subscribeMessage = channel.subscribe().message(0);
const operationId = operation.id();
const message = operation.messages().all()[0];

const exportedHandler = `
/**
* Registers a middleware function for the ${subscribeOperationId} operation to be executed during request processing.
* Registers a middleware function for the ${operationId} operation to be executed during request processing.
*
* Middleware functions have access to options object that you can use to access the message content and other helper functions
*
* @param {function} middlewareFn - The middleware function to be registered.
* @throws {TypeError} If middlewareFn is not a function.
*/
handler.${convertOpertionIdToMiddlewareFn(
channel.subscribe().id()
)} = (middlewareFn) => {
handler.${convertOpertionIdToMiddlewareFn(operationId)} = (middlewareFn) => {
if (typeof middlewareFn !== 'function') {
throw new TypeError('middlewareFn must be a function');
}
${subscribeOperationId}Middlewares.push(middlewareFn);
${operationId}Middlewares.push(middlewareFn);
}
`;

const privateHandlerLogic = `
/**
* ${channel.subscribe().summary() || ''}
* ${operation.hasSummary() ? operation.summary() : ''}
*
* @param {object} options
* @param {object} options.message
${
subscribeMessage.headers()
? Object.entries(subscribeMessage.headers().properties())
message.headers()
? Object.entries(message.headers().properties())
.map(([fieldName, field]) => {
return docline(field, fieldName, OPTIONS_MESSAGE_HEADERS_STRING);
})
Expand All @@ -136,24 +132,24 @@ function subscribeHandler(channel) {
}
*
${
subscribeMessage.payload()
? Object.entries(subscribeMessage.payload().properties())
message.payload()
? Object.entries(message.payload().properties())
.map(([fieldName, field]) => {
return docline(field, fieldName, OPTIONS_MESSAGE_HEADERS_STRING);
})
.join('\n')
: ''
}
*/
handler._${subscribeOperationId} = async ({message}) => {
for (const middleware of ${subscribeOperationId}Middlewares) {
handler._${operationId} = async ({message}) => {
for (const middleware of ${operationId}Middlewares) {
await middleware(message);
}
};
`;

return `
const ${subscribeOperationId}Middlewares = [];
const ${operationId}Middlewares = [];
${exportedHandler}
Expand All @@ -167,21 +163,22 @@ export default function handlerRender({
const general = `
const handler = module.exports = {};
`;

const channels = asyncapi.channels();

return Object.entries(channels).map(([channelName, channel]) => {
const hasPublish = channel.publish();
const hasSubscribe = channel.hasSubscribe();

return (
<File name={`${convertToFilename(channelName)}.js`}>
{`
${general}
${hasPublish ? publishHandler(channel) : ''}
${hasSubscribe ? subscribeHandler(channel) : ''}
`}
</File>
);
return asyncapi.channels().all().map(channel => {
const channelName = channel.id();

let routeHandler = `
${general}
`;

for (let operation of channel.operations()) {
if (operation.isSend()) {
routeHandler += sendHandler(operation);
}
if (operation.isReceive()) {
routeHandler += receiveHandler(operation);
}
}
return <File name={`${convertToFilename(channelName)}.js`}>{routeHandler}</File>;
});
}
7 changes: 4 additions & 3 deletions template/src/api/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,12 @@ export default function indexEntrypointFile({asyncapi, params}) {

const handlers = asyncapi.channels().all().map(channel => {
const channelName = channel.id();
return channel.operations().all().map(operation => {
const x = channel.operations().all().map(operation => {
let operationId = operation.id();
return `${convertOpertionIdToMiddlewareFn(operationId)} : require('./handlers/${convertToFilename(channelName)}').${convertOpertionIdToMiddlewareFn(operationId)}`
}).join(',');
}).join('\n');
});
return x;
}).join(',');

return <File name={'index.js'}>
{`
Expand Down
Loading

0 comments on commit dd4bbd5

Please sign in to comment.