@kubb/plugin-oas 3.0.0-alpha.3 → 3.0.0-alpha.31

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 (105) hide show
  1. package/README.md +13 -4
  2. package/dist/OperationGenerator-BgQeGRzk.d.cts +550 -0
  3. package/dist/OperationGenerator-BgQeGRzk.d.ts +550 -0
  4. package/dist/Schema-1iM2I0dK.d.ts +22 -0
  5. package/dist/Schema-5o-c5UOy.d.cts +22 -0
  6. package/dist/chunk-ABOQ73FL.cjs +36 -0
  7. package/dist/chunk-ABOQ73FL.cjs.map +1 -0
  8. package/dist/chunk-BG77DP54.js +30 -0
  9. package/dist/chunk-BG77DP54.js.map +1 -0
  10. package/dist/chunk-GF26SDHQ.js +28 -0
  11. package/dist/chunk-GF26SDHQ.js.map +1 -0
  12. package/dist/chunk-PADR76WZ.cjs +4 -0
  13. package/dist/chunk-PADR76WZ.cjs.map +1 -0
  14. package/dist/chunk-QAFBZLJA.cjs +48 -0
  15. package/dist/chunk-QAFBZLJA.cjs.map +1 -0
  16. package/dist/chunk-QT6ZFRNJ.cjs +752 -0
  17. package/dist/chunk-QT6ZFRNJ.cjs.map +1 -0
  18. package/dist/chunk-QWO5NQGQ.js +88 -0
  19. package/dist/chunk-QWO5NQGQ.js.map +1 -0
  20. package/dist/chunk-R47XMJ32.js +3 -0
  21. package/dist/chunk-R47XMJ32.js.map +1 -0
  22. package/dist/chunk-SR63CBLH.cjs +92 -0
  23. package/dist/chunk-SR63CBLH.cjs.map +1 -0
  24. package/dist/chunk-V2JO6RHI.js +744 -0
  25. package/dist/chunk-V2JO6RHI.js.map +1 -0
  26. package/dist/chunk-XNCEFOE6.js +45 -0
  27. package/dist/chunk-XNCEFOE6.js.map +1 -0
  28. package/dist/chunk-ZWHQ54JM.cjs +32 -0
  29. package/dist/chunk-ZWHQ54JM.cjs.map +1 -0
  30. package/dist/components.cjs +20 -12
  31. package/dist/components.cjs.map +1 -1
  32. package/dist/components.d.cts +4 -7
  33. package/dist/components.d.ts +4 -7
  34. package/dist/components.js +3 -12
  35. package/dist/components.js.map +1 -1
  36. package/dist/generators.cjs +14 -0
  37. package/dist/generators.cjs.map +1 -0
  38. package/dist/generators.d.cts +9 -0
  39. package/dist/generators.d.ts +9 -0
  40. package/dist/generators.js +5 -0
  41. package/dist/generators.js.map +1 -0
  42. package/dist/hooks.cjs +102 -57
  43. package/dist/hooks.cjs.map +1 -1
  44. package/dist/hooks.d.cts +41 -10
  45. package/dist/hooks.d.ts +41 -10
  46. package/dist/hooks.js +91 -53
  47. package/dist/hooks.js.map +1 -1
  48. package/dist/index.cjs +192 -258
  49. package/dist/index.cjs.map +1 -1
  50. package/dist/index.d.cts +3 -6
  51. package/dist/index.d.ts +3 -6
  52. package/dist/index.js +135 -228
  53. package/dist/index.js.map +1 -1
  54. package/dist/utils.cjs +32 -87
  55. package/dist/utils.cjs.map +1 -1
  56. package/dist/utils.d.cts +8 -43
  57. package/dist/utils.d.ts +8 -43
  58. package/dist/utils.js +8 -86
  59. package/dist/utils.js.map +1 -1
  60. package/package.json +20 -14
  61. package/src/OperationGenerator.ts +23 -30
  62. package/src/SchemaGenerator.ts +80 -23
  63. package/src/SchemaMapper.ts +7 -5
  64. package/src/components/Oas.tsx +1 -1
  65. package/src/components/Operation.tsx +1 -1
  66. package/src/components/Schema.tsx +2 -102
  67. package/src/{parser.tsx → generator.tsx} +31 -22
  68. package/src/generators/index.ts +1 -0
  69. package/src/generators/jsonGenerator.ts +32 -0
  70. package/src/hooks/index.ts +2 -0
  71. package/src/hooks/useOperationManager.ts +77 -29
  72. package/src/hooks/useSchemaManager.ts +77 -0
  73. package/src/index.ts +3 -3
  74. package/src/plugin.ts +67 -59
  75. package/src/types.ts +24 -16
  76. package/src/utils/getParams.ts +2 -2
  77. package/src/utils/getSchemaFactory.ts +1 -1
  78. package/src/utils/index.ts +2 -2
  79. package/src/utils/parseFromConfig.ts +7 -7
  80. package/dist/OperationGenerator-D7rSlflc.d.cts +0 -158
  81. package/dist/OperationGenerator-vw0Zf-Mi.d.ts +0 -158
  82. package/dist/Schema-DxyOIX7q.d.cts +0 -35
  83. package/dist/Schema-gHgN14i2.d.ts +0 -35
  84. package/dist/SchemaMapper-BM1IGWqD.d.cts +0 -248
  85. package/dist/SchemaMapper-BM1IGWqD.d.ts +0 -248
  86. package/dist/chunk-264TCCJF.cjs +0 -3973
  87. package/dist/chunk-264TCCJF.cjs.map +0 -1
  88. package/dist/chunk-7KIEQOVZ.cjs +0 -7
  89. package/dist/chunk-7KIEQOVZ.cjs.map +0 -1
  90. package/dist/chunk-FZN3PBEK.js +0 -3973
  91. package/dist/chunk-FZN3PBEK.js.map +0 -1
  92. package/dist/chunk-P42X362U.cjs +0 -101
  93. package/dist/chunk-P42X362U.cjs.map +0 -1
  94. package/dist/chunk-QLJIL3U5.cjs +0 -35
  95. package/dist/chunk-QLJIL3U5.cjs.map +0 -1
  96. package/dist/chunk-TWKZEVSM.js +0 -7
  97. package/dist/chunk-TWKZEVSM.js.map +0 -1
  98. package/dist/chunk-UB552H4J.js +0 -101
  99. package/dist/chunk-UB552H4J.js.map +0 -1
  100. package/dist/chunk-Y4V7HHX7.js +0 -35
  101. package/dist/chunk-Y4V7HHX7.js.map +0 -1
  102. package/dist/types-C2RXaY0_.d.cts +0 -143
  103. package/dist/types-C2RXaY0_.d.ts +0 -143
  104. package/src/utils/getGroupedByTagFiles.ts +0 -82
  105. package/src/utils/refSorter.ts +0 -13
