@kubb/core 2.0.0-beta.1 → 2.0.0-beta.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (67) hide show
  1. package/dist/Queue-2-6pMcCx.d.cts +32 -0
  2. package/dist/Queue-2-6pMcCx.d.ts +32 -0
  3. package/dist/fs.cjs +2383 -0
  4. package/dist/fs.cjs.map +1 -0
  5. package/dist/fs.d.cts +5 -0
  6. package/dist/fs.d.ts +5 -0
  7. package/dist/fs.js +2380 -0
  8. package/dist/fs.js.map +1 -0
  9. package/dist/index.cjs +3448 -394
  10. package/dist/index.cjs.map +1 -1
  11. package/dist/index.d.cts +77 -127
  12. package/dist/index.d.ts +77 -127
  13. package/dist/index.js +3761 -423
  14. package/dist/index.js.map +1 -1
  15. package/dist/logger.cjs +90 -0
  16. package/dist/logger.cjs.map +1 -0
  17. package/dist/logger.d.cts +32 -0
  18. package/dist/logger.d.ts +32 -0
  19. package/dist/logger.js +78 -0
  20. package/dist/logger.js.map +1 -0
  21. package/dist/transformers.cjs +222 -0
  22. package/dist/transformers.cjs.map +1 -0
  23. package/dist/transformers.d.cts +55 -0
  24. package/dist/transformers.d.ts +55 -0
  25. package/dist/transformers.js +207 -0
  26. package/dist/transformers.js.map +1 -0
  27. package/dist/utils.cjs +174 -899
  28. package/dist/utils.cjs.map +1 -1
  29. package/dist/utils.d.cts +2 -146
  30. package/dist/utils.d.ts +2 -146
  31. package/dist/utils.js +175 -859
  32. package/dist/utils.js.map +1 -1
  33. package/dist/write-46ytbnu9.d.cts +7 -0
  34. package/dist/write-46ytbnu9.d.ts +7 -0
  35. package/package.json +27 -12
  36. package/src/BarrelManager.ts +55 -65
  37. package/src/FileManager.ts +109 -68
  38. package/src/PluginManager.ts +55 -32
  39. package/src/build.ts +5 -16
  40. package/src/fs/index.ts +3 -0
  41. package/src/index.ts +4 -5
  42. package/src/{utils/logger.ts → logger.ts} +37 -0
  43. package/src/plugin.ts +4 -4
  44. package/src/transformers/casing.ts +9 -0
  45. package/src/transformers/createJSDocBlockText.ts +9 -0
  46. package/src/transformers/index.ts +36 -0
  47. package/src/transformers/trim.ts +7 -0
  48. package/src/types.ts +23 -42
  49. package/src/utils/FunctionParams.ts +3 -2
  50. package/src/utils/TreeNode.ts +6 -3
  51. package/src/utils/URLPath.ts +5 -5
  52. package/src/utils/index.ts +10 -19
  53. package/src/SchemaGenerator.ts +0 -8
  54. package/src/utils/randomColour.ts +0 -39
  55. package/src/utils/throttle.ts +0 -30
  56. package/src/utils/transformers/createJSDocBlockText.ts +0 -15
  57. package/src/utils/transformers/index.ts +0 -22
  58. package/src/utils/transformers/trim.ts +0 -3
  59. /package/src/{utils → fs}/clean.ts +0 -0
  60. /package/src/{utils → fs}/read.ts +0 -0
  61. /package/src/{utils → fs}/write.ts +0 -0
  62. /package/src/{utils/transformers → transformers}/combineCodes.ts +0 -0
  63. /package/src/{utils/transformers → transformers}/escape.ts +0 -0
  64. /package/src/{utils/transformers → transformers}/indent.ts +0 -0
  65. /package/src/{utils/transformers → transformers}/nameSorter.ts +0 -0
  66. /package/src/{utils/transformers → transformers}/searchAndReplace.ts +0 -0
  67. /package/src/{utils/transformers → transformers}/transformReservedWord.ts +0 -0
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-namespace */
2
2
  import crypto from 'node:crypto'
3
- import { extname } from 'node:path'
3
+ import { extname, resolve } from 'node:path'
4
4
 
5
5
  import { print } from '@kubb/parser'
6
6
  import * as factory from '@kubb/parser/factory'
