@kubb/plugin-oas 4.4.0 → 4.5.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 (109) hide show
  1. package/dist/{SchemaGenerator-7wBwdv8G.js → SchemaGenerator-BwYbrh7a.js} +93 -36
  2. package/dist/SchemaGenerator-BwYbrh7a.js.map +1 -0
  3. package/dist/{SchemaGenerator-DzVHk6OP.cjs → SchemaGenerator-C81yEgKY.cjs} +114 -37
  4. package/dist/SchemaGenerator-C81yEgKY.cjs.map +1 -0
  5. package/dist/{SchemaMapper-DoL-a6qq.cjs → SchemaMapper-BUV8vhg0.cjs} +1 -1
  6. package/dist/SchemaMapper-BUV8vhg0.cjs.map +1 -0
  7. package/dist/{SchemaMapper-CqBW0VOy.d.ts → SchemaMapper-CgGWx6jF.d.cts} +15 -116
  8. package/dist/{SchemaMapper-MiRB5_Zp.d.cts → SchemaMapper-Cj3vjPGs.d.ts} +15 -116
  9. package/dist/{SchemaMapper-Cx4X1al6.js → SchemaMapper-D30tqRoX.js} +1 -1
  10. package/dist/SchemaMapper-D30tqRoX.js.map +1 -0
  11. package/dist/{OperationGenerator-BZPWkxw4.d.ts → createGenerator-BvCDyuKS.d.ts} +128 -191
  12. package/dist/{OperationGenerator-CJTAer7l.d.cts → createGenerator-CPNglV1d.d.cts} +129 -192
  13. package/dist/{generators-C61FxVIj.js → generators-CJDEf8Kn.js} +6 -6
  14. package/dist/generators-CJDEf8Kn.js.map +1 -0
  15. package/dist/{generators-B27La9Vd.cjs → generators-udGOxdUV.cjs} +6 -6
  16. package/dist/generators-udGOxdUV.cjs.map +1 -0
  17. package/dist/generators.cjs +2 -7
  18. package/dist/generators.d.cts +8 -3
  19. package/dist/generators.d.ts +8 -3
  20. package/dist/generators.js +3 -5
  21. package/dist/{getFooter-D5MdeUVv.js → getFooter-CV73pVXj.js} +2 -2
  22. package/dist/{getFooter-D5MdeUVv.js.map → getFooter-CV73pVXj.js.map} +1 -1
  23. package/dist/{getFooter-CwjCW4h5.cjs → getFooter-DPh4lxBH.cjs} +3 -3
  24. package/dist/{getFooter-CwjCW4h5.cjs.map → getFooter-DPh4lxBH.cjs.map} +1 -1
  25. package/dist/getSchemas-32BHoMO-.js +100 -0
  26. package/dist/getSchemas-32BHoMO-.js.map +1 -0
  27. package/dist/getSchemas-Cl0TZ4XY.cjs +113 -0
  28. package/dist/getSchemas-Cl0TZ4XY.cjs.map +1 -0
  29. package/dist/hooks.cjs +6 -47
  30. package/dist/hooks.cjs.map +1 -1
  31. package/dist/hooks.d.cts +11 -45
  32. package/dist/hooks.d.ts +11 -45
  33. package/dist/hooks.js +8 -46
  34. package/dist/hooks.js.map +1 -1
  35. package/dist/index.cjs +37 -32
  36. package/dist/index.cjs.map +1 -1
  37. package/dist/index.d.cts +58 -3
  38. package/dist/index.d.ts +58 -3
  39. package/dist/index.js +32 -24
  40. package/dist/index.js.map +1 -1
  41. package/dist/mocks.cjs +1 -1
  42. package/dist/mocks.d.cts +1 -1
  43. package/dist/mocks.d.ts +1 -1
  44. package/dist/mocks.js +1 -1
  45. package/dist/{parseFromConfig-CqiiLCPe.js → parseFromConfig-BkUoWC2U.js} +1 -1
  46. package/dist/parseFromConfig-BkUoWC2U.js.map +1 -0
  47. package/dist/{parseFromConfig-RR31a98-.cjs → parseFromConfig-EjsCZ0-8.cjs} +1 -1
  48. package/dist/parseFromConfig-EjsCZ0-8.cjs.map +1 -0
  49. package/dist/utils.cjs +3 -3
  50. package/dist/utils.cjs.map +1 -1
  51. package/dist/utils.d.cts +28 -24
  52. package/dist/utils.d.ts +28 -24
  53. package/dist/utils.js +3 -3
  54. package/dist/utils.js.map +1 -1
  55. package/package.json +14 -17
  56. package/src/OperationGenerator.ts +27 -14
  57. package/src/SchemaGenerator.ts +25 -47
  58. package/src/SchemaMapper.ts +3 -1
  59. package/src/generators/createGenerator.ts +1 -1
  60. package/src/generators/index.ts +0 -1
  61. package/src/generators/jsonGenerator.ts +4 -4
  62. package/src/generators/types.ts +13 -14
  63. package/src/hooks/index.ts +1 -4
  64. package/src/hooks/useOas.ts +5 -11
  65. package/src/hooks/useOperationManager.ts +3 -5
  66. package/src/hooks/useSchemaManager.ts +1 -1
  67. package/src/index.ts +1 -1
  68. package/src/types.ts +1 -1
  69. package/src/utils/getBanner.ts +1 -1
  70. package/src/utils/getParams.ts +1 -2
  71. package/src/utils/getSchemaFactory.ts +1 -2
  72. package/src/utils/getSchemas.ts +89 -15
  73. package/src/utils/index.ts +3 -4
  74. package/src/utils/parseFromConfig.ts +2 -6
  75. package/src/utils.tsx +101 -0
  76. package/dist/Oas-BzrQ6RGC.cjs +0 -80
  77. package/dist/Oas-BzrQ6RGC.cjs.map +0 -1
  78. package/dist/Oas-CIeHKOo0.js +0 -60
  79. package/dist/Oas-CIeHKOo0.js.map +0 -1
  80. package/dist/Schema-CjraJhJi.d.ts +0 -38
  81. package/dist/Schema-zcZF0UIp.d.cts +0 -38
  82. package/dist/SchemaGenerator-7wBwdv8G.js.map +0 -1
  83. package/dist/SchemaGenerator-DzVHk6OP.cjs.map +0 -1
  84. package/dist/SchemaMapper-Cx4X1al6.js.map +0 -1
  85. package/dist/SchemaMapper-DoL-a6qq.cjs.map +0 -1
  86. package/dist/components.cjs +0 -5
  87. package/dist/components.d.cts +0 -42
  88. package/dist/components.d.ts +0 -42
  89. package/dist/components.js +0 -3
  90. package/dist/generators-B27La9Vd.cjs.map +0 -1
  91. package/dist/generators-C61FxVIj.js.map +0 -1
  92. package/dist/getSchemas-Bdg6n9Qk.js +0 -55
  93. package/dist/getSchemas-Bdg6n9Qk.js.map +0 -1
  94. package/dist/getSchemas-DY8s2CSl.cjs +0 -68
  95. package/dist/getSchemas-DY8s2CSl.cjs.map +0 -1
  96. package/dist/parseFromConfig-CqiiLCPe.js.map +0 -1
  97. package/dist/parseFromConfig-RR31a98-.cjs.map +0 -1
  98. package/dist/utils-BnkB1ikY.js +0 -99
  99. package/dist/utils-BnkB1ikY.js.map +0 -1
  100. package/dist/utils-nzdccPlU.cjs +0 -119
  101. package/dist/utils-nzdccPlU.cjs.map +0 -1
  102. package/src/components/Oas.tsx +0 -35
  103. package/src/components/Operation.tsx +0 -20
  104. package/src/components/Schema.tsx +0 -38
  105. package/src/components/index.ts +0 -3
  106. package/src/generators/utils.tsx +0 -114
  107. package/src/hooks/useOperation.ts +0 -18
  108. package/src/hooks/useOperations.ts +0 -40
  109. package/src/hooks/useSchema.ts +0 -16