@@ -1,11 +1,13 @@
1
1
  import type { PluginFactoryOptions } from '@kubb/core'
2
- import type { Operation, SchemaObject } from '@kubb/oas'
3
- import { App, createRoot, type KubbNode } from '@kubb/react'
4
2
  import type * as KubbFile from '@kubb/fs/types'
5
- import type { OperationsByMethod } from './types.ts'
3
+ import type { Operation, SchemaObject } from '@kubb/oas'
6
4
  import { Oas } from '@kubb/plugin-oas/components'
5
+ import { App, createRoot } from '@kubb/react'
6
+ import type { KubbNode } from '@kubb/react/types'
7
7
  import type { OperationGenerator } from './OperationGenerator.ts'
8
8
  import type { SchemaGenerator, SchemaGeneratorOptions } from './SchemaGenerator.ts'
9
+ import type { Schema } from './SchemaMapper.ts'
10
+ import type { OperationsByMethod } from './types.ts'
9
11
 
10
12
  type OperationsProps<TOptions extends PluginFactoryOptions> = {
11
13
  instance: Omit<OperationGenerator<TOptions>, 'build'>
@@ -22,32 +24,35 @@ type OperationProps<TOptions extends PluginFactoryOptions> = {
22
24
 
23
25
  type SchemaProps<TOptions extends PluginFactoryOptions> = {
24
26
  instance: Omit<SchemaGenerator<SchemaGeneratorOptions, TOptions>, 'build'>
25
- name: string
26
- schema: SchemaObject
27
+ schema: {
28
+ name: string
29
+ tree: Array<Schema>
30
+ value: SchemaObject
31
+ }
27
32
  options: TOptions['resolvedOptions']
28
33
  }
29
34
 
30
- export type ParserOptions<TOptions extends PluginFactoryOptions> = {
35
+ export type GeneratorOptions<TOptions extends PluginFactoryOptions> = {
31
36
  name: string
32
- operations?: (props: OperationsProps<TOptions>) => Promise<KubbFile.File[]>
33
- operation?: (props: OperationProps<TOptions>) => Promise<KubbFile.File[]>
34
- schema?: (props: SchemaProps<TOptions>) => Promise<KubbFile.File[]>
37
+ operations?: (this: GeneratorOptions<TOptions>, props: OperationsProps<TOptions>) => Promise<KubbFile.File[]>
38
+ operation?: (this: GeneratorOptions<TOptions>, props: OperationProps<TOptions>) => Promise<KubbFile.File[]>
39
+ schema?: (this: GeneratorOptions<TOptions>, props: SchemaProps<TOptions>) => Promise<KubbFile.File[]>
35
40
  }
36
41
 
37
- export type Parser<TOptions extends PluginFactoryOptions> = ParserOptions<TOptions>
42
+ export type Generator<TOptions extends PluginFactoryOptions> = GeneratorOptions<TOptions>
38
43
 
39
- export function createParser<TOptions extends PluginFactoryOptions>(parseOptions: ParserOptions<TOptions>): Parser<TOptions> {
44
+ export function createGenerator<TOptions extends PluginFactoryOptions>(parseOptions: GeneratorOptions<TOptions>): Generator<TOptions> {
40
45
  return parseOptions
41
46
  }
42
47
 
43
- export type ParserReactOptions<TOptions extends PluginFactoryOptions> = {
48
+ export type ReactGeneratorOptions<TOptions extends PluginFactoryOptions> = {
44
49
  name: string
45
- Operations?: (props: OperationsProps<TOptions>) => KubbNode
46
- Operation?: (props: OperationProps<TOptions>) => KubbNode
47
- Schema?: (props: SchemaProps<TOptions>) => KubbNode
50
+ Operations?: (this: ReactGeneratorOptions<TOptions>, props: OperationsProps<TOptions>) => KubbNode
51
+ Operation?: (this: ReactGeneratorOptions<TOptions>, props: OperationProps<TOptions>) => KubbNode
52
+ Schema?: (this: ReactGeneratorOptions<TOptions>, props: SchemaProps<TOptions>) => KubbNode
48
53
  }
49
54
 
50
- export function createReactParser<TOptions extends PluginFactoryOptions>(parseOptions: ParserReactOptions<TOptions>): Parser<TOptions> {
55
+ export function createReactGenerator<TOptions extends PluginFactoryOptions>(parseOptions: ReactGeneratorOptions<TOptions>): Generator<TOptions> {
51
56
  return {
52
57
  ...parseOptions,
53
58
  async operations({ instance, options, operations, operationsByMethod }) {
@@ -60,10 +65,12 @@ export function createReactParser<TOptions extends PluginFactoryOptions>(parseOp
60
65
  logger: pluginManager.logger,
61
66
  })
62
67
 
68
+ const Component = parseOptions.Operations.bind(this)
69
+
63
70
  root.render(
64
71
  <App pluginManager={pluginManager} plugin={plugin} mode={mode}>
65
72
  <Oas oas={oas} operations={operations} generator={instance}>
66
- <parseOptions.Operations operations={operations} instance={instance} operationsByMethod={operationsByMethod} options={options} />
73
+ <Component operations={operations} instance={instance} operationsByMethod={operationsByMethod} options={options} />
67
74
  </Oas>
68
75
  </App>,
69
76
  )
@@ -80,11 +87,13 @@ export function createReactParser<TOptions extends PluginFactoryOptions>(parseOp
80
87
  logger: pluginManager.logger,
81
88
  })
82
89
 
90
+ const Component = parseOptions.Operation.bind(this)
91
+
83
92
  root.render(
84
93
  <App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
85
94
  <Oas oas={oas} operations={[operation]} generator={instance}>
86
95
  <Oas.Operation operation={operation}>
87
- <parseOptions.Operation operation={operation} options={options} instance={instance} />
96
+ <Component operation={operation} options={options} instance={instance} />
88
97
  </Oas.Operation>
89
98
  </Oas>
90
99
  </App>,
@@ -92,7 +101,7 @@ export function createReactParser<TOptions extends PluginFactoryOptions>(parseOp
92
101
 
93
102
  return root.files
94
103
  },
95
- async schema({ instance, schema, name, options }) {
104
+ async schema({ instance, schema, options }) {
96
105
  if (!parseOptions.Schema) {
97
106
  return []
98
107
  }
@@ -102,13 +111,13 @@ export function createReactParser<TOptions extends PluginFactoryOptions>(parseOp
102
111
  logger: pluginManager.logger,
103
112
  })
104
113
 
105
- const tree = instance.parse({ schema, name })
114
+ const Component = parseOptions.Schema.bind(this)
106
115
 
107
116
  root.render(
108
117
  <App pluginManager={pluginManager} plugin={{ ...plugin, options }} mode={mode}>
109
118
  <Oas oas={oas}>
110
- <Oas.Schema name={name} value={schema} tree={tree}>
111
- <parseOptions.Schema schema={schema} options={options} instance={instance} name={name} />
119
+ <Oas.Schema name={schema.name} value={schema.value} tree={schema.tree}>
120
+ <Component schema={schema} options={options} instance={instance} />
112
121
  </Oas.Schema>
113
122
  </Oas>
114
123
  </App>,
@@ -0,0 +1 @@
1
+ export { jsonGenerator } from './jsonGenerator.ts'
@@ -0,0 +1,32 @@
1
+ import { camelCase } from '@kubb/core/transformers'
2
+ import { createGenerator } from '../generator.tsx'
3
+ import type { PluginOas } from '../types.ts'
4
+
5
+ export const jsonGenerator = createGenerator<PluginOas>({
6
+ name: 'plugin-oas',
7
+ async schema({ schema, instance }) {
8
+ const { pluginManager, plugin } = instance.context
9
+ const file = pluginManager.getFile({
10
+ name: camelCase(schema.name),
11
+ extname: '.json',
12
+ mode: 'split',
13
+ pluginKey: plugin.key,
14
+ })
15
+
16
+ return [
17
+ {
18
+ ...file,
19
+ sources: [
20
+ {
21
+ name: camelCase(schema.name),
22
+ isExportable: false,
23
+ isIndexable: false,
24
+ value: JSON.stringify(schema.value),
25
+ },
26
+ ],
27
+ banner: plugin.options.output?.banner,
28
+ format: plugin.options.output?.footer,
29
+ },
30
+ ]
31
+ },
32
+ })
@@ -1,5 +1,7 @@
1
1
  export { useOas } from './useOas.ts'
2
2
  export { useOperation } from './useOperation.ts'
3
3
  export { useOperationManager } from './useOperationManager.ts'
4
+ export type { SchemaNames } from './useOperationManager.ts'
4
5
  export { useOperations } from './useOperations.ts'
5
6
  export { useSchema } from './useSchema.ts'
7
+ export { useSchemaManager } from './useSchemaManager.ts'
@@ -13,7 +13,7 @@ type FileMeta = FileMetaBase & {
13
13
  tag?: string
14
14
  }
15
15
 
16
- type SchemaNames = {
16
+ export type SchemaNames = {
17
17
  request: string | undefined
18
18
  parameters: {
19
19
  path: string | undefined
@@ -25,14 +25,41 @@ type SchemaNames = {
25
25
  }
26
26
 
27
27
  type UseOperationManagerResult = {
28
- getName: (operation: OperationType, params: { pluginKey?: Plugin['key']; type: ResolveNameParams['type'] }) => string
29
- getFile: (operation: OperationType, params?: { pluginKey?: Plugin['key']; extName?: KubbFile.Extname }) => KubbFile.File<FileMeta>
30
- groupSchemasByName: (operation: OperationType, params: { pluginKey?: Plugin['key']; type: ResolveNameParams['type'] }) => SchemaNames
31
- getSchemas: (
28
+ getName: (
29
+ operation: OperationType,
30
+ params: {
31
+ prefix?: string
32
+ suffix?: string
33
+ pluginKey?: Plugin['key']
34
+ type: ResolveNameParams['type']
35
+ },
36
+ ) => string
37
+ getSchemaName: (
32
38
  operation: Operation,
33
- params?: { pluginKey?: Plugin['key']; type?: ResolveNameParams['type'] },
34
- forStatusCode?: string | number,
35
- ) => OperationSchemas
39
+ key: keyof Omit<OperationSchemas, 'errors' | 'statusCodes'>,
40
+ params?: {
41
+ pluginKey?: Plugin['key']
42
+ type?: ResolveNameParams['type']
43
+ },
44
+ ) => string
45
+ getFile: (
46
+ operation: OperationType,
47
+ params?: {
48
+ prefix?: string
49
+ suffix?: string
50
+ pluginKey?: Plugin['key']
51
+ extname?: KubbFile.Extname
52
+ tag?: string
53
+ },
54
+ ) => KubbFile.File<FileMeta>
55
+ groupSchemasByName: (
56
+ operation: OperationType,
57
+ params: {
58
+ pluginKey?: Plugin['key']
59
+ type: ResolveNameParams['type']
60
+ },
61
+ ) => SchemaNames
62
+ getSchemas: (operation: Operation, params?: { pluginKey?: Plugin['key']; type?: ResolveNameParams['type'] }) => OperationSchemas
36
63
  }
37
64
 
38
65
  /**
@@ -42,26 +69,51 @@ export function useOperationManager(): UseOperationManagerResult {
42
69
  const { plugin, pluginManager } = useApp()
43
70
  const { generator } = useContext(Oas.Context)
44
71
 
45
- if (!generator) {
46
- throw new Error(`'generator' is not defined`)
47
- }
48
-
49
- const getName: UseOperationManagerResult['getName'] = (operation, { pluginKey = plugin.key, type }) => {
72
+ const getName: UseOperationManagerResult['getName'] = (operation, { prefix = '', suffix = '', pluginKey = plugin.key, type }) => {
50
73
  return pluginManager.resolveName({
51
- name: operation.getOperationId(),
74
+ name: `${prefix} ${operation.getOperationId()} ${suffix}`,
52
75
  pluginKey,
53
76
  type,
54
77
  })
55
78
  }
56
79
 
57
- const getFile: UseOperationManagerResult['getFile'] = (operation, { pluginKey = plugin.key, extName = '.ts' } = {}) => {
58
- // needed for the `output.group`
59
- const tag = operation.getTags().at(0)?.name
60
- const name = getName(operation, { type: 'file', pluginKey })
80
+ const getSchemas: UseOperationManagerResult['getSchemas'] = (operation, params) => {
81
+ if (!generator) {
82
+ throw new Error(`'generator' is not defined`)
83
+ }
61
84
 
85
+ return generator.getSchemas(operation, {
86
+ resolveName: (name) =>
87
+ pluginManager.resolveName({
88
+ name,
89
+ pluginKey: params?.pluginKey,
90
+ type: params?.type,
91
+ }),
92
+ })
93
+ }
94
+
95
+ const getSchemaName: UseOperationManagerResult['getSchemaName'] = (operation, key, { pluginKey = plugin.key, type } = {}) => {
96
+ const schemas = getSchemas(operation)
97
+
98
+ if (!schemas[key]?.name) {
99
+ throw new Error(`SchemaName not found for ${operation.getOperationId()}`)
100
+ }
101
+
102
+ return pluginManager.resolveName({
103
+ name: schemas[key]?.name,
104
+ pluginKey,
105
+ type,
106
+ })
107
+ }
108
+ //TODO replace tag with group
109
+ const getFile: UseOperationManagerResult['getFile'] = (
110
+ operation,
111
+ { prefix, suffix, pluginKey = plugin.key, tag = operation.getTags().at(0)?.name, extname = '.ts' } = {},
112
+ ) => {
113
+ const name = getName(operation, { type: 'file', pluginKey, prefix, suffix })
62
114
  const file = pluginManager.getFile({
63
115
  name,
64
- extName,
116
+ extname,
65
117
  pluginKey,
66
118
  options: { type: 'file', pluginKey, tag },
67
119
  })
@@ -78,6 +130,10 @@ export function useOperationManager(): UseOperationManagerResult {
78
130
  }
79
131
 
80
132
  const groupSchemasByName: UseOperationManagerResult['groupSchemasByName'] = (operation, { pluginKey = plugin.key, type }) => {
133
+ if (!generator) {
134
+ throw new Error(`'generator' is not defined`)
135
+ }
136
+
81
137
  const schemas = generator.getSchemas(operation)
82
138
 
83
139
  const errors = (schemas.errors || []).reduce(
@@ -148,16 +204,8 @@ export function useOperationManager(): UseOperationManagerResult {
148
204
  return {
149
205
  getName,
150
206
  getFile,
151
- getSchemas: (operation, params, forStatusCode) =>
152
- generator.getSchemas(operation, {
153
- forStatusCode,
154
- resolveName: (name) =>
155
- pluginManager.resolveName({
156
- name,
157
- pluginKey: params?.pluginKey,
158
- type: params?.type,
159
- }),
160
- }),
207
+ getSchemas,
208
+ getSchemaName,
161
209
  groupSchemasByName,
162
210
  }
163
211
  }
@@ -0,0 +1,77 @@
1
+ import { useApp } from '@kubb/react'
2
+
3
+ import type { FileMetaBase, Plugin, ResolveNameParams } from '@kubb/core'
4
+ import type * as KubbFile from '@kubb/fs/types'
5
+ import type { Mode } from '@kubb/fs/types'
6
+ import { SchemaGenerator } from '../SchemaGenerator.ts'
7
+ import { type Schema, schemaKeywords } from '../SchemaMapper'
8
+
9
+ type FileMeta = FileMetaBase & {
10
+ pluginKey: Plugin['key']
11
+ name: string
12
+ tag?: string
13
+ }
14
+
15
+ type UseSchemaManagerResult = {
16
+ getName: (name: string, params: { pluginKey?: Plugin['key']; type: ResolveNameParams['type'] }) => string
17
+ getFile: (name: string, params?: { pluginKey?: Plugin['key']; mode?: Mode; extname?: KubbFile.Extname; tag?: string }) => KubbFile.File<FileMeta>
18
+ getImports: (tree: Array<Schema>) => Array<KubbFile.Import>
19
+ }
20
+
21
+ /**
22
+ * `useSchemaManager` will return some helper functions that can be used to get the schema file, get the schema name.
23
+ */
24
+ export function useSchemaManager(): UseSchemaManagerResult {
25
+ const { mode, plugin, pluginManager, fileManager } = useApp()
26
+
27
+ const getName: UseSchemaManagerResult['getName'] = (name, { pluginKey = plugin.key, type }) => {
28
+ return pluginManager.resolveName({
29
+ name,
30
+ pluginKey,
31
+ type,
32
+ })
33
+ }
34
+ //TODO replace tag with group
35
+ const getFile: UseSchemaManagerResult['getFile'] = (name, { mode = 'split', pluginKey = plugin.key, extname = '.ts', tag } = {}) => {
36
+ const resolvedName = mode === 'single' ? '' : getName(name, { type: 'file', pluginKey })
37
+
38
+ const file = pluginManager.getFile({
39
+ name: resolvedName,
40
+ extname,
41
+ pluginKey,
42
+ options: { type: 'file', pluginKey, tag },
43
+ })
44
+
45
+ return {
46
+ ...file,
47
+ meta: {
48
+ ...file.meta,
49
+ name: resolvedName,
50
+ pluginKey,
51
+ },
52
+ }
53
+ }
54
+
55
+ const getImports: UseSchemaManagerResult['getImports'] = (tree) => {
56
+ const refs = SchemaGenerator.deepSearch(tree, schemaKeywords.ref)
57
+
58
+ return refs
59
+ ?.map((item, i) => {
60
+ if (!item.args.path) {
61
+ return undefined
62
+ }
63
+
64
+ return {
65
+ name: [item.args.name],
66
+ path: item.args.path,
67
+ }
68
+ })
69
+ .filter(Boolean)
70
+ }
71
+
72
+ return {
73
+ getName,
74
+ getFile,
75
+ getImports,
76
+ }
77
+ }
package/src/index.ts CHANGED
@@ -20,6 +20,6 @@ export type {
20
20
  } from './SchemaMapper.ts'
21
21
  export { isKeyword, schemaKeywords } from './SchemaMapper.ts'
22
22
  export type * from './types.ts'
23
- export { createParser, createReactParser } from './parser.tsx'
24
- export type { ParserReactOptions } from './parser.tsx'
25
- export type { Parser, ParserOptions } from './parser.tsx'
23
+ export { createGenerator, createReactGenerator } from './generator.tsx'
24
+ export type { ReactGeneratorOptions } from './generator.tsx'
25
+ export type { Generator, GeneratorOptions } from './generator.tsx'
package/src/plugin.ts CHANGED
@@ -1,34 +1,35 @@
1
- import path from 'node:path'
2
-
3
- import { createPlugin } from '@kubb/core'
4
- import { camelCase } from '@kubb/core/transformers'
1
+ import { FileManager, createPlugin } from '@kubb/core'
5
2
 
6
3
  import { getSchemas } from './utils/getSchemas.ts'
4
+ import { parseFromConfig } from './utils/parseFromConfig.ts'
7
5
 
6
+ import path from 'node:path'
8
7
  import type { Config } from '@kubb/core'
9
8
  import type { Logger } from '@kubb/core/logger'
10
- import type { Oas, OasTypes } from '@kubb/oas'
11
- import type { FormatOptions } from '@kubb/oas/parser'
9
+ import type { Oas } from '@kubb/oas'
10
+ import { OperationGenerator } from './OperationGenerator.ts'
11
+ import { SchemaGenerator } from './SchemaGenerator.ts'
12
+ import { jsonGenerator } from './generators'
12
13
  import type { PluginOas } from './types.ts'
13
- import { parseFromConfig } from './utils/parseFromConfig.ts'
14
14
 
15
15
  export const pluginOasName = 'plugin-oas' satisfies PluginOas['name']
16
16
 
17
17
  export const pluginOas = createPlugin<PluginOas>((options) => {
18
18
  const {
19
- output = { path: 'schemas', export: false },
20
- experimentalFilter: filter,
21
- experimentalSort: sort,
19
+ output = {
20
+ path: 'schemas',
21
+ },
22
22
  validate = true,
23
+ generators = [jsonGenerator],
23
24
  serverIndex = 0,
24
25
  contentType,
25
26
  oasClass,
26
27
  } = options
27
28
 
28
- const getOas = async ({ config, logger, formatOptions }: { config: Config; logger: Logger; formatOptions?: FormatOptions }): Promise<Oas> => {
29
+ const getOas = async ({ config, logger }: { config: Config; logger: Logger }): Promise<Oas> => {
29
30
  try {
30
31
  // needs to be in a different variable or the catch here will not work(return of a promise instead)
31
- const oas = await parseFromConfig(config, formatOptions, oasClass)
32
+ const oas = await parseFromConfig(config, oasClass)
32
33
 
33
34
  if (validate) {
34
35
  await oas.valdiate()
@@ -39,19 +40,22 @@ export const pluginOas = createPlugin<PluginOas>((options) => {
39
40
  const error = e as Error
40
41
 
41
42
  logger.emit('warning', error?.message)
42
- return parseFromConfig(config, {}, oasClass)
43
+ return parseFromConfig(config, oasClass)
43
44
  }
44
45
  }
45
46
 
46
47
  return {
47
48
  name: pluginOasName,
48
- options,
49
+ options: {
50
+ output,
51
+ ...options,
52
+ },
49
53
  context() {
50
54
  const { config, logger } = this
51
55
 
52
56
  return {
53
- getOas(formatOptions) {
54
- return getOas({ config, logger, formatOptions })
57
+ getOas() {
58
+ return getOas({ config, logger })
55
59
  },
56
60
  async getSchemas({ includes } = {}) {
57
61
  const oas = await this.getOas()
@@ -59,24 +63,25 @@ export const pluginOas = createPlugin<PluginOas>((options) => {
59
63
  },
60
64
  async getBaseURL() {
61
65
  const oasInstance = await this.getOas()
62
- const baseURL = oasInstance.api.servers?.at(serverIndex)?.url
63
- return baseURL
66
+ return oasInstance.api.servers?.at(serverIndex)?.url
64
67
  },
65
68
  contentType,
66
69
  }
67
70
  },
68
- resolvePath(baseName) {
69
- if (output === false) {
70
- return undefined
71
- }
72
-
71
+ resolvePath(baseName, pathMode, options) {
73
72
  const root = path.resolve(this.config.root, this.config.output.path)
73
+ const mode = pathMode ?? FileManager.getMode(path.resolve(root, output.path))
74
+
75
+ if (mode === 'single') {
76
+ /**
77
+ * when output is a file then we will always append to the same file(output file), see fileManager.addOrAppend
78
+ * Other plugins then need to call addOrAppend instead of just add from the fileManager class
79
+ */
80
+ return path.resolve(root, output.path)
81
+ }
74
82
 
75
83
  return path.resolve(root, output.path, baseName)
76
84
  },
77
- resolveName(name, type) {
78
- return camelCase(name, { isFile: type === 'file' })
79
- },
80
85
  async buildStart() {
81
86
  if (!output) {
82
87
  return
@@ -85,42 +90,45 @@ export const pluginOas = createPlugin<PluginOas>((options) => {
85
90
  const oas = await getOas({
86
91
  config: this.config,
87
92
  logger: this.logger,
88
- formatOptions: {
89
- filterSet: filter,
90
- sortSet: sort,
91
- },
92
93
  })
93
94
  await oas.dereference()
94
- const schemas = getSchemas({ oas, contentType })
95
-
96
- const mapSchema = async ([name, schema]: [string, OasTypes.SchemaObject]) => {
97
- const resolvedPath = this.resolvePath({
98
- baseName: `${name}.json`,
99
- pluginKey: this.plugin.key,
100
- })
101
-
102
- const resvoledFileName = this.resolveName({
103
- name: `${name}.json`,
104
- pluginKey: [pluginOasName],
105
- type: 'file',
106
- }) as `${string}.json`
107
-
108
- if (!resolvedPath) {
109
- return
110
- }
111
-
112
- await this.addFile({
113
- path: resolvedPath,
114
- baseName: resvoledFileName,
115
- source: JSON.stringify(schema),
116
- meta: {
117
- pluginKey: this.plugin.key,
118
- },
119
- })
120
- }
121
95
 
122
- const promises = Object.entries(schemas).map(mapSchema)
123
- await Promise.all(promises)
96
+ const schemaGenerator = new SchemaGenerator(
97
+ {
98
+ unknownType: 'unknown',
99
+ dateType: 'date',
100
+ transformers: {},
101
+ ...this.plugin.options,
102
+ },
103
+ {
104
+ oas,
105
+ pluginManager: this.pluginManager,
106
+ plugin: this.plugin,
107
+ contentType,
108
+ include: undefined,
109
+ override: undefined,
110
+ mode: 'split',
111
+ output: output.path,
112
+ },
113
+ )
114
+
115
+ const schemaFiles = await schemaGenerator.build(...generators)
116
+ await this.addFile(...schemaFiles)
117
+
118
+ const operationGenerator = new OperationGenerator(this.plugin.options, {
119
+ oas,
120
+ pluginManager: this.pluginManager,
121
+ plugin: this.plugin,
122
+ contentType,
123
+ exclude: undefined,
124
+ include: undefined,
125
+ override: undefined,
126
+ mode: 'split',
127
+ })
128
+
129
+ const operationFiles = await operationGenerator.build(...generators)
130
+
131
+ await this.addFile(...operationFiles)
124
132
  },
125
133
  }
126
134
  })
package/src/types.ts CHANGED
@@ -1,9 +1,9 @@
1
- import type { Plugin } from '@kubb/core'
1
+ import type { Output, Plugin } from '@kubb/core'
2
2
  import type { PluginFactoryOptions, ResolveNameParams } from '@kubb/core'
3
3
  import type * as KubbFile from '@kubb/fs/types'
4
4
 
5
5
  import type { HttpMethod, Oas, Operation, SchemaObject, contentType } from '@kubb/oas'
6
- import type { FormatOptions } from '@kubb/oas/parser'
6
+ import type { Generator } from './generator.tsx'
7
7
  import type { GetSchemasProps } from './utils/getSchemas.ts'
8
8
 
9
9
  export type ResolvePathOptions = {
@@ -13,7 +13,7 @@ export type ResolvePathOptions = {
13
13
  }
14
14
 
15
15
  export type API = {
16
- getOas: (formatOptions?: FormatOptions) => Promise<Oas>
16
+ getOas: () => Promise<Oas>
17
17
  getSchemas: (options?: Pick<GetSchemasProps, 'includes'>) => Promise<Record<string, SchemaObject>>
18
18
  getBaseURL: () => Promise<string | undefined>
19
19
  contentType?: contentType
@@ -25,16 +25,10 @@ export type Options = {
25
25
  * @default true
26
26
  */
27
27
  validate?: boolean
28
- output?:
29
- | {
30
- /**
31
- * Relative path to save the JSON models.
32
- * False will not generate the schema JSON's.
33
- * @default 'schemas'
34
- */
35
- path: string
36
- }
37
- | false
28
+ /**
29
+ * @default 'schemas'
30
+ */
31
+ output?: Output
38
32
  /**
39
33
  * Which server to use from the array of `servers.url[serverIndex]`
40
34
  * @example
@@ -48,9 +42,14 @@ export type Options = {
48
42
  * By default, this is set based on the first used contentType..
49
43
  */
50
44
  contentType?: contentType
51
- experimentalFilter?: FormatOptions['filterSet']
52
- experimentalSort?: FormatOptions['sortSet']
45
+ /**
46
+ * Override some behaviour of the Oas class instance, see '@kubb/oas'
47
+ */
53
48
  oasClass?: typeof Oas
49
+ /**
50
+ * Define some generators next to the JSON generation
51
+ */
52
+ generators?: Array<Generator<PluginOas>>
54
53
  }
55
54
 
56
55
  /**
@@ -128,6 +127,11 @@ type ByMethod = {
128
127
  type: 'method'
129
128
  pattern: HttpMethod | RegExp
130
129
  }
130
+ // TODO implement as alternative for ByMethod
131
+ type ByMethods = {
132
+ type: 'methods'
133
+ pattern: Array<HttpMethod>
134
+ }
131
135
 
132
136
  type BySchemaName = {
133
137
  type: 'schemaName'
@@ -141,4 +145,8 @@ export type Override<TOptions> = (ByTag | ByOperationId | ByPath | ByMethod | By
141
145
  options: Partial<TOptions>
142
146
  }
143
147
 
144
- export type PluginOas = PluginFactoryOptions<'plugin-oas', Options, Options, API, never>
148
+ type ResolvedOptions = Options & {
149
+ output: Output
150
+ }
151
+
152
+ export type PluginOas = PluginFactoryOptions<'plugin-oas', Options, ResolvedOptions, API, never>