@kubb/core 1.1.10 → 1.1.12

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 (42) hide show
  1. package/dist/index.cjs +44 -16
  2. package/dist/index.d.ts +18 -13
  3. package/dist/index.js +44 -17
  4. package/package.json +3 -4
  5. package/src/build.ts +0 -106
  6. package/src/config.ts +0 -15
  7. package/src/generators/Generator.ts +0 -23
  8. package/src/generators/SchemaGenerator.ts +0 -8
  9. package/src/generators/index.ts +0 -2
  10. package/src/index.ts +0 -12
  11. package/src/managers/fileManager/FileManager.ts +0 -127
  12. package/src/managers/fileManager/index.ts +0 -3
  13. package/src/managers/fileManager/types.ts +0 -40
  14. package/src/managers/fileManager/utils.ts +0 -167
  15. package/src/managers/index.ts +0 -2
  16. package/src/managers/pluginManager/ParallelPluginError.ts +0 -15
  17. package/src/managers/pluginManager/PluginError.ts +0 -11
  18. package/src/managers/pluginManager/PluginManager.ts +0 -472
  19. package/src/managers/pluginManager/index.ts +0 -5
  20. package/src/managers/pluginManager/types.ts +0 -25
  21. package/src/managers/pluginManager/validate.ts +0 -21
  22. package/src/plugin.ts +0 -110
  23. package/src/types.ts +0 -253
  24. package/src/utils/Queue.ts +0 -46
  25. package/src/utils/TreeNode.ts +0 -122
  26. package/src/utils/cache.ts +0 -33
  27. package/src/utils/clean.ts +0 -5
  28. package/src/utils/getEncodedText.ts +0 -3
  29. package/src/utils/getStackTrace.ts +0 -20
  30. package/src/utils/getUniqueName.ts +0 -9
  31. package/src/utils/index.ts +0 -18
  32. package/src/utils/isPromise.ts +0 -5
  33. package/src/utils/isURL.ts +0 -11
  34. package/src/utils/jsdoc.ts +0 -13
  35. package/src/utils/nameSorter.ts +0 -9
  36. package/src/utils/objectToParameters.ts +0 -28
  37. package/src/utils/read.ts +0 -45
  38. package/src/utils/renderTemplate.ts +0 -11
  39. package/src/utils/timeout.ts +0 -7
  40. package/src/utils/transformReservedWord.ts +0 -97
  41. package/src/utils/uniqueId.ts +0 -5
  42. package/src/utils/write.ts +0 -25
