Skip to content

Commit 8a50471

Browse files
authored
Merge pull request #406 from OpenAPI-Qraft/refactor/asyncapi-channel-parameters
feat: enhance AsyncAPI `Parameter Object` support for channel parameters
2 parents 95b7a45 + 5b080ee commit 8a50471

10 files changed

Lines changed: 137 additions & 48 deletions

File tree

.changeset/tall-animals-sink.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@qraft/asyncapi-typescript-plugin': patch
3+
'@openapi-qraft/test-fixtures': patch
4+
---
5+
6+
Added AsyncAPI `Parameter Object` support for channel parameters: we now type channel params as `string` by default and
7+
as literal unions when `enum` is provided, and we generate `location`/`enum`/`default` in `components.parameters`.

packages/asyncapi-typescript-plugin/src/__snapshots__/no-extra-options.ts.snapshot.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface channels {
2525
lightMeasuredResponse: components["messages"]["lightMeasuredResponse"];
2626
};
2727
parameters: {
28-
streetlightId: components["parameters"]["streetlightId"];
28+
streetlightId: "streetlight-1" | "streetlight-2";
2929
};
3030
servers: [
3131
servers["events-test"],
@@ -39,7 +39,7 @@ export interface channels {
3939
turnOnResponse: components["messages"]["commandResponse"];
4040
};
4141
parameters: {
42-
streetlightId: components["parameters"]["streetlightId"];
42+
streetlightId: "streetlight-1" | "streetlight-2";
4343
};
4444
servers: [
4545
servers["commands-test"],
@@ -53,7 +53,7 @@ export interface channels {
5353
turnOffResponse: components["messages"]["commandResponse"];
5454
};
5555
parameters: {
56-
streetlightId: components["parameters"]["streetlightId"];
56+
streetlightId: "streetlight-1" | "streetlight-2";
5757
};
5858
servers: [
5959
servers["commands-test"],
@@ -67,7 +67,7 @@ export interface channels {
6767
dimLightResponse: components["messages"]["commandResponse"];
6868
};
6969
parameters: {
70-
streetlightId: components["parameters"]["streetlightId"];
70+
streetlightId: "streetlight-1" | "streetlight-2";
7171
};
7272
servers: [
7373
servers["commands-test"],
@@ -401,10 +401,18 @@ export interface components {
401401
};
402402
};
403403
parameters: {
404-
/** @description The ID of the streetlight. */
404+
/**
405+
* @description The ID of the streetlight.
406+
* @default streetlight-1
407+
* @enum {unknown}
408+
*/
405409
streetlightId: {
406-
description: "The ID of the streetlight.";
407410
location: "$message.payload#/item/id";
411+
default: "streetlight-1";
412+
enum: [
413+
"streetlight-1",
414+
"streetlight-2"
415+
];
408416
};
409417
};
410418
securitySchemes: {

packages/asyncapi-typescript-plugin/src/__snapshots__/with-asyncapi-types-file-name.ts.snapshot.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface channels {
2525
lightMeasuredResponse: components["messages"]["lightMeasuredResponse"];
2626
};
2727
parameters: {
28-
streetlightId: components["parameters"]["streetlightId"];
28+
streetlightId: "streetlight-1" | "streetlight-2";
2929
};
3030
servers: [
3131
servers["events-test"],
@@ -39,7 +39,7 @@ export interface channels {
3939
turnOnResponse: components["messages"]["commandResponse"];
4040
};
4141
parameters: {
42-
streetlightId: components["parameters"]["streetlightId"];
42+
streetlightId: "streetlight-1" | "streetlight-2";
4343
};
4444
servers: [
4545
servers["commands-test"],
@@ -53,7 +53,7 @@ export interface channels {
5353
turnOffResponse: components["messages"]["commandResponse"];
5454
};
5555
parameters: {
56-
streetlightId: components["parameters"]["streetlightId"];
56+
streetlightId: "streetlight-1" | "streetlight-2";
5757
};
5858
servers: [
5959
servers["commands-test"],
@@ -67,7 +67,7 @@ export interface channels {
6767
dimLightResponse: components["messages"]["commandResponse"];
6868
};
6969
parameters: {
70-
streetlightId: components["parameters"]["streetlightId"];
70+
streetlightId: "streetlight-1" | "streetlight-2";
7171
};
7272
servers: [
7373
servers["commands-test"],
@@ -401,10 +401,18 @@ export interface components {
401401
};
402402
};
403403
parameters: {
404-
/** @description The ID of the streetlight. */
404+
/**
405+
* @description The ID of the streetlight.
406+
* @default streetlight-1
407+
* @enum {unknown}
408+
*/
405409
streetlightId: {
406-
description: "The ID of the streetlight.";
407410
location: "$message.payload#/item/id";
411+
default: "streetlight-1";
412+
enum: [
413+
"streetlight-1",
414+
"streetlight-2"
415+
];
408416
};
409417
};
410418
securitySchemes: {

packages/asyncapi-typescript-plugin/src/__snapshots__/with-enum-values.ts.snapshot.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface channels {
2525
lightMeasuredResponse: components["messages"]["lightMeasuredResponse"];
2626
};
2727
parameters: {
28-
streetlightId: components["parameters"]["streetlightId"];
28+
streetlightId: "streetlight-1" | "streetlight-2";
2929
};
3030
servers: [
3131
servers["events-test"],
@@ -39,7 +39,7 @@ export interface channels {
3939
turnOnResponse: components["messages"]["commandResponse"];
4040
};
4141
parameters: {
42-
streetlightId: components["parameters"]["streetlightId"];
42+
streetlightId: "streetlight-1" | "streetlight-2";
4343
};
4444
servers: [
4545
servers["commands-test"],
@@ -53,7 +53,7 @@ export interface channels {
5353
turnOffResponse: components["messages"]["commandResponse"];
5454
};
5555
parameters: {
56-
streetlightId: components["parameters"]["streetlightId"];
56+
streetlightId: "streetlight-1" | "streetlight-2";
5757
};
5858
servers: [
5959
servers["commands-test"],
@@ -67,7 +67,7 @@ export interface channels {
6767
dimLightResponse: components["messages"]["commandResponse"];
6868
};
6969
parameters: {
70-
streetlightId: components["parameters"]["streetlightId"];
70+
streetlightId: "streetlight-1" | "streetlight-2";
7171
};
7272
servers: [
7373
servers["commands-test"],
@@ -401,10 +401,18 @@ export interface components {
401401
};
402402
};
403403
parameters: {
404-
/** @description The ID of the streetlight. */
404+
/**
405+
* @description The ID of the streetlight.
406+
* @default streetlight-1
407+
* @enum {unknown}
408+
*/
405409
streetlightId: {
406-
description: "The ID of the streetlight.";
407410
location: "$message.payload#/item/id";
411+
default: "streetlight-1";
412+
enum: [
413+
"streetlight-1",
414+
"streetlight-2"
415+
];
408416
};
409417
};
410418
securitySchemes: {

packages/asyncapi-typescript-plugin/src/__snapshots__/with-enum.ts.snapshot.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface channels {
2525
lightMeasuredResponse: components["messages"]["lightMeasuredResponse"];
2626
};
2727
parameters: {
28-
streetlightId: components["parameters"]["streetlightId"];
28+
streetlightId: "streetlight-1" | "streetlight-2";
2929
};
3030
servers: [
3131
servers["events-test"],
@@ -39,7 +39,7 @@ export interface channels {
3939
turnOnResponse: components["messages"]["commandResponse"];
4040
};
4141
parameters: {
42-
streetlightId: components["parameters"]["streetlightId"];
42+
streetlightId: "streetlight-1" | "streetlight-2";
4343
};
4444
servers: [
4545
servers["commands-test"],
@@ -53,7 +53,7 @@ export interface channels {
5353
turnOffResponse: components["messages"]["commandResponse"];
5454
};
5555
parameters: {
56-
streetlightId: components["parameters"]["streetlightId"];
56+
streetlightId: "streetlight-1" | "streetlight-2";
5757
};
5858
servers: [
5959
servers["commands-test"],
@@ -67,7 +67,7 @@ export interface channels {
6767
dimLightResponse: components["messages"]["commandResponse"];
6868
};
6969
parameters: {
70-
streetlightId: components["parameters"]["streetlightId"];
70+
streetlightId: "streetlight-1" | "streetlight-2";
7171
};
7272
servers: [
7373
servers["commands-test"],
@@ -401,10 +401,18 @@ export interface components {
401401
};
402402
};
403403
parameters: {
404-
/** @description The ID of the streetlight. */
404+
/**
405+
* @description The ID of the streetlight.
406+
* @default streetlight-1
407+
* @enum {unknown}
408+
*/
405409
streetlightId: {
406-
description: "The ID of the streetlight.";
407410
location: "$message.payload#/item/id";
411+
default: "streetlight-1";
412+
enum: [
413+
"streetlight-1",
414+
"streetlight-2"
415+
];
408416
};
409417
};
410418
securitySchemes: {

packages/asyncapi-typescript-plugin/src/__snapshots__/with-immutable.ts.snapshot.ts

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export interface channels {
2525
readonly lightMeasuredResponse: components["messages"]["lightMeasuredResponse"];
2626
};
2727
readonly parameters: {
28-
readonly streetlightId: components["parameters"]["streetlightId"];
28+
readonly streetlightId: "streetlight-1" | "streetlight-2";
2929
};
3030
readonly servers: [
3131
servers["events-test"],
@@ -39,7 +39,7 @@ export interface channels {
3939
readonly turnOnResponse: components["messages"]["commandResponse"];
4040
};
4141
readonly parameters: {
42-
readonly streetlightId: components["parameters"]["streetlightId"];
42+
readonly streetlightId: "streetlight-1" | "streetlight-2";
4343
};
4444
readonly servers: [
4545
servers["commands-test"],
@@ -53,7 +53,7 @@ export interface channels {
5353
readonly turnOffResponse: components["messages"]["commandResponse"];
5454
};
5555
readonly parameters: {
56-
readonly streetlightId: components["parameters"]["streetlightId"];
56+
readonly streetlightId: "streetlight-1" | "streetlight-2";
5757
};
5858
readonly servers: [
5959
servers["commands-test"],
@@ -67,7 +67,7 @@ export interface channels {
6767
readonly dimLightResponse: components["messages"]["commandResponse"];
6868
};
6969
readonly parameters: {
70-
readonly streetlightId: components["parameters"]["streetlightId"];
70+
readonly streetlightId: "streetlight-1" | "streetlight-2";
7171
};
7272
readonly servers: [
7373
servers["commands-test"],
@@ -401,10 +401,18 @@ export interface components {
401401
};
402402
};
403403
parameters: {
404-
/** @description The ID of the streetlight. */
404+
/**
405+
* @description The ID of the streetlight.
406+
* @default streetlight-1
407+
* @enum {unknown}
408+
*/
405409
readonly streetlightId: {
406-
readonly description: "The ID of the streetlight.";
407410
readonly location: "$message.payload#/item/id";
411+
readonly default: "streetlight-1";
412+
readonly enum: [
413+
"streetlight-1",
414+
"streetlight-2"
415+
];
408416
};
409417
};
410418
securitySchemes: {

packages/asyncapi-typescript-plugin/src/transform/channels-object.ts

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type {
22
AsyncAPIChannelObject,
33
AsyncAPIContext,
4+
AsyncAPIParameterObject,
45
ReferenceObject,
56
} from '../types.js';
67
import {
@@ -9,6 +10,7 @@ import {
910
tsLiteral,
1011
tsModifiers,
1112
tsPropertyIndex,
13+
tsUnion,
1214
} from 'openapi-typescript/dist/lib/ts.js';
1315
import { getEntries } from 'openapi-typescript/dist/lib/utils.js';
1416
import ts from 'typescript';
@@ -84,22 +86,15 @@ export default function transformChannelsObject(
8486
const paramMembers: ts.TypeElement[] = [];
8587

8688
for (const [paramId, param] of Object.entries(channel.parameters)) {
87-
let paramType: ts.TypeNode;
88-
89-
if (param && '$ref' in param) {
90-
paramType = oapiRef((param as ReferenceObject).$ref);
91-
} else {
92-
paramType = ts.factory.createKeywordTypeNode(
93-
ts.SyntaxKind.UnknownKeyword
94-
);
95-
}
96-
9789
paramMembers.push(
9890
ts.factory.createPropertySignature(
9991
tsModifiers({ readonly: ctx.immutable }),
10092
tsPropertyIndex(paramId),
10193
undefined,
102-
paramType
94+
transformChannelParameterType(
95+
param as AsyncAPIParameterObject | ReferenceObject,
96+
ctx
97+
)
10398
)
10499
);
105100
}
@@ -161,3 +156,24 @@ export default function transformChannelsObject(
161156

162157
return ts.factory.createTypeLiteralNode(members);
163158
}
159+
160+
function transformChannelParameterType(
161+
parameter: AsyncAPIParameterObject | ReferenceObject,
162+
ctx: AsyncAPIContext
163+
): ts.TypeNode {
164+
const parameterObject =
165+
'$ref' in parameter
166+
? ctx.resolve<AsyncAPIParameterObject>(parameter.$ref)
167+
: parameter;
168+
169+
const enumValues =
170+
parameterObject?.enum?.filter(
171+
(value): value is string => typeof value === 'string'
172+
) ?? [];
173+
174+
if (enumValues.length > 0) {
175+
return tsUnion(enumValues.map(tsLiteral));
176+
}
177+
178+
return ts.factory.createKeywordTypeNode(ts.SyntaxKind.StringKeyword);
179+
}

0 commit comments

Comments
 (0)