Skip to content
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
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,4 @@ Get an overview of how to contribute to the project




1 change: 1 addition & 0 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,3 +153,4 @@ Prefix that follows specification is not enough though. Remember that the title




1 change: 1 addition & 0 deletions docs/migrations/v0.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,4 @@ const subscriber = await jetStreamPullSubscribeToReceiveUserSignedup({
```



6 changes: 3 additions & 3 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ $ npm install -g @the-codegen-project/cli
$ codegen COMMAND
running command...
$ codegen (--version)
@the-codegen-project/cli/0.40.0 linux-x64 node-v18.20.8
@the-codegen-project/cli/0.41.0 linux-x64 node-v18.20.8
$ codegen --help [COMMAND]
USAGE
$ codegen COMMAND
Expand Down Expand Up @@ -81,7 +81,7 @@ DESCRIPTION
Generate code based on your configuration, use `init` to get started.
```

_See code: [src/commands/generate.ts](https://github.com/the-codegen-project/cli/blob/v0.40.0/src/commands/generate.ts)_
_See code: [src/commands/generate.ts](https://github.com/the-codegen-project/cli/blob/v0.41.0/src/commands/generate.ts)_

## `codegen help [COMMAND]`

Expand Down Expand Up @@ -139,7 +139,7 @@ DESCRIPTION
Initialize The Codegen Project in your project
```

_See code: [src/commands/init.ts](https://github.com/the-codegen-project/cli/blob/v0.40.0/src/commands/init.ts)_
_See code: [src/commands/init.ts](https://github.com/the-codegen-project/cli/blob/v0.41.0/src/commands/init.ts)_

## `codegen version`

Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@the-codegen-project/cli",
"description": "CLI to work with code generation in any environment",
"version": "0.40.0",
"version": "0.41.0",
"bin": {
"codegen": "./bin/run.mjs"
},
Expand Down
6 changes: 4 additions & 2 deletions schemas/configuration-schema-0.json
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,8 @@
"kafka",
"mqtt",
"amqp",
"event_source"
"event_source",
"http_client"
]
},
"default": [],
Expand Down Expand Up @@ -224,8 +225,9 @@
"kafka_publish",
"kafka_subscribe",
"amqp_queue_publish",
"amqp_exchange_publish",
"amqp_queue_subscribe",
"amqp_exchange_publish",
"http_client",
"event_source_fetch",
"event_source_express"
]
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/generators/typescript/channels/asyncapi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {generateKafkaChannels} from './protocols/kafka';
import {generateMqttChannels} from './protocols/mqtt';
import {generateAmqpChannels} from './protocols/amqp';
import {generateEventSourceChannels} from './protocols/eventsource';
import { generatehttpChannels } from './protocols/http';
import {generatehttpChannels} from './protocols/http';

type Action = 'send' | 'receive' | 'subscribe' | 'publish';
const sendingFunctionTypes = [
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/generators/typescript/channels/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export async function generateTypeScriptChannels(
context: TypeScriptChannelsContext
): Promise<TypeScriptChannelRenderType> {
const protocolCodeFunctions: Record<string, string[]> = {};

// Render before renders
const coreCode: string[] = [];
const externalProtocolFunctionInformation: Record<
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpRenderType } from "../../../../../types";
import { pascalCase } from "../../../utils";
import { ChannelFunctionTypes, RenderHttpParameters } from "../../types";
import {HttpRenderType} from '../../../../../types';
import {pascalCase} from '../../../utils';
import {ChannelFunctionTypes, RenderHttpParameters} from '../../types';

export function renderHttpFetchClient({
requestTopic,
Expand All @@ -13,7 +13,7 @@ export function renderHttpFetchClient({
statusCodes = [],
servers = [],
subName = pascalCase(requestTopic),
functionName = `${method.toLowerCase()}${subName}`,
functionName = `${method.toLowerCase()}${subName}`
}: RenderHttpParameters): HttpRenderType {
const addressToUse = channelParameters
? `parameters.getChannelWithParameters('${requestTopic}')`
Expand Down Expand Up @@ -85,7 +85,7 @@ export function renderHttpFetchClient({
})
},
path: ${addressToUse},
server: ${servers[0] ?? '\'localhost:3000\''},
server: ${servers[0] ?? "'localhost:3000'"},
apiKeyIn: 'header',
apiKeyName: 'X-API-Key',
},
Expand Down Expand Up @@ -142,9 +142,13 @@ export function renderHttpFetchClient({
let url = \`\${parsedContext.server}\${parsedContext.path}\`;

let body: any;
${messageType ? `if (parsedContext.payload) {
${
messageType
? `if (parsedContext.payload) {
body = parsedContext.payload.marshal();
}` : ''}
}`
: ''
}

// Handle different authentication methods
if (parsedContext.oauth2 && parsedContext.oauth2.accessToken) {
Expand Down Expand Up @@ -390,7 +394,10 @@ export function renderHttpFetchClient({
if (!response.ok) {
// For multi-status responses (with replyMessageModule), let unmarshalByStatusCode handle the parsing
// Only throw standardized errors for simple responses or when JSON parsing fails
${replyMessageModule ? '' : `// Handle common HTTP error codes with standardized messages
${
replyMessageModule
? ''
: `// Handle common HTTP error codes with standardized messages
if (response.status === 401) {
return Promise.reject(new Error('Unauthorized'));
} else if (response.status === 403) {
Expand All @@ -401,10 +408,13 @@ export function renderHttpFetchClient({
return Promise.reject(new Error('Internal Server Error'));
} else {
return Promise.reject(new Error(\`HTTP Error: \${response.status} \${response.statusText}\`));
}`}
}`
}
}

${replyMessageModule ? `// For multi-status responses, always try to parse JSON and let unmarshalByStatusCode handle it
${
replyMessageModule
? `// For multi-status responses, always try to parse JSON and let unmarshalByStatusCode handle it
try {
const data = await response.json();
return ${replyMessageModule}.unmarshalByStatusCode(data, response.status);
Expand All @@ -421,15 +431,20 @@ export function renderHttpFetchClient({
} else {
return Promise.reject(new Error(\`HTTP Error: \${response.status} \${response.statusText}\`));
}
}` : `const data = await response.json();
return ${replyMessageType}.unmarshal(data);`}
}`
: `const data = await response.json();
return ${replyMessageType}.unmarshal(data);`
}
}`;
return {
messageType,
replyType,
code,
functionName,
dependencies: [`import { URLSearchParams, URL } from 'url';`, `import * as NodeFetch from 'node-fetch';`],
dependencies: [
`import { URLSearchParams, URL } from 'url';`,
`import * as NodeFetch from 'node-fetch';`
],
functionType: ChannelFunctionTypes.HTTP_CLIENT
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,9 @@ function addRendersToExternal(
dependencies: string[],
parameter?: ConstrainedObjectModel
) {
protocolCodeFunctions['http_client'].push(...renders.map((value) => value.code));
protocolCodeFunctions['http_client'].push(
...renders.map((value) => value.code)
);

externalProtocolFunctionInformation['http_client'].push(
...renders.map((value) => ({
Expand Down Expand Up @@ -143,7 +145,8 @@ function generateForOperations(
renders.push(
renderHttpFetchClient({
subName: findNameFromOperation(operation, channel),
requestMessageModule: httpMethod === 'POST' ? messageModule : undefined,
requestMessageModule:
httpMethod === 'POST' ? messageModule : undefined,
requestMessageType: httpMethod === 'POST' ? messageType : undefined,
replyMessageModule,
replyMessageType,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,9 @@ function generateForOperations(
}
const {messageModule, messageType} = getMessageTypeAndModule(payload);
if (messageType === undefined) {
throw new Error(`Could not find message type for ${payloadId} for mqtt channel typescript generator`);
throw new Error(
`Could not find message type for ${payloadId} for mqtt channel typescript generator`
);
}
const updatedContext = {
...mqttContext,
Expand Down Expand Up @@ -142,10 +144,12 @@ function generateForChannels(
throw new Error(
`Could not find payload for ${channel.id()} for mqtt channel typescript generator`
);
}
}
const {messageModule, messageType} = getMessageTypeAndModule(payload);
if (messageType === undefined) {
throw new Error(`Could not find message type for ${channel.id()} for mqtt channel typescript generator`);
throw new Error(
`Could not find message type for ${channel.id()} for mqtt channel typescript generator`
);
}
const updatedContext = {...mqttContext, messageType, messageModule};
if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@ import {
findOperationId,
findReplyId
} from '../../../../../utils';
import { getMessageTypeAndModule } from '../../utils';
import {getMessageTypeAndModule} from '../../utils';
import {
getFunctionTypeMappingFromAsyncAPI,
shouldRenderFunctionType
} from '../../asyncapi';
import { renderCoreRequest } from './coreRequest';
import { renderCoreReply } from './coreReply';
import { renderCorePublish } from './corePublish';
import { renderCoreSubscribe } from './coreSubscribe';
import { renderJetstreamPullSubscribe } from './jetstreamPullSubscribe';
import { renderJetstreamPushSubscription } from './jetstreamPushSubscription';
import { renderJetstreamPublish } from './jetstreamPublish';
import { ChannelInterface, OperationInterface } from '@asyncapi/parser';
import { SingleFunctionRenderType } from '../../../../../types';
import { ConstrainedObjectModel } from '@asyncapi/modelina';
import { TypeScriptPayloadRenderType } from '../../../payloads';
import {renderCoreRequest} from './coreRequest';
import {renderCoreReply} from './coreReply';
import {renderCorePublish} from './corePublish';
import {renderCoreSubscribe} from './coreSubscribe';
import {renderJetstreamPullSubscribe} from './jetstreamPullSubscribe';
import {renderJetstreamPushSubscription} from './jetstreamPushSubscription';
import {renderJetstreamPublish} from './jetstreamPublish';
import {ChannelInterface, OperationInterface} from '@asyncapi/parser';
import {SingleFunctionRenderType} from '../../../../../types';
import {ConstrainedObjectModel} from '@asyncapi/modelina';
import {TypeScriptPayloadRenderType} from '../../../payloads';

export {
renderCoreRequest,
Expand All @@ -48,7 +48,7 @@ export async function generateNatsChannels(
>,
dependencies: string[]
) {
const { parameter, topic, payloads } = context;
const {parameter, topic, payloads} = context;
const ignoreOperation = !context.generator.asyncapiGenerateForOperations;
let natsTopic = topic.startsWith('/') ? topic.slice(1) : topic;
natsTopic = natsTopic.replace(/\//g, '.');
Expand Down Expand Up @@ -108,14 +108,15 @@ async function generateForOperations(
natsContext: RenderRegularParameters
): Promise<SingleFunctionRenderType[]> {
const renders: SingleFunctionRenderType[] = [];
const { generator, payloads } = context;
const {generator, payloads} = context;
const functionTypeMapping = generator.functionTypeMapping[channel.id()];

for (const operation of channel.operations().all()) {
const updatedFunctionTypeMapping =
getFunctionTypeMappingFromAsyncAPI(operation) ?? functionTypeMapping;
if (
updatedFunctionTypeMapping !== undefined && !updatedFunctionTypeMapping?.some((f) =>
updatedFunctionTypeMapping !== undefined &&
!updatedFunctionTypeMapping?.some((f) =>
[
ChannelFunctionTypes.NATS_REQUEST,
ChannelFunctionTypes.NATS_REPLY,
Expand All @@ -137,7 +138,7 @@ async function generateForOperations(
);
}

const { messageModule, messageType } = getMessageTypeAndModule(payload);
const {messageModule, messageType} = getMessageTypeAndModule(payload);
if (messageType === undefined) {
throw new Error(
`Could not find message type for channel typescript generator for NATS`
Expand Down Expand Up @@ -217,7 +218,7 @@ async function handleReplyOperation(
return renders;
}

const { messageModule: replyMessageModule, messageType: replyMessageType } =
const {messageModule: replyMessageModule, messageType: replyMessageType} =
getMessageTypeAndModule(replyMessageModel);

if (replyMessageType === undefined) {
Expand Down Expand Up @@ -276,8 +277,8 @@ async function handleNonReplyOperation(
const renders: SingleFunctionRenderType[] = [];
const action = operation.action();
const renderChecks = [
{ check: ChannelFunctionTypes.NATS_PUBLISH, render: renderCorePublish },
{ check: ChannelFunctionTypes.NATS_SUBSCRIBE, render: renderCoreSubscribe },
{check: ChannelFunctionTypes.NATS_PUBLISH, render: renderCorePublish},
{check: ChannelFunctionTypes.NATS_SUBSCRIBE, render: renderCoreSubscribe},
{
check: ChannelFunctionTypes.NATS_JETSTREAM_PULL_SUBSCRIBE,
render: renderJetstreamPullSubscribe
Expand All @@ -292,7 +293,7 @@ async function handleNonReplyOperation(
}
];

for (const { check, render } of renderChecks) {
for (const {check, render} of renderChecks) {
if (
shouldRenderFunctionType(
functionTypeMapping,
Expand All @@ -313,7 +314,7 @@ async function generateForChannels(
natsContext: RenderRegularParameters
): Promise<SingleFunctionRenderType[]> {
const renders: SingleFunctionRenderType[] = [];
const { generator, payloads } = context;
const {generator, payloads} = context;
const functionTypeMapping =
getFunctionTypeMappingFromAsyncAPI(channel) ??
generator.functionTypeMapping[channel.id()];
Expand All @@ -323,13 +324,13 @@ async function generateForChannels(
throw new Error(`Could not find payload for channel typescript generator`);
}

const { messageModule, messageType } = getMessageTypeAndModule(payload);
const {messageModule, messageType} = getMessageTypeAndModule(payload);
if (messageType === undefined) {
throw new Error(
`Could not find message type for channel typescript generator for NATS`
);
}
const updatedContext = { ...natsContext, messageType, messageModule };
const updatedContext = {...natsContext, messageType, messageModule};

const renderChecks = [
{
Expand Down Expand Up @@ -359,7 +360,7 @@ async function generateForChannels(
}
];

for (const { check, render, action } of renderChecks) {
for (const {check, render, action} of renderChecks) {
if (
shouldRenderFunctionType(
functionTypeMapping,
Expand Down
Loading