@@ -1,20 +1,20 @@
1
1
  import type { Plugin, PluginFactoryOptions, PluginManager, ResolveNameParams } from '@kubb/core'
2
2
  import { BaseGenerator, type FileMetaBase } from '@kubb/core'
3
- import type { KubbFile } from '@kubb/core/fs'
4
3
  import transformers, { pascalCase } from '@kubb/core/transformers'
5
4
  import { getUniqueName } from '@kubb/core/utils'
5
+ import type { KubbFile } from '@kubb/fabric-core/types'
6
6
  import type { contentType, Oas, OpenAPIV3, SchemaObject } from '@kubb/oas'
7
7
  import { isDiscriminator, isNullable, isReference } from '@kubb/oas'
8
8
  import type { Fabric } from '@kubb/react-fabric'
9
9
  import pLimit from 'p-limit'
10
10
  import { isDeepEqual, isNumber, uniqueWith } from 'remeda'
11
11
  import type { Generator } from './generators/types.ts'
12
- import { buildSchema } from './generators/utils.tsx'
13
12
  import type { Schema, SchemaKeywordMapper } from './SchemaMapper.ts'
14
13
  import { isKeyword, schemaKeywords } from './SchemaMapper.ts'
15
14
  import type { OperationSchema, Override, Refs } from './types.ts'
