@kubb/plugin-oas 3.15.1 → 3.16.0

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.
Files changed (37) hide show
  1. package/dist/{OperationGenerator-DyM5QANw.d.ts → OperationGenerator-C7NPZtOM.d.ts} +7 -21
  2. package/dist/{OperationGenerator-LFwakDt7.d.cts → OperationGenerator-DJE2XQ83.d.cts} +7 -21
  3. package/dist/{chunk-2LJ3ZJZP.cjs → chunk-CNSA5TDG.cjs} +34 -42
  4. package/dist/chunk-CNSA5TDG.cjs.map +1 -0
  5. package/dist/{chunk-JSR2ZSPP.js → chunk-ISOHAFCA.js} +33 -42
  6. package/dist/chunk-ISOHAFCA.js.map +1 -0
  7. package/dist/{chunk-S7ZYTJXL.js → chunk-MBX66JAT.js} +5 -5
  8. package/dist/chunk-MBX66JAT.js.map +1 -0
  9. package/dist/{chunk-S3UPJP7I.cjs → chunk-QJMOOF2A.cjs} +5 -5
  10. package/dist/chunk-QJMOOF2A.cjs.map +1 -0
  11. package/dist/components.d.cts +1 -1
  12. package/dist/components.d.ts +1 -1
  13. package/dist/generators.cjs +2 -2
  14. package/dist/generators.d.cts +1 -1
  15. package/dist/generators.d.ts +1 -1
  16. package/dist/generators.js +1 -1
  17. package/dist/hooks.cjs +2 -2
  18. package/dist/hooks.d.cts +1 -1
  19. package/dist/hooks.d.ts +1 -1
  20. package/dist/hooks.js +1 -1
  21. package/dist/index.cjs +126 -191
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.cts +2 -2
  24. package/dist/index.d.ts +2 -2
  25. package/dist/index.js +122 -188
  26. package/dist/index.js.map +1 -1
  27. package/dist/utils.d.cts +1 -1
  28. package/dist/utils.d.ts +1 -1
  29. package/package.json +8 -7
  30. package/src/OperationGenerator.ts +126 -223
  31. package/src/SchemaGenerator.ts +31 -45
  32. package/src/generator.tsx +4 -12
  33. package/src/types.ts +0 -1
  34. package/dist/chunk-2LJ3ZJZP.cjs.map +0 -1
  35. package/dist/chunk-JSR2ZSPP.js.map +0 -1
  36. package/dist/chunk-S3UPJP7I.cjs.map +0 -1
  37. package/dist/chunk-S7ZYTJXL.js.map +0 -1
@@ -3,11 +3,11 @@ import transformers from '@kubb/core/transformers'
3
3
 
4
4
  import type { PluginFactoryOptions, PluginManager } from '@kubb/core'
5
5
  import type { KubbFile } from '@kubb/core/fs'
6
-
7
6
  import type { Plugin } from '@kubb/core'
8
7
  import type { HttpMethod, Oas, OasTypes, Operation, SchemaObject, contentType } from '@kubb/oas'
9
8
  import type { Generator } from './generator.tsx'
10
- import type { Exclude, Include, OperationSchemas, OperationsByMethod, Override } from './types.ts'
9
+ import type { Exclude, Include, OperationSchemas, Override } from './types.ts'
10
+ import pLimit from 'p-limit'
11
11
 
12
12
  export type OperationMethodResult<TFileMeta extends FileMetaBase> = Promise<KubbFile.File<TFileMeta> | Array<KubbFile.File<TFileMeta>> | null>
13
13
 
@@ -29,101 +29,75 @@ export class OperationGenerator<
29
29
  TPluginOptions extends PluginFactoryOptions = PluginFactoryOptions,
30
30
  TFileMeta extends FileMetaBase = FileMetaBase,
