@kubb/core 4.32.4 → 4.33.1

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 (85) hide show
  1. package/dist/hooks.d.ts +1 -1
  2. package/dist/index.cjs +1695 -82
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.ts +150 -20
  5. package/dist/index.js +1673 -65
  6. package/dist/index.js.map +1 -1
  7. package/dist/{types-f_no0d7G.d.ts → types-DfjjJb2r.d.ts} +70 -27
  8. package/package.json +3 -24
  9. package/src/BarrelManager.ts +10 -31
  10. package/src/PackageManager.ts +13 -21
  11. package/src/PluginManager.ts +65 -87
  12. package/src/PromiseManager.ts +3 -5
  13. package/src/build.ts +61 -47
  14. package/src/config.ts +1 -1
  15. package/src/constants.ts +60 -0
  16. package/src/errors.ts +1 -14
  17. package/src/index.ts +6 -3
  18. package/src/types.ts +5 -14
  19. package/src/utils/FunctionParams.ts +7 -8
  20. package/src/utils/TreeNode.ts +12 -23
  21. package/src/utils/executeStrategies.ts +5 -3
  22. package/src/utils/formatters.ts +3 -20
  23. package/src/utils/getBarrelFiles.ts +8 -2
  24. package/src/utils/getConfigs.ts +6 -15
  25. package/src/utils/getPlugins.ts +7 -7
  26. package/src/utils/linters.ts +3 -20
  27. package/dist/fs-D4eqq6bR.cjs +0 -103
  28. package/dist/fs-D4eqq6bR.cjs.map +0 -1
  29. package/dist/fs-TVBCPkE-.js +0 -67
  30. package/dist/fs-TVBCPkE-.js.map +0 -1
  31. package/dist/fs.cjs +0 -8
  32. package/dist/fs.d.ts +0 -23
  33. package/dist/fs.js +0 -2
  34. package/dist/packageManager-_7I0WFQU.d.ts +0 -82
  35. package/dist/packageManager-jzjuEj2U.cjs +0 -1103
  36. package/dist/packageManager-jzjuEj2U.cjs.map +0 -1
  37. package/dist/packageManager-wMCQlgd6.js +0 -1024
  38. package/dist/packageManager-wMCQlgd6.js.map +0 -1
  39. package/dist/transformers-BwSpAhvT.js +0 -267
  40. package/dist/transformers-BwSpAhvT.js.map +0 -1
  41. package/dist/transformers-BweFhqh-.cjs +0 -380
  42. package/dist/transformers-BweFhqh-.cjs.map +0 -1
  43. package/dist/transformers.cjs +0 -24
  44. package/dist/transformers.d.ts +0 -108
  45. package/dist/transformers.js +0 -2
  46. package/dist/utils.cjs +0 -430
  47. package/dist/utils.cjs.map +0 -1
  48. package/dist/utils.d.ts +0 -290
  49. package/dist/utils.js +0 -402
  50. package/dist/utils.js.map +0 -1
  51. package/src/BaseGenerator.ts +0 -34
  52. package/src/fs/clean.ts +0 -5
  53. package/src/fs/exists.ts +0 -16
  54. package/src/fs/index.ts +0 -5
  55. package/src/fs/read.ts +0 -13
  56. package/src/fs/utils.ts +0 -32
  57. package/src/fs/write.ts +0 -46
  58. package/src/transformers/casing.ts +0 -62
  59. package/src/transformers/combineCodes.ts +0 -3
  60. package/src/transformers/createJSDocBlockText.ts +0 -9
  61. package/src/transformers/escape.ts +0 -31
  62. package/src/transformers/indent.ts +0 -3
  63. package/src/transformers/index.ts +0 -46
  64. package/src/transformers/nameSorter.ts +0 -9
  65. package/src/transformers/searchAndReplace.ts +0 -25
  66. package/src/transformers/stringify.ts +0 -25
  67. package/src/transformers/toRegExp.ts +0 -22
  68. package/src/transformers/transformReservedWord.ts +0 -106
  69. package/src/transformers/trim.ts +0 -18
  70. package/src/utils/AsyncEventEmitter.ts +0 -48
  71. package/src/utils/Cache.ts +0 -31
  72. package/src/utils/URLPath.ts +0 -146
  73. package/src/utils/buildJSDoc.ts +0 -34
  74. package/src/utils/checkOnlineStatus.ts +0 -40
  75. package/src/utils/formatHrtime.ts +0 -33
  76. package/src/utils/getNestedAccessor.ts +0 -25
  77. package/src/utils/index.ts +0 -26
  78. package/src/utils/packageManager.ts +0 -58
  79. package/src/utils/promise.ts +0 -13
  80. package/src/utils/renderTemplate.ts +0 -31
  81. package/src/utils/serializePluginOptions.ts +0 -29
  82. package/src/utils/timeout.ts +0 -11
  83. package/src/utils/tokenize.ts +0 -23
  84. package/src/utils/types.ts +0 -1
  85. package/src/utils/uniqueName.ts +0 -20