@@ -8,10 +8,10 @@ import * as factory from '@kubb/parser/factory'
8
8
  import isEqual from 'lodash.isequal'
9
9
  import { orderBy } from 'natural-orderby'
10
10
 
11
- import { read } from './utils/read.ts'
11
+ import { getRelativePath, read } from './fs/read.ts'
12
+ import { write } from './fs/write.ts'
13
+ import transformers from './transformers/index.ts'
12
14
  import { timeout } from './utils/timeout.ts'
13
- import { transformers } from './utils/transformers/index.ts'
14
- import { write } from './utils/write.ts'
15
15
  import { BarrelManager } from './BarrelManager.ts'
16
16
 
17
17
  import type { GreaterThan } from '@kubb/types'
@@ -28,7 +28,14 @@ export namespace KubbFile {
28
28
  * @example ["useState"]
29
29
  * @example "React"
30
30
  */
31
- name: string | Array<string>
31
+ name:
32
+ | string
33
+ | Array<
34
+ string | {
35
+ propertyName: string
36
+ name?: string
37
+ }
38
+ >
32
39
  /**
33
40
  * Path for the import
34
41
  * @xample '@kubb/core'
@@ -38,6 +45,14 @@ export namespace KubbFile {
38
45
  * Add `type` prefix to the import, this will result in: `import type { Type } from './path'`.
39
46
  */
40
47
  isTypeOnly?: boolean
48
+ /**
49
+ * Add `* as` prefix to the import, this will result in: `import * as path from './path'`.
50
+ */
51
+ isNameSpace?: boolean
52
+ /**
53
+ * When root is set it will get the path with relative getRelativePath(root, path).
54
+ */
55
+ root?: string
41
56
  }
42
57
 