31
31
  > extends BaseGenerator<TPluginOptions['resolvedOptions'], Context<TPluginOptions['resolvedOptions'], TPluginOptions>> {
32
- #operationsByMethod: OperationsByMethod = {}
33
- get operationsByMethod(): OperationsByMethod {
34
- return this.#operationsByMethod
35
- }
36
-
37
- set operationsByMethod(paths: OperationsByMethod) {
38
- this.#operationsByMethod = paths
39
- }
40
-
41
32
  #getOptions(operation: Operation, method: HttpMethod): Partial<TPluginOptions['resolvedOptions']> {
42
33
  const { override = [] } = this.context
34
+ const operationId = operation.getOperationId({ friendlyCase: true })
35
+ const contentType = operation.getContentType()
43
36
 
44
37
  return (
45
38
  override.find(({ pattern, type }) => {
46
- if (type === 'tag') {
47
- return !!operation.getTags().some((tag) => tag.name.match(pattern))
48
- }
49
-
50
- if (type === 'operationId') {
51
- return !!operation.getOperationId({ friendlyCase: true }).match(pattern)
52
- }
53
-
54
- if (type === 'path') {
55
- return !!operation.path.match(pattern)
39
+ switch (type) {
40
+ case 'tag':
41
+ return operation.getTags().some((tag) => tag.name.match(pattern))
42
+ case 'operationId':
43
+ return !!operationId.match(pattern)
44
+ case 'path':
45
+ return !!operation.path.match(pattern)
46
+ case 'method':
47
+ return !!method.match(pattern)
48
+ case 'contentType':
49
+ return !!contentType.match(pattern)
50
+ default:
51
+ return false
56
52
  }
57
-
58
- if (type === 'method') {
59
- return !!method.match(pattern)
60
- }
61
-
62
- if (type === 'contentType') {
63
- return !!operation.getContentType().match(pattern)
64
- }
65
-
66
- return false
67
53
  })?.options || {}
68
54
  )
69
55
  }
70
56
 
71
57
  #isExcluded(operation: Operation, method: HttpMethod): boolean {
72
58
  const { exclude = [] } = this.context
73
- let matched = false
74
-
75
- exclude.forEach(({ pattern, type }) => {
76
- if (type === 'tag' && !matched) {
77
- matched = !!operation.getTags().some((tag) => tag.name.match(pattern))
78
- }
79
-
80
- if (type === 'operationId' && !matched) {
81
- matched = !!operation.getOperationId({ friendlyCase: true }).match(pattern)
82
- }
83
-
84
- if (type === 'path' && !matched) {
85
- matched = !!operation.path.match(pattern)
86
- }
87
-
88
- if (type === 'method' && !matched) {
89
- matched = !!method.match(pattern)
90
- }
91
-
92
- if (type === 'contentType' && !matched) {
93
- return !!operation.getContentType().match(pattern)
59
+ const operationId = operation.getOperationId({ friendlyCase: true })
60
+ const contentType = operation.getContentType()
61
+
62
+ return exclude.some(({ pattern, type }) => {
63
+ switch (type) {
64
+ case 'tag':
65
+ return operation.getTags().some((tag) => tag.name.match(pattern))
66
+ case 'operationId':
67
+ return !!operationId.match(pattern)
68
+ case 'path':
69
+ return !!operation.path.match(pattern)
70
+ case 'method':
71
+ return !!method.match(pattern)
72
+ case 'contentType':
73
+ return !!contentType.match(pattern)
74
+ default:
75
+ return false
94
76
  }
95
77
  })
96
-
97
- return matched
98
78
  }
99
79
 
100
80
  #isIncluded(operation: Operation, method: HttpMethod): boolean {
101
81
  const { include = [] } = this.context
102
- let matched = false
103
-
104
- include.forEach(({ pattern, type }) => {
105
- if (type === 'tag' && !matched) {
106
- matched = !!operation.getTags().some((tag) => tag.name.match(pattern))
107
- }
108
-
109
- if (type === 'operationId' && !matched) {
110
- matched = !!operation.getOperationId({ friendlyCase: true }).match(pattern)
111
- }
112
-
113
- if (type === 'path' && !matched) {
114
- matched = !!operation.path.match(pattern)
115
- }
116
-
117
- if (type === 'method' && !matched) {
118
- matched = !!method.match(pattern)
119
- }
120
-
121
- if (type === 'contentType' && !matched) {
122
- matched = !!operation.getContentType().match(pattern)
82
+ const operationId = operation.getOperationId({ friendlyCase: true })
83
+ const contentType = operation.getContentType()
84
+
85
+ return include.some(({ pattern, type }) => {
86
+ switch (type) {
87
+ case 'tag':
88
+ return operation.getTags().some((tag) => tag.name.match(pattern))
89
+ case 'operationId':
90
+ return !!operationId.match(pattern)
91
+ case 'path':
92
+ return !!operation.path.match(pattern)
93
+ case 'method':
94
+ return !!method.match(pattern)
95
+ case 'contentType':
96
+ return !!contentType.match(pattern)
97
+ default:
98
+ return false
123
99
  }
124
100
  })
125
-
126
- return matched
127
101
  }
128
102
 
129
103
  getSchemas(
@@ -134,220 +108,149 @@ export class OperationGenerator<
134
108
  resolveName?: (name: string) => string
135
109
  } = {},
136
110
  ): OperationSchemas {
111
+ const operationId = operation.getOperationId({ friendlyCase: true })
112
+ const method = operation.method
113
+ const operationName = transformers.pascalCase(operationId)
114
+
115
+ const resolveKeys = (schema?: SchemaObject) => (schema?.properties ? Object.keys(schema.properties) : undefined)
116
+
137
117
  const pathParamsSchema = this.context.oas.getParametersSchema(operation, 'path')
138
118
  const queryParamsSchema = this.context.oas.getParametersSchema(operation, 'query')
139
119
  const headerParamsSchema = this.context.oas.getParametersSchema(operation, 'header')
140
120
  const requestSchema = this.context.oas.getRequestSchema(operation)
141
121
  const statusCodes = operation.getResponseStatusCodes().map((statusCode) => {
142
- let name = statusCode
143
- if (name === 'default') {
144
- name = 'error'
145
- }
146
-
122
+ const name = statusCode === 'default' ? 'error' : statusCode
147
123
  const schema = this.context.oas.getResponseSchema(operation, statusCode)
124
+ const keys = resolveKeys(schema)
148
125
 
149
126
  return {
150
- name: resolveName(transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} ${name}`)),
127
+ name: resolveName(transformers.pascalCase(`${operationId} ${name}`)),
151
128
  description: (operation.getResponseByStatusCode(statusCode) as OasTypes.ResponseObject)?.description,
152
129
  schema,
153
130
  operation,
154
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
131
+ operationName,
155
132
  statusCode: name === 'error' ? undefined : Number(statusCode),
156
- keys: schema?.properties ? Object.keys(schema.properties) : undefined,
157
- keysToOmit: schema?.properties
158
- ? Object.keys(schema.properties).filter((key) => {
159
- const item = schema.properties?.[key] as OasTypes.SchemaObject
160
- return item?.writeOnly
161
- })
162
- : undefined,
133
+ keys,
134
+ keysToOmit: keys?.filter((key) => (schema?.properties?.[key] as OasTypes.SchemaObject)?.writeOnly),
163
135
  }
164
136
  })
165
- const hasResponses = statusCodes.some((item) => item.statusCode?.toString().startsWith('2'))
137
+
138
+ const successful = statusCodes.filter((item) => item.statusCode?.toString().startsWith('2'))
139
+ const errors = statusCodes.filter((item) => item.statusCode?.toString().startsWith('4') || item.statusCode?.toString().startsWith('5'))
166
140
 
167
141
  return {
168
142
  pathParams: pathParamsSchema
169
143
  ? {
170
- name: resolveName(transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} PathParams`)),
144
+ name: resolveName(transformers.pascalCase(`${operationId} PathParams`)),
171
145
  operation,
172
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
146
+ operationName,
173
147
  schema: pathParamsSchema,
174
- keys: pathParamsSchema.properties ? Object.keys(pathParamsSchema.properties) : undefined,
148
+ keys: resolveKeys(pathParamsSchema),
175
149
  }
176
150
  : undefined,
177
151
  queryParams: queryParamsSchema
178
152
  ? {
179
- name: resolveName(transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} QueryParams`)),
153
+ name: resolveName(transformers.pascalCase(`${operationId} QueryParams`)),
180
154
  operation,
181
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
155
+ operationName,
182
156
  schema: queryParamsSchema,
183
- keys: queryParamsSchema.properties ? Object.keys(queryParamsSchema.properties) : [],
157
+ keys: resolveKeys(queryParamsSchema) || [],
184
158
  }
185
159
  : undefined,
186
160
  headerParams: headerParamsSchema
187
161
  ? {
188
- name: resolveName(transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} HeaderParams`)),
162
+ name: resolveName(transformers.pascalCase(`${operationId} HeaderParams`)),
189
163
  operation,
190
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
164
+ operationName,
191
165
  schema: headerParamsSchema,
192
- keys: headerParamsSchema.properties ? Object.keys(headerParamsSchema.properties) : undefined,
166
+ keys: resolveKeys(headerParamsSchema),
193
167
  }
194
168
  : undefined,
195
169
  request: requestSchema
196
170
  ? {
197
- name: resolveName(
198
- transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} ${operation.method === 'get' ? 'queryRequest' : 'mutationRequest'}`),
199
- ),
171
+ name: resolveName(transformers.pascalCase(`${operationId} ${method === 'get' ? 'queryRequest' : 'mutationRequest'}`)),
200
172
  description: (operation.schema.requestBody as OasTypes.RequestBodyObject)?.description,
201
173
  operation,
202
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
174
+ operationName,
203
175
  schema: requestSchema,
204
- keys: requestSchema.properties ? Object.keys(requestSchema.properties) : undefined,
205
- keysToOmit: requestSchema.properties
206
- ? Object.keys(requestSchema.properties).filter((key) => {
207
- const item = requestSchema.properties?.[key] as OasTypes.SchemaObject
208
-
209
- return item?.readOnly
210
- })
211
- : undefined,
176
+ keys: resolveKeys(requestSchema),
177
+ keysToOmit: resolveKeys(requestSchema)?.filter((key) => (requestSchema.properties?.[key] as OasTypes.SchemaObject)?.readOnly),
212
178
  }
213
179
  : undefined,
214
180
  response: {
215
- name: resolveName(
216
- transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} ${operation.method === 'get' ? 'queryResponse' : 'mutationResponse'}`),
217
- ),
181
+ name: resolveName(transformers.pascalCase(`${operationId} ${method === 'get' ? 'queryResponse' : 'mutationResponse'}`)),
218
182
  operation,
219
- operationName: transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })}`),
183
+ operationName,
220
184
  schema: {
221
- oneOf: hasResponses
222
- ? statusCodes
223
- .filter((item) => item.statusCode?.toString().startsWith('2'))
224
- .map((item) => {
225
- return {
226
- ...item.schema,
227
- $ref: resolveName(transformers.pascalCase(`${operation.getOperationId({ friendlyCase: true })} ${item.statusCode}`)),
228
- }
229
- })
230
- : undefined,
185
+ oneOf: successful.map((item) => ({ ...item.schema, $ref: item.name })) || undefined,
231
186
  } as SchemaObject,
232
187
  },
233
- responses: statusCodes.filter((item) => item.statusCode?.toString().startsWith('2')),
234
- errors: statusCodes.filter((item) => item.statusCode?.toString().startsWith('4') || item.statusCode?.toString().startsWith('5')),
188
+ responses: successful,
189
+ errors,
235
190
  statusCodes,
236
191
  }
237
192
  }
238
193
 
239
- async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
194
+ async getOperations(): Promise<Array<{ path: string; method: HttpMethod; operation: Operation }>> {
240
195
  const { oas } = this.context
241
196
 
242
197
  const paths = oas.getPaths()
243
- this.operationsByMethod = Object.entries(paths).reduce((acc, [path, method]) => {
244
- const methods = Object.keys(method) as HttpMethod[]
245
198
 
246
- methods.forEach((method) => {
247
- const operation = oas.operation(path, method)
248
- if (operation && method === operation.method) {
249
- const isExcluded = this.#isExcluded(operation, method)
250
- const isIncluded = this.context.include ? this.#isIncluded(operation, method) : true
251
-
252
- if (isIncluded && !isExcluded) {
253
- if (!acc[path]) {
254
- acc[path] = {} as OperationsByMethod['get']
255
- }
256
- acc[path] = {
257
- ...acc[path],
258
- [method]: {
259
- operation,
260
- schemas: this.getSchemas(operation),
261
- },
262
- } as OperationsByMethod['get']
199
+ return Object.entries(paths).flatMap(([path, methods]) =>
200
+ Object.entries(methods)
201
+ .map((values) => {
202
+ const [method, operation] = values as [HttpMethod, Operation]
203
+ if (this.#isExcluded(operation, method)) {
204
+ return null
263
205
  }
264
- }
265
- })
266
-
267
- return acc
268
- }, {} as OperationsByMethod)
269
-
270
- const promises = Object.keys(this.operationsByMethod).reduce((acc, path) => {
271
- const methods = this.operationsByMethod[path] ? (Object.keys(this.operationsByMethod[path]!) as HttpMethod[]) : []
272
-
273
- methods.forEach((method) => {
274
- const { operation } = this.operationsByMethod[path]?.[method]!
275
- const options = this.#getOptions(operation, method)
276
206
 
277
- const methodToCall = this[method as keyof typeof this] as any
278
-
279
- if (typeof methodToCall === 'function') {
280
- const promiseMethod = methodToCall?.call(this, operation, {
281
- ...this.options,
282
- ...options,
283
- })
284
-
285
- if (promiseMethod) {
286
- acc.push(promiseMethod)
207
+ if (this.context.include && !this.#isIncluded(operation, method)) {
208
+ return null
287
209
  }
288
- }
289
210
 
290
- const promiseOperation = this.operation.call(this, operation, {
291
- ...this.options,
292
- ...options,
211
+ return operation ? { path, method: method as HttpMethod, operation } : null
293
212
  })
213
+ .filter(Boolean),
214
+ )
215
+ }
294
216
 
295
- if (promiseOperation) {
296
- acc.push(promiseOperation)
297
- }
298
-
299
- generators?.forEach((generator) => {
300
- const promise = generator.operation?.({
301
- instance: this,
302
- operation,
303
- options: {
304
- ...this.options,
305
- ...options,
306
- },
307
- } as any) as Promise<Array<KubbFile.File<TFileMeta>>>
217
+ async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
218
+ const operations = await this.getOperations()
308
219
 
309
- if (promise) {
310
- acc.push(promise)
311
- }
312
- })
313
- })
220
+ const generatorLimit = pLimit(1)
221
+ const operationLimit = pLimit(10)
314
222
 
315
- return acc
316
- }, [] as OperationMethodResult<TFileMeta>[])
223
+ const writeTasks = generators.map((generator) =>
224
+ generatorLimit(async () => {
225
+ const operationTasks = operations.map(({ operation, method }) =>
226
+ operationLimit(async () => {
227
+ const options = this.#getOptions(operation, method)
317
228
 
318
- const operations = Object.values(this.operationsByMethod).map((item) => Object.values(item).map((item) => item.operation))
229
+ const result = await generator.operation?.({
230
+ instance: this,
231
+ operation,
232
+ options: { ...this.options, ...options },
233
+ })
319
234
 
320
- promises.push(this.all(operations.flat().filter(Boolean), this.operationsByMethod))
235
+ return result ?? []
236
+ }),
237
+ )
321
238
 
322
- generators?.forEach((generator) => {
323
- const promise = generator.operations?.({
324
- instance: this,
325
- operations: operations.flat().filter(Boolean),
326
- operationsByMethod: this.operationsByMethod,
327
- options: this.options,
328
- } as any) as Promise<Array<KubbFile.File<TFileMeta>>>
239
+ const operationResults = await Promise.all(operationTasks)
240
+ const opResultsFlat = operationResults.flat()
329
241
 
330
- if (promise) {
331
- promises.push(promise)
332
- }
333
- })
242
+ const operationsResult = await generator.operations?.({
243
+ instance: this,
244
+ operations: operations.map((op) => op.operation),
245
+ options: this.options,
246
+ })
334
247
 
335
- const files = await Promise.all(promises)
248
+ return [...opResultsFlat, ...(operationsResult ?? [])] as unknown as KubbFile.File<TFileMeta>
249
+ }),
250
+ )
336
251
 
337
- // using .flat because operationGenerator[method] can return a array of files or just one file
338
- return files.flat().filter(Boolean)
339
- }
252
+ const nestedResults = await Promise.all(writeTasks)
340
253
 
341
- /**
342
- * Operation
343
- */
344
- async operation(_operation: Operation, _options: TPluginOptions['resolvedOptions']): OperationMethodResult<TFileMeta> {
345
- return []
346
- }
347
- /**
348
- * Combination of GET, POST, PATCH, PUT, DELETE
349
- */
350
- async all(_operations: Operation[], _paths: OperationsByMethod): OperationMethodResult<TFileMeta> {
351
- return []
254
+ return nestedResults.flat()
352
255
  }
353
256
  }
@@ -12,6 +12,7 @@ import { isKeyword, schemaKeywords } from './SchemaMapper.ts'
12
12
  import type { OperationSchema, Override, Refs } from './types.ts'
13
13
  import { getSchemaFactory } from './utils/getSchemaFactory.ts'
14
14
  import { getSchemas } from './utils/getSchemas.ts'
15
+ import pLimit from 'p-limit'
15
16
 
16
17
  export type GetSchemaGeneratorOptions<T extends SchemaGenerator<any, any, any>> = T extends SchemaGenerator<infer Options, any, any> ? Options : never
17
18
 
@@ -1082,58 +1083,43 @@ export class SchemaGenerator<
1082
1083
 
1083
1084
  async build(...generators: Array<Generator<TPluginOptions>>): Promise<Array<KubbFile.File<TFileMeta>>> {
1084
1085
  const { oas, contentType, include } = this.context
1085
-
1086
1086
  const schemas = getSchemas({ oas, contentType, includes: include })
1087
+ const schemaEntries = Object.entries(schemas)
1087
1088
 
1088
- const promises = Object.entries(schemas).reduce((acc, [name, value]) => {
1089
- if (!value) {
1090
- return acc
1091
- }
1092
-
1093
- const options = this.#getOptions({ name })
1094
- const promiseOperation = this.schema.call(this, name, value, {
1095
- ...this.options,
1096
- ...options,
1097
- })
1098
-
1099
- if (promiseOperation) {
1100
- acc.push(promiseOperation)
1101
- }
1102
-
1103
- generators?.forEach((generator) => {
1104
- const tree = this.parse({ schemaObject: value, name: name })
1089
+ const generatorLimit = pLimit(1)
1090
+ const schemaLimit = pLimit(10)
1105
1091
 
1106
- const promise = generator.schema?.({
1107
- instance: this,
1108
- schema: {
1109
- name,
1110
- value,
1111
- tree,
1112
- },
1113
- options: {
1114
- ...this.options,
1115
- ...options,
1116
- },
1117
- } as any) as Promise<Array<KubbFile.File<TFileMeta>>>
1092
+ const writeTasks = generators.map((generator) =>
1093
+ generatorLimit(async () => {
1094
+ const schemaTasks = schemaEntries.map(([name, schemaObject]) =>
1095
+ schemaLimit(async () => {
1096
+ const options = this.#getOptions({ name })
1097
+ const tree = this.parse({ name, schemaObject })
1118
1098
 
1119
- if (promise) {
1120
- acc.push(promise)
1121
- }
1122
- })
1099
+ const result = await generator.schema?.({
1100
+ instance: this,
1101
+ schema: {
1102
+ name,
1103
+ value: schemaObject,
1104
+ tree,
1105
+ },
1106
+ options: {
1107
+ ...this.options,
1108
+ ...options,
1109
+ },
1110
+ })
1123
1111
 
1124
- return acc
1125
- }, [] as SchemaMethodResult<TFileMeta>[])
1112
+ return result ?? []
1113
+ }),
1114
+ )
1126
1115
 
1127
- const files = await Promise.all(promises)
1116
+ const schemaResults = await Promise.all(schemaTasks)
1117
+ return schemaResults.flat() as unknown as KubbFile.File<TFileMeta>
1118
+ }),
1119
+ )
1128
1120
 
1129
- // using .flat because schemaGenerator[method] can return an array of files or just one file
1130
- return files.flat().filter(Boolean)
1131
- }
1121
+ const nestedResults = await Promise.all(writeTasks)
1132
1122
 
1133
- /**
1134
- * Schema
1135
- */
1136
- async schema(_name: string, _object: SchemaObject, _options: TOptions): SchemaMethodResult<TFileMeta> {
1137
- return []
1123
+ return nestedResults.flat()
1138
1124
  }
1139
1125
  }
package/src/generator.tsx CHANGED
@@ -7,13 +7,11 @@ import { Oas } from './components/Oas.tsx'
7
7
  import type { OperationGenerator } from './OperationGenerator.ts'
8
8
  import type { SchemaGenerator, SchemaGeneratorOptions } from './SchemaGenerator.ts'
9
9
  import type { Schema } from './SchemaMapper.ts'
10
- import type { OperationsByMethod } from './types.ts'
11
10
 
12
11
  type OperationsProps<TOptions extends PluginFactoryOptions> = {
13
12
  instance: Omit<OperationGenerator<TOptions>, 'build'>
14
13
  options: TOptions['resolvedOptions']
15
14
  operations: Array<Operation>
16
- operationsByMethod: OperationsByMethod
17
15
  }
18
16
 
19
17
  type OperationProps<TOptions extends PluginFactoryOptions> = {
@@ -62,7 +60,7 @@ export type ReactGeneratorOptions<TOptions extends PluginFactoryOptions> = {
62
60
  export function createReactGenerator<TOptions extends PluginFactoryOptions>(parseOptions: ReactGeneratorOptions<TOptions>): Generator<TOptions> {
63
61
  return {
64
62
  ...parseOptions,
65
- async operations({ instance, options, operations, operationsByMethod }) {
63
+ async operations({ instance, options, operations }) {
66
64
  if (!parseOptions.Operations) {
67
65
  return []
68
66
  }
@@ -71,17 +69,15 @@ export function createReactGenerator<TOptions extends PluginFactoryOptions>(pars
71
69
  const root = createRoot({
72
70
  logger: pluginManager.logger,
73
71
  })
74
-
75
72
  const Component = parseOptions.Operations.bind(this)
76
73
 
77
74
  root.render(
78
75
  <App pluginManager={pluginManager} plugin={plugin} mode={mode}>
79
76
  <Oas oas={oas} operations={operations} generator={instance}>
80
- <Component operations={operations} instance={instance} operationsByMethod={operationsByMethod} options={options} />
77
+ <Component operations={operations} instance={instance} options={options} />
81
78
  </Oas>
82
79
  </App>,
83
80
  )
84
-
85
81
  return root.files
86
82
  },
87
83
  async operation({ instance, operation, options }) {
@@ -93,7 +89,6 @@ export function createReactGenerator<TOptions extends PluginFactoryOptions>(pars
93
89
  const root = createRoot({
94
90
  logger: pluginManager.logger,
95
91
  })
96
-
97
92
  const Component = parseOptions.Operation.bind(this)
98
93
 
99
94
  root.render(
@@ -105,7 +100,6 @@ export function createReactGenerator<TOptions extends PluginFactoryOptions>(pars
105
100
  </Oas>
106
101
  </App>,
107
102
  )
108
-
109
103
  return root.files
110
104
  },
111
105
  async schema({ instance, schema, options }) {
@@ -114,12 +108,11 @@ export function createReactGenerator<TOptions extends PluginFactoryOptions>(pars
114
108
  }
115
109
 
116
110
  const { pluginManager, oas, plugin, mode } = instance.context
111
+
112
+ const Component = parseOptions.Schema.bind(this)
117
113
  const root = createRoot({
118
114
  logger: pluginManager.logger,
119
115
  })
120
-
121
- const Component = parseOptions.Schema.bind(this)
122
-
123
116
  root.render(
124
117
  <App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
125
118
  <Oas oas={oas}>
@@ -129,7 +122,6 @@ export function createReactGenerator<TOptions extends PluginFactoryOptions>(pars
129
122
  </Oas>
130
123
  </App>,
131
124
  )
132
-
133
125
  return root.files
134
126
  },
135
127
  }
package/src/types.ts CHANGED
@@ -122,7 +122,6 @@ export type OperationSchemas = {
122
122
  errors?: Array<OperationSchema>
123
123
  }
124
124
 
125
- export type OperationsByMethod = Record<string, Record<HttpMethod, { operation: Operation; schemas: OperationSchemas }>>
126
125
  type ByTag = {
127
126
  type: 'tag'
128
127
  pattern: string | RegExp