@@ -1,3 +0,0 @@
1
- export * from './FileManager.ts'
2
- export * from './types.ts'
3
- export * from './utils.ts'
@@ -1,40 +0,0 @@
1
- type Import = {
2
- name: string | string[]
3
- path: string
4
- isTypeOnly?: boolean
5
- }
6
-
7
- type Export = {
8
- name?: string | string[]
9
- path: string
10
- isTypeOnly?: boolean
11
- asAlias?: boolean
12
- }
13
-
14
- export type File = {
15
- /**
16
- * Name to be used to dynamicly create the fileName(based on input.path)
17
- */
18
- fileName: string
19
- /**
20
- * Path will be full qualified path to a specified file
21
- */
22
- path: string
23
- source: string
24
- imports?: Import[]
25
- exports?: Export[]
26
- /**
27
- * This will call fileManager.add instead of fileManager.addOrAppend, adding the source when the files already exists
28
- * @default `false`
29
- */
30
- override?: boolean
31
- meta?: {
32
- pluginName?: string
33
- }
34
- }
35
-
36
- export type UUID = string
37
-
38
- export type CacheStore = { id: UUID; file: File; status: Status }
39
-
40
- export type Status = 'new' | 'success' | 'removed'
@@ -1,167 +0,0 @@
1
- import pathParser from 'node:path'
2
-
3
- import { createExportDeclaration, createImportDeclaration, print } from '@kubb/ts-codegen'
4
-
5
- import { TreeNode } from '../../utils/index.ts'
6
-
7
- import type ts from 'typescript'
8
- import type { Path } from '../../types.ts'
9
- import type { PathMode, TreeNodeOptions } from '../../utils/index.ts'
10
- import type { File } from './types.ts'
11
-
12
- type TreeNodeData = { type: PathMode; path: Path; name: string }
13
-
14
- export function writeIndexes(root: string, options: TreeNodeOptions = {}): File[] | null {
15
- const tree = TreeNode.build<TreeNodeData>(root, { extensions: /\.ts/, ...options })
16
-
17
- if (!tree) {
18
- return null
19
- }
20
-
21
- const fileReducer = (files: File[], currentTree: typeof tree) => {
22
- if (!currentTree.children) {
23
- return []
24
- }
25
-
26
- if (currentTree.children?.length > 1) {
27
- const path = pathParser.resolve(currentTree.data.path, 'index.ts')
28
- const exports = currentTree.children
29
- .map((file) => {
30
- if (!file) {
31
- return undefined
32
- }
33
-
34
- const importPath: string = file.data.type === 'directory' ? `./${file.data.name}` : `./${file.data.name.replace(/\.[^.]*$/, '')}`
35
-
36
- // TODO weird hacky fix
37
- if (importPath.includes('index') && path.includes('index')) {
38
- return undefined
39
- }
40
-
41
- return { path: importPath }
42
- })
43
- .filter(Boolean) as File['exports']
44
-
45
- files.push({
46
- path,
47
- fileName: 'index.ts',
48
- source: '',
49
- exports,
50
- })
51
- } else {
52
- currentTree.children?.forEach((child) => {
53
- const path = pathParser.resolve(currentTree.data.path, 'index.ts')
54
- const importPath = child.data.type === 'directory' ? `./${child.data.name}` : `./${child.data.name.replace(/\.[^.]*$/, '')}`
55
-
56
- files.push({
57
- path,
58
- fileName: 'index.ts',
59
- source: '',
60
- exports: [{ path: importPath }],
61
- })
62
- })
63
- }
64
-
65
- currentTree.children.forEach((childItem) => {
66
- fileReducer(files, childItem)
67
- })
68
-
69
- return files
70
- }
71
-
72
- const files = fileReducer([], tree)
73
-
74
- return files
75
- }
76
-
77
- export function combineFiles(files: Array<File | null>): File[] {
78
- return (files.filter(Boolean) as File[]).reduce((acc, curr: File) => {
79
- const prevIndex = acc.findIndex((item) => item.path === curr.path)
80
-
81
- if (prevIndex !== -1) {
82
- const prev = acc[prevIndex]
83
- acc[prevIndex] = {
84
- ...curr,
85
- source: `${prev.source}\n${curr.source}`,
86
- imports: [...(prev.imports || []), ...(curr.imports || [])],
87
- exports: [...(prev.exports || []), ...(curr.exports || [])],
88
- }
89
- } else {
90
- acc.push(curr)
91
- }
92
-
93
- return acc
94
- }, [] as File[])
95
- }
96
-
97
- export function getFileSource(file: File): string {
98
- let { source } = file
99
-
100
- // TODO make generic check
101
- if (!file.fileName.endsWith('.ts')) {
102
- return file.source
103
- }
104
- const imports: File['imports'] = []
105
- const exports: File['exports'] = []
106
-
107
- file.imports?.forEach((curr) => {
108
- const existingImport = imports.find((imp) => imp.path === curr.path)
109
-
110
- if (!existingImport) {
111
- imports.push({
112
- ...curr,
113
- name: Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name,
114
- })
115
- }
116
-
117
- if (existingImport && !Array.isArray(existingImport.name) && existingImport.name !== curr.name) {
118
- imports.push(curr)
119
- }
120
-
121
- if (existingImport && Array.isArray(existingImport.name)) {
122
- if (Array.isArray(curr.name)) {
123
- existingImport.name = [...new Set([...existingImport.name, ...curr.name])]
124
- }
125
- }
126
- })
127
-
128
- file.exports?.forEach((curr) => {
129
- const exists = exports.find((imp) => imp.path === curr.path)
130
- if (!exists) {
131
- exports.push({
132
- ...curr,
133
- name: Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name,
134
- })
135
- }
136
-
137
- if (exists && !Array.isArray(exists.name) && exists.name !== curr.name && exists.asAlias === curr.asAlias) {
138
- exports.push(curr)
139
- }
140
-
141
- if (exists && Array.isArray(exists.name)) {
142
- if (Array.isArray(curr.name)) {
143
- exists.name = [...new Set([...exists.name, ...curr.name])]
144
- }
145
- }
146
- })
147
-
148
- const importNodes = imports.reduce((prev, curr) => {
149
- return [...prev, createImportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly })]
150
- }, [] as ts.ImportDeclaration[])
151
- const importSource = print(importNodes)
152
-
153
- const exportNodes = exports.reduce((prev, curr) => {
154
- return [...prev, createExportDeclaration({ name: curr.name, path: curr.path, isTypeOnly: curr.isTypeOnly, asAlias: curr.asAlias })]
155
- }, [] as ts.ExportDeclaration[])
156
- const exportSource = print(exportNodes)
157
-
158
- if (importSource) {
159
- source = `${importSource}\n${source}`
160
- }
161
-
162
- if (exportSource) {
163
- source = `${exportSource}\n${source}`
164
- }
165
-
166
- return source
167
- }
@@ -1,2 +0,0 @@
1
- export * from './fileManager/index.ts'
2
- export * from './pluginManager/index.ts'
@@ -1,15 +0,0 @@
1
- import type { PluginError } from './PluginError.ts'
2
- import type { PluginManager } from './PluginManager'
3
-
4
- export class ParallelPluginError extends Error {
5
- public errors: PluginError[]
6
-
7
- public pluginManager: PluginManager
8
-
9
- constructor(message: string, options: { cause?: Error; errors: PluginError[]; pluginManager: PluginManager }) {
10
- super(message, { cause: options.cause })
11
-
12
- this.errors = options.errors
13
- this.pluginManager = options.pluginManager
14
- }
15
- }
@@ -1,11 +0,0 @@
1
- import type { PluginManager } from './PluginManager'
2
-
3
- export class PluginError extends Error {
4
- public pluginManager: PluginManager
5
-
6
- constructor(message: string, options: { cause?: Error; pluginManager: PluginManager }) {
7
- super(message, { cause: options.cause })
8
-
9
- this.pluginManager = options.pluginManager
10
- }
11
- }
@@ -1,472 +0,0 @@
1
- /* eslint-disable @typescript-eslint/ban-types */
2
-
3
- import { definePlugin } from '../../plugin.ts'
4
- import { isPromise } from '../../utils/isPromise.ts'
5
- import { Queue } from '../../utils/Queue.ts'
6
- import { FileManager } from '../fileManager/FileManager.ts'
7
- import { ParallelPluginError } from './ParallelPluginError.ts'
8
- import { PluginError } from './PluginError.ts'
9
-
10
- import type { CorePluginOptions } from '../../plugin.ts'
11
- import type { KubbConfig, KubbPlugin, MaybePromise, PluginLifecycle, PluginLifecycleHooks, ResolveNameParams, ResolvePathParams } from '../../types.ts'
12
- import type { QueueTask } from '../../utils/Queue.ts'
13
- import type { Argument0, Executer, OnExecute, ParseResult, SafeParseResult, Strategy } from './types.ts'
14
-
15
- // inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#
16
-
17
- // This will make sure no input hook is omitted
18
- const hookNames: {
19
- [P in PluginLifecycleHooks]: 1
20
- } = {
21
- validate: 1,
22
- buildStart: 1,
23
- resolvePath: 1,
24
- resolveName: 1,
25
- load: 1,
26
- transform: 1,
27
- writeFile: 1,
28
- buildEnd: 1,
29
- }
30
- export const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]
31
-
32
- type Options = { task: QueueTask; onExecute?: OnExecute<PluginLifecycleHooks> }
33
-
34
- export class PluginManager {
35
- public plugins: KubbPlugin[]
36
-
37
- public readonly fileManager: FileManager
38
-
39
- private readonly onExecute?: OnExecute
40
-
41
- private readonly core: KubbPlugin<CorePluginOptions>
42
-
43
- public queue: Queue
44
-
45
- public executer: Executer | undefined
46
-
47
- public executed: Executer[] = []
48
-
49
- constructor(config: KubbConfig, options: Options) {
50
- this.onExecute = options.onExecute
51
- this.queue = new Queue(10)
52
-
53
- this.fileManager = new FileManager({ task: options.task, queue: this.queue })
54
- this.core = definePlugin({
55
- config,
56
- fileManager: this.fileManager,
57
- load: this.load,
58
- resolvePath: this.resolvePath,
59
- resolveName: this.resolveName,
60
- getExecuter: this.getExecuter.bind(this),
61
- }) as KubbPlugin<CorePluginOptions> & {
62
- api: CorePluginOptions['api']
63
- }
64
- this.plugins = [this.core, ...(config.plugins || [])]
65
- }
66
-
67
- getExecuter() {
68
- return this.executer
69
- }
70
-
71
- resolvePath = (params: ResolvePathParams) => {
72
- if (params.pluginName) {
73
- return this.hookForPluginSync({
74
- pluginName: params.pluginName,
75
- hookName: 'resolvePath',
76
- parameters: [params.fileName, params.directory, params.options],
77
- })
78
- }
79
- return this.hookFirstSync({
80
- hookName: 'resolvePath',
81
- parameters: [params.fileName, params.directory, params.options],
82
- }).result
83
- }
84
-
85
- resolveName = (params: ResolveNameParams) => {
86
- if (params.pluginName) {
87
- return this.hookForPluginSync({
88
- pluginName: params.pluginName,
89
- hookName: 'resolveName',
90
- parameters: [params.name],
91
- })
92
- }
93
- return this.hookFirstSync({
94
- hookName: 'resolveName',
95
- parameters: [params.name],
96
- }).result
97
- }
98
-
99
- load = async (id: string) => {
100
- return this.hookFirst({
101
- hookName: 'load',
102
- parameters: [id],
103
- })
104
- }
105
-
106
- /**
107
- *
108
- * Run only hook for a specific plugin name
109
- */
110
- hookForPlugin<H extends PluginLifecycleHooks>({
111
- pluginName,
112
- hookName,
113
- parameters,
114
- }: {
115
- pluginName: string
116
- hookName: H
117
- parameters: Parameters<PluginLifecycle[H]>
118
- }): Promise<ReturnType<ParseResult<H>> | null> | null {
119
- const plugin = this.getPlugin(hookName, pluginName)
120
-
121
- return this.execute({
122
- strategy: 'hookFirst',
123
- hookName,
124
- parameters,
125
- plugin,
126
- })
127
- }
128
-
129
- hookForPluginSync<H extends PluginLifecycleHooks>({
130
- pluginName,
131
- hookName,
132
- parameters,
133
- }: {
134
- pluginName: string
135
- hookName: H
136
- parameters: Parameters<PluginLifecycle[H]>
137
- }): ReturnType<ParseResult<H>> | null {
138
- const plugin = this.getPlugin(hookName, pluginName)
139
-
140
- return this.executeSync({
141
- strategy: 'hookFirst',
142
- hookName,
143
- parameters,
144
- plugin,
145
- })
146
- }
147
-
148
- /**
149
- *
150
- * Chains, first non-null result stops and returns
151
- */
152
- hookFirst<H extends PluginLifecycleHooks>({
153
- hookName,
154
- parameters,
155
- skipped,
156
- }: {
157
- hookName: H
158
- parameters: Parameters<PluginLifecycle[H]>
159
- skipped?: ReadonlySet<KubbPlugin> | null
160
- }): Promise<SafeParseResult<H>> {
161
- let promise: Promise<SafeParseResult<H>> = Promise.resolve(null as unknown as SafeParseResult<H>)
162
-
163
- for (const plugin of this.getSortedPlugins(hookName)) {
164
- if (skipped && skipped.has(plugin)) {
165
- continue
166
- }
167
- promise = promise.then(async (parseResult) => {
168
- if (parseResult?.result != null) {
169
- return parseResult
170
- }
171
- const value = await this.execute<H>({
172
- strategy: 'hookFirst',
173
- hookName,
174
- parameters,
175
- plugin,
176
- })
177
-
178
- return Promise.resolve({
179
- plugin,
180
- result: value,
181
- } as typeof parseResult)
182
- })
183
- }
184
-
185
- return promise
186
- }
187
-
188
- /**
189
- *
190
- * Chains, first non-null result stops and returns
191
- */
192
- hookFirstSync<H extends PluginLifecycleHooks>({
193
- hookName,
194
- parameters,
195
- skipped,
196
- }: {
197
- hookName: H
198
- parameters: Parameters<PluginLifecycle[H]>
199
- skipped?: ReadonlySet<KubbPlugin> | null
200
- }): SafeParseResult<H> {
201
- let parseResult: SafeParseResult<H> = null as unknown as SafeParseResult<H>
202
-
203
- for (const plugin of this.getSortedPlugins(hookName)) {
204
- if (skipped && skipped.has(plugin)) {
205
- continue
206
- }
207
-
208
- parseResult = {
209
- result: this.executeSync<H>({
210
- strategy: 'hookFirst',
211
- hookName,
212
- parameters,
213
- plugin,
214
- }),
215
- plugin,
216
- } as SafeParseResult<H>
217
-
218
- if (parseResult?.result != null) {
219
- break
220
- }
221
- }
222
- return parseResult
223
- }
224
-
225
- /**
226
- *
227
- * Parallel, runs all plugins
228
- */
229
- async hookParallel<H extends PluginLifecycleHooks, TOuput = void>({
230
- hookName,
231
- parameters,
232
- }: {
233
- hookName: H
234
- parameters?: Parameters<PluginLifecycle[H]> | undefined
235
- }): Promise<Awaited<TOuput>[]> {
236
- const parallelPromises: Promise<TOuput>[] = []
237
-
238
- for (const plugin of this.getSortedPlugins(hookName)) {
239
- // TODO implement sequential with `buildStart` as an object({ sequential: boolean; handler: PluginContext["buildStart"] })
240
- // if ((plugin[hookName] as { sequential?: boolean })?.sequential) {
241
- // await Promise.all(parallelPromises)
242
- // parallelPromises.length = 0
243
- // await this.execute({
244
- // strategy: 'hookParallel',
245
- // hookName,
246
- // parameters,
247
- // plugin,
248
- // })
249
- // }
250
- const promise: Promise<TOuput> | null = this.execute({ strategy: 'hookParallel', hookName, parameters, plugin })
251
-
252
- if (promise) {
253
- parallelPromises.push(promise)
254
- }
255
- }
256
- const results = await Promise.allSettled(parallelPromises)
257
- const errors = results.filter((result) => result.status === 'rejected').map((result) => (result as PromiseRejectedResult).reason) as PluginError[]
258
-
259
- if (errors.length) {
260
- throw new ParallelPluginError('Error', { errors, pluginManager: this })
261
- }
262
-
263
- return results.filter((result) => result.status === 'fulfilled').map((result) => (result as PromiseFulfilledResult<Awaited<TOuput>>).value)
264
- }
265
-
266
- /**
267
- *
268
- * Chains, reduces returned value, handling the reduced value as the first hook argument
269
- */
270
- hookReduceArg0<H extends PluginLifecycleHooks>({
271
- hookName,
272
- parameters,
273
- reduce,
274
- }: {
275
- hookName: H
276
- parameters: Parameters<PluginLifecycle[H]>
277
- reduce: (reduction: Argument0<H>, result: ReturnType<ParseResult<H>>, plugin: KubbPlugin) => MaybePromise<Argument0<H> | null>
278
- }): Promise<Argument0<H>> {
279
- const [argument0, ...rest] = parameters
280
-
281
- let promise: Promise<Argument0<H>> = Promise.resolve(argument0)
282
- for (const plugin of this.getSortedPlugins(hookName)) {
283
- promise = promise
284
- .then((arg0) => {
285
- const value = this.execute({
286
- strategy: 'hookReduceArg0',
287
- hookName,
288
- parameters: [arg0, ...rest] as Parameters<PluginLifecycle[H]>,
289
- plugin,
290
- })
291
- return value
292
- })
293
- .then((result) => reduce.call(this.core.api, argument0, result as ReturnType<ParseResult<H>>, plugin)) as Promise<Argument0<H>>
294
- }
295
- return promise
296
- }
297
-
298
- /**
299
- * Chains plugins
300
- */
301
- hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: { hookName: H; parameters?: Parameters<PluginLifecycle[H]> }) {
302
- let promise: Promise<void | null> = Promise.resolve()
303
- for (const plugin of this.getSortedPlugins(hookName)) {
304
- promise = promise.then(() =>
305
- this.execute({
306
- strategy: 'hookSeq',
307
- hookName,
308
- parameters,
309
- plugin,
310
- })
311
- )
312
- }
313
- return promise.then(noReturn)
314
- }
315
-
316
- private getSortedPlugins(_hookName: keyof PluginLifecycle): KubbPlugin[] {
317
- const plugins = [...this.plugins].filter((plugin) => plugin.name !== 'core')
318
-
319
- return plugins
320
- }
321
-
322
- public getPlugin(hookName: keyof PluginLifecycle, pluginName: string): KubbPlugin {
323
- const plugins = [...this.plugins]
324
-
325
- const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName])
326
- if (!pluginByPluginName) {
327
- // fallback on the core plugin when there is no match
328
-
329
- return this.core
330
- }
331
- return pluginByPluginName
332
- }
333
-
334
- private addExecuter(executer: Executer | undefined) {
335
- this.onExecute?.call(this, executer)
336
-
337
- if (executer) {
338
- this.executed.push(executer)
339
- }
340
- }
341
-
342
- /**
343
- * Run an async plugin hook and return the result.
344
- * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.
345
- * @param args Arguments passed to the plugin hook.
346
- * @param plugin The actual pluginObject to run.
347
- */
348
- // Implementation signature
349
- private execute<H extends PluginLifecycleHooks, TResult = void>({
350
- strategy,
351
- hookName,
352
- parameters,
353
- plugin,
354
- }: {
355
- strategy: Strategy
356
- hookName: H
357
- parameters: unknown[] | undefined
358
- plugin: KubbPlugin
359
- }): Promise<TResult> | null {
360
- const hook = plugin[hookName]
361
-
362
- if (!hook) {
363
- return null
364
- }
365
-
366
- return Promise.resolve()
367
- .then(() => {
368
- // add current execution to the variable `this.executer` so we can track which plugin is getting called
369
- this.executer = {
370
- strategy,
371
- hookName,
372
- plugin,
373
- }
374
-
375
- if (typeof hook === 'function') {
376
- const hookResult = (hook as Function).apply(this.core.api, parameters) as TResult
377
-
378
- if (isPromise(hookResult)) {
379
- return Promise.resolve(hookResult).then((result: TResult) => {
380
- this.addExecuter({
381
- strategy,
382
- hookName,
383
- plugin,
384
- })
385
-
386
- return result
387
- })
388
- }
389
-
390
- return hookResult
391
- }
392
-
393
- this.addExecuter({
394
- strategy,
395
- hookName,
396
- plugin,
397
- })
398
-
399
- return hook
400
- })
401
- .catch((e: Error) => {
402
- this.catcher<H>(e, plugin, hookName)
403
- }) as Promise<TResult>
404
- }
405
-
406
- /**
407
- * Run a sync plugin hook and return the result.
408
- * @param hookName Name of the plugin hook. Must be in `PluginHooks`.
409
- * @param args Arguments passed to the plugin hook.
410
- * @param plugin The acutal plugin
411
- * @param replaceContext When passed, the plugin context can be overridden.
412
- */
413
- private executeSync<H extends PluginLifecycleHooks>({
414
- strategy,
415
- hookName,
416
- parameters,
417
- plugin,
418
- }: {
419
- strategy: Strategy
420
- hookName: H
421
- parameters: Parameters<PluginLifecycle[H]>
422
- plugin: KubbPlugin
423
- }): ReturnType<ParseResult<H>> | null {
424
- const hook = plugin[hookName]
425
-
426
- if (!hook) {
427
- return null
428
- }
429
-
430
- try {
431
- // add current execution to the variable `this.executer` so we can track which plugin is getting called
432
- this.executer = {
433
- strategy,
434
- hookName,
435
- plugin,
436
- }
437
-
438
- if (typeof hook === 'function') {
439
- const fn = (hook as Function).apply(this.core.api, parameters) as ReturnType<ParseResult<H>>
440
-
441
- this.addExecuter({
442
- strategy,
443
- hookName,
444
- plugin,
445
- })
446
-
447
- return fn
448
- }
449
-
450
- this.addExecuter({
451
- strategy,
452
- hookName,
453
- plugin,
454
- })
455
-
456
- return hook
457
- } catch (e) {
458
- this.catcher<H>(e as Error, plugin, hookName)
459
-
460
- return null as ReturnType<ParseResult<H>>
461
- }
462
- }
463
-
464
- private catcher<H extends PluginLifecycleHooks>(e: Error, plugin: KubbPlugin, hookName: H) {
465
- const text = `${e.message} (plugin: ${plugin.name}, hook: ${hookName})\n`
466
-
467
- throw new PluginError(text, { cause: e, pluginManager: this })
468
- }
469
- }
470
-
471
- // eslint-disable-next-line @typescript-eslint/no-empty-function
472
- function noReturn() {}