@kubb/core 1.0.0 → 1.0.2

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.
@@ -1,15 +1,19 @@
1
+ /* eslint-disable @typescript-eslint/ban-types */
1
2
  /* eslint-disable no-await-in-loop */
2
3
  /* eslint-disable no-restricted-syntax */
3
4
 
4
- import { definePlugin } from '../../plugin'
5
- import { FileManager } from '../fileManager'
6
- import { Queue } from '../../utils/Queue'
5
+ import { PluginError } from './PluginError.ts'
6
+ import { ParallelPluginError } from './ParallelPluginError.ts'
7
7
 
8
- import type { QueueTask } from '../../utils/Queue'
9
- import type { Argument0, Strategy } from './types'
10
- import type { KubbConfig, KubbPlugin, PluginLifecycleHooks, PluginLifecycle, MaybePromise, ResolvePathParams, ResolveNameParams } from '../../types'
11
- import type { Logger } from '../../build'
12
- import type { CorePluginOptions } from '../../plugin'
8
+ import { definePlugin } from '../../plugin.ts'
9
+ import { FileManager } from '../fileManager/FileManager.ts'
10
+ import { Queue } from '../../utils/Queue.ts'
11
+ import { isPromise } from '../../utils/isPromise.ts'
12
+
13
+ import type { QueueTask } from '../../utils/Queue.ts'
14
+ import type { Argument0, Strategy, Executer, OnExecute } from './types.ts'
15
+ import type { KubbConfig, KubbPlugin, PluginLifecycleHooks, PluginLifecycle, MaybePromise, ResolvePathParams, ResolveNameParams } from '../../types.ts'
16
+ import type { CorePluginOptions } from '../../plugin.ts'
13
17
 
14
18
  // inspired by: https://github.com/rollup/rollup/blob/master/src/utils/PluginDriver.ts#
15
19
 
@@ -28,22 +32,25 @@ const hookNames: {
28
32
  }
29
33
  export const hooks = Object.keys(hookNames) as [PluginLifecycleHooks]
30
34
 
