@kubb/core 2.0.0-canary.20231030T124950 → 2.0.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 (100) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-4A7WG6IA.js +128 -0
  3. package/dist/chunk-4A7WG6IA.js.map +1 -0
  4. package/dist/chunk-54P4AWHI.js +71 -0
  5. package/dist/chunk-54P4AWHI.js.map +1 -0
  6. package/dist/chunk-5TK7TMV6.cjs +131 -0
  7. package/dist/chunk-5TK7TMV6.cjs.map +1 -0
  8. package/dist/chunk-7S67BJXQ.js +85 -0
  9. package/dist/chunk-7S67BJXQ.js.map +1 -0
  10. package/dist/chunk-E3ANGQ5N.cjs +2290 -0
  11. package/dist/chunk-E3ANGQ5N.cjs.map +1 -0
  12. package/dist/chunk-H47IKRXJ.cjs +129 -0
  13. package/dist/chunk-H47IKRXJ.cjs.map +1 -0
  14. package/dist/chunk-HIE46T3F.js +129 -0
  15. package/dist/chunk-HIE46T3F.js.map +1 -0
  16. package/dist/chunk-K2H7BYQB.js +155 -0
  17. package/dist/chunk-K2H7BYQB.js.map +1 -0
  18. package/dist/chunk-NAWI7UXW.js +67 -0
  19. package/dist/chunk-NAWI7UXW.js.map +1 -0
  20. package/dist/chunk-PLVKILIY.cjs +162 -0
  21. package/dist/chunk-PLVKILIY.cjs.map +1 -0
  22. package/dist/chunk-W2FP7ZWW.cjs +71 -0
  23. package/dist/chunk-W2FP7ZWW.cjs.map +1 -0
  24. package/dist/chunk-WZQO3EPM.cjs +91 -0
  25. package/dist/chunk-WZQO3EPM.cjs.map +1 -0
  26. package/dist/chunk-XDHI63G7.cjs +104 -0
  27. package/dist/chunk-XDHI63G7.cjs.map +1 -0
  28. package/dist/chunk-XPOF4D5N.js +18 -0
  29. package/dist/chunk-XPOF4D5N.js.map +1 -0
  30. package/dist/fs.cjs +31 -0
  31. package/dist/fs.cjs.map +1 -0
  32. package/dist/fs.d.cts +5 -0
  33. package/dist/fs.d.ts +5 -0
  34. package/dist/fs.js +11 -0
  35. package/dist/fs.js.map +1 -0
  36. package/dist/index.cjs +1866 -977
  37. package/dist/index.cjs.map +1 -1
  38. package/dist/index.d.cts +302 -319
  39. package/dist/index.d.ts +302 -319
  40. package/dist/index.js +1071 -846
  41. package/dist/index.js.map +1 -1
  42. package/dist/logger.cjs +26 -0
  43. package/dist/logger.cjs.map +1 -0
  44. package/dist/logger.d.cts +32 -0
  45. package/dist/logger.d.ts +32 -0
  46. package/dist/logger.js +8 -0
  47. package/dist/logger.js.map +1 -0
  48. package/dist/transformers.cjs +124 -0
  49. package/dist/transformers.cjs.map +1 -0
  50. package/dist/transformers.d.cts +55 -0
  51. package/dist/transformers.d.ts +55 -0
  52. package/dist/transformers.js +95 -0
  53. package/dist/transformers.js.map +1 -0
  54. package/dist/utils.cjs +23 -1163
  55. package/dist/utils.cjs.map +1 -1
  56. package/dist/utils.d.cts +2 -143
  57. package/dist/utils.d.ts +2 -143
  58. package/dist/utils.js +15 -1118
  59. package/dist/utils.js.map +1 -1
  60. package/dist/write-A6VgHkYA.d.cts +10 -0
  61. package/dist/write-A6VgHkYA.d.ts +10 -0
  62. package/package.json +40 -23
  63. package/src/BarrelManager.ts +113 -0
  64. package/src/FileManager.ts +581 -0
  65. package/src/Generator.ts +34 -0
  66. package/src/PackageManager.ts +178 -0
  67. package/src/PluginManager.ts +645 -0
  68. package/src/PromiseManager.ts +51 -0
  69. package/src/build.ts +221 -0
  70. package/src/config.ts +22 -0
  71. package/src/errors.ts +12 -0
  72. package/src/fs/clean.ts +5 -0
  73. package/src/fs/index.ts +3 -0
  74. package/src/fs/read.ts +68 -0
  75. package/src/fs/write.ts +79 -0
  76. package/src/index.ts +27 -0
  77. package/src/logger.ts +121 -0
  78. package/src/plugin.ts +80 -0
  79. package/src/transformers/casing.ts +9 -0
  80. package/src/transformers/combineCodes.ts +3 -0
  81. package/src/transformers/createJSDocBlockText.ts +9 -0
  82. package/src/transformers/escape.ts +31 -0
  83. package/src/transformers/indent.ts +3 -0
  84. package/src/transformers/index.ts +36 -0
  85. package/src/transformers/nameSorter.ts +9 -0
  86. package/src/transformers/searchAndReplace.ts +25 -0
  87. package/src/transformers/transformReservedWord.ts +97 -0
  88. package/src/transformers/trim.ts +7 -0
  89. package/src/types.ts +334 -0
  90. package/src/utils/EventEmitter.ts +24 -0
  91. package/src/utils/FunctionParams.ts +86 -0
  92. package/src/utils/TreeNode.ts +125 -0
  93. package/src/utils/URLPath.ts +133 -0
  94. package/src/utils/cache.ts +35 -0
  95. package/src/utils/executeStrategies.ts +83 -0
  96. package/src/utils/index.ts +8 -0
  97. package/src/utils/promise.ts +13 -0
  98. package/src/utils/renderTemplate.ts +31 -0
  99. package/src/utils/timeout.ts +7 -0
  100. package/src/utils/uniqueName.ts +20 -0