16
15
  import { getSchemaFactory } from './utils/getSchemaFactory.ts'
17
16
  import { getSchemas } from './utils/getSchemas.ts'
17
+ import { buildSchema } from './utils.tsx'
18
18
 
19
19
  export type GetSchemaGeneratorOptions<T extends SchemaGenerator<any, any, any>> = T extends SchemaGenerator<infer Options, any, any> ? Options : never
20
20
 
@@ -91,14 +91,6 @@ export class SchemaGenerator<
91
91
  return uniqueWith(schemas, isDeepEqual)
92
92
  }
93
93
 
94
- deepSearch<T extends keyof SchemaKeywordMapper>(tree: Schema[] | undefined, keyword: T): Array<SchemaKeywordMapper[T]> {
95
- return SchemaGenerator.deepSearch<T>(tree, keyword)
96
- }
97
-
98
- find<T extends keyof SchemaKeywordMapper>(tree: Schema[] | undefined, keyword: T): SchemaKeywordMapper[T] | undefined {
99
- return SchemaGenerator.find<T>(tree, keyword)
100
- }
101
-
102
94
  static deepSearch<T extends keyof SchemaKeywordMapper>(tree: Schema[] | undefined, keyword: T): Array<SchemaKeywordMapper[T]> {
103
95
  const foundItems: SchemaKeywordMapper[T][] = []
104
96
 
@@ -145,32 +137,6 @@ export class SchemaGenerator<
145
137
  return foundItems
146
138
  }
147
139
 
148
- static findInObject<T extends keyof SchemaKeywordMapper>(tree: Schema[] | undefined, keyword: T): SchemaKeywordMapper[T] | undefined {
149
- let foundItem: SchemaKeywordMapper[T] | undefined
150
-
151
- tree?.forEach((schema) => {
152
- if (!foundItem && schema.keyword === keyword) {
153
- foundItem = schema as SchemaKeywordMapper[T]
154
- }
155
-
156
- if (isKeyword(schema, schemaKeywords.object)) {
157
- Object.values(schema.args?.properties || {}).forEach((entrySchema) => {
158
- if (!foundItem) {
159
- foundItem = SchemaGenerator.find<T>(entrySchema, keyword)
160
- }
161
- })
162
-
163
- Object.values(schema.args?.additionalProperties || {}).forEach((entrySchema) => {
164
- if (!foundItem) {
165
- foundItem = SchemaGenerator.find<T>([entrySchema], keyword)
166
- }
167
- })
168
- }
169
- })
170
-
171
- return foundItem
172
- }
173
-
174
140
  static find<T extends keyof SchemaKeywordMapper>(tree: Schema[] | undefined, keyword: T): SchemaKeywordMapper[T] | undefined {
175
141
  let foundItem: SchemaKeywordMapper[T] | undefined
176
142
 
@@ -563,13 +529,17 @@ export class SchemaGenerator<
563
529
  if (max !== undefined) {
564
530
  if (exclusiveMaximum) {
565
531
  baseItems.unshift({ keyword: schemaKeywords.exclusiveMaximum, args: max })
566
- } else baseItems.unshift({ keyword: schemaKeywords.max, args: max })
532
+ } else {
533
+ baseItems.unshift({ keyword: schemaKeywords.max, args: max })
534
+ }
567
535
  }
568
536
 
569
537
  if (min !== undefined) {
570
538
  if (exclusiveMinimum) {
571
539
  baseItems.unshift({ keyword: schemaKeywords.exclusiveMinimum, args: min })
572
- } else baseItems.unshift({ keyword: schemaKeywords.min, args: min })
540
+ } else {
541
+ baseItems.unshift({ keyword: schemaKeywords.min, args: min })
542
+ }
573
543
  }
574
544
 
575
545
  if (typeof exclusiveMaximum === 'number') {
@@ -1127,12 +1097,16 @@ export class SchemaGenerator<
1127
1097
  tree,
1128
1098
  },
1129
1099
  {
1100
+ config: this.context.pluginManager.config,
1130
1101
  fabric: this.context.fabric,
1131
- generator,
1132
- instance: this,
1133
- options: {
1134
- ...this.options,
1135
- ...options,
1102
+ Component: generator.Schema,
1103
+ generator: this,
1104
+ plugin: {
1105
+ ...this.context.plugin,
1106
+ options: {
1107
+ ...this.options,
1108
+ ...options,
1109
+ },
1136
1110
  },
1137
1111
  },
1138
1112
  )