@@ -1,31 +0,0 @@
1
- export class Cache<T> {
2
- #buffer = new Map<string, T>()
3
-
4
- async get(key: string): Promise<T | null> {
5
- return this.#buffer.get(key) ?? null
6
- }
7
-
8
- async set(key: string, value: T): Promise<void> {
9
- this.#buffer.set(key, value)
10
- }
11
-
12
- async delete(key: string): Promise<void> {
13
- this.#buffer.delete(key)
14
- }
15
-
16
- async clear(): Promise<void> {
17
- this.#buffer.clear()
18
- }
19
-
20
- async keys(): Promise<string[]> {
21
- return [...this.#buffer.keys()]
22
- }
23
-
24
- async values(): Promise<T[]> {
25
- return [...this.#buffer.values()]
26
- }
27
-
28
- async flush(): Promise<void> {
29
- // No-op for base cache
30
- }
31
- }
@@ -1,146 +0,0 @@
1
- import { camelCase, isValidVarName } from '../transformers'
2
-
3
- export type URLObject = {
4
- url: string
5
- params?: Record<string, string>
6
- }
7
-
8
- type ObjectOptions = {
9
- type?: 'path' | 'template'
10
- replacer?: (pathParam: string) => string
11
- stringify?: boolean
12
- }
13
-
14
- type Options = {
15
- casing?: 'camelcase'
16
- }
17
-
18
- export class URLPath {
19
- path: string
20
- #options: Options
21
-
22
- constructor(path: string, options: Options = {}) {
23
- this.path = path
24
- this.#options = options
25
-
26
- return this
27
- }
28
-
29
- /**
30
- * Convert Swagger path to URLPath(syntax of Express)
31
- * @example /pet/{petId} => /pet/:petId
32
- */
33
- get URL(): string {
34
- return this.toURLPath()
35
- }
36
- get isURL(): boolean {
37
- try {
38
- const url = new URL(this.path)
39
- if (url?.href) {
40
- return true
41
- }
42
- } catch (_error) {
43
- return false
44
- }
45
- return false
46
- }
47
-
48
- /**
49
- * Convert Swagger path to template literals/ template strings(camelcase)
50
- * @example /pet/{petId} => `/pet/${petId}`
51
- * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
52
- * @example /account/userID => `/account/${userId}`
53
- */
54
- get template(): string {
55
- return this.toTemplateString()
56
- }
57
- get object(): URLObject | string {
58
- return this.toObject()
59
- }
60
- get params(): Record<string, string> | undefined {
61
- return this.getParams()
62
- }
63
-
64
- toObject({ type = 'path', replacer, stringify }: ObjectOptions = {}): URLObject | string {
65
- const object = {
66
- url: type === 'path' ? this.toURLPath() : this.toTemplateString({ replacer }),
67
- params: this.getParams(),
68
- }
69
-
70
- if (stringify) {
71
- if (type === 'template') {
72
- return JSON.stringify(object).replaceAll("'", '').replaceAll(`"`, '')
73
- }
74
-
75
- if (object.params) {
76
- return `{ url: '${object.url}', params: ${JSON.stringify(object.params).replaceAll("'", '').replaceAll(`"`, '')} }`
77
- }
78
-
79
- return `{ url: '${object.url}' }`
80
- }
81
-
82
- return object
83
- }
84
-
85
- /**
86
- * Convert Swagger path to template literals/ template strings(camelcase)
87
- * @example /pet/{petId} => `/pet/${petId}`
88
- * @example /account/monetary-accountID => `/account/${monetaryAccountId}`
89
- * @example /account/userID => `/account/${userId}`
90
- */
91
- toTemplateString({ prefix = '', replacer }: { prefix?: string; replacer?: (pathParam: string) => string } = {}): string {
92
- const regex = /{(\w|-)*}/g
93
- const found = this.path.match(regex)
94
- let newPath = this.path.replaceAll('{', '${')
95
-
96
- if (found) {
97
- newPath = found.reduce((prev, path) => {
98
- const pathWithoutBrackets = path.replaceAll('{', '').replaceAll('}', '')
99
-
100
- let param = isValidVarName(pathWithoutBrackets) ? pathWithoutBrackets : camelCase(pathWithoutBrackets)
101
-
102
- if (this.#options.casing === 'camelcase') {
103
- param = camelCase(param)
104
- }
105
-
106
- return prev.replace(path, `\${${replacer ? replacer(param) : param}}`)
107
- }, this.path)
108
- }
109
-
110
- return `\`${prefix}${newPath}\``
111
- }
112
-
113
- getParams(replacer?: (pathParam: string) => string): Record<string, string> | undefined {
114
- const regex = /{(\w|-)*}/g
115
- const found = this.path.match(regex)
116
-
117
- if (!found) {
118
- return undefined
119
- }
120
-
121
- const params: Record<string, string> = {}
122
- found.forEach((item) => {
123
- item = item.replaceAll('{', '').replaceAll('}', '')
124
-
125
- let param = isValidVarName(item) ? item : camelCase(item)
126
-
127
- if (this.#options.casing === 'camelcase') {
128
- param = camelCase(param)
129
- }
130
-
131
- const key = replacer ? replacer(param) : param
132
-
133
- params[key] = key
134
- }, this.path)
135
-
136
- return params
137
- }
138
-
139
- /**
140
- * Convert Swagger path to URLPath(syntax of Express)
141
- * @example /pet/{petId} => /pet/:petId
142
- */
143
- toURLPath(): string {
144
- return this.path.replaceAll('{', ':').replaceAll('}', '')
145
- }
146
- }
@@ -1,34 +0,0 @@
1
- /**
2
- * Builds a JSDoc comment block with custom indentation.
3
- * @param comments - Array of comment strings to include in the JSDoc block
4
- * @param options - Configuration options for formatting
5
- * @returns Formatted JSDoc string or fallback string if no comments
6
- */
7
- export function buildJSDoc(
8
- comments: Array<string>,
9
- options: {
10
- /**
11
- * String to use for indenting each line of the JSDoc comment
12
- * @default ' * ' (3 spaces + asterisk + space)
13
- */
14
- indent?: string
15
- /**
16
- * String to append after the closing JSDoc tag
17
- * @default '\n ' (newline + 2 spaces)
18
- */
19
- suffix?: string
20
- /**
21
- * String to return when there are no comments
22
- * @default ' ' (2 spaces)
23
- */
24
- fallback?: string
25
- } = {},
26
- ): string {
27
- const { indent = ' * ', suffix = '\n ', fallback = ' ' } = options
28
-
29
- if (comments.length === 0) {
30
- return fallback
31
- }
32
-
33
- return `/**\n${comments.map((c) => `${indent}${c}`).join('\n')}\n */${suffix}`
34
- }
@@ -1,40 +0,0 @@
1
- import dns from 'node:dns'
2
-
3
- /**
4
- * Check if the system has internet connectivity
5
- * Uses DNS lookup to well-known stable domains as a lightweight connectivity test
6
- */
7
- export async function isOnline(): Promise<boolean> {
8
- const testDomains = [
9
- 'dns.google.com', // Google Public DNS
10
- 'cloudflare.com', // Cloudflare
11
- 'one.one.one.one', // Cloudflare DNS
12
- ]
13
-
14
- for (const domain of testDomains) {
15
- try {
16
- await dns.promises.resolve(domain)
17
- return true
18
- } catch {
19
- // Try next domain
20
- }
21
- }
22
-
23
- return false
24
- }
25
-
26
- /**
27
- * Execute a function only if online, otherwise silently skip
28
- */
29
- export async function executeIfOnline<T>(fn: () => Promise<T>): Promise<T | null> {
30
- const online = await isOnline()
31
- if (!online) {
32
- return null
33
- }
34
-
35
- try {
36
- return await fn()
37
- } catch {
38
- return null
39
- }
40
- }
@@ -1,33 +0,0 @@
1
- /**
2
- * Calculates elapsed time in milliseconds from a high-resolution start time.
3
- * Rounds to 2 decimal places to provide sub-millisecond precision without noise.
4
- */
5
- export function getElapsedMs(hrStart: [number, number]): number {
6
- const [seconds, nanoseconds] = process.hrtime(hrStart)
7
- const ms = seconds * 1000 + nanoseconds / 1e6
8
- return Math.round(ms * 100) / 100
9
- }
10
-
11
- /**
12
- * Converts a millisecond duration into a human-readable string.
13
- * Adjusts units (ms, s, m s) based on the magnitude of the duration.
14
- */
15
- export function formatMs(ms: number): string {
16
- if (ms >= 60000) {
17
- const mins = Math.floor(ms / 60000)
18
- const secs = ((ms % 60000) / 1000).toFixed(1)
19
- return `${mins}m ${secs}s`
20
- }
21
-
22
- if (ms >= 1000) {
23
- return `${(ms / 1000).toFixed(2)}s`
24
- }
25
- return `${Math.round(ms).toFixed(0)}ms`
26
- }
27
-
28
- /**
29
- * Convenience helper to get and format elapsed time in one step.
30
- */
31
- export function formatHrtime(hrStart: [number, number]): string {
32
- return formatMs(getElapsedMs(hrStart))
33
- }
@@ -1,25 +0,0 @@
1
- /**
2
- * Converts a param path (string with dot notation or array of strings) to a JavaScript accessor expression.
3
- * @param param - The param path, e.g., 'pagination.next.id' or ['pagination', 'next', 'id']
4
- * @param accessor - The base accessor, e.g., 'lastPage' or 'firstPage'
5
- * @returns A JavaScript accessor expression, e.g., "lastPage?.['pagination']?.['next']?.['id']", or undefined if param is empty
6
- *
7
- * @example
8
- * ```ts
9
- * getNestedAccessor('pagination.next.id', 'lastPage')
10
- * // returns: "lastPage?.['pagination']?.['next']?.['id']"
11
- *
12
- * getNestedAccessor(['pagination', 'next', 'id'], 'lastPage')
13
- * // returns: "lastPage?.['pagination']?.['next']?.['id']"
14
- *
15
- * getNestedAccessor('', 'lastPage')
16
- * // returns: undefined
17
- * ```
18
- */
19
- export function getNestedAccessor(param: string | string[], accessor: string): string | undefined {
20
- const parts = Array.isArray(param) ? param : param.split('.')
21
- if (parts.length === 0 || (parts.length === 1 && parts[0] === '')) {
22
- return undefined
23
- }
24
- return parts.reduce((acc, part) => `${acc}?.['${part}']`, accessor)
25
- }
@@ -1,26 +0,0 @@
1
- export { AsyncEventEmitter } from './AsyncEventEmitter.ts'
2
- export { buildJSDoc } from './buildJSDoc.ts'
3
- export { Cache } from './Cache.ts'
4
- export { executeIfOnline, isOnline } from './checkOnlineStatus.ts'
5
- export type { FunctionParamsAST } from './FunctionParams.ts'
6
- export { FunctionParams } from './FunctionParams.ts'
7
- export { formatHrtime, formatMs, getElapsedMs } from './formatHrtime.ts'
8
- export { detectFormatter, formatters } from './formatters.ts'
9
- export { getBarrelFiles } from './getBarrelFiles.ts'
10
- export { getConfigs } from './getConfigs.ts'
11
- export { getNestedAccessor } from './getNestedAccessor.ts'
12
- export { detectLinter, linters } from './linters.ts'
13
- export type { PackageManagerInfo, PackageManagerName } from './packageManager.ts'
14
- export { detectPackageManager } from './packageManager.ts'
15
- export {
16
- isPromise,
17
- isPromiseFulfilledResult,
18
- isPromiseRejectedResult,
19
- } from './promise.ts'
20
- export { renderTemplate } from './renderTemplate.ts'
21
- export { serializePluginOptions } from './serializePluginOptions.ts'
22
- export { timeout } from './timeout.ts'
23
- export { tokenize } from './tokenize.ts'
24
- export type { URLObject } from './URLPath.ts'
25
- export { URLPath } from './URLPath.ts'
26
- export { getUniqueName, setUniqueName } from './uniqueName.ts'
@@ -1,58 +0,0 @@
1
- import fs from 'node:fs'
2
- import path from 'node:path'
3
-
4
- export type PackageManagerName = 'npm' | 'pnpm' | 'yarn' | 'bun'
5
-
6
- export interface PackageManagerInfo {
7
- name: PackageManagerName
8
- lockFile: string
9
- installCommand: string[]
10
- }
11
-
12
- const packageManagers: Record<PackageManagerName, PackageManagerInfo> = {
13
- pnpm: {
14
- name: 'pnpm',
15
- lockFile: 'pnpm-lock.yaml',
16
- installCommand: ['add', '-D'],
17
- },
18
- yarn: {
19
- name: 'yarn',
20
- lockFile: 'yarn.lock',
21
- installCommand: ['add', '-D'],
22
- },
23
- bun: {
24
- name: 'bun',
25
- lockFile: 'bun.lockb',
26
- installCommand: ['add', '-d'],
27
- },
28
- npm: {
29
- name: 'npm',
30
- lockFile: 'package-lock.json',
31
- installCommand: ['install', '--save-dev'],
32
- },
33
- }
34
-
35
- export function detectPackageManager(cwd: string = process.cwd()): PackageManagerInfo {
36
- const packageJsonPath = path.join(cwd, 'package.json')
37
- if (fs.existsSync(packageJsonPath)) {
38
- try {
39
- const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'))
40
- if (packageJson.packageManager) {
41
- const [name] = packageJson.packageManager.split('@')
42
- if (name in packageManagers) {
43
- return packageManagers[name as PackageManagerName]
44
- }
45
- }
46
- } catch {
47
- // Continue to lock file detection
48
- }
49
- }
50
-
51
- for (const pm of Object.values(packageManagers)) {
52
- if (fs.existsSync(path.join(cwd, pm.lockFile))) {
53
- return pm
54
- }
55
- }
56
-
57
- return packageManagers.npm
58
- }
@@ -1,13 +0,0 @@
1
- import type { PossiblePromise } from './types.ts'
2
-
3
- export function isPromise<T>(result: PossiblePromise<T>): result is Promise<T> {
4
- return !!result && typeof (result as Promise<unknown>)?.then === 'function'
5
- }
6
-
7
- export function isPromiseFulfilledResult<T = unknown>(result: PromiseSettledResult<unknown>): result is PromiseFulfilledResult<T> {
8
- return result.status === 'fulfilled'
9
- }
10
-
11
- export function isPromiseRejectedResult<T>(result: PromiseSettledResult<unknown>): result is Omit<PromiseRejectedResult, 'reason'> & { reason: T } {
12
- return result.status === 'rejected'
13
- }
@@ -1,31 +0,0 @@
1
- export function renderTemplate<TData extends Record<string, unknown> = Record<string, unknown>>(template: string, data: TData | undefined = undefined): string {
2
- if (!data || !Object.keys(data).length) {
3
- return template.replace(/{{(.*?)}}/g, '')
4
- }
5
-
6
- const matches = template.match(/{{(.*?)}}/g)
7
-
8
- return (
9
- matches?.reduce((prev, curr) => {
10
- const index = curr.split(/{{|}}/).filter(Boolean)[0]?.trim()
11
- if (index === undefined) {
12
- return prev
13
- }
14
- const value = data[index]
15
-
16
- if (value === undefined) {
17
- return prev
18
- }
19
-
20
- return prev
21
- .replace(curr, () => {
22
- if (typeof value === 'boolean') {
23
- return `${value.toString()}` || 'false'
24
- }
25
-
26
- return (value as string) || ''
27
- })
28
- .trim()
29
- }, template) || ''
30
- )
31
- }
@@ -1,29 +0,0 @@
1
- /**
2
- * Serialize plugin options for safe JSON transport.
3
- * Strips functions, symbols, and undefined values recursively.
4
- */
5
- export function serializePluginOptions<TOptions extends object = object>(options: TOptions): TOptions {
6
- if (options === null || options === undefined) {
7
- return {} as TOptions
8
- }
9
- if (typeof options !== 'object') {
10
- return options
11
- }
12
- if (Array.isArray(options)) {
13
- return options.map(serializePluginOptions) as TOptions
14
- }
15
-
16
- const serialized: Record<string, unknown> = {}
17
- for (const [key, value] of Object.entries(options)) {
18
- if (typeof value === 'function' || typeof value === 'symbol' || value === undefined) {
19
- continue
20
- }
21
- if (typeof value === 'object' && value !== null) {
22
- serialized[key] = serializePluginOptions(value)
23
- } else {
24
- serialized[key] = value
25
- }
26
- }
27
-
28
- return serialized as TOptions
29
- }
@@ -1,11 +0,0 @@
1
- export async function timeout(ms: number): Promise<unknown> {
2
- return new Promise((resolve) => {
3
- const timeout = setTimeout(() => {
4
- resolve(timeout)
5
- }, ms)
6
- }).then((timeout) => {
7
- clearTimeout(timeout as NodeJS.Timeout)
8
-
9
- return true
10
- })
11
- }
@@ -1,23 +0,0 @@
1
- /** Shell-like tokenizer: splits a command string respecting single/double quotes. */
2
- export function tokenize(command: string): string[] {
3
- const args: string[] = []
4
- let current = ''
5
- let quote = ''
6
- for (const ch of command) {
7
- if (quote) {
8
- if (ch === quote) quote = ''
9
- else current += ch
10
- } else if (ch === '"' || ch === "'") {
11
- quote = ch
12
- } else if (ch === ' ' || ch === '\t') {
13
- if (current) {
14
- args.push(current)
15
- current = ''
16
- }
17
- } else {
18
- current += ch
19
- }
20
- }
21
- if (current) args.push(current)
22
- return args
23
- }
@@ -1 +0,0 @@
1
- export type PossiblePromise<T> = Promise<T> | T
@@ -1,20 +0,0 @@
1
- export function getUniqueName(originalName: string, data: Record<string, number>): string {
2
- let used = data[originalName] || 0
3
- if (used) {
4
- data[originalName] = ++used
5
- originalName += used
6
- }
7
- data[originalName] = 1
8
- return originalName
9
- }
10
-
11
- export function setUniqueName(originalName: string, data: Record<string, number>): string {
12
- let used = data[originalName] || 0
13
- if (used) {
14
- data[originalName] = ++used
15
-
16
- return originalName
17
- }
18
- data[originalName] = 1
19
- return originalName
20
- }