43
58
  export type Export = {
@@ -104,8 +119,8 @@ export namespace KubbFile {
104
119
  */
105
120
  id?: string
106
121
  /**
107
- * Name to be used to dynamicly create the baseName(based on input.path)
108
- * Based on UNIX basename
122
+ * Name to be used to create the path
123
+ * Based on UNIX basename, `${name}.extName`
109
124
  * @link https://nodejs.org/api/path.html#pathbasenamepath-suffix
110
125
  */
111
126
  baseName: TBaseName
@@ -130,10 +145,6 @@ export namespace KubbFile {
130
145
  * This will override `process.env[key]` inside the `source`, see `getFileSource`.
131
146
  */
132
147
  env?: NodeJS.ProcessEnv
133
- /**
134
- * @deprecated
135
- */
136
- validate?: boolean
137
148
  }
138
149
 
139
150
  export type ResolvedFile<
@@ -144,6 +155,12 @@ export namespace KubbFile {
144
155
  * @default crypto.randomUUID()
145
156
  */
146
157
  id: UUID
158
+ /**
159
+ * Contains the first part of the baseName, generated based on baseName
160
+ * @link https://nodejs.org/api/path.html#pathformatpathobject
161
+ */
162
+
163
+ name: string
147
164
  }
148
165
  }
149
166
 
@@ -156,8 +173,19 @@ type AddResult<T extends Array<KubbFile.File>> = Promise<
156
173
  >
157
174
 
158
175
  type AddIndexesProps = {
159
- root: KubbFile.Path
160
- extName?: KubbFile.Extname
176
+ /**
177
+ * Root based on root and output.path specified in the config
178
+ */
179
+ root: string
180
+ /**
181
+ * Output for plugin
182
+ */
183
+ output: {
184
+ path: string
185
+ exportAs?: string
186
+ extName?: KubbFile.Extname
187
+ exportType?: 'barrel' | false
188
+ }
161
189
  options?: BarrelManagerOptions
162
190
  meta?: KubbFile.File['meta']
163
191
  }
@@ -205,10 +233,6 @@ export class FileManager {
205
233
  }
206
234
 
207
235
  #validate(file: KubbFile.File): void {
208
- if (!file.validate) {
209
- return
210
- }
211
-
212
236
  if (!file.path.toLowerCase().endsWith(file.baseName.toLowerCase())) {
213
237
  throw new Error(`${file.path} should end with the baseName ${file.baseName}`)
214
238
  }
@@ -218,7 +242,7 @@ export class FileManager {
218
242
  ...files: T
219
243
  ): AddResult<T> {
220
244
  const promises = files.map((file) => {
221
- this.#validate(file)
245
+ // this.#validate(file)
222
246
 
223
247
  if (file.override) {
224
248
  return this.#add(file)
@@ -238,7 +262,7 @@ export class FileManager {
238
262
 
239
263
  async #add(file: KubbFile.File): Promise<KubbFile.ResolvedFile> {
240
264
  const controller = new AbortController()
241
- const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), ...file }
265
+ const resolvedFile: KubbFile.ResolvedFile = { id: crypto.randomUUID(), name: transformers.trimExtName(file.baseName), ...file }
242
266
 
243
267
  this.#cache.set(resolvedFile.path, [{ cancel: () => controller.abort(), ...resolvedFile }])
244
268
 
@@ -272,15 +296,45 @@ export class FileManager {
272
296
  return this.#add(file)
273
297
  }
274
298
 
275
- async addIndexes({ root, extName = '.ts', meta, options = {} }: AddIndexesProps): Promise<Array<KubbFile.File> | undefined> {
276
- const barrelManager = new BarrelManager(options)
299
+ async addIndexes({ root, output, meta, options = {} }: AddIndexesProps): Promise<Array<KubbFile.File> | undefined> {
300
+ const { exportType = 'barrel' } = output
277
301
 
278
- const files = barrelManager.getIndexes(root, extName)
302
+ if (!exportType) {
303
+ return undefined
304
+ }
305
+
306
+ const exportPath = output.path.startsWith('./') ? output.path : `./${output.path}`
307
+ const barrelManager = new BarrelManager({ extName: output.extName, ...options })
308
+ const files = barrelManager.getIndexes(resolve(root, output.path))
279
309
 
280
310
  if (!files) {
281
311
  return undefined
282
312
  }
283
313
 
314
+ const rootFile: KubbFile.File = {
315
+ path: resolve(root, 'index.ts'),
316
+ baseName: 'index.ts',
317
+ source: '',
318
+ exports: [
319
+ output.exportAs
320
+ ? {
321
+ name: output.exportAs,
322
+ asAlias: true,
323
+ path: exportPath,
324
+ isTypeOnly: options.isTypeOnly,
325
+ }
326
+ : {
327
+ path: exportPath,
328
+ isTypeOnly: options.isTypeOnly,
329
+ },
330
+ ],
331
+ }
332
+
333
+ await this.#addOrAppend({
334
+ ...rootFile,
335
+ meta: meta ? meta : rootFile.meta,
336
+ })
337
+
284
338
  return await Promise.all(
285
339
  files.map((file) => {
286
340
  return this.#addOrAppend({
@@ -335,51 +389,7 @@ export class FileManager {
335
389
  // statics
336
390
 
337
391
  static getSource<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(file: KubbFile.File<TMeta>): string {
338
- if (!FileManager.isExtensionAllowed(file.baseName)) {
339
- return file.source
340
- }
341
-
342
- const exports = file.exports ? combineExports(file.exports) : []
343
- const imports = file.imports ? combineImports(file.imports, exports, file.source) : []
344
-
345
- const importNodes = imports.map((item) => factory.createImportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly }))
346
- const exportNodes = exports.map((item) =>
347
- factory.createExportDeclaration({ name: item.name, path: item.path, isTypeOnly: item.isTypeOnly, asAlias: item.asAlias })
348
- )
349
-
350
- return [print([...importNodes, ...exportNodes]), getEnvSource(file.source, file.env)].join('\n')
351
- }
352
- static combineFiles<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(files: Array<KubbFile.File<TMeta> | null>): Array<KubbFile.File<TMeta>> {
353
- return files.filter(Boolean).reduce((acc, file: KubbFile.File<TMeta>) => {
354
- const prevIndex = acc.findIndex((item) => item.path === file.path)
355
-
356
- if (prevIndex === -1) {
357
- return [...acc, file]
358
- }
359
-
360
- const prev = acc[prevIndex]
361
-
362
- if (prev && file.override) {
363
- acc[prevIndex] = {
364
- imports: [],
365
- exports: [],
366
- ...file,
367
- }
368
- return acc
369
- }
370
-
371
- if (prev) {
372
- acc[prevIndex] = {
373
- ...file,
374
- source: prev.source && file.source ? `${prev.source}\n${file.source}` : '',
375
- imports: [...(prev.imports || []), ...(file.imports || [])],
376
- exports: [...(prev.exports || []), ...(file.exports || [])],
377
- env: { ...(prev.env || {}), ...(file.env || {}) },
378
- }
379
- }
380
-
381
- return acc
382
- }, [] as Array<KubbFile.File<TMeta>>)
392
+ return getSource<TMeta>(file)
383
393
  }
384
394
  static getMode(path: string | undefined | null): KubbFile.Mode {
385
395
  if (!path) {
@@ -397,6 +407,37 @@ export class FileManager {
397
407
  }
398
408
  }
399
409
 
410
+ export function getSource<TMeta extends KubbFile.FileMetaBase = KubbFile.FileMetaBase>(file: KubbFile.File<TMeta>): string {
411
+ if (!FileManager.isExtensionAllowed(file.baseName)) {
412
+ return file.source
413
+ }
414
+
415
+ const exports = file.exports ? combineExports(file.exports) : []
416
+ const imports = file.imports ? combineImports(file.imports, exports, file.source) : []
417
+
418
+ const importNodes = imports.filter(item => {
419
+ // isImportNotNeeded
420
+ // trim extName
421
+ return item.path !== transformers.trimExtName(file.path)
422
+ }).map((item) => {
423
+ return factory.createImportDeclaration({
424
+ name: item.name,
425
+ path: item.root ? getRelativePath(item.root, item.path) : item.path,
426
+ isTypeOnly: item.isTypeOnly,
427
+ })
428
+ })
429
+ const exportNodes = exports.map((item) =>
430
+ factory.createExportDeclaration({
431
+ name: item.name,
432
+ path: item.path,
433
+ isTypeOnly: item.isTypeOnly,
434
+ asAlias: item.asAlias,
435
+ })
436
+ )
437
+
438
+ return [print([...importNodes, ...exportNodes]), getEnvSource(file.source, file.env)].join('\n')
439
+ }
440
+
400
441
  export function combineExports(exports: Array<KubbFile.Export>): Array<KubbFile.Export> {
401
442
  const combinedExports = orderBy(exports, [(v) => !v.isTypeOnly], ['asc']).reduce((prev, curr) => {
402
443
  const name = curr.name
@@ -452,7 +493,7 @@ export function combineImports(imports: Array<KubbFile.Import>, exports: Array<K
452
493
  }
453
494
 
454
495
  if (Array.isArray(name)) {
455
- name = name.filter((item) => hasImportInSource(item))
496
+ name = name.filter((item) => typeof item === 'string' ? hasImportInSource(item) : hasImportInSource(item.propertyName))
456
497
  }
457
498
 
458
499
  const prevByPath = prev.findLast((imp) => imp.path === curr.path && imp.isTypeOnly === curr.isTypeOnly)
@@ -1,18 +1,19 @@
1
1
  /* eslint-disable @typescript-eslint/ban-types, @typescript-eslint/no-unsafe-argument */
2
2
 
3
+ import { transformReservedWord } from './transformers/transformReservedWord.ts'
3
4
  import { EventEmitter } from './utils/EventEmitter.ts'
4
- import { LogLevel } from './utils/logger.ts'
5
5
  import { Queue } from './utils/Queue.ts'
6
- import { transformReservedWord } from './utils/transformers/transformReservedWord.ts'
7
6
  import { setUniqueName } from './utils/uniqueName.ts'
8
7
  import { ValidationPluginError } from './errors.ts'
9
8
  import { FileManager } from './FileManager.ts'
9
+ import { LogLevel } from './logger.ts'
10
10
  import { definePlugin as defineCorePlugin } from './plugin.ts'
11
11
  import { isPromise, isPromiseRejectedResult } from './PromiseManager.ts'
12
12
  import { PromiseManager } from './PromiseManager.ts'
13
13
 
14
14
  import type { PossiblePromise } from '@kubb/types'
15
15
  import type { KubbFile } from './FileManager.ts'
16
+ import type { Logger } from './logger.ts'
16
17
  import type { CorePluginOptions } from './plugin.ts'
17
18
  import type {
18
19
  GetPluginFactoryOptions,
@@ -28,7 +29,6 @@ import type {
28
29
  ResolveNameParams,
29
30
  ResolvePathParams,
30
31
  } from './types.ts'
31
- import type { Logger } from './utils/logger.ts'
32
32
  import type { QueueJob } from './utils/Queue.ts'
33
33
 
34
34
  type RequiredPluginLifecycle = Required<PluginLifecycle>
@@ -80,12 +80,12 @@ type Events = {
80
80
  export class PluginManager {
81
81
  readonly plugins: KubbPluginWithLifeCycle[]
82
82
  readonly fileManager: FileManager
83
- readonly eventEmitter: EventEmitter<Events> = new EventEmitter()
83
+ readonly events: EventEmitter<Events> = new EventEmitter()
84
84
 
85
85
  readonly queue: Queue
86
86
  readonly config: KubbConfig
87
87
 
88
- readonly executed: Executer[] = []
88
+ readonly executed: Array<Executer> = []
89
89
  readonly logger: Logger
90
90
  readonly #core: KubbPlugin<CorePluginOptions>
91
91
 
@@ -129,11 +129,11 @@ export class PluginManager {
129
129
  parameters: [params.baseName, params.directory, params.options as object],
130
130
  })
131
131
 
132
- if (paths && paths?.length > 1) {
133
- throw new Error(
132
+ if (paths && paths?.length > 1 && this.logger.logLevel === LogLevel.debug) {
133
+ this.logger.warn(
134
134
  `Cannot return a path where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough\n\nPaths: ${
135
135
  JSON.stringify(paths, undefined, 2)
136
- }`,
136
+ }\n\nFalling back on the first item.\n`,
137
137
  )
138
138
  }
139
139
 
@@ -144,7 +144,6 @@ export class PluginManager {
144
144
  parameters: [params.baseName, params.directory, params.options as object],
145
145
  }).result
146
146
  }
147
-
148
147
  resolveName = (params: ResolveNameParams): string => {
149
148
  if (params.pluginKey) {
150
149
  const names = this.hookForPluginSync({
@@ -153,11 +152,11 @@ export class PluginManager {
153
152
  parameters: [params.name, params.type],
154
153
  })
155
154
 
156
- if (names && names?.length > 1) {
157
- throw new Error(
155
+ if (names && names?.length > 1 && this.logger.logLevel === LogLevel.debug) {
156
+ this.logger.warn(
158
157
  `Cannot return a name where the 'pluginKey' ${params.pluginKey ? JSON.stringify(params.pluginKey) : '"'} is not unique enough\n\nNames: ${
159
158
  JSON.stringify(names, undefined, 2)
160
- }`,
159
+ }\n\nFalling back on the first item.\n`,
161
160
  )
162
161
  }
163
162
 
@@ -172,12 +171,15 @@ export class PluginManager {
172
171
  return transformReservedWord(name)
173
172
  }
174
173
 
174
+ /**
175
+ * Instead of calling `pluginManager.events.on` you can use `pluginManager.on`. This one also has better types.
176
+ */
175
177
  on<TEventName extends keyof Events & string>(eventName: TEventName, handler: (...eventArg: Events[TEventName]) => void): void {
176
- this.eventEmitter.on(eventName, handler as any)
178
+ this.events.on(eventName, handler as any)
177
179
  }
178
180
 
179
181
  /**
180
- * Run only hook for a specific plugin name
182
+ * Run a specific hookName for plugin x.
181
183
  */
182
184
  hookForPlugin<H extends PluginLifecycleHooks>({
183
185
  pluginKey,
@@ -203,6 +205,9 @@ export class PluginManager {
203
205
 
204
206
  return Promise.all(promises)
205
207
  }
208
+ /**
209
+ * Run a specific hookName for plugin x.
210
+ */
206
211
 
207
212
  hookForPluginSync<H extends PluginLifecycleHooks>({
208
213
  pluginKey,
@@ -228,7 +233,7 @@ export class PluginManager {
228
233
  }
229
234
 
230
235
  /**
231
- * Chains, first non-null result stops and returns
236
+ * First non-null result stops and will return it's value.
232
237
  */
233
238
  async hookFirst<H extends PluginLifecycleHooks>({
234
239
  hookName,
@@ -263,7 +268,7 @@ export class PluginManager {
263
268
  }
264
269
 
265
270
  /**
266
- * Chains, first non-null result stops and returns
271
+ * First non-null result stops and will return it's value.
267
272
  */
268
273
  hookFirstSync<H extends PluginLifecycleHooks>({
269
274
  hookName,
@@ -299,7 +304,7 @@ export class PluginManager {
299
304
  }
300
305
 
301
306
  /**
302
- * Parallel, runs all plugins
307
+ * Run all plugins in parallel(order will be based on `this.plugin` and if `pre` or `post` is set).
303
308
  */
304
309
  async hookParallel<H extends PluginLifecycleHooks, TOuput = void>({
305
310
  hookName,
@@ -327,7 +332,7 @@ export class PluginManager {
327
332
  }
328
333
 
329
334
  /**
330
- * Chains, reduces returned value, handling the reduced value as the first hook argument
335
+ * Chain all plugins, `reduce` can be passed through to handle every returned value. The return value of the first plugin will be used as the first parameter for the plugin after that.
331
336
  */
332
337
  hookReduceArg0<H extends PluginLifecycleHooks>({
333
338
  hookName,
@@ -379,7 +384,7 @@ export class PluginManager {
379
384
  const plugins = [...this.plugins].filter((plugin) => plugin.name !== 'core')
380
385
 
381
386
  if (hookName) {
382
- if (this.logger.logLevel === 'info') {
387
+ if (this.logger.logLevel === LogLevel.info) {
383
388
  const containsHookName = plugins.some((item) => item[hookName])
384
389
  if (!containsHookName) {
385
390
  this.logger.warn(`No hook ${hookName} found`)
@@ -388,28 +393,46 @@ export class PluginManager {
388
393
 
389
394
  return plugins.filter((item) => item[hookName])
390
395
  }
396
+ // TODO add test case for sorting with pre/post
391
397
 
392
- return plugins
398
+ return plugins.map(plugin => {
399
+ if (plugin.pre) {
400
+ const isValid = plugin.pre.every(pluginName => plugins.find(pluginToFind => pluginToFind.name === pluginName))
401
+
402
+ if (!isValid) {
403
+ throw new ValidationPluginError(`This plugin has a pre set that is not valid(${JSON.stringify(plugin.pre, undefined, 2)})`)
404
+ }
405
+ }
406
+
407
+ return plugin
408
+ }).sort((a, b) => {
409
+ if (b.pre?.includes(a.name)) {
410
+ return 1
411
+ }
412
+ if (b.post?.includes(a.name)) {
413
+ return -1
414
+ }
415
+ return 0
416
+ })
393
417
  }
394
418
 
395
419
  getPluginsByKey(hookName: keyof PluginLifecycle, pluginKey: KubbPlugin['key']): KubbPlugin[] {
396
420
  const plugins = [...this.plugins]
397
- const [searchKind, searchPluginName, searchIdentifier] = pluginKey
421
+ const [searchPluginName, searchIdentifier] = pluginKey
398
422
 
399
423
  const pluginByPluginName = plugins
400
424
  .filter((plugin) => plugin[hookName])
401
425
  .filter((item) => {
402
- const [kind, name, identifier] = item.key
426
+ const [name, identifier] = item.key
403
427
 
404
428
  const identifierCheck = identifier?.toString() === searchIdentifier?.toString()
405
- const kindCheck = kind === searchKind
406
429
  const nameCheck = name === searchPluginName
407
430
 
408
431
  if (searchIdentifier) {
409
- return identifierCheck && kindCheck && nameCheck
432
+ return identifierCheck && nameCheck
410
433
  }
411
434
 
412
- return kindCheck && nameCheck
435
+ return nameCheck
413
436
  })
414
437
 
415
438
  if (!pluginByPluginName?.length) {
@@ -417,7 +440,7 @@ export class PluginManager {
417
440
 
418
441
  const corePlugin = plugins.find((plugin) => plugin.name === 'core' && plugin[hookName])
419
442
 
420
- if (this.logger.logLevel === 'info') {
443
+ if (this.logger.logLevel === LogLevel.debug) {
421
444
  if (corePlugin) {
422
445
  this.logger.warn(`No hook '${hookName}' for pluginKey '${JSON.stringify(pluginKey)}' found, falling back on the '@kubb/core' plugin`)
423
446
  } else {
@@ -433,7 +456,7 @@ export class PluginManager {
433
456
 
434
457
  #addExecutedToCallStack(executer: Executer | undefined) {
435
458
  if (executer) {
436
- this.eventEmitter.emit('executed', executer)
459
+ this.events.emit('executed', executer)
437
460
  this.executed.push(executer)
438
461
  }
439
462
  }
@@ -463,7 +486,7 @@ export class PluginManager {
463
486
  return null
464
487
  }
465
488
 
466
- this.eventEmitter.emit('execute', { strategy, hookName, parameters, plugin })
489
+ this.events.emit('execute', { strategy, hookName, parameters, plugin })
467
490
 
468
491
  const task = Promise.resolve()
469
492
  .then(() => {
@@ -525,7 +548,7 @@ export class PluginManager {
525
548
  return null
526
549
  }
527
550
 
528
- this.eventEmitter.emit('execute', { strategy, hookName, parameters, plugin })
551
+ this.events.emit('execute', { strategy, hookName, parameters, plugin })
529
552
 
530
553
  try {
531
554
  if (typeof hook === 'function') {
@@ -557,7 +580,7 @@ export class PluginManager {
557
580
  const text = `${e.message} (plugin: ${plugin?.name || 'unknown'}, hook: ${hookName || 'unknown'})\n`
558
581
 
559
582
  this.logger.error(text)
560
- this.eventEmitter.emit('error', e)
583
+ this.events.emit('error', e)
561
584
  }
562
585
 
563
586
  #parse<TPlugin extends KubbUserPluginWithLifeCycle>(
@@ -569,7 +592,7 @@ export class PluginManager {
569
592
 
570
593
  setUniqueName(plugin.name, usedPluginNames)
571
594
 
572
- const key = plugin.key || ([plugin.kind, plugin.name, usedPluginNames[plugin.name]].filter(Boolean) as [typeof plugin.kind, typeof plugin.name, string])
595
+ const key = [plugin.name, usedPluginNames[plugin.name]].filter(Boolean) as [typeof plugin.name, string]
573
596
 
574
597
  if (plugin.name !== 'core' && usedPluginNames[plugin.name]! >= 2) {
575
598
  pluginManager.logger.warn('Using multiple of the same plugin is an experimental feature')
@@ -624,6 +647,6 @@ export class PluginManager {
624
647
 
625
648
  // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
626
649
  static get hooks() {
627
- return ['validate', 'buildStart', 'resolvePath', 'resolveName', 'load', 'transform', 'writeFile', 'buildEnd'] as const
650
+ return ['buildStart', 'resolvePath', 'resolveName', 'load', 'transform', 'writeFile', 'buildEnd'] as const
628
651
  }
629
652
  }
package/src/build.ts CHANGED
@@ -1,18 +1,17 @@
1
1
  import pc from 'picocolors'
2
2
 
3
- import { clean } from './utils/clean.ts'
4
- import { createLogger, LogLevel } from './utils/logger.ts'
5
- import { randomPicoColour } from './utils/randomColour.ts'
6
- import { read } from './utils/read.ts'
3
+ import { clean } from './fs/clean.ts'
4
+ import { read } from './fs/read.ts'
7
5
  import { URLPath } from './utils/URLPath.ts'
8
6
  import { isInputPath } from './config.ts'
9
7
  import { FileManager } from './FileManager.ts'
8
+ import { createLogger, LogLevel, randomPicoColour } from './logger.ts'
10
9
  import { PluginManager } from './PluginManager.ts'
11
10
  import { isPromise } from './PromiseManager.ts'
12
11
 
13
12
  import type { KubbFile } from './FileManager.ts'
13
+ import type { Logger } from './logger.ts'
14
14
  import type { KubbPlugin, PluginContext, PluginParameter, TransformResult } from './types.ts'
15
- import type { Logger } from './utils/logger.ts'
16
15
  import type { QueueJob } from './utils/Queue.ts'
17
16
 
18
17
  type BuildOptions = {
@@ -116,7 +115,7 @@ async function setup(options: BuildOptions): Promise<PluginManager> {
116
115
  logger.spinner.start(`💾 Writing`)
117
116
  }
118
117
 
119
- if (logger.logLevel === 'debug') {
118
+ if (logger.logLevel === LogLevel.debug) {
120
119
  logger.info(`PluginKey ${pc.dim(JSON.stringify(plugin.key))} \nwith source\n\n${code}`)
121
120
  }
122
121
  }
@@ -157,11 +156,6 @@ export async function build(options: BuildOptions): Promise<BuildOutput> {
157
156
 
158
157
  const { fileManager, logger } = pluginManager
159
158
 
160
- await pluginManager.hookParallel<'validate', true>({
161
- hookName: 'validate',
162
- parameters: [pluginManager.plugins],
163
- })
164
-
165
159
  await pluginManager.hookParallel({
166
160
  hookName: 'buildStart',
167
161
  parameters: [options.config],
@@ -183,11 +177,6 @@ export async function safeBuild(options: BuildOptions): Promise<BuildOutput> {
183
177
  const { fileManager, logger } = pluginManager
184
178
 
185
179
  try {
186
- await pluginManager.hookParallel<'validate', true>({
187
- hookName: 'validate',
188
- parameters: [pluginManager.plugins],
189
- })
190
-
191
180
  await pluginManager.hookParallel({
192
181
  hookName: 'buildStart',
193
182
  parameters: [options.config],
@@ -0,0 +1,3 @@
1
+ export { clean } from './clean.ts'
2
+ export { getRelativePath, read, readSync } from './read.ts'
3
+ export { write } from './write.ts'
package/src/index.ts CHANGED
@@ -3,17 +3,16 @@ import { build } from './build.ts'
3
3
  import type { ObjValueTuple, TupleToUnion } from '@kubb/types'
4
4
 
5
5
  export { build, safeBuild } from './build.ts'
6
- export * from './config.ts'
7
- export * from './errors.ts'
8
- export * from './FileManager.ts'
6
+ export { defineConfig, isInputPath } from './config.ts'
7
+ export { Warning } from './errors.ts'
8
+ export { FileManager, KubbFile } from './FileManager.ts'
9
9
  export { Generator } from './Generator.ts'
10
10
  export { PackageManager } from './PackageManager.ts'
11
11
  // dprint-ignore
12
12
  export { createPlugin, pluginName as name, pluginName } from './plugin.ts'
13
13
  export { PluginManager } from './PluginManager.ts'
14
14
  export { PromiseManager } from './PromiseManager.ts'
15
- export { SchemaGenerator } from './SchemaGenerator.ts'
16
- export * from './types.ts'
15
+ export type * from './types.ts'
17
16
 
18
17
  export interface _Register {}
19
18
  export type Plugins = _Register
@@ -1,6 +1,8 @@
1
1
  import pc from 'picocolors'
2
+ import seedrandom from 'seedrandom'
2
3
 
3
4
  import type { Ora } from 'ora'
5
+ import type { Formatter } from 'picocolors/types.ts'
4
6
 
5
7
  export const LogLevel = {
6
8
  silent: 'silent',
@@ -73,4 +75,39 @@ export function createLogger({ logLevel, name, spinner }: Props): Logger {
73
75
  return logger
74
76
  }
75
77
 
78
+ const defaultColours = ['black', 'blue', 'darkBlue', 'cyan', 'gray', 'green', 'darkGreen', 'magenta', 'red', 'darkRed', 'yellow', 'darkYellow'] as const
79
+
80
+ export function randomColour(text?: string, colours = defaultColours): string {
81
+ if (!text) {
82
+ return 'white'
83
+ }
84
+
85
+ const random = seedrandom(text)
86
+ const colour = colours.at(Math.floor(random() * colours.length)) || 'white'
87
+
88
+ return colour
89
+ }
90
+
91
+ export function randomPicoColour(text?: string, colors = defaultColours): string {
92
+ const colours = pc.createColors(true)
93
+
94
+ if (!text) {
95
+ return colours.white(text)
96
+ }
97
+
98
+ const colour = randomColour(text, colors)
99
+ const isDark = colour.includes('dark')
100
+ const key = colour.replace('dark', '').toLowerCase() as keyof typeof colours
101
+ const formatter: Formatter = colours[key] as Formatter
102
+
103
+ if (isDark) {
104
+ return pc.bold(formatter(text))
105
+ }
106
+
107
+ if (typeof formatter !== 'function') {
108
+ throw new Error('Formatter for picoColor is not of type function/Formatter')
109
+ }
110
+ return formatter(text)
111
+ }
112
+
76
113
  export { default as pc } from 'picocolors'