@ioka-technologies/asyncapi-ts-client-template 0.0.8 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/template/index.js CHANGED
@@ -38,70 +38,67 @@ module.exports = function ({ asyncapi, params }) {
38
38
  ? params.packageVersion
39
39
  : version;
40
40
 
41
- const transports = (params.transports || 'websocket,http').split(',').map(t => t.trim());
42
-
43
41
  // Generate all files from the main index.js
44
42
  return [
45
- React.createElement(File, { name: "package.json" },
43
+ React.createElement(File, { name: 'package.json' },
46
44
  JSON.stringify({
47
45
  name: packageName,
48
46
  version: packageVersion,
49
47
  description: `${description || title} - TypeScript AsyncAPI Client`,
50
- main: "dist/index.js",
51
- types: "dist/index.d.ts",
48
+ main: 'dist/index.js',
49
+ types: 'dist/index.d.ts',
52
50
  scripts: {
53
- build: "tsc",
54
- dev: "tsc --watch",
55
- test: "jest",
56
- lint: "eslint src/**/*.ts",
57
- prepare: "npm run build"
51
+ build: 'tsc',
52
+ dev: 'tsc --watch',
53
+ test: 'jest',
54
+ lint: 'eslint src/**/*.ts',
55
+ prepare: 'npm run build'
58
56
  },
59
57
  keywords: [
60
- "asyncapi",
61
- "websocket",
62
- "http",
63
- "client",
64
- "typescript",
58
+ 'asyncapi',
59
+ 'websocket',
60
+ 'http',
61
+ 'client',
62
+ 'typescript',
65
63
  title.toLowerCase().replace(/[^a-z0-9]/g, '-')
66
64
  ],
67
- author: params.author || "AsyncAPI Generator",
68
- license: params.license || "Apache-2.0",
65
+ author: params.author || 'AsyncAPI Generator',
66
+ license: params.license || 'Apache-2.0',
69
67
  dependencies: {
70
- uuid: "^9.0.0"
68
+ uuid: '^9.0.0'
71
69
  },
72
70
  optionalDependencies: {
73
- ws: "^8.14.0"
71
+ ws: '^8.14.0'
74
72
  },
75
73
  devDependencies: {
76
- "@types/ws": "^8.5.0",
77
- "@types/uuid": "^9.0.0",
78
- "@types/node": "^20.0.0",
79
- typescript: "^5.0.0",
80
- eslint: "^8.0.0",
81
- "@typescript-eslint/eslint-plugin": "^6.0.0",
82
- "@typescript-eslint/parser": "^6.0.0",
74
+ '@types/ws': '^8.5.0',
75
+ '@types/uuid': '^9.0.0',
76
+ '@types/node': '^20.0.0',
77
+ typescript: '^5.0.0',
78
+ eslint: '^8.0.0',
79
+ '@typescript-eslint/eslint-plugin': '^6.0.0',
80
+ '@typescript-eslint/parser': '^6.0.0',
83
81
  ...(params.generateTests && {
84
- jest: "^29.0.0",
85
- "@types/jest": "^29.0.0",
86
- "ts-jest": "^29.0.0"
82
+ jest: '^29.0.0',
83
+ '@types/jest': '^29.0.0',
84
+ 'ts-jest': '^29.0.0'
87
85
  })
88
86
  },
89
87
  files: [
90
- "dist/**/*",
91
- "README.md",
92
- "USAGE.md"
88
+ 'dist/**/*',
89
+ 'README.md'
93
90
  ]
94
91
  }, null, 2)
95
92
  ),
96
93
 
97
- React.createElement(File, { name: "tsconfig.json" },
94
+ React.createElement(File, { name: 'tsconfig.json' },
98
95
  JSON.stringify({
99
96
  compilerOptions: {
100
- target: "ES2020",
101
- module: "ES2020",
102
- lib: ["ES2020", "DOM"],
103
- outDir: "./dist",
104
- rootDir: "./src",
97
+ target: 'ES2020',
98
+ module: 'ES2020',
99
+ lib: ['ES2020', 'DOM'],
100
+ outDir: './dist',
101
+ rootDir: './src',
105
102
  strict: true,
106
103
  esModuleInterop: true,
107
104
  skipLibCheck: true,
@@ -109,75 +106,61 @@ module.exports = function ({ asyncapi, params }) {
109
106
  declaration: true,
110
107
  declarationMap: true,
111
108
  sourceMap: true,
112
- moduleResolution: "node",
109
+ moduleResolution: 'node',
113
110
  allowSyntheticDefaultImports: true,
114
111
  experimentalDecorators: true,
115
112
  emitDecoratorMetadata: true,
116
113
  resolveJsonModule: true,
117
- typeRoots: ["node_modules/@types"]
114
+ typeRoots: ['node_modules/@types']
118
115
  },
119
116
  include: [
120
- "src/**/*"
117
+ 'src/**/*'
121
118
  ],
122
119
  exclude: [
123
- "node_modules",
124
- "dist",
125
- "**/*.test.ts",
126
- "**/*.spec.ts"
120
+ 'node_modules',
121
+ 'dist',
122
+ '**/*.test.ts',
123
+ '**/*.spec.ts'
127
124
  ]
128
125
  }, null, 2)
129
126
  ),
130
127
 
131
- React.createElement(File, { name: "README.md" },
128
+ React.createElement(File, { name: 'README.md' },
132
129
  `# ${title}
133
130
 
134
131
  ${description || 'Generated TypeScript AsyncAPI client'}
135
132
 
136
- ## Installation
137
-
138
- \`\`\`bash
139
- npm install ${packageName}
140
- \`\`\`
141
-
142
- ## Quick Start
143
-
144
- See [USAGE.md](./USAGE.md) for detailed usage instructions.
133
+ ## Overview
145
134
 
146
- ## Generated from AsyncAPI
135
+ This TypeScript client provides type-safe access to your AsyncAPI service with automatic transport selection and built-in error handling. Generated from your AsyncAPI specification, it offers seamless integration with both WebSocket and HTTP protocols.
147
136
 
148
- This client was generated from an AsyncAPI specification using the TypeScript AsyncAPI Client Generator.
137
+ ## Technical Requirements
149
138
 
150
- - AsyncAPI Version: ${asyncapi.version()}
151
- - Generated: ${new Date().toISOString()}
152
- `
153
- ),
139
+ - Node.js 16+
140
+ - TypeScript 4.5+
154
141
 
155
- React.createElement(File, { name: "USAGE.md" },
156
- `# ${title} - Usage Guide
142
+ ## Supported Transports
157
143
 
158
- This document shows how to use the generated TypeScript AsyncAPI client.
144
+ - WebSocket (with auto-reconnection)
145
+ - HTTP (with retry logic)
159
146
 
160
147
  ## Installation
161
148
 
162
- ### Browser Usage
163
- For browser environments, install the package normally:
164
- \`\`\`bash
165
- npm install ${packageName}
166
- \`\`\`
149
+ ### For Node.js Projects
167
150
 
168
- ### Node.js Usage
169
- For Node.js environments, you'll also need the WebSocket library:
170
151
  \`\`\`bash
171
152
  npm install ${packageName} ws
172
153
  \`\`\`
173
154
 
174
- ## Environment Compatibility
155
+ ### For Browser Projects
156
+
157
+ \`\`\`bash
158
+ npm install ${packageName}
159
+ \`\`\`
175
160
 
176
- This client automatically detects the environment and uses the appropriate WebSocket implementation:
177
- - **Browser**: Uses the native \`WebSocket\` API
178
- - **Node.js**: Uses the \`ws\` library (must be installed separately)
161
+ ## Quick Start
179
162
 
180
- ## WebSocket Usage
163
+ ### WebSocket Client
181
164
 
182
165
  \`\`\`typescript
183
166
  import { ${clientName} } from '${packageName}';
@@ -190,25 +173,16 @@ const client = new ${clientName}({
190
173
  }
191
174
  });
192
175
 
193
- // Connect to the WebSocket
176
+ // Connect and send messages
194
177
  await client.connect();
195
-
196
- // Send a message and wait for response
197
- try {
198
- const response = await client.sendMessage({
199
- text: 'Hello, World!',
200
- userId: '123'
201
- });
202
- console.log('Response:', response);
203
- } catch (error) {
204
- console.error('Error:', error);
205
- }
206
-
207
- // Disconnect when done
208
- await client.disconnect();
178
+ const response = await client.sendMessage({
179
+ text: 'Hello, World!',
180
+ userId: '123'
181
+ });
182
+ console.log('Response:', response);
209
183
  \`\`\`
210
184
 
211
- ## HTTP Usage
185
+ ### HTTP Client
212
186
 
213
187
  \`\`\`typescript
214
188
  import { ${clientName} } from '${packageName}';
@@ -221,36 +195,24 @@ const client = new ${clientName}({
221
195
  }
222
196
  });
223
197
 
224
- // Send HTTP request
225
- try {
226
- const response = await client.sendMessage({
227
- text: 'Hello, World!',
228
- userId: '123'
229
- });
230
- console.log('Response:', response);
231
- } catch (error) {
232
- console.error('Error:', error);
233
- }
198
+ const response = await client.sendMessage({
199
+ text: 'Hello, World!',
200
+ userId: '123'
201
+ });
234
202
  \`\`\`
235
203
 
236
204
  ## Configuration Options
237
205
 
238
- \`\`\`typescript
239
- interface TransportConfig {
240
- type: 'websocket' | 'http';
241
- url: string;
242
- headers?: Record<string, string>;
243
- timeout?: number;
244
- }
245
- \`\`\`
206
+ | Option | Type | Description | Default |
207
+ |--------|------|-------------|---------|
208
+ | \`type\` | \`'websocket' \\| 'http'\` | Transport protocol | Required |
209
+ | \`url\` | \`string\` | Server URL | Required |
210
+ | \`headers\` | \`Record<string, string>\` | Request headers | \`{}\` |
211
+ | \`timeout\` | \`number\` | Request timeout (ms) | \`30000\` |
246
212
 
247
213
  ## Error Handling
248
214
 
249
- The client throws specific error types:
250
-
251
- - \`TransportError\`: General transport errors
252
- - \`ConnectionError\`: Connection-related errors
253
- - \`TimeoutError\`: Request timeout errors
215
+ The client provides specific error types for different scenarios:
254
216
 
255
217
  \`\`\`typescript
256
218
  import { TransportError, ConnectionError, TimeoutError } from '${packageName}';
@@ -261,23 +223,52 @@ try {
261
223
  if (error instanceof ConnectionError) {
262
224
  console.error('Connection failed:', error.message);
263
225
  } else if (error instanceof TimeoutError) {
264
- console.error('Request timed out:', error.message);
226
+ console.error('Request timed out');
265
227
  } else if (error instanceof TransportError) {
266
228
  console.error('Transport error:', error.message);
267
229
  }
268
230
  }
269
231
  \`\`\`
270
232
 
271
- ## Troubleshooting
233
+ ## Environment Compatibility
234
+
235
+ - **Browser**: Uses native WebSocket API (no additional dependencies)
236
+ - **Node.js**: Requires \`ws\` package for WebSocket support
237
+
238
+ ## Development
272
239
 
273
- ### WebSocket Issues in Node.js
274
- If you get an error like "WebSocket implementation not available", make sure you have installed the \`ws\` package:
275
240
  \`\`\`bash
276
- npm install ws
241
+ # Build the project
242
+ npm run build
243
+
244
+ # Watch for changes
245
+ npm run dev
246
+
247
+ # Run tests
248
+ npm test
249
+
250
+ # Lint code
251
+ npm run lint
277
252
  \`\`\`
278
253
 
279
- ### Browser Compatibility
280
- The client uses the native WebSocket API in browsers, which is supported in all modern browsers. No additional dependencies are required.
254
+ ## Generated from AsyncAPI
255
+
256
+ - **AsyncAPI Version**: ${asyncapi.version()}
257
+ - **Generated**: ${new Date().toISOString()}
258
+ - **Title**: ${title}
259
+ - **Version**: ${packageVersion}
260
+
261
+ ## Contributing
262
+
263
+ 1. Fork the repository
264
+ 2. Create a feature branch
265
+ 3. Make your changes and add tests
266
+ 4. Run the test suite: \`npm test\`
267
+ 5. Submit a pull request
268
+
269
+ ## License
270
+
271
+ ${params.license || 'Apache-2.0'}
281
272
  `
282
273
  )
283
274
  ];
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable no-unused-vars */
2
2
  import { File } from '@asyncapi/generator-react-sdk';
3
+ import { operationRequiresAuth, extractOperationSecurityMap } from '../helpers/security.js';
3
4
 
4
5
  function generateClient(asyncapi, clientName) {
5
6
  // Method name sanitization function
@@ -9,7 +10,7 @@ function generateClient(asyncapi, clientName) {
9
10
  // Convert to camelCase and remove invalid characters
10
11
  let sanitized = operationId
11
12
  // Replace dots, hyphens, underscores, spaces, and forward slashes with camelCase
12
- .replace(/[.\-_\s\/]+(.)/g, (_, char) => char.toUpperCase())
13
+ .replace(/[.\-_\s/]+(.)/g, (_, char) => char.toUpperCase())
13
14
  // Remove any remaining invalid characters
14
15
  .replace(/[^a-zA-Z0-9]/g, '')
15
16
  // Ensure it starts with a lowercase letter if it starts with a number
@@ -42,6 +43,7 @@ function generateClient(asyncapi, clientName) {
42
43
 
43
44
  let content = `import { TransportFactory } from './runtime/transports/factory';
44
45
  import { Transport, TransportConfig, RequestOptions, MessageEnvelope } from './runtime/types';
46
+ import { AuthCredentials } from './runtime/auth/types';
45
47
  import * as Models from './models';
46
48
 
47
49
  export class ${clientName} {
@@ -70,6 +72,26 @@ export class ${clientName} {
70
72
  this.transport.unsubscribe(channel, callback);
71
73
  }
72
74
 
75
+ /**
76
+ * Update authentication configuration
77
+ * @param auth New authentication configuration
78
+ */
79
+ updateAuth(auth: AuthCredentials): void {
80
+ this.config.auth = auth;
81
+ // If transport supports auth updates, update it
82
+ if (this.transport && typeof (this.transport as any).updateAuth === 'function') {
83
+ (this.transport as any).updateAuth(auth);
84
+ }
85
+ }
86
+
87
+ /**
88
+ * Get current authentication configuration
89
+ * @returns Current auth configuration
90
+ */
91
+ getAuth(): AuthCredentials | undefined {
92
+ return this.config.auth;
93
+ }
94
+
73
95
  // Generated operation methods
74
96
  `;
75
97
 
@@ -374,4 +396,4 @@ module.exports = function ({ asyncapi, params }) {
374
396
  {generatedContent}
375
397
  </File>
376
398
  );
377
- }
399
+ };
@@ -2,7 +2,7 @@
2
2
  import { File } from '@asyncapi/generator-react-sdk';
3
3
 
4
4
  function generateModels(asyncapi) {
5
- let content = `// Generated TypeScript models from AsyncAPI specification\n\n`;
5
+ let content = '// Generated TypeScript models from AsyncAPI specification\n\n';
6
6
 
7
7
  // Helper functions for TypeScript identifier generation
8
8
  function toTypeScriptIdentifier(str) {
@@ -42,8 +42,104 @@ function generateModels(asyncapi) {
42
42
  // Extract message schemas and build channel mapping
43
43
  const components = asyncapi.components();
44
44
  const messageSchemas = [];
45
+ const componentSchemas = [];
45
46
  const messageToChannels = new Map();
46
47
  const generatedTypes = new Set();
48
+ const schemaRegistry = new Map();
49
+
50
+ // Build schema registry from components.schemas
51
+ // Try to access the raw AsyncAPI document
52
+ let rawDoc = null;
53
+ try {
54
+ if (asyncapi.json && typeof asyncapi.json === 'function') {
55
+ rawDoc = asyncapi.json();
56
+ } else if (asyncapi._json) {
57
+ rawDoc = asyncapi._json;
58
+ }
59
+ } catch (e) {
60
+ // Ignore
61
+ }
62
+
63
+ // Extract schemas from raw document if available
64
+ if (rawDoc && rawDoc.components && rawDoc.components.schemas) {
65
+ Object.entries(rawDoc.components.schemas).forEach(([name, schema]) => {
66
+ if (name && typeof name === 'string' && schema && typeof schema === 'object') {
67
+ schemaRegistry.set(name, schema);
68
+ componentSchemas.push({
69
+ name,
70
+ typeName: toTypeScriptTypeName(name),
71
+ schema: schema,
72
+ description: schema.description
73
+ });
74
+ }
75
+ });
76
+ }
77
+
78
+ // Fallback: try the components.schemas() method
79
+ if (componentSchemas.length === 0 && components && components.schemas) {
80
+ try {
81
+ const schemas = components.schemas();
82
+ if (schemas) {
83
+ // Try different ways to access schemas
84
+ let schemaEntries = [];
85
+
86
+ if (schemas instanceof Map) {
87
+ schemaEntries = Array.from(schemas.entries());
88
+ } else if (typeof schemas === 'object') {
89
+ schemaEntries = Object.entries(schemas);
90
+ } else if (schemas.all && typeof schemas.all === 'function') {
91
+ // AsyncAPI parser might have an all() method
92
+ const allSchemas = schemas.all();
93
+ if (Array.isArray(allSchemas)) {
94
+ schemaEntries = allSchemas.map(schema => {
95
+ const name = schema.uid ? schema.uid() : (schema.id ? schema.id() : null);
96
+ return [name, schema];
97
+ }).filter(([name]) => name);
98
+ }
99
+ }
100
+
101
+ schemaEntries.forEach(([name, schema]) => {
102
+ // Skip internal AsyncAPI parser objects and numeric keys
103
+ if (!name || name === 'collections' || name === '_meta' || name.startsWith('_') || /^\d+$/.test(name)) {
104
+ return;
105
+ }
106
+
107
+ let schemaData = null;
108
+ let description = null;
109
+
110
+ try {
111
+ // Handle different schema object types
112
+ if (schema && typeof schema.json === 'function') {
113
+ schemaData = schema.json();
114
+ } else if (schema && typeof schema === 'object') {
115
+ schemaData = schema;
116
+ }
117
+
118
+ if (schema && typeof schema.description === 'function') {
119
+ description = schema.description();
120
+ } else if (schema && schema.description) {
121
+ description = schema.description;
122
+ }
123
+ } catch (e) {
124
+ // Ignore schema extraction errors
125
+ console.warn(`Failed to extract schema for ${name}:`, e.message);
126
+ }
127
+
128
+ if (schemaData && typeof name === 'string' && name.length > 0) {
129
+ schemaRegistry.set(name, schemaData);
130
+ componentSchemas.push({
131
+ name,
132
+ typeName: toTypeScriptTypeName(name),
133
+ schema: schemaData,
134
+ description
135
+ });
136
+ }
137
+ });
138
+ }
139
+ } catch (e) {
140
+ console.warn('Failed to extract component schemas:', e.message);
141
+ }
142
+ }
47
143
 
48
144
  // First, build channel to message mapping
49
145
  if (asyncapi.channels) {
@@ -126,13 +222,25 @@ function generateModels(asyncapi) {
126
222
  }
127
223
 
128
224
  // Helper function to convert JSON schema to TypeScript type
129
- function jsonSchemaToTypeScriptType(schema) {
225
+ function jsonSchemaToTypeScriptType(schema, fieldName = '') {
130
226
  if (!schema) return 'any';
131
227
 
132
- // Handle $ref
228
+ // Handle $ref - resolve from schema registry
133
229
  if (schema.$ref) {
134
230
  const refName = schema.$ref.split('/').pop();
135
- return toTypeScriptTypeName(refName);
231
+ // Always return the type name for $ref, since we generate all component schemas
232
+ const typeName = toTypeScriptTypeName(refName);
233
+ return typeName;
234
+ }
235
+
236
+ // Handle resolved $ref - check for x-parser-schema-id which indicates original schema name
237
+ if (schema['x-parser-schema-id'] && typeof schema['x-parser-schema-id'] === 'string') {
238
+ const schemaId = schema['x-parser-schema-id'];
239
+ // Check if this matches a known component schema
240
+ if (schemaRegistry.has(schemaId)) {
241
+ const typeName = toTypeScriptTypeName(schemaId);
242
+ return typeName;
243
+ }
136
244
  }
137
245
 
138
246
  if (!schema.type) {
@@ -158,10 +266,19 @@ function generateModels(asyncapi) {
158
266
  case 'boolean':
159
267
  return 'boolean';
160
268
  case 'array': {
161
- const itemType = jsonSchemaToTypeScriptType(schema.items);
162
- return `${itemType}[]`;
269
+ if (schema.items) {
270
+ const itemType = jsonSchemaToTypeScriptType(schema.items, fieldName);
271
+ return `${itemType}[]`;
272
+ }
273
+ return 'any[]';
163
274
  }
164
275
  case 'object':
276
+ // For objects with properties, we should generate inline types or check if it's a known schema
277
+ if (schema.properties) {
278
+ // This is a complex object - for now return Record<string, any>
279
+ // In a more sophisticated implementation, we could generate inline types
280
+ return 'Record<string, any>';
281
+ }
165
282
  return 'Record<string, any>';
166
283
  default:
167
284
  return 'any';
@@ -175,7 +292,7 @@ function generateModels(asyncapi) {
175
292
  }
176
293
 
177
294
  const fields = Object.entries(schema.properties).map(([fieldName, fieldSchema]) => {
178
- const tsType = jsonSchemaToTypeScriptType(fieldSchema);
295
+ const tsType = jsonSchemaToTypeScriptType(fieldSchema, fieldName);
179
296
  const optional = !schema.required || !schema.required.includes(fieldName);
180
297
  const optionalMarker = optional ? '?' : '';
181
298
 
@@ -190,31 +307,54 @@ function generateModels(asyncapi) {
190
307
  return fields;
191
308
  }
192
309
 
193
- // Generate interfaces for each message
310
+ // Generate interfaces for component schemas first (so they can be referenced by messages)
311
+ componentSchemas.forEach(schema => {
312
+ const doc = schema.description ? `/** ${schema.description} */\n` : `/** ${schema.name} */\n`;
313
+
314
+ content += `${doc}export interface ${schema.typeName} {\n`;
315
+ content += generateMessageInterface(schema.schema, schema.typeName);
316
+ content += '\n}\n\n';
317
+
318
+ // Track generated types to avoid duplicates
319
+ generatedTypes.add(schema.typeName);
320
+ });
321
+
322
+ // Generate interfaces for each message (only if not already generated as component schema)
194
323
  messageSchemas.forEach(schema => {
324
+ const interfaceName = `${schema.typeName}Payload`;
325
+
326
+ // Check if this is a duplicate of a component schema
327
+ // For message payloads that match component schema names, skip the payload version
328
+ if (generatedTypes.has(schema.typeName) || generatedTypes.has(interfaceName)) {
329
+ // Skip generating the payload version if we already have the component schema
330
+ return;
331
+ }
332
+
195
333
  const doc = schema.description ? `/** ${schema.description} */\n` : `/** ${schema.name} message payload */\n`;
196
334
 
197
- content += `${doc}export interface ${schema.typeName}Payload {\n`;
335
+ content += `${doc}export interface ${interfaceName} {\n`;
198
336
  content += generateMessageInterface(schema.payload, schema.typeName);
199
- content += `\n}\n\n`;
337
+ content += '\n}\n\n';
338
+
339
+ generatedTypes.add(interfaceName);
200
340
  });
201
341
 
202
342
  // Generate a union type for all message payloads
203
343
  if (messageSchemas.length > 0) {
204
344
  const payloadTypes = messageSchemas.map(schema => `${schema.typeName}Payload`).join(' | ');
205
- content += `/** Union type for all message payloads */\n`;
345
+ content += '/** Union type for all message payloads */\n';
206
346
  content += `export type MessagePayload = ${payloadTypes};\n\n`;
207
347
 
208
348
  // Generate message type constants
209
- content += `/** Message type constants */\n`;
210
- content += `export const MessageTypes = {\n`;
349
+ content += '/** Message type constants */\n';
350
+ content += 'export const MessageTypes = {\n';
211
351
  messageSchemas.forEach(schema => {
212
352
  content += ` ${schema.typeName.toUpperCase()}: '${schema.name}',\n`;
213
353
  });
214
- content += `} as const;\n\n`;
354
+ content += '} as const;\n\n';
215
355
 
216
- content += `/** Message type union */\n`;
217
- content += `export type MessageType = typeof MessageTypes[keyof typeof MessageTypes];\n\n`;
356
+ content += '/** Message type union */\n';
357
+ content += 'export type MessageType = typeof MessageTypes[keyof typeof MessageTypes];\n\n';
218
358
  }
219
359
 
220
360
  return content;
@@ -226,4 +366,4 @@ module.exports = function ({ asyncapi, params }) {
226
366
  {generateModels(asyncapi)}
227
367
  </File>
228
368
  );
229
- }
369
+ };