@@ -0,0 +1,31 @@
1
+ export function escape(text?: string): string {
2
+ return text ? text.replaceAll('`', '\\`') : ''
3
+ }
4
+
5
+ /**
6
+ * Escape all characters not included in SingleStringCharacters and DoubleStringCharacters on
7
+ * @link http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
8
+ * @link https://github.com/joliss/js-string-escape/blob/master/index.js
9
+ */
10
+ // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
11
+ export function jsStringEscape(input: any): string {
12
+ return `${input}`.replace(/["'\\\n\r\u2028\u2029]/g, (character) => {
13
+ switch (character) {
14
+ case '"':
15
+ case "'":
16
+ case '\\':
17
+ return '\\' + character
18
+ // Four possible LineTerminator characters need to be escaped:
19
+ case '\n':
20
+ return '\\n'
21
+ case '\r':
22
+ return '\\r'
23
+ case '\u2028':
24
+ return '\\u2028'
25
+ case '\u2029':
26
+ return '\\u2029'
27
+ default:
28
+ return ''
29
+ }
30
+ })
31
+ }
@@ -0,0 +1,3 @@
1
+ export function createIndent(size: number): string {
2
+ return Array.from({ length: size + 1 }).join(' ')
3
+ }
@@ -0,0 +1,36 @@
1
+ import { camelCase, pascalCase } from './casing.ts'
2
+ import { combineCodes } from './combineCodes.ts'
3
+ import { createJSDocBlockText } from './createJSDocBlockText.ts'
4
+ import { escape, jsStringEscape } from './escape.ts'
5
+ import { createIndent } from './indent.ts'
6
+ import { nameSorter } from './nameSorter.ts'
7
+ import { searchAndReplace } from './searchAndReplace.ts'
8
+ import { transformReservedWord } from './transformReservedWord.ts'
9
+ import { trim, trimExtName } from './trim.ts'
10
+
11
+ export { camelCase, pascalCase } from './casing.ts'
12
+ export { combineCodes } from './combineCodes.ts'
13
+ export { createJSDocBlockText } from './createJSDocBlockText.ts'
14
+ export { escape, jsStringEscape } from './escape.ts'
15
+ export { createIndent } from './indent.ts'
16
+ export { nameSorter } from './nameSorter.ts'
17
+ export { searchAndReplace } from './searchAndReplace.ts'
18
+ export { transformReservedWord } from './transformReservedWord.ts'
19
+ export { trim, trimExtName } from './trim.ts'
20
+
21
+ export default {
22
+ combineCodes,
23
+ escape,
24
+ jsStringEscape,
25
+ createIndent,
26
+ transformReservedWord,
27
+ nameSorter,
28
+ searchAndReplace,
29
+ trim,
30
+ trimExtName,
31
+ JSDoc: {
32
+ createJSDocBlockText,
33
+ },
34
+ camelCase,
35
+ pascalCase,
36
+ } as const
@@ -0,0 +1,9 @@
1
+ export function nameSorter<T extends { name: string }>(a: T, b: T): 0 | 1 | -1 {
2
+ if (a.name < b.name) {
3
+ return -1
4
+ }
5
+ if (a.name > b.name) {
6
+ return 1
7
+ }
8
+ return 0
9
+ }
@@ -0,0 +1,25 @@
1
+ type Options = {
2
+ text: string
3
+ replaceBy: string
4
+ prefix?: string
5
+ key: string
6
+ searchValues?: (prefix: string, key: string) => Array<RegExp | string>
7
+ }
8
+
9
+ export function searchAndReplace(options: Options): string {
10
+ const { text, replaceBy, prefix = '', key } = options
11
+
12
+ const searchValues = options.searchValues?.(prefix, key) || [
13
+ `${prefix}["${key}"]`,
14
+ `${prefix}['${key}']`,
15
+ `${prefix}[\`${key}\`]`,
16
+ `${prefix}"${key}"`,
17
+ `${prefix}'${key}'`,
18
+ `${prefix}\`${key}\``,
19
+ new RegExp(`${prefix}${key}`, 'g'),
20
+ ]
21
+
22
+ return searchValues.reduce((prev, searchValue) => {
23
+ return prev.toString().replaceAll(searchValue, replaceBy)
24
+ }, text) as string
25
+ }
@@ -0,0 +1,97 @@
1
+ /**
2
+ * @link https://github.com/jonschlinkert/reserved/blob/master/index.js
3
+ */
4
+ const reservedWords = [
5
+ 'abstract',
6
+ 'arguments',
7
+ 'boolean',
8
+ 'break',
9
+ 'byte',
10
+ 'case',
11
+ 'catch',
12
+ 'char',
13
+ 'class',
14
+ 'const',
15
+ 'continue',
16
+ 'debugger',
17
+ 'default',
18
+ 'delete',
19
+ 'do',
20
+ 'double',
21
+ 'else',
22
+ 'enum',
23
+ 'eval',
24
+ 'export',
25
+ 'extends',
26
+ 'false',
27
+ 'final',
28
+ 'finally',
29
+ 'float',
30
+ 'for',
31
+ 'function',
32
+ 'goto',
33
+ 'if',
34
+ 'implements',
35
+ 'import',
36
+ 'in',
37
+ 'instanceof',
38
+ 'int',
39
+ 'interface',
40
+ 'let',
41
+ 'long',
42
+ 'native',
43
+ 'new',
44
+ 'null',
45
+ 'package',
46
+ 'private',
47
+ 'protected',
48
+ 'public',
49
+ 'return',
50
+ 'short',
51
+ 'static',
52
+ 'super',
53
+ 'switch',
54
+ 'synchronized',
55
+ 'this',
56
+ 'throw',
57
+ 'throws',
58
+ 'transient',
59
+ 'true',
60
+ 'try',
61
+ 'typeof',
62
+ 'var',
63
+ 'void',
64
+ 'volatile',
65
+ 'while',
66
+ 'with',
67
+ 'yield',
68
+
69
+ 'Array',
70
+ 'Date',
71
+ 'eval',
72
+ 'function',
73
+ 'hasOwnProperty',
74
+ 'Infinity',
75
+ 'isFinite',
76
+ 'isNaN',
77
+ 'isPrototypeOf',
78
+ 'length',
79
+ 'Math',
80
+ 'name',
81
+ 'NaN',
82
+ 'Number',
83
+ 'Object',
84
+ 'prototype',
85
+ 'String',
86
+ 'toString',
87
+ 'undefined',
88
+ 'valueOf',
89
+ ]
90
+
91
+ export function transformReservedWord(word: string): string {
92
+ if ((word && reservedWords.includes(word)) || word?.match(/^\d/)) {
93
+ return `_${word}`
94
+ }
95
+
96
+ return word
97
+ }
@@ -0,0 +1,7 @@
1
+ export function trim(text: string): string {
2
+ return text.replaceAll(/\n/g, '').trim()
3
+ }
4
+
5
+ export function trimExtName(text: string): string {
6
+ return text.replace(/\.[^/.]+$/, '')
7
+ }
package/src/types.ts ADDED
@@ -0,0 +1,334 @@
1
+ import type { PossiblePromise } from '@kubb/types'
2
+ import type { FileManager, KubbFile } from './FileManager.ts'
3
+ import type { OptionsPlugins, PluginUnion } from './index.ts'
4
+ import type { Logger, LogLevel } from './logger.ts'
5
+ import type { PluginManager } from './PluginManager.ts'
6
+ import type { Cache } from './utils/cache.ts'
7
+
8
+ // config
9
+
10
+ /**
11
+ * Config used in `kubb.config.js`
12
+ *
13
+ * @example import { defineConfig } from '@kubb/core'
14
+ * export default defineConfig({
15
+ * ...
16
+ * })
17
+ */
18
+ export type KubbUserConfig =
19
+ & Omit<KubbConfig, 'root' | 'plugins'>
20
+ & {
21
+ /**
22
+ * Project root directory. Can be an absolute path, or a path relative from
23
+ * the location of the config file itself.
24
+ * @default process.cwd()
25
+ */
26
+ root?: string
27
+ /**
28
+ * Plugin type can be KubbJSONPlugin or KubbPlugin
29
+ * Example: ['@kubb/swagger', { output: false }]
30
+ * Or: createSwagger({ output: false })
31
+ */
32
+ plugins?: Array<Omit<UnknownKubbUserPlugin, 'api'> | KubbUnionPlugins | [name: string, options: object]>
33
+ }
34
+
35
+ export type InputPath = {
36
+ /**
37
+ * Path to be used as the input. This can be an absolute path or a path relative to the `root`.
38
+ */
39
+ path: string
40
+ }
41
+
42
+ export type InputData = {
43
+ /**
44
+ * `string` or `object` containing the data.
45
+ */
46
+ data: string | unknown
47
+ }
48
+
49
+ type Input = InputPath | InputData
50
+
51
+ /**
52
+ * @private
53
+ */
54
+ export type KubbConfig<TInput = Input> = {
55
+ /**
56
+ * Optional config name to show in CLI output
57
+ */
58
+ name?: string
59
+ /**
60
+ * Project root directory. Can be an absolute path, or a path relative from
61
+ * the location of the config file itself.
62
+ * @default process.cwd()
63
+ */
64
+ root: string
65
+ input: TInput
66
+ output: {
67
+ /**
68
+ * Path to be used to export all generated files.
69
+ * This can be an absolute path, or a path relative based of the defined `root` option.
70
+ */
71
+ path: string
72
+ /**
73
+ * Clean output directory before each build.
74
+ */
75
+ clean?: boolean
76
+ /**
77
+ * Write files to the fileSystem
78
+ * This is being used for the playground.
79
+ * @default true
80
+ */
81
+ write?: boolean
82
+ }
83
+ /**
84
+ * Array of Kubb plugins to use.
85
+ * The plugin/package can forsee some options that you need to pass through.
86
+ * Sometimes a plugin is depended on another plugin, if that's the case you will get an error back from the plugin you installed.
87
+ */
88
+ plugins?: Array<KubbPlugin>
89
+ /**
90
+ * Hooks that will be called when a specific action is triggered in Kubb.
91
+ */
92
+ hooks?: {
93
+ /**
94
+ * Hook that will be triggered at the end of all executions.
95
+ * Useful for running Prettier or ESLint to format/lint your code.
96
+ */
97
+ done?: string | Array<string>
98
+ }
99
+ }
100
+
101
+ export type CLIOptions = {
102
+ /**
103
+ * Path to `kubb.config.js`
104
+ */
105
+ config?: string
106
+ /**
107
+ * Watch changes on input
108
+ */
109
+ watch?: string
110
+
111
+ /**
112
+ * Log level to report when using the CLI
113
+ *
114
+ * `silent` will hide all information that is not relevant
115
+ *
116
+ * `info` will show all information possible(not related to the PluginManager)
117
+ *
118
+ * `debug` will show all information possible(related to the PluginManager), handy for seeing logs
119
+ * @default `silent`
120
+ */
121
+ logLevel?: LogLevel
122
+ }
123
+
124
+ // plugin
125
+
126
+ export type KubbUnionPlugins = PluginUnion
127
+
128
+ export type KubbObjectPlugin = keyof OptionsPlugins
129
+
130
+ export type PluginFactoryOptions<
131
+ /**
132
+ * Name to be used for the plugin, this will also be used for they key.
133
+ */
134
+ TName extends string = string,
135
+ /**
136
+ * Options of the plugin.
137
+ */
138
+ TOptions extends object = object,
139
+ /**
140
+ * Options of the plugin that can be used later on, see `options` inside your plugin config.
141
+ */
142
+ TResolvedOptions extends object = TOptions,
143
+ /**
144
+ * API that you want to expose to other plugins.
145
+ */
146
+ TAPI = any,
147
+ /**
148
+ * When calling `resolvePath` you can specify better types.
149
+ */
150
+ TResolvePathOptions extends object = object,
151
+ /**
152
+ * When using @kubb/react(based on React) you can specify here which types should be used when calling render.
153
+ * Always extend from `AppMeta` of the core.
154
+ */
155
+ TAppMeta = unknown,
156
+ > = {
157
+ name: TName
158
+ /**
159
+ * Same behaviour like what has been done with `QueryKey` in `@tanstack/react-query`
160
+ */
161
+ key: [name: TName | string, identifier?: string | number]
162
+ options: TOptions
163
+ resolvedOptions: TResolvedOptions
164
+ api: TAPI
165
+ resolvePathOptions: TResolvePathOptions
166
+ appMeta: {
167
+ pluginManager: PluginManager
168
+ plugin: KubbPlugin<PluginFactoryOptions<TName, TOptions, TResolvedOptions, TAPI, TResolvePathOptions, TAppMeta>>
169
+ } & TAppMeta
170
+ }
171
+
172
+ export type GetPluginFactoryOptions<TPlugin extends KubbUserPlugin> = TPlugin extends KubbUserPlugin<infer X> ? X : never
173
+
174
+ export type KubbUserPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> =
175
+ & {
176
+ /**
177
+ * Unique name used for the plugin
178
+ * The name of the plugin follows the format scope:foo-bar or foo-bar, adding scope: can avoid naming conflicts with other plugins.
179
+ * @example @kubb/typescript
180
+ */
181
+ name: TOptions['name']
182
+ /**
183
+ * Options set for a specific plugin(see kubb.config.js), passthrough of options.
184
+ */
185
+ options: TOptions['resolvedOptions']
186
+ /**
187
+ * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin will be executed after these plugins.
188
+ * Can be used to validate depended plugins.
189
+ */
190
+ pre?: Array<string>
191
+ /**
192
+ * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin will be executed before these plugins.
193
+ */
194
+ post?: Array<string>
195
+ }
196
+ & (TOptions['api'] extends never ? {
197
+ api?: never
198
+ }
199
+ : {
200
+ api: (this: TOptions['name'] extends 'core' ? null : Omit<PluginContext<TOptions>, 'addFile'>) => TOptions['api']
201
+ })
202
+
203
+ export type KubbUserPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = KubbUserPlugin<TOptions> & PluginLifecycle<TOptions>
204
+
205
+ type UnknownKubbUserPlugin = KubbUserPlugin<PluginFactoryOptions<any, any, any, any, any, any>>
206
+
207
+ export type KubbPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOptions> =
208
+ & {
209
+ /**
210
+ * Unique name used for the plugin
211
+ * @example @kubb/typescript
212
+ */
213
+ name: TOptions['name']
214
+ /**
215
+ * Internal key used when a developer uses more than one of the same plugin
216
+ * @private
217
+ */
218
+ key: TOptions['key']
219
+ /**
220
+ * Specifies the preceding plugins for the current plugin. You can pass an array of preceding plugin names, and the current plugin will be executed after these plugins.
221
+ * Can be used to validate depended plugins.
222
+ */
223
+ pre?: Array<string>
224
+ /**
225
+ * Specifies the succeeding plugins for the current plugin. You can pass an array of succeeding plugin names, and the current plugin will be executed before these plugins.
226
+ */
227
+ post?: Array<string>
228
+ /**
229
+ * Options set for a specific plugin(see kubb.config.js), passthrough of options.
230
+ */
231
+ options: TOptions['resolvedOptions']
232
+ /**
233
+ * Define an api that can be used by other plugins, see `PluginManager' where we convert from `KubbUserPlugin` to `KubbPlugin`(used when calling `createPlugin`).
234
+ */
235
+ }
236
+ & (TOptions['api'] extends never ? {
237
+ api?: never
238
+ }
239
+ : {
240
+ api: TOptions['api']
241
+ })
242
+
243
+ export type KubbPluginWithLifeCycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = KubbPlugin<TOptions> & PluginLifecycle<TOptions>
244
+
245
+ export type PluginLifecycle<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
246
+ /**
247
+ * Start of the lifecycle of a plugin.
248
+ * @type hookParallel
249
+ */
250
+ buildStart?: (this: PluginContext<TOptions>, kubbConfig: KubbConfig) => PossiblePromise<void>
251
+ /**
252
+ * Resolve to a Path based on a baseName(example: `./Pet.ts`) and directory(example: `./models`).
253
+ * Options can als be included.
254
+ * @type hookFirst
255
+ * @example ('./Pet.ts', './src/gen/') => '/src/gen/Pet.ts'
256
+ */
257
+ resolvePath?: (this: PluginContext<TOptions>, baseName: string, directory?: string, options?: TOptions['resolvePathOptions']) => KubbFile.OptionalPath
258
+ /**
259
+ * Resolve to a name based on a string.
260
+ * Useful when converting to PascalCase or camelCase.
261
+ * @type hookFirst
262
+ * @example ('pet') => 'Pet'
263
+ */
264
+ resolveName?: (this: PluginContext<TOptions>, name: ResolveNameParams['name'], type?: ResolveNameParams['type']) => string
265
+ /**
266
+ * Makes it possible to run async logic to override the path defined previously by `resolvePath`.
267
+ * @type hookFirst
268
+ */
269
+ load?: (this: Omit<PluginContext<TOptions>, 'addFile'>, path: KubbFile.Path) => PossiblePromise<TransformResult | null>
270
+ /**
271
+ * Transform the source-code.
272
+ * @type hookReduceArg0
273
+ */
274
+ transform?: (this: Omit<PluginContext<TOptions>, 'addFile'>, source: string, path: KubbFile.Path) => PossiblePromise<TransformResult>
275
+ /**
276
+ * Write the result to the file-system based on the id(defined by `resolvePath` or changed by `load`).
277
+ * @type hookParallel
278
+ */
279
+ writeFile?: (this: Omit<PluginContext<TOptions>, 'addFile'>, source: string | undefined, path: KubbFile.Path) => PossiblePromise<string | void>
280
+ /**
281
+ * End of the plugin lifecycle.
282
+ * @type hookParallel
283
+ */
284
+ buildEnd?: (this: PluginContext<TOptions>) => PossiblePromise<void>
285
+ }
286
+
287
+ export type PluginLifecycleHooks = keyof PluginLifecycle
288
+
289
+ export type PluginParameter<H extends PluginLifecycleHooks> = Parameters<Required<PluginLifecycle>[H]>
290
+
291
+ export type PluginCache = Record<string, [number, unknown]>
292
+
293
+ export type ResolvePathParams<TOptions = object> = {
294
+ pluginKey?: KubbPlugin['key']
295
+ baseName: string
296
+ directory?: string | undefined
297
+ /**
298
+ * Options to be passed to 'resolvePath' 3th parameter
299
+ */
300
+ options?: TOptions
301
+ }
302
+
303
+ export type ResolveNameParams = {
304
+ name: string
305
+ pluginKey?: KubbPlugin['key']
306
+ /**
307
+ * `file` will be used to customize the name of the created file(use of camelCase)
308
+ * `function` can be used used to customize the exported functions(use of camelCase)
309
+ * `type` is a special type for TypeScript(use of PascalCase)
310
+ */
311
+ type?: 'file' | 'function' | 'type'
312
+ }
313
+
314
+ export type PluginContext<TOptions extends PluginFactoryOptions = PluginFactoryOptions> = {
315
+ config: KubbConfig
316
+ cache: Cache<PluginCache>
317
+ fileManager: FileManager
318
+ pluginManager: PluginManager
319
+ addFile: (...file: Array<KubbFile.File>) => Promise<Array<KubbFile.File>>
320
+ resolvePath: (params: ResolvePathParams<TOptions['resolvePathOptions']>) => KubbFile.OptionalPath
321
+ resolveName: (params: ResolveNameParams) => string
322
+ logger: Logger
323
+ /**
324
+ * All plugins
325
+ */
326
+ plugins: KubbPlugin[]
327
+ /**
328
+ * Current plugin
329
+ */
330
+ plugin: KubbPlugin<TOptions>
331
+ }
332
+
333
+ // null will mean clear the watcher for this key
334
+ export type TransformResult = string | null
@@ -0,0 +1,24 @@
1
+ /* eslint-disable @typescript-eslint/no-unsafe-argument */
2
+ import { EventEmitter as NodeEventEmitter } from 'node:events'
3
+
4
+ export class EventEmitter<TEvents extends Record<string, any>> {
5
+ constructor() {
6
+ this.#emitter.setMaxListeners(100)
7
+ }
8
+ #emitter = new NodeEventEmitter()
9
+
10
+ emit<TEventName extends keyof TEvents & string>(eventName: TEventName, ...eventArg: TEvents[TEventName]): void {
11
+ this.#emitter.emit(eventName, ...(eventArg as []))
12
+ }
13
+
14
+ on<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {
15
+ this.#emitter.on(eventName, handler as any)
16
+ }
17
+
18
+ off<TEventName extends keyof TEvents & string>(eventName: TEventName, handler: (...eventArg: TEvents[TEventName]) => void): void {
19
+ this.#emitter.off(eventName, handler as any)
20
+ }
21
+ removeAll(): void {
22
+ this.#emitter.removeAllListeners()
23
+ }
24
+ }
@@ -0,0 +1,86 @@
1
+ import { orderBy } from 'natural-orderby'
2
+
3
+ import { camelCase } from '../transformers/casing.ts'
4
+
5
+ type FunctionParamsASTWithoutType = {
6
+ name?: string
7
+ type?: string
8
+ /**
9
+ * @default true
10
+ */
11
+ required?: boolean
12
+ /**
13
+ * @default true
14
+ */
15
+ enabled?: boolean
16
+ default?: string
17
+ }
18
+
19
+ type FunctionParamsASTWithType = {
20
+ name?: never
21
+ type: string
22
+ /**
23
+ * @default true
24
+ */
25
+ required?: boolean
26
+ /**
27
+ * @default true
28
+ */
29
+ enabled?: boolean
30
+ default?: string
31
+ }
32
+
33
+ export type FunctionParamsAST = FunctionParamsASTWithoutType | FunctionParamsASTWithType
34
+ export class FunctionParams {
35
+ public type?: 'generics' | 'typed'
36
+ public items: FunctionParamsAST[] = []
37
+ constructor(type?: 'generics' | 'typed') {
38
+ this.type = type
39
+
40
+ return this
41
+ }
42
+
43
+ add(item: FunctionParamsAST | Array<FunctionParamsAST | undefined> | undefined): FunctionParams {
44
+ if (!item) {
45
+ return this
46
+ }
47
+
48
+ if (Array.isArray(item)) {
49
+ item.filter(Boolean).forEach((it) => this.items.push(it))
50
+ return this
51
+ }
52
+ this.items.push(item)
53
+
54
+ return this
55
+ }
56
+
57
+ toString(): string {
58
+ const sortedData = orderBy(this.items.filter(Boolean), [(v) => !v.default, (v) => v.required ?? true], ['desc', 'desc'])
59
+
60
+ return sortedData
61
+ .filter(({ enabled = true }) => enabled)
62
+ .reduce((acc, { name, type, required = true, ...rest }) => {
63
+ if (!name) {
64
+ // when name is not se we will use TypeScript generics
65
+ acc.push(`${type}${rest.default ? ` = ${rest.default}` : ''}`)
66
+
67
+ return acc
68
+ }
69
+ // TODO check whey we still need the camelcase here
70
+ const parameterName = name.startsWith('{') ? name : camelCase(name)
71
+
72
+ if (type) {
73
+ if (required) {
74
+ acc.push(`${parameterName}: ${type}${rest.default ? ` = ${rest.default}` : ''}`)
75
+ } else {
76
+ acc.push(`${parameterName}?: ${type}`)
77
+ }
78
+ } else {
79
+ acc.push(`${parameterName}`)
80
+ }
81
+
82
+ return acc
83
+ }, [] as string[])
84
+ .join(', ')
85
+ }
86
+ }