@@ -1141,15 +1115,19 @@ export class SchemaGenerator<
1141
1115
  }
1142
1116
 
1143
1117
  const result = await generator.schema?.({
1144
- instance: this,
1118
+ config: this.context.pluginManager.config,
1119
+ generator: this,
1145
1120
  schema: {
1146
1121
  name,
1147
1122
  value: schemaObject,
1148
1123
  tree,
1149
1124
  },
1150
- options: {
1151
- ...this.options,
1152
- ...options,
1125
+ plugin: {
1126
+ ...this.context.plugin,
1127
+ options: {
1128
+ ...this.options,
1129
+ ...options,
1130
+ },
1153
1131
  },
1154
1132
  })
1155
1133
 
@@ -1,4 +1,5 @@
1
- import type { KubbFile } from '@kubb/core/fs'
1
+ import type { KubbFile } from '@kubb/fabric-core/types'
2
+ import type { SchemaObject } from '@kubb/oas'
2
3
 
3
4
  export type SchemaKeywordMapper = {
4
5
  object: {
@@ -161,6 +162,7 @@ export type SchemaKeywordBase<T> = {
161
162
  export type Schema = { keyword: string } | SchemaKeywordMapper[keyof SchemaKeywordMapper]
162
163
 
163
164
  export type SchemaTree = {
165
+ schema: SchemaObject
164
166
  parent: Schema | undefined
165
167
  current: Schema
166
168
  siblings: Schema[]
@@ -1,5 +1,5 @@
1
1
  import type { PluginFactoryOptions } from '@kubb/core'
2
- import type { KubbFile } from '@kubb/core/fs'
2
+ import type { KubbFile } from '@kubb/fabric-core/types'
3
3
  import type { OperationProps, OperationsProps, SchemaProps } from './types.ts'
4
4
 
5
5
  type UserGenerator<TOptions extends PluginFactoryOptions> = {
@@ -2,4 +2,3 @@ export { createGenerator } from './createGenerator.ts'
2
2
  export { createReactGenerator } from './createReactGenerator.ts'
3
3
  export { jsonGenerator } from './jsonGenerator.ts'
4
4
  export type { Generator } from './types.ts'
5
- export { buildOperation, buildOperations, buildSchema } from './utils.tsx'
@@ -6,8 +6,8 @@ import { createGenerator } from './createGenerator.ts'
6
6
 
7
7
  export const jsonGenerator = createGenerator<PluginOas>({
8
8
  name: 'plugin-oas',
9
- async schema({ schema, instance }) {
10
- const { pluginManager, plugin } = instance.context
9
+ async schema({ schema, generator }) {
10
+ const { pluginManager, plugin } = generator.context
11
11
  const file = pluginManager.getFile({
12
12
  name: camelCase(schema.name),
13
13
  extname: '.json',
@@ -27,11 +27,11 @@ export const jsonGenerator = createGenerator<PluginOas>({
27
27
  },
28
28
  ],
29
29
  banner: getBanner({
30
- oas: instance.context.oas,
30
+ oas: generator.context.oas,
31
31
  output: plugin.options.output,
32
32
  config: pluginManager.config,
33
33
  }),
34
- format: getFooter({ oas: instance.context.oas, output: plugin.options.output }),
34
+ format: getFooter({ oas: generator.context.oas, output: plugin.options.output }),
35
35
  },
36
36
  ]
37
37
  },
@@ -1,30 +1,29 @@
1
- import type { PluginFactoryOptions } from '@kubb/core'
1
+ import type { Config, Plugin, PluginFactoryOptions } from '@kubb/core'
2
2
  import type { Operation, SchemaObject } from '@kubb/oas'
3
- import type { OperationGenerator, Schema, SchemaGenerator, SchemaGeneratorOptions } from '@kubb/plugin-oas'
3
+ import type { OperationGenerator } from '../OperationGenerator.ts'
4
+ import type { SchemaGenerator, SchemaGeneratorOptions } from '../SchemaGenerator.ts'
5
+ import type { Schema } from '../SchemaMapper.ts'
4
6
  import type { CoreGenerator } from './createGenerator.ts'
5
7
  import type { ReactGenerator } from './createReactGenerator.ts'
6
8
 
7
9
  export type OperationsProps<TOptions extends PluginFactoryOptions> = {
8
- /**
9
- * @deprecated
10
- */
11
- instance: Omit<OperationGenerator<TOptions>, 'build'>
12
- options: TOptions['resolvedOptions']
10
+ config: Config
11
+ generator: Omit<OperationGenerator<TOptions>, 'build'>
12
+ plugin: Plugin<TOptions>
13
13
  operations: Array<Operation>
14
14
  }
15
15
 
16
16
  export type OperationProps<TOptions extends PluginFactoryOptions> = {
17
- /**
18
- * @deprecated
19
- */
20
- instance: Omit<OperationGenerator<TOptions>, 'build'>
21
- options: TOptions['resolvedOptions']
17
+ config: Config
18
+ generator: Omit<OperationGenerator<TOptions>, 'build'>
19
+ plugin: Plugin<TOptions>
22
20
  operation: Operation
23
21
  }
24
22
 
25
23
  export type SchemaProps<TOptions extends PluginFactoryOptions> = {
26
- instance: Omit<SchemaGenerator<SchemaGeneratorOptions, TOptions>, 'build'>
27
- options: TOptions['resolvedOptions']
24
+ config: Config
25
+ generator: Omit<SchemaGenerator<SchemaGeneratorOptions, TOptions>, 'build'>
26
+ plugin: Plugin<TOptions>
28
27
  schema: {
29
28
  name: string
30
29
  tree: Array<Schema>
@@ -1,7 +1,4 @@
1
1
  export { useOas } from './useOas.ts'
2
- export { useOperation } from './useOperation.ts'
3
- export { useOperationManager } from './useOperationManager.ts'
4
2
  export type { SchemaNames } from './useOperationManager.ts'
5
- export { useOperations } from './useOperations.ts'
6
- export { useSchema } from './useSchema.ts'
3
+ export { useOperationManager } from './useOperationManager.ts'
7
4
  export { useSchemaManager } from './useSchemaManager.ts'
@@ -1,15 +1,9 @@
1
- import { useContext } from '@kubb/react-fabric'
1
+ import type { Oas } from '@kubb/oas'
2
2
 
3
- import { Oas } from '../components/Oas.tsx'
3
+ import { useApp } from '@kubb/react-fabric'
4
4
 
5
- import type { Oas as OasType } from '@kubb/oas'
5
+ export function useOas(): Oas {
6
+ const { meta } = useApp<{ oas: Oas }>()
6
7
 
7
- export function useOas(): OasType {
8
- const { oas } = useContext(Oas.Context)
9
-
10
- if (!oas) {
11
- throw new Error('Oas is not defined')
12
- }
13
-
14
- return oas
8
+ return meta.oas
15
9
  }
@@ -1,9 +1,8 @@
1
1
  import type { FileMetaBase, Plugin, ResolveNameParams } from '@kubb/core'
2
- import type { KubbFile } from '@kubb/core/fs'
3
2
  import { usePlugin, usePluginManager } from '@kubb/core/hooks'
3
+ import type { KubbFile } from '@kubb/fabric-core/types'
4
4
  import type { Operation, Operation as OperationType } from '@kubb/oas'
5
- import { useContext } from '@kubb/react-fabric'
6
- import { Oas } from '../components/Oas.tsx'
5
+ import type { OperationGenerator } from '../OperationGenerator.ts'
7
6
  import type { OperationSchemas } from '../types.ts'
8
7
 
9
8
  type FileMeta = FileMetaBase & {
@@ -63,10 +62,9 @@ type UseOperationManagerResult = {
63
62
  /**
64
63
  * `useOperationManager` will return some helper functions that can be used to get the operation file, get the operation name.
65
64
  */
66
- export function useOperationManager(): UseOperationManagerResult {
65
+ export function useOperationManager(generator: Omit<OperationGenerator, 'build'>): UseOperationManagerResult {
67
66
  const plugin = usePlugin()
68
67
  const pluginManager = usePluginManager()
69
- const { generator } = useContext(Oas.Context)
70
68
 
71
69
  const getName: UseOperationManagerResult['getName'] = (operation, { prefix = '', suffix = '', pluginKey = plugin.key, type }) => {
72
70
  return pluginManager.resolveName({
@@ -1,6 +1,6 @@
1
1
  import type { FileMetaBase, Plugin, ResolveNameParams } from '@kubb/core'
2
- import type { KubbFile } from '@kubb/core/fs'
3
2
  import { usePlugin, usePluginManager } from '@kubb/core/hooks'
3
+ import type { KubbFile } from '@kubb/fabric-core/types'
4
4
  import { SchemaGenerator } from '../SchemaGenerator.ts'
5
5
  import { type Schema, schemaKeywords } from '../SchemaMapper'
6
6
 
package/src/index.ts CHANGED
@@ -1,4 +1,3 @@
1
- export * from './generators/index.ts'
2
1
  export type { OperationMethodResult } from './OperationGenerator.ts'
3
2
  export { OperationGenerator } from './OperationGenerator.ts'
4
3
  export { pluginOas, pluginOasName } from './plugin.ts'
@@ -19,3 +18,4 @@ export type {
19
18
  } from './SchemaMapper.ts'
20
19
  export { isKeyword, schemaKeywords } from './SchemaMapper.ts'
21
20
  export type * from './types.ts'
21
+ export { buildOperation, buildOperations, buildSchema } from './utils.tsx'
package/src/types.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Group, Output, Plugin, PluginFactoryOptions, ResolveNameParams } from '@kubb/core'
2
- import type { KubbFile } from '@kubb/core/fs'
2
+ import type { KubbFile } from '@kubb/fabric-core/types'
3
3
 
4
4
  import type { contentType, HttpMethod, Oas, Operation, SchemaObject } from '@kubb/oas'
5
5
  import type { Generator } from './generators/types.ts'
@@ -1,7 +1,7 @@
1
+ import path from 'node:path'
1
2
  import type { Config, Output } from '@kubb/core'
2
3
  import type { Oas } from '@kubb/oas'
3
4
  import { isFunction } from 'remeda'
4
- import path from 'node:path'
5
5
 
6
6
  type Props<TOas extends Oas> = {
7
7
  oas: TOas
@@ -1,8 +1,7 @@
1
- import { isParameterObject } from '@kubb/oas'
2
-
3
1
  import { camelCase, isValidVarName } from '@kubb/core/transformers'
4
2
  import type { FunctionParamsAST } from '@kubb/core/utils'
5
3
  import type { OasTypes } from '@kubb/oas'
4
+ import { isParameterObject } from '@kubb/oas'
6
5
  import type { Params } from '@kubb/react-fabric/types'
7
6
  import type { OperationSchema } from '../types.ts'
8
7
  /**
@@ -1,6 +1,5 @@
1
- import { isOpenApiV3_1Document } from '@kubb/oas'
2
-
3
1
  import type { Oas, OpenAPIV3, OpenAPIV3_1, SchemaObject } from '@kubb/oas'
2
+ import { isOpenApiV3_1Document } from '@kubb/oas'
4
3
 
5
4
  /**
6
5
  * Make it possible to narrow down the schema based on a specific version(3 or 3.1)
@@ -1,4 +1,4 @@
1
- import type { Oas, OasTypes, contentType } from '@kubb/oas'
1
+ import type { contentType, Oas, OasTypes } from '@kubb/oas'
2
2
 
3
3
  type Mode = 'schemas' | 'responses' | 'requestBodies'
4
4
 
@@ -8,9 +8,82 @@ type GetSchemasProps = {
8
8
  includes?: Mode[]
9
9
  }
10
10
 
11
+ /**
12
+ * Collect all schema $ref dependencies recursively.
13
+ */
14
+ function collectRefs(schema: unknown, refs = new Set<string>()): Set<string> {
15
+ if (Array.isArray(schema)) {
16
+ for (const item of schema) {
17
+ collectRefs(item, refs)
18
+ }
19
+ return refs
20
+ }
21
+
22
+ if (schema && typeof schema === 'object') {
23
+ for (const [key, value] of Object.entries(schema)) {
24
+ if (key === '$ref' && typeof value === 'string') {
25
+ const match = value.match(/^#\/components\/schemas\/(.+)$/)
26
+ if (match) {
27
+ refs.add(match[1]!)
28
+ }
29
+ } else {
30
+ collectRefs(value, refs)
31
+ }
32
+ }
33
+ }
34
+
35
+ return refs
36
+ }
37
+
38
+ /**
39
+ * Sort schemas topologically so referenced schemas appear first.
40
+ */
41
+ function sortSchemas(schemas: Record<string, OasTypes.SchemaObject>): Record<string, OasTypes.SchemaObject> {
42
+ const deps = new Map<string, string[]>()
43
+
44
+ for (const [name, schema] of Object.entries(schemas)) {
45
+ deps.set(name, Array.from(collectRefs(schema)))
46
+ }
47
+
48
+ const sorted: string[] = []
49
+ const visited = new Set<string>()
50
+
51
+ function visit(name: string, stack = new Set<string>()) {
52
+ if (visited.has(name)) {
53
+ return
54
+ }
55
+ if (stack.has(name)) {
56
+ return
57
+ } // circular refs, ignore
58
+ stack.add(name)
59
+ const children = deps.get(name) || []
60
+ for (const child of children) {
61
+ if (deps.has(child)) {
62
+ visit(child, stack)
63
+ }
64
+ }
65
+ stack.delete(name)
66
+ visited.add(name)
67
+ sorted.push(name)
68
+ }
69
+
70
+ for (const name of Object.keys(schemas)) {
71
+ visit(name)
72
+ }
73
+
74
+ const sortedSchemas: Record<string, OasTypes.SchemaObject> = {}
75
+ for (const name of sorted) {
76
+ sortedSchemas[name] = schemas[name]!
77
+ }
78
+ return sortedSchemas
79
+ }
80
+
81
+ /**
82
+ * Collect schemas from OpenAPI components (schemas, responses, requestBodies)
83
+ * and return them in dependency order.
84
+ */
11
85
  export function getSchemas({ oas, contentType, includes = ['schemas', 'requestBodies', 'responses'] }: GetSchemasProps): Record<string, OasTypes.SchemaObject> {
12
86
  const components = oas.getDefinition().components
13
-
14
87
  let schemas: Record<string, OasTypes.SchemaObject> = {}
15
88
 
16
89
  if (includes.includes('schemas')) {
@@ -20,26 +93,27 @@ export function getSchemas({ oas, contentType, includes = ['schemas', 'requestBo
20
93
  }
21
94
  }
22
95
 
23
- const requestBodies = components?.requestBodies || {}
24
96
  if (includes.includes('responses')) {
25
97
  const responses = components?.responses || {}
26
-
27
- Object.entries(responses).forEach(([name, response]: [string, OasTypes.ResponseObject]) => {
28
- if (response.content && !schemas[name]) {
29
- const firstContentType = Object.keys(response.content)[0] || 'application/json'
30
- schemas[name] = response.content?.[contentType || firstContentType]?.schema as OasTypes.SchemaObject
98
+ for (const [name, response] of Object.entries(responses)) {
99
+ const r = response as OasTypes.ResponseObject
100
+ if (r.content && !schemas[name]) {
101
+ const firstContentType = Object.keys(r.content)[0] || 'application/json'
102
+ schemas[name] = r.content?.[contentType || firstContentType]?.schema as OasTypes.SchemaObject
31
103
  }
32
- })
104
+ }
33
105
  }
34
106
 
35
107
  if (includes.includes('requestBodies')) {
36
- Object.entries(requestBodies).forEach(([name, request]: [string, OasTypes.RequestBodyObject]) => {
37
- if (request.content && !schemas[name]) {
38
- const firstContentType = Object.keys(request.content)[0] || 'application/json'
39
- schemas[name] = request.content?.[contentType || firstContentType]?.schema as OasTypes.SchemaObject
108
+ const requestBodies = components?.requestBodies || {}
109
+ for (const [name, request] of Object.entries(requestBodies)) {
110
+ const r = request as OasTypes.RequestBodyObject
111
+ if (r.content && !schemas[name]) {
112
+ const firstContentType = Object.keys(r.content)[0] || 'application/json'
113
+ schemas[name] = r.content?.[contentType || firstContentType]?.schema as OasTypes.SchemaObject
40
114
  }
41
- })
115
+ }
42
116
  }
43
117
 
44
- return schemas
118
+ return sortSchemas(schemas)
45
119
  }
@@ -1,9 +1,8 @@
1
+ export { isOptional } from '@kubb/oas'
2
+ export { getBanner } from './getBanner.ts'
1
3
  export { getComments } from './getComments.ts'
4
+ export { getFooter } from './getFooter.ts'
2
5
  export { getPathParams } from './getParams.ts'
3
6
  export { getSchemaFactory } from './getSchemaFactory.ts'
4
7
  export { getSchemas } from './getSchemas.ts'
5
8
  export { parseFromConfig } from './parseFromConfig.ts'
6
- export { getBanner } from './getBanner.ts'
7
- export { getFooter } from './getFooter.ts'
8
-
9
- export { isOptional } from '@kubb/oas'
@@ -1,11 +1,7 @@
1
1
  import { resolve } from 'node:path'
2
-
3
- import { URLPath } from '@kubb/core/utils'
4
-
5
- import { merge, parse } from '@kubb/oas'
6
-
7
2
  import type { Config } from '@kubb/core'
8
- import { Oas, type OasTypes } from '@kubb/oas'
3
+ import { URLPath } from '@kubb/core/utils'
4
+ import { merge, Oas, type OasTypes, parse } from '@kubb/oas'
9
5
  import yaml from '@stoplight/yaml'
10
6
 
11
7
  export function parseFromConfig(config: Config, oasClass: typeof Oas = Oas): Promise<Oas> {
package/src/utils.tsx ADDED
@@ -0,0 +1,101 @@
1
+ import type { Config, Plugin, PluginFactoryOptions } from '@kubb/core'
2
+ import type { Operation, SchemaObject } from '@kubb/oas'
3
+ import { App, createReactFabric, type Fabric } from '@kubb/react-fabric'
4
+ import type { ReactGenerator } from './generators/createReactGenerator.ts'
5
+ import type { OperationGenerator } from './OperationGenerator.ts'
6
+ import type { SchemaGenerator, SchemaGeneratorOptions } from './SchemaGenerator.ts'
7
+ import type { Schema } from './SchemaMapper.ts'
8
+
9
+ type BuildOperationsOptions<TOptions extends PluginFactoryOptions> = {
10
+ config: Config
11
+ fabric: Fabric
12
+ Component: ReactGenerator<any>['Operations']
13
+ generator: Omit<OperationGenerator<TOptions>, 'build'>
14
+ plugin: Plugin<TOptions>
15
+ }
16
+
17
+ export async function buildOperations<TOptions extends PluginFactoryOptions>(
18
+ operations: Array<Operation>,
19
+ { config, fabric, plugin, generator, Component }: BuildOperationsOptions<TOptions>,
20
+ ): Promise<void> {
21
+ if (!Component) {
22
+ return undefined
23
+ }
24
+
25
+ const { pluginManager, oas, mode } = generator.context
26
+
27
+ const fabricChild = createReactFabric()
28
+ fabricChild.render(() => {
29
+ return (
30
+ <App meta={{ pluginManager, plugin, mode, oas }}>
31
+ <Component config={config} operations={operations} generator={generator} plugin={plugin} />
32
+ </App>
33
+ )
34
+ })
35
+
36
+ await fabric.context.fileManager.add(...fabricChild.files)
37
+ }
38
+
39
+ type BuildOperationOptions<TOptions extends PluginFactoryOptions> = {
40
+ config: Config
41
+ fabric: Fabric
42
+ Component: ReactGenerator<any>['Operation']
43
+ generator: Omit<OperationGenerator<TOptions>, 'build'>
44
+ plugin: Plugin<TOptions>
45
+ }
46
+
47
+ export async function buildOperation<TOptions extends PluginFactoryOptions>(
48
+ operation: Operation,
49
+ { config, fabric, plugin, generator, Component }: BuildOperationOptions<TOptions>,
50
+ ): Promise<void> {
51
+ if (!Component) {
52
+ return undefined
53
+ }
54
+
55
+ const { pluginManager, oas, mode } = generator.context
56
+
57
+ const fabricChild = createReactFabric()
58
+ fabricChild.render(() => {
59
+ return (
60
+ <App meta={{ pluginManager, plugin, mode, oas }}>
61
+ <Component config={config} operation={operation} plugin={plugin} generator={generator} />
62
+ </App>
63
+ )
64
+ })
65
+
66
+ await fabric.context.fileManager.add(...fabricChild.files)
67
+ }
68
+
69
+ type BuildSchemaOptions<TOptions extends PluginFactoryOptions> = {
70
+ config: Config
71
+ fabric: Fabric
72
+ Component: ReactGenerator<any>['Schema']
73
+ generator: Omit<SchemaGenerator<SchemaGeneratorOptions, TOptions>, 'build'>
74
+ plugin: Plugin<TOptions>
75
+ }
76
+
77
+ export async function buildSchema<TOptions extends PluginFactoryOptions>(
78
+ schema: {
79
+ name: string
80
+ tree: Array<Schema>
81
+ value: SchemaObject
82
+ },
83
+ { config, fabric, plugin, Component, generator }: BuildSchemaOptions<TOptions>,
84
+ ): Promise<void> {
85
+ if (!Component) {
86
+ return undefined
87
+ }
88
+
89
+ const { pluginManager, oas, mode } = generator.context
90
+
91
+ const fabricChild = createReactFabric()
92
+ fabricChild.render(() => {
93
+ return (
94
+ <App meta={{ pluginManager, plugin, mode, oas }}>
95
+ <Component config={config} schema={schema} plugin={plugin} generator={generator} />
96
+ </App>
97
+ )
98
+ })
99
+
100
+ await fabric.context.fileManager.add(...fabricChild.files)
101
+ }