35
+ type Options = { task: QueueTask; onExecute?: OnExecute<PluginLifecycleHooks> }
36
+
31
37
  export class PluginManager {
32
38
  public plugins: KubbPlugin[]
33
39
 
34
40
  public readonly fileManager: FileManager
35
41
 
36
- private readonly logger?: Logger
37
-
38
- private readonly config: KubbConfig
42
+ private readonly onExecute?: OnExecute
39
43
 
40
44
  public readonly core: KubbPlugin<CorePluginOptions>
41
45
 
42
46
  public queue: Queue
43
47
 
44
- constructor(config: KubbConfig, options: { logger?: Logger; task: QueueTask }) {
45
- this.logger = options.logger
46
- this.config = config
48
+ public executer: Executer | undefined
49
+
50
+ public executed: Executer[] = []
51
+
52
+ constructor(config: KubbConfig, options: Options) {
53
+ this.onExecute = options.onExecute
47
54
  this.queue = new Queue(10)
48
55
 
49
56
  this.fileManager = new FileManager({ task: options.task, queue: this.queue })
@@ -53,12 +60,17 @@ export class PluginManager {
53
60
  load: this.load,
54
61
  resolvePath: this.resolvePath,
55
62
  resolveName: this.resolveName,
63
+ getExecuter: this.getExecuter.bind(this),
56
64
  }) as KubbPlugin<CorePluginOptions> & {
57
65
  api: CorePluginOptions['api']
58
66
  }
59
67
  this.plugins = [this.core, ...(config.plugins || [])]
60
68
  }
61
69
 
70
+ getExecuter() {
71
+ return this.executer
72
+ }
73
+
62
74
  resolvePath = (params: ResolvePathParams) => {
63
75
  if (params.pluginName) {
64
76
  return this.hookForPluginSync({
@@ -106,10 +118,10 @@ export class PluginManager {
106
118
  pluginName: string
107
119
  hookName: H
108
120
  parameters: Parameters<PluginLifecycle[H]>
109
- }): Promise<ReturnType<PluginLifecycle[H]> | null> {
121
+ }): Promise<ReturnType<PluginLifecycle[H]> | null> | null {
110
122
  const plugin = this.getPlugin(hookName, pluginName)
111
123
 
112
- return this.run({
124
+ return this.execute({
113
125
  strategy: 'hookFirst',
114
126
  hookName,
115
127
  parameters,
@@ -125,10 +137,10 @@ export class PluginManager {
125
137
  pluginName: string
126
138
  hookName: H
127
139
  parameters: Parameters<PluginLifecycle[H]>
128
- }): ReturnType<PluginLifecycle[H]> {
140
+ }): ReturnType<PluginLifecycle[H]> | null {
129
141
  const plugin = this.getPlugin(hookName, pluginName)
130
142
 
131
- return this.runSync({
143
+ return this.executeSync({
132
144
  strategy: 'hookFirst',
133
145
  hookName,
134
146
  parameters,
@@ -154,7 +166,7 @@ export class PluginManager {
154
166
  if (skipped && skipped.has(plugin)) continue
155
167
  promise = promise.then((result) => {
156
168
  if (result != null) return result
157
- return this.run({
169
+ return this.execute({
158
170
  strategy: 'hookFirst',
159
171
  hookName,
160
172
  parameters,
@@ -183,7 +195,7 @@ export class PluginManager {
183
195
  for (const plugin of this.getSortedPlugins(hookName)) {
184
196
  if (skipped && skipped.has(plugin)) continue
185
197
 
186
- result = this.runSync<H>({
198
+ result = this.executeSync<H>({
187
199
  strategy: 'hookFirst',
188
200
  hookName,
189
201
  parameters,
@@ -211,19 +223,28 @@ export class PluginManager {
211
223
  if ((plugin[hookName] as { sequential?: boolean })?.sequential) {
212
224
  await Promise.all(parallelPromises)
213
225
  parallelPromises.length = 0
214
- await this.run({
226
+ await this.execute({
215
227
  strategy: 'hookParallel',
216
228
  hookName,
217
229
  parameters,
218
230
  plugin,
219
231
  })
220
232
  } else {
221
- const promise: Promise<TOuput> = this.run({ strategy: 'hookParallel', hookName, parameters, plugin })
233
+ const promise: Promise<TOuput> | null = this.execute({ strategy: 'hookParallel', hookName, parameters, plugin })
222
234
 
223
- parallelPromises.push(promise)
235
+ if (promise) {
236
+ parallelPromises.push(promise)
237
+ }
224
238
  }
225
239
  }
226
- return Promise.all(parallelPromises)
240
+ const results = await Promise.allSettled(parallelPromises)
241
+ const errors = results.filter((result) => result.status === 'rejected').map((result) => (result as PromiseRejectedResult).reason) as PluginError[]
242
+
243
+ if (errors.length) {
244
+ throw new ParallelPluginError('Error', { errors, pluginManager: this })
245
+ }
246
+
247
+ return results.filter((result) => result.status === 'fulfilled').map((result) => (result as PromiseFulfilledResult<Awaited<TOuput>>).value)
227
248
  }
228
249
 
229
250
  // chains, reduces returned value, handling the reduced value as the first hook argument
@@ -240,14 +261,17 @@ export class PluginManager {
240
261
 
241
262
  let promise: Promise<Argument0<H>> = Promise.resolve(argument0)
242
263
  for (const plugin of this.getSortedPlugins(hookName)) {
243
- promise = promise.then((argument0) =>
244
- this.run({
245
- strategy: 'hookReduceArg0',
246
- hookName,
247
- parameters: [argument0, ...rest] as Parameters<PluginLifecycle[H]>,
248
- plugin,
249
- }).then((result) => reduce.call(this.core.api, argument0, result as ReturnType<PluginLifecycle[H]>, plugin))
250
- ) as Promise<Argument0<H>>
264
+ promise = promise
265
+ .then((argument0) => {
266
+ const value = this.execute({
267
+ strategy: 'hookReduceArg0',
268
+ hookName,
269
+ parameters: [argument0, ...rest] as Parameters<PluginLifecycle[H]>,
270
+ plugin,
271
+ })
272
+ return value
273
+ })
274
+ .then((result) => reduce.call(this.core.api, argument0, result as ReturnType<PluginLifecycle[H]>, plugin)) as Promise<Argument0<H>>
251
275
  }
252
276
  return promise
253
277
  }
@@ -255,10 +279,10 @@ export class PluginManager {
255
279
  // chains
256
280
 
257
281
  hookSeq<H extends PluginLifecycleHooks>({ hookName, parameters }: { hookName: H; parameters?: Parameters<PluginLifecycle[H]> }) {
258
- let promise: Promise<void> = Promise.resolve()
282
+ let promise: Promise<void | null> = Promise.resolve()
259
283
  for (const plugin of this.getSortedPlugins(hookName)) {
260
284
  promise = promise.then(() =>
261
- this.run({
285
+ this.execute({
262
286
  strategy: 'hookSeq',
263
287
  hookName,
264
288
  parameters,
@@ -281,14 +305,20 @@ export class PluginManager {
281
305
  const pluginByPluginName = plugins.find((item) => item.name === pluginName && item[hookName])
282
306
  if (!pluginByPluginName) {
283
307
  // fallback on the core plugin when there is no match
284
- if (this.config.logLevel === 'warn' && this.logger?.spinner) {
285
- this.logger.spinner.info(`Plugin hook with ${hookName} not found for plugin ${pluginName}`)
286
- }
308
+
287
309
  return this.core
288
310
  }
289
311
  return pluginByPluginName
290
312
  }
291
313
 
314
+ private addExecuter(executer: Executer | undefined) {
315
+ this.onExecute?.call(this, executer)
316
+
317
+ if (executer) {
318
+ this.executed.push(executer)
319
+ }
320
+ }
321
+
292
322
  /**
293
323
  * Run an async plugin hook and return the result.
294
324
  * @param hookName Name of the plugin hook. Must be either in `PluginHooks` or `OutputPluginValueHooks`.
@@ -296,7 +326,7 @@ export class PluginManager {
296
326
  * @param plugin The actual pluginObject to run.
297
327
  */
298
328
  // Implementation signature
299
- private run<H extends PluginLifecycleHooks, TResult = void>({
329
+ private execute<H extends PluginLifecycleHooks, TResult = void>({
300
330
  strategy,
301
331
  hookName,
302
332
  parameters,
@@ -306,36 +336,47 @@ export class PluginManager {
306
336
  hookName: H
307
337
  parameters: unknown[] | undefined
308
338
  plugin: KubbPlugin
309
- }): Promise<TResult> {
310
- const hook = plugin[hookName]!
339
+ }): Promise<TResult> | null {
340
+ const hook = plugin[hookName]
341
+
342
+ if (!hook) {
343
+ return null
344
+ }
311
345
 
312
346
  return Promise.resolve()
313
347
  .then(() => {
314
- if (typeof hook !== 'function') {
315
- return hook
348
+ // add current execution to the variable `this.executer` so we can track which plugin is getting called
349
+ this.executer = {
350
+ strategy,
351
+ hookName,
352
+ plugin,
316
353
  }
317
354
 
318
- if (this.config.logLevel === 'info' && this.logger?.spinner) {
319
- this.logger.spinner.text = `[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \n`
320
- }
355
+ if (typeof hook === 'function') {
356
+ const hookResult = (hook as Function).apply(this.core.api, parameters)
321
357
 
322
- const hookResult = (hook as Function).apply(this.core.api, parameters)
358
+ if (isPromise(hookResult)) {
359
+ return Promise.resolve(hookResult).then((result) => {
360
+ this.addExecuter({
361
+ strategy,
362
+ hookName,
363
+ plugin,
364
+ })
323
365
 
324
- if (!(hookResult as Promise<unknown>)?.then) {
325
- // short circuit for non-thenables and non-Promises
326
- if (this.config.logLevel === 'info' && this.logger?.spinner) {
327
- this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \n`)
366
+ return result
367
+ })
328
368
  }
369
+
329
370
  return hookResult
330
371
  }
331
372
 
332
- return Promise.resolve(hookResult).then((result) => {
333
- // action was fulfilled
334
- if (this.config.logLevel === 'info' && this.logger?.spinner) {
335
- this.logger.spinner.succeed(`[${strategy}] ${hookName}: Excecuting task for plugin ${plugin.name} \n`)
336
- }
337
- return result
373
+ this.addExecuter({
374
+ strategy,
375
+ hookName,
376
+ plugin,
338
377
  })
378
+
379
+ return hook
339
380
  })
340
381
  .catch((e: Error) => {
341
382
  this.catcher<H>(e, plugin, hookName)
@@ -349,7 +390,7 @@ export class PluginManager {
349
390
  * @param plugin The acutal plugin
350
391
  * @param replaceContext When passed, the plugin context can be overridden.
351
392
  */
352
- private runSync<H extends PluginLifecycleHooks>({
393
+ private executeSync<H extends PluginLifecycleHooks>({
353
394
  strategy,
354
395
  hookName,
355
396
  parameters,
@@ -359,20 +400,44 @@ export class PluginManager {
359
400
  hookName: H
360
401
  parameters: Parameters<PluginLifecycle[H]>
361
402
  plugin: KubbPlugin
362
- }): ReturnType<PluginLifecycle[H]> {
363
- const hook = plugin[hookName]!
403
+ }): ReturnType<PluginLifecycle[H]> | null {
404
+ const hook = plugin[hookName]
364
405
 
365
- // const context = this.pluginContexts.get(plugin)!;
406
+ if (!hook) {
407
+ return null
408
+ }
366
409
 
367
410
  try {
411
+ // add current execution to the variable `this.executer` so we can track which plugin is getting called
412
+ this.executer = {
413
+ strategy,
414
+ hookName,
415
+ plugin,
416
+ }
417
+
368
418
  // eslint-disable-next-line @typescript-eslint/ban-types
369
- if (typeof hook !== 'function') {
370
- return hook
419
+ if (typeof hook === 'function') {
420
+ const fn = (hook as Function).apply(this.core.api, parameters)
421
+
422
+ this.addExecuter({
423
+ strategy,
424
+ hookName,
425
+ plugin,
426
+ })
427
+
428
+ return fn
371
429
  }
372
430
 
373
- return (hook as Function).apply(this.core.api, parameters)
431
+ this.addExecuter({
432
+ strategy,
433
+ hookName,
434
+ plugin,
435
+ })
436
+
437
+ return hook
374
438
  } catch (e) {
375
439
  this.catcher<H>(e as Error, plugin, hookName)
440
+
376
441
  return null as ReturnType<PluginLifecycle[H]>
377
442
  }
378
443
  }
@@ -380,7 +445,7 @@ export class PluginManager {
380
445
  private catcher<H extends PluginLifecycleHooks>(e: Error, plugin: KubbPlugin, hookName: H) {
381
446
  const text = `${e.message} (plugin: ${plugin.name}, hook: ${hookName})\n`
382
447
 
383
- throw new Error(text, { cause: e })
448
+ throw new PluginError(text, { cause: e, pluginManager: this })
384
449
  }
385
450
  }
386
451
 
@@ -1,3 +1,5 @@
1
- export * from './PluginManager'
2
- export * from './types'
3
- export * from './validate'
1
+ export * from './PluginManager.ts'
2
+ export * from './types.ts'
3
+ export * from './validate.ts'
4
+ export * from './PluginError.ts'
5
+ export * from './ParallelPluginError.ts'
@@ -1,4 +1,5 @@
1
- import type { PluginLifecycle } from '../../types'
1
+ import type { PluginManager } from './PluginManager.ts'
2
+ import type { KubbPlugin, PluginLifecycle, PluginLifecycleHooks } from '../../types.ts'
2
3
  /**
3
4
  * Get the type of the first argument in a function.
4
5
  * @example Arg0<(a: string, b: number) => void> -> string
@@ -6,3 +7,11 @@ import type { PluginLifecycle } from '../../types'
6
7
  export type Argument0<H extends keyof PluginLifecycle> = Parameters<PluginLifecycle[H]>[0]
7
8
 
8
9
  export type Strategy = 'hookFirst' | 'hookForPlugin' | 'hookParallel' | 'hookReduceArg0' | 'hookSeq'
10
+
11
+ export type Executer<H extends PluginLifecycleHooks = PluginLifecycleHooks> = {
12
+ strategy: Strategy
13
+ hookName: H
14
+ plugin: KubbPlugin
15
+ }
16
+
17
+ export type OnExecute<H extends PluginLifecycleHooks = PluginLifecycleHooks> = (this: PluginManager, executer: Executer<H> | undefined) => void
@@ -1,4 +1,4 @@
1
- import type { KubbPlugin } from '../../types'
1
+ import type { KubbPlugin } from '../../types.ts'
2
2
 
3
3
  export class ValidationPluginError extends Error {}
4
4
 
package/src/plugin.ts CHANGED
@@ -1,9 +1,10 @@
1
- import pathParser from 'path'
1
+ import pathParser from 'node:path'
2
2
 
3
- import { createPluginCache, transformReservedWord } from './utils'
3
+ import { createPluginCache, getStackTrace, transformReservedWord } from './utils/index.ts'
4
4
 
5
- import type { FileManager } from './managers/fileManager'
6
- import type { PluginContext, KubbPlugin, PluginFactoryOptions } from './types'
5
+ import type { Executer } from './managers/index.ts'
6
+ import type { FileManager } from './managers/fileManager/FileManager.ts'
7
+ import type { PluginContext, KubbPlugin, PluginFactoryOptions, PluginLifecycleHooks } from './types.ts'
7
8
 
8
9
  type KubbPluginFactory<T extends PluginFactoryOptions = PluginFactoryOptions> = (
9
10
  options: T['options']
@@ -33,6 +34,7 @@ type Options = {
33
34
  resolvePath: PluginContext['resolvePath']
34
35
  resolveName: PluginContext['resolveName']
35
36
  load: PluginContext['load']
37
+ getExecuter: () => Executer<PluginLifecycleHooks> | undefined
36
38
  }
37
39
 
38
40
  // not publicly exported
@@ -49,7 +51,34 @@ export const definePlugin = createPlugin<CorePluginOptions>((options) => {
49
51
  },
50
52
  fileManager,
51
53
  async addFile(...files) {
52
- return Promise.all(files.map((file) => (file.override ? fileManager.add(file) : fileManager.addOrAppend(file))))
54
+ // TODO unstable, based on stack trace and name of the file(can be different)
55
+ const trace = getStackTrace()
56
+ const plugins = options.config.plugins
57
+ ?.filter((plugin) => trace[1].getFileName()?.includes(plugin.name))
58
+ .sort((a, b) => {
59
+ if (a.name.length < b.name.length) return 1
60
+ if (a.name.length > b.name.length) return -1
61
+ return 0
62
+ })
63
+ const pluginName = plugins?.[0].name
64
+
65
+ return Promise.all(
66
+ files.map((file) => {
67
+ const fileWithMeta = {
68
+ ...file,
69
+ meta: {
70
+ ...(file.meta || {}),
71
+ pluginName,
72
+ },
73
+ }
74
+
75
+ if (file.override) {
76
+ return fileManager.add(fileWithMeta)
77
+ }
78
+
79
+ return fileManager.addOrAppend(fileWithMeta)
80
+ })
81
+ )
53
82
  },
54
83
  resolvePath,
55
84
  resolveName: (params) => {
package/src/types.ts CHANGED
@@ -1,11 +1,20 @@
1
1
  /* eslint-disable @typescript-eslint/no-empty-interface */
2
- import type { FileManager, File } from './managers/fileManager'
3
- import type { Cache } from './utils/cache'
2
+ import type { PluginManager } from './managers/index.ts'
3
+ import type { FileManager, File } from './managers/fileManager/index.ts'
4
+ import type { Cache } from './utils/cache.ts'
4
5
 
5
6
  export interface Register {}
6
7
 
7
8
  export type MaybePromise<T> = Promise<T> | T
8
9
 
10
+ /**
11
+ * Config used in `kubb.config.js`
12
+ *
13
+ * @example import { defineConfig } from '@kubb/core'
14
+ * export default defineConfig({
15
+ * ...
16
+ * })
17
+ */
9
18
  export type KubbUserConfig = Omit<KubbConfig, 'root' | 'plugins'> & {
10
19
  /**
11
20
  * Project root directory. Can be an absolute path, or a path relative from
@@ -76,9 +85,27 @@ export type KubbConfig = {
76
85
  }
77
86
 
78
87
  export type CLIOptions = {
88
+ /**
89
+ * Path to `kubb.config.js`
90
+ */
79
91
  config?: string
92
+ /**
93
+ * Enable debug mode
94
+ */
80
95
  debug?: boolean
96
+ /**
97
+ * Watch changes on input
98
+ */
81
99
  watch?: string
100
+ /**
101
+ * Override input defined in `kubb.config.js`
102
+ */
103
+ input?: string
104
+ }
105
+
106
+ export type BuildOutput = {
107
+ files: FileManager['files']
108
+ pluginManager: PluginManager
82
109
  }
83
110
 
84
111
  // plugin
@@ -109,7 +136,7 @@ export type KubbPlugin<TOptions extends PluginFactoryOptions = PluginFactoryOpti
109
136
  */
110
137
  api?: TOptions['api']
111
138
  /**
112
- * Options set for a specific plugin(see kubb.config.ts)
139
+ * Options set for a specific plugin(see kubb.config.js)
113
140
  */
114
141
  options?: TOptions['options']
115
142
  } & Partial<PluginLifecycle<TOptions>>
@@ -200,7 +227,7 @@ export type PluginContext<TOptions = Record<string, any>> = {
200
227
  fileManager: FileManager
201
228
  addFile: (...file: File[]) => Promise<File[]>
202
229
  resolvePath: (params: ResolvePathParams<TOptions>) => OptionalPath
203
- resolveName: (params: ResolveNameParams) => string
230
+ resolveName: (params: ResolveNameParams) => string | null | undefined
204
231
  load: (id: string) => MaybePromise<TransformResult | void>
205
232
  }
206
233
 
@@ -1,13 +1,5 @@
1
- import rimraf from 'rimraf'
1
+ import { rimraf } from 'rimraf'
2
2
 
3
3
  export async function clean(path: string) {
4
- return new Promise((resolve, reject) => {
5
- rimraf(path, (err) => {
6
- if (err) {
7
- reject(err)
8
- } else {
9
- resolve(true)
10
- }
11
- })
12
- })
4
+ return rimraf(path)
13
5
  }
@@ -0,0 +1,19 @@
1
+ // eslint-disable-next-line @typescript-eslint/ban-types, no-undef
2
+ export function getStackTrace(belowFn?: Function): NodeJS.CallSite[] {
3
+ const oldLimit = Error.stackTraceLimit
4
+ Error.stackTraceLimit = Infinity
5
+
6
+ const dummyObject = {} as any
7
+
8
+ const v8Handler = Error.prepareStackTrace
9
+ Error.prepareStackTrace = function prepareStackTrace(dummyObject, v8StackTrace) {
10
+ return v8StackTrace
11
+ }
12
+ Error.captureStackTrace(dummyObject, belowFn || getStackTrace)
13
+
14
+ const v8StackTrace = dummyObject.stack
15
+ Error.prepareStackTrace = v8Handler
16
+ Error.stackTraceLimit = oldLimit
17
+
18
+ return v8StackTrace
19
+ }
@@ -1,16 +1,17 @@
1
- export * from './isPromise'
2
- export * from './write'
3
- export * from './cache'
4
- export * from './read'
5
- export * from './isURL'
6
- export * from './objectToParameters'
7
- export * from './nameSorter'
8
- export * from './jsdoc'
9
- export * from './getUniqueName'
10
- export * from './timeout'
11
- export * from './Queue'
12
- export * from './getEncodedText'
13
- export * from './renderTemplate'
14
- export * from './clean'
15
- export * from './TreeNode'
16
- export * from './transformReservedWord'
1
+ export * from './isPromise.ts'
2
+ export * from './write.ts'
3
+ export * from './cache.ts'
4
+ export * from './read.ts'
5
+ export * from './isURL.ts'
6
+ export * from './objectToParameters.ts'
7
+ export * from './nameSorter.ts'
8
+ export * from './jsdoc.ts'
9
+ export * from './getUniqueName.ts'
10
+ export * from './timeout.ts'
11
+ export * from './Queue.ts'
12
+ export * from './getEncodedText.ts'
13
+ export * from './renderTemplate.ts'
14
+ export * from './clean.ts'
15
+ export * from './TreeNode.ts'
16
+ export * from './transformReservedWord.ts'
17
+ export * from './getStackTrace.ts'
@@ -1,4 +1,4 @@
1
- import type { MaybePromise } from '../types'
1
+ import type { MaybePromise } from '../types.ts'
2
2
 
3
3
  export function isPromise<T>(result: MaybePromise<T>): result is Promise<T> {
4
4
  return typeof (result as Promise<unknown>)?.then === 'function'
package/src/utils/read.ts CHANGED
@@ -1,5 +1,5 @@
1
- import pathParser from 'path'
2
- import { promises as fs } from 'fs'
1
+ import pathParser from 'node:path'
2
+ import { promises as fs } from 'node:fs'
3
3
 
4
4
  function slash(path: string) {
5
5
  const isExtendedLengthPath = /^\\\\\?\\/.test(path)
@@ -88,8 +88,8 @@ const reservedWords = [
88
88
  'valueOf',
89
89
  ]
90
90
 
91
- export function transformReservedWord(word: string) {
92
- if (reservedWords.includes(word)) {
91
+ export function transformReservedWord(word?: string | null) {
92
+ if (word && reservedWords.includes(word)) {
93
93
  return `_${word}`
94
94
  }
95
95
 
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable consistent-return */
2
- import { promises as fs } from 'fs'
3
- import pathParser from 'path'
2
+ import { promises as fs } from 'node:fs'
3
+ import pathParser from 'node:path'
4
4
 
5
5
  async function safeWriteFileToPath(path: string, data: string) {
6
6
  // resolve the full path and get just the directory, ignoring the file and extension