Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ export class ChannelConverter2_X extends AbstractChannelConverter<AsyncAPIV2.Cha
const queryParameters: QueryParameter[] = [];
const headers: HttpHeader[] = [];

const displayNameExtension = new DisplayNameExtension({
const channelDisplayNameExtension = new DisplayNameExtension({
breadcrumbs: this.breadcrumbs,
channel: this.channel,
node: this.channel,
context: this.context
});
const displayName = displayNameExtension.convert() ?? this.websocketGroup?.join(".");
const displayName = channelDisplayNameExtension.convert() ?? this.websocketGroup?.join(".");

if (this.channel.parameters) {
this.convertPathParameters({
Expand Down Expand Up @@ -240,9 +240,15 @@ export class ChannelConverter2_X extends AbstractChannelConverter<AsyncAPIV2.Cha
});

const messageType = origin === "server" ? "subscribe" : "publish";
const operationDisplayNameExtension = new DisplayNameExtension({
breadcrumbs: [...this.breadcrumbs, messageType],
node: operation,
context: this.context
});
const operationDisplayName = operationDisplayNameExtension.convert() ?? messageType;
return {
type: messageType,
displayName: messageType,
displayName: operationDisplayName,
origin,
body,
availability: context.getAvailability({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export class ChannelConverter3_0 extends AbstractChannelConverter<AsyncAPIV3.Cha
const queryParameters: QueryParameter[] = [];
const headers: HttpHeader[] = [];

const displayNameExtension = new DisplayNameExtension({
const channelDisplayNameExtension = new DisplayNameExtension({
breadcrumbs: this.breadcrumbs,
channel: this.channel,
node: this.channel,
context: this.context
});
const displayName = displayNameExtension.convert() ?? this.websocketGroup?.join(".") ?? this.channelPath;
const displayName = channelDisplayNameExtension.convert() ?? this.websocketGroup?.join(".") ?? this.channelPath;

if (this.channel.parameters) {
this.convertChannelParameters({
Expand All @@ -70,6 +70,13 @@ export class ChannelConverter3_0 extends AbstractChannelConverter<AsyncAPIV3.Cha
const messages: WebSocketMessage[] = [];

for (const [operationId, operation] of Object.entries(channelOperations)) {
const operationDisplayNameExtension = new DisplayNameExtension({
breadcrumbs: [...this.breadcrumbs, operationId],
node: operation,
context: this.context
});
const operationDisplayName = operationDisplayNameExtension.convert() ?? operationId;

for (const message of operation.messages) {
const resolved = this.context.convertReferenceToTypeReference({ reference: message });
if (resolved.ok) {
Expand All @@ -79,7 +86,7 @@ export class ChannelConverter3_0 extends AbstractChannelConverter<AsyncAPIV3.Cha
});
messages.push({
type: operationId,
displayName: operationId,
displayName: operationDisplayName,
origin: operation.action === "send" ? "client" : "server",
body: messageBody,
availability: this.context.getAvailability({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,31 @@ import { AsyncAPIV3 } from "../3.0/index.js";

export declare namespace DisplayNameExtension {
export interface Args extends AbstractExtension.Args {
channel: AsyncAPIV2.ChannelV2 | AsyncAPIV3.ChannelV3;
node:
| AsyncAPIV2.ChannelV2
| AsyncAPIV3.ChannelV3
| AsyncAPIV2.PublishEvent
| AsyncAPIV2.SubscribeEvent
| AsyncAPIV3.Operation;
}
}

export class DisplayNameExtension extends AbstractExtension<string> {
private readonly channel: AsyncAPIV3.ChannelV3 | AsyncAPIV2.ChannelV2;
private readonly node:
| AsyncAPIV3.ChannelV3
| AsyncAPIV2.ChannelV2
| AsyncAPIV2.PublishEvent
| AsyncAPIV2.SubscribeEvent
| AsyncAPIV3.Operation;
public readonly key = "x-fern-display-name";

constructor({ breadcrumbs, channel, context }: DisplayNameExtension.Args) {
constructor({ breadcrumbs, node, context }: DisplayNameExtension.Args) {
super({ breadcrumbs, context });
this.channel = channel;
this.node = node;
}

public convert(): string | undefined {
const extensionValue = this.getExtensionValue(this.channel);
const extensionValue = this.getExtensionValue(this.node);
if (extensionValue == null || typeof extensionValue !== "string") {
return undefined;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,10 @@ export function parseAsyncAPIV2({
messages.push({
origin: "client",
name: "publish",
displayName:
channel.publish != null
? getExtension<string>(channel.publish, FernAsyncAPIExtension.FERN_DISPLAY_NAME)
: undefined,
body: convertSchemaWithExampleToSchema(publishSchema),
methodName:
channel.publish != null
Expand All @@ -337,6 +341,10 @@ export function parseAsyncAPIV2({
messages.push({
origin: "server",
name: "subscribe",
displayName:
channel.subscribe != null
? getExtension<string>(channel.subscribe, FernAsyncAPIExtension.FERN_DISPLAY_NAME)
: undefined,
body: convertSchemaWithExampleToSchema(subscribeSchema),
methodName:
channel.subscribe != null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { AsyncAPIV3ParserContext } from "./AsyncAPIV3ParserContext.js";
interface MessageWithMethodName {
ref: OpenAPIV3.ReferenceObject;
methodName: string | undefined;
displayName: string | undefined;
}

interface ChannelEvents {
Expand Down Expand Up @@ -207,17 +208,21 @@ export function parseAsyncAPIV3({
// Extract method name from x-fern-sdk-method-name extension
const methodName = getExtension<string>(operation, FernAsyncAPIExtension.FERN_SDK_METHOD_NAME);

// Extract display name from x-fern-display-name extension
const operationDisplayName = getExtension<string>(operation, FernAsyncAPIExtension.FERN_DISPLAY_NAME);

// Skip operations without messages
if (!operation.messages || !Array.isArray(operation.messages)) {
continue;
}

// Associate the method name with each message from this operation, filtering out invalid references
// Associate the method name and display name with each message from this operation, filtering out invalid references
const messagesWithMethodName: MessageWithMethodName[] = operation.messages
.filter((ref) => ref != null && ref.$ref != null)
.map((ref) => ({
ref,
methodName
methodName,
displayName: operationDisplayName
}));

const channelEvent = channelEvents[channelPath];
Expand Down Expand Up @@ -716,6 +721,7 @@ function convertMessageReferencesToWebsocketSchemas({
results.push({
origin,
name: schemaId ?? `${origin}Message${i + 1}`,
displayName: message.displayName,
body: convertSchemaWithExampleToSchema(schema),
methodName: message.methodName
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ export function buildChannel({
})
};

if (message.displayName != null) {
messageSchema["display-name"] = message.displayName;
}

if (message.methodName != null) {
messageSchema["method-name"] = message.methodName;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ types:
WebsocketMessageSchema:
properties:
name: string
displayName: optional<string>
origin: WebsocketMessageOrigin
body: Schema
methodName: optional<string>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type * as FernOpenapiIr from "../../../index.js";

export interface WebsocketMessageSchema {
name: string;
displayName: string | undefined;
origin: FernOpenapiIr.WebsocketMessageOrigin;
body: FernOpenapiIr.Schema;
methodName: string | undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export const WebsocketMessageSchema: core.serialization.ObjectSchema<
FernOpenapiIr.WebsocketMessageSchema
> = core.serialization.objectWithoutOptionalProperties({
name: core.serialization.string(),
displayName: core.serialization.string().optional(),
origin: WebsocketMessageOrigin,
body: core.serialization.lazy(() => serializers.Schema),
methodName: core.serialization.string().optional(),
Expand All @@ -18,6 +19,7 @@ export const WebsocketMessageSchema: core.serialization.ObjectSchema<
export declare namespace WebsocketMessageSchema {
export interface Raw {
name: string;
displayName?: string | null;
origin: WebsocketMessageOrigin.Raw;
body: serializers.Schema.Raw;
methodName?: string | null;
Expand Down
Loading