@kubb/core 5.0.0-alpha.5 → 5.0.0-alpha.50
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.
- package/README.md +3 -2
- package/dist/PluginDriver-DtwggkXg.cjs +1082 -0
- package/dist/PluginDriver-DtwggkXg.cjs.map +1 -0
- package/dist/PluginDriver-mXeqWp-U.js +979 -0
- package/dist/PluginDriver-mXeqWp-U.js.map +1 -0
- package/dist/index.cjs +1013 -1829
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +274 -265
- package/dist/index.js +1003 -1799
- package/dist/index.js.map +1 -1
- package/dist/mocks.cjs +138 -0
- package/dist/mocks.cjs.map +1 -0
- package/dist/mocks.d.ts +74 -0
- package/dist/mocks.js +133 -0
- package/dist/mocks.js.map +1 -0
- package/dist/types-DfEv9d_c.d.ts +1721 -0
- package/package.json +51 -57
- package/src/FileManager.ts +133 -0
- package/src/FileProcessor.ts +86 -0
- package/src/Kubb.ts +154 -101
- package/src/PluginDriver.ts +418 -0
- package/src/constants.ts +43 -47
- package/src/createAdapter.ts +25 -0
- package/src/createKubb.ts +614 -0
- package/src/createRenderer.ts +57 -0
- package/src/createStorage.ts +58 -0
- package/src/defineGenerator.ts +88 -100
- package/src/defineLogger.ts +13 -3
- package/src/defineParser.ts +45 -0
- package/src/definePlugin.ts +68 -7
- package/src/defineResolver.ts +501 -0
- package/src/devtools.ts +14 -14
- package/src/index.ts +12 -17
- package/src/mocks.ts +171 -0
- package/src/renderNode.ts +35 -0
- package/src/storages/fsStorage.ts +40 -11
- package/src/storages/memoryStorage.ts +4 -3
- package/src/types.ts +575 -205
- package/src/utils/TreeNode.ts +47 -9
- package/src/utils/diagnostics.ts +4 -1
- package/src/utils/getBarrelFiles.ts +94 -16
- package/src/utils/isInputPath.ts +10 -0
- package/src/utils/packageJSON.ts +99 -0
- package/dist/PluginManager-vZodFEMe.d.ts +0 -1056
- package/dist/chunk-ByKO4r7w.cjs +0 -38
- package/dist/hooks.cjs +0 -60
- package/dist/hooks.cjs.map +0 -1
- package/dist/hooks.d.ts +0 -56
- package/dist/hooks.js +0 -56
- package/dist/hooks.js.map +0 -1
- package/src/BarrelManager.ts +0 -74
- package/src/PackageManager.ts +0 -180
- package/src/PluginManager.ts +0 -667
- package/src/PromiseManager.ts +0 -40
- package/src/build.ts +0 -419
- package/src/config.ts +0 -56
- package/src/defineAdapter.ts +0 -22
- package/src/defineStorage.ts +0 -56
- package/src/errors.ts +0 -1
- package/src/hooks/index.ts +0 -4
- package/src/hooks/useKubb.ts +0 -46
- package/src/hooks/useMode.ts +0 -11
- package/src/hooks/usePlugin.ts +0 -11
- package/src/hooks/usePluginManager.ts +0 -11
- package/src/utils/FunctionParams.ts +0 -155
- package/src/utils/executeStrategies.ts +0 -81
- package/src/utils/formatters.ts +0 -56
- package/src/utils/getConfigs.ts +0 -30
- package/src/utils/getPlugins.ts +0 -23
- package/src/utils/linters.ts +0 -25
- package/src/utils/resolveOptions.ts +0 -93
package/package.json
CHANGED
|
@@ -1,50 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/core",
|
|
3
|
-
"version": "5.0.0-alpha.
|
|
3
|
+
"version": "5.0.0-alpha.50",
|
|
4
4
|
"description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"
|
|
7
|
-
"plugins",
|
|
8
|
-
"plugin-system",
|
|
9
|
-
"plugin-framework",
|
|
6
|
+
"ast",
|
|
10
7
|
"code-generator",
|
|
11
8
|
"codegen",
|
|
12
|
-
"
|
|
9
|
+
"core-library",
|
|
13
10
|
"file-system",
|
|
11
|
+
"kubb",
|
|
12
|
+
"oas",
|
|
14
13
|
"openapi",
|
|
14
|
+
"plugin-framework",
|
|
15
|
+
"plugin-system",
|
|
16
|
+
"plugins",
|
|
15
17
|
"swagger",
|
|
16
|
-
"
|
|
17
|
-
"core-library",
|
|
18
|
-
"kubb"
|
|
18
|
+
"typescript"
|
|
19
19
|
],
|
|
20
|
+
"license": "MIT",
|
|
21
|
+
"author": "stijnvanhulle",
|
|
20
22
|
"repository": {
|
|
21
23
|
"type": "git",
|
|
22
24
|
"url": "git+https://github.com/kubb-labs/kubb.git",
|
|
23
25
|
"directory": "packages/core"
|
|
24
26
|
},
|
|
25
|
-
"license": "MIT",
|
|
26
|
-
"author": "stijnvanhulle",
|
|
27
|
-
"sideEffects": false,
|
|
28
|
-
"type": "module",
|
|
29
|
-
"exports": {
|
|
30
|
-
".": {
|
|
31
|
-
"import": "./dist/index.js",
|
|
32
|
-
"require": "./dist/index.cjs"
|
|
33
|
-
},
|
|
34
|
-
"./hooks": {
|
|
35
|
-
"import": "./dist/hooks.js",
|
|
36
|
-
"require": "./dist/hooks.cjs"
|
|
37
|
-
},
|
|
38
|
-
"./package.json": "./package.json"
|
|
39
|
-
},
|
|
40
|
-
"types": "./dist/index.d.ts",
|
|
41
|
-
"typesVersions": {
|
|
42
|
-
"*": {
|
|
43
|
-
"hooks": [
|
|
44
|
-
"./dist/hooks.d.ts"
|
|
45
|
-
]
|
|
46
|
-
}
|
|
47
|
-
},
|
|
48
27
|
"files": [
|
|
49
28
|
"src",
|
|
50
29
|
"schemas",
|
|
@@ -56,41 +35,56 @@
|
|
|
56
35
|
"!/**/__tests__/**",
|
|
57
36
|
"!/**/__snapshots__/**"
|
|
58
37
|
],
|
|
59
|
-
"
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
38
|
+
"type": "module",
|
|
39
|
+
"sideEffects": false,
|
|
40
|
+
"main": "./dist/index.cjs",
|
|
41
|
+
"module": "./dist/index.js",
|
|
42
|
+
"types": "./dist/index.d.ts",
|
|
43
|
+
"typesVersions": {
|
|
44
|
+
"*": {
|
|
45
|
+
"mocks": [
|
|
46
|
+
"./dist/mocks.d.ts"
|
|
47
|
+
]
|
|
64
48
|
}
|
|
65
|
-
|
|
49
|
+
},
|
|
50
|
+
"exports": {
|
|
51
|
+
".": {
|
|
52
|
+
"import": "./dist/index.js",
|
|
53
|
+
"require": "./dist/index.cjs"
|
|
54
|
+
},
|
|
55
|
+
"./mocks": {
|
|
56
|
+
"import": "./dist/mocks.js",
|
|
57
|
+
"require": "./dist/mocks.cjs"
|
|
58
|
+
},
|
|
59
|
+
"./package.json": "./package.json"
|
|
60
|
+
},
|
|
61
|
+
"publishConfig": {
|
|
62
|
+
"access": "public",
|
|
63
|
+
"registry": "https://registry.npmjs.org/"
|
|
64
|
+
},
|
|
66
65
|
"dependencies": {
|
|
67
|
-
"@kubb/fabric-core": "0.14.0",
|
|
68
|
-
"@kubb/react-fabric": "0.14.0",
|
|
69
|
-
"empathic": "^2.0.0",
|
|
70
66
|
"fflate": "^0.8.2",
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"tinyexec": "^1.0.4",
|
|
74
|
-
"@kubb/ast": "5.0.0-alpha.5"
|
|
67
|
+
"tinyexec": "^1.1.1",
|
|
68
|
+
"@kubb/ast": "5.0.0-alpha.50"
|
|
75
69
|
},
|
|
76
70
|
"devDependencies": {
|
|
77
|
-
"@types/semver": "^7.7.1",
|
|
78
71
|
"p-limit": "^7.3.0",
|
|
79
|
-
"@internals/utils": "0.0.0"
|
|
72
|
+
"@internals/utils": "0.0.0",
|
|
73
|
+
"@kubb/renderer-jsx": "5.0.0-alpha.50"
|
|
80
74
|
},
|
|
81
75
|
"peerDependencies": {
|
|
82
|
-
"@kubb/
|
|
83
|
-
"@kubb/react-fabric": "0.14.0"
|
|
76
|
+
"@kubb/renderer-jsx": "5.0.0-alpha.50"
|
|
84
77
|
},
|
|
78
|
+
"size-limit": [
|
|
79
|
+
{
|
|
80
|
+
"path": "./dist/*.js",
|
|
81
|
+
"limit": "510 KiB",
|
|
82
|
+
"gzip": true
|
|
83
|
+
}
|
|
84
|
+
],
|
|
85
85
|
"engines": {
|
|
86
86
|
"node": ">=22"
|
|
87
87
|
},
|
|
88
|
-
"publishConfig": {
|
|
89
|
-
"access": "public",
|
|
90
|
-
"registry": "https://registry.npmjs.org/"
|
|
91
|
-
},
|
|
92
|
-
"main": "./dist/index.cjs",
|
|
93
|
-
"module": "./dist/index.js",
|
|
94
88
|
"inlinedDependencies": {
|
|
95
89
|
"p-limit": "7.3.0",
|
|
96
90
|
"yocto-queue": "1.2.2"
|
|
@@ -98,8 +92,8 @@
|
|
|
98
92
|
"scripts": {
|
|
99
93
|
"build": "tsdown && size-limit",
|
|
100
94
|
"clean": "npx rimraf ./dist",
|
|
101
|
-
"lint": "
|
|
102
|
-
"lint:fix": "
|
|
95
|
+
"lint": "oxlint .",
|
|
96
|
+
"lint:fix": "oxlint --fix .",
|
|
103
97
|
"release": "pnpm publish --no-git-check",
|
|
104
98
|
"release:canary": "bash ../../.github/canary.sh && node ../../scripts/build.js canary && pnpm publish --no-git-check",
|
|
105
99
|
"start": "tsdown --watch",
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { trimExtName } from '@internals/utils'
|
|
2
|
+
import type { FileNode } from '@kubb/ast'
|
|
3
|
+
import { createFile } from '@kubb/ast'
|
|
4
|
+
import { BARREL_BASENAME } from './constants.ts'
|
|
5
|
+
|
|
6
|
+
function mergeFile<TMeta extends object = object>(a: FileNode<TMeta>, b: FileNode<TMeta>): FileNode<TMeta> {
|
|
7
|
+
return {
|
|
8
|
+
...a,
|
|
9
|
+
sources: [...(a.sources || []), ...(b.sources || [])],
|
|
10
|
+
imports: [...(a.imports || []), ...(b.imports || [])],
|
|
11
|
+
exports: [...(a.exports || []), ...(b.exports || [])],
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* In-memory file store for generated files.
|
|
17
|
+
*
|
|
18
|
+
* Files with the same `path` are merged — sources, imports, and exports are concatenated.
|
|
19
|
+
* The `files` getter returns all stored files sorted by path length (shortest first).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* ```ts
|
|
23
|
+
* import { FileManager } from '@kubb/core'
|
|
24
|
+
*
|
|
25
|
+
* const manager = new FileManager()
|
|
26
|
+
* manager.upsert(myFile)
|
|
27
|
+
* console.log(manager.files) // all stored files
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
export class FileManager {
|
|
31
|
+
readonly #cache = new Map<string, FileNode>()
|
|
32
|
+
#filesCache: Array<FileNode> | null = null
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Adds one or more files. Files with the same path are merged — sources, imports,
|
|
36
|
+
* and exports from all calls with the same path are concatenated together.
|
|
37
|
+
*/
|
|
38
|
+
add(...files: Array<FileNode>): Array<FileNode> {
|
|
39
|
+
const resolvedFiles: Array<FileNode> = []
|
|
40
|
+
const mergedFiles = new Map<string, FileNode>()
|
|
41
|
+
|
|
42
|
+
for (const file of files) {
|
|
43
|
+
const existing = mergedFiles.get(file.path)
|
|
44
|
+
mergedFiles.set(file.path, existing ? mergeFile(existing, file) : file)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
for (const file of mergedFiles.values()) {
|
|
48
|
+
const resolvedFile = createFile(file)
|
|
49
|
+
this.#cache.set(resolvedFile.path, resolvedFile)
|
|
50
|
+
resolvedFiles.push(resolvedFile)
|
|
51
|
+
}
|
|
52
|
+
this.#filesCache = null
|
|
53
|
+
|
|
54
|
+
return resolvedFiles
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Adds or merges one or more files.
|
|
59
|
+
* If a file with the same path already exists, its sources/imports/exports are merged together.
|
|
60
|
+
*/
|
|
61
|
+
upsert(...files: Array<FileNode>): Array<FileNode> {
|
|
62
|
+
const resolvedFiles: Array<FileNode> = []
|
|
63
|
+
const mergedFiles = new Map<string, FileNode>()
|
|
64
|
+
|
|
65
|
+
for (const file of files) {
|
|
66
|
+
const existing = mergedFiles.get(file.path)
|
|
67
|
+
mergedFiles.set(file.path, existing ? mergeFile(existing, file) : file)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
for (const file of mergedFiles.values()) {
|
|
71
|
+
const existing = this.#cache.get(file.path)
|
|
72
|
+
const merged = existing ? mergeFile(existing, file) : file
|
|
73
|
+
const resolvedFile = createFile(merged)
|
|
74
|
+
this.#cache.set(resolvedFile.path, resolvedFile)
|
|
75
|
+
resolvedFiles.push(resolvedFile)
|
|
76
|
+
}
|
|
77
|
+
this.#filesCache = null
|
|
78
|
+
|
|
79
|
+
return resolvedFiles
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
getByPath(path: string): FileNode | null {
|
|
83
|
+
return this.#cache.get(path) ?? null
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
deleteByPath(path: string): void {
|
|
87
|
+
this.#cache.delete(path)
|
|
88
|
+
this.#filesCache = null
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
clear(): void {
|
|
92
|
+
this.#cache.clear()
|
|
93
|
+
this.#filesCache = null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* All stored files, sorted by path length (shorter paths first).
|
|
98
|
+
* Barrel/index files (e.g. index.ts) are sorted last within each length bucket.
|
|
99
|
+
*/
|
|
100
|
+
get files(): Array<FileNode> {
|
|
101
|
+
if (this.#filesCache) {
|
|
102
|
+
return this.#filesCache
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// Precompute the barrel-file flag per key so the comparator avoids repeated string work.
|
|
106
|
+
const keys = [...this.#cache.keys()]
|
|
107
|
+
const meta = new Map<string, { length: number; isIndex: boolean }>()
|
|
108
|
+
for (const key of keys) {
|
|
109
|
+
meta.set(key, {
|
|
110
|
+
length: key.length,
|
|
111
|
+
isIndex: trimExtName(key).endsWith(BARREL_BASENAME),
|
|
112
|
+
})
|
|
113
|
+
}
|
|
114
|
+
keys.sort((a, b) => {
|
|
115
|
+
const ma = meta.get(a)!
|
|
116
|
+
const mb = meta.get(b)!
|
|
117
|
+
if (ma.length !== mb.length) return ma.length - mb.length
|
|
118
|
+
if (ma.isIndex !== mb.isIndex) return ma.isIndex ? 1 : -1
|
|
119
|
+
return 0
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
const files: Array<FileNode> = []
|
|
123
|
+
for (const key of keys) {
|
|
124
|
+
const file = this.#cache.get(key)
|
|
125
|
+
if (file) {
|
|
126
|
+
files.push(file)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
this.#filesCache = files
|
|
131
|
+
return files
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import type { CodeNode, FileNode } from '@kubb/ast'
|
|
2
|
+
import { extractStringsFromNodes } from '@kubb/ast'
|
|
3
|
+
import pLimit from 'p-limit'
|
|
4
|
+
import { PARALLEL_CONCURRENCY_LIMIT } from './constants.ts'
|
|
5
|
+
import type { Parser } from './defineParser.ts'
|
|
6
|
+
|
|
7
|
+
type ParseOptions = {
|
|
8
|
+
parsers?: Map<FileNode['extname'], Parser>
|
|
9
|
+
extension?: Record<FileNode['extname'], FileNode['extname'] | ''>
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
type RunOptions = ParseOptions & {
|
|
13
|
+
/**
|
|
14
|
+
* @default 'sequential'
|
|
15
|
+
*/
|
|
16
|
+
mode?: 'sequential' | 'parallel'
|
|
17
|
+
onStart?: (files: Array<FileNode>) => Promise<void> | void
|
|
18
|
+
onEnd?: (files: Array<FileNode>) => Promise<void> | void
|
|
19
|
+
onUpdate?: (params: { file: FileNode; source?: string; processed: number; total: number; percentage: number }) => Promise<void> | void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function joinSources(file: FileNode): string {
|
|
23
|
+
return file.sources
|
|
24
|
+
.map((item) => extractStringsFromNodes(item.nodes as Array<CodeNode>))
|
|
25
|
+
.filter(Boolean)
|
|
26
|
+
.join('\n\n')
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Converts a single file to a string using the registered parsers.
|
|
31
|
+
* Falls back to joining source values when no matching parser is found.
|
|
32
|
+
*
|
|
33
|
+
* @internal
|
|
34
|
+
*/
|
|
35
|
+
export class FileProcessor {
|
|
36
|
+
readonly #limit = pLimit(PARALLEL_CONCURRENCY_LIMIT)
|
|
37
|
+
|
|
38
|
+
async parse(file: FileNode, { parsers, extension }: ParseOptions = {}): Promise<string> {
|
|
39
|
+
const parseExtName = extension?.[file.extname] || undefined
|
|
40
|
+
|
|
41
|
+
if (!parsers || !file.extname) {
|
|
42
|
+
return joinSources(file)
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const parser = parsers.get(file.extname)
|
|
46
|
+
|
|
47
|
+
if (!parser) {
|
|
48
|
+
return joinSources(file)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return parser.parse(file, { extname: parseExtName })
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async run(files: Array<FileNode>, { parsers, mode = 'sequential', extension, onStart, onEnd, onUpdate }: RunOptions = {}): Promise<Array<FileNode>> {
|
|
55
|
+
await onStart?.(files)
|
|
56
|
+
|
|
57
|
+
const total = files.length
|
|
58
|
+
let processed = 0
|
|
59
|
+
|
|
60
|
+
const processOne = async (file: FileNode) => {
|
|
61
|
+
const source = await this.parse(file, { extension, parsers })
|
|
62
|
+
const currentProcessed = ++processed
|
|
63
|
+
const percentage = (currentProcessed / total) * 100
|
|
64
|
+
|
|
65
|
+
await onUpdate?.({
|
|
66
|
+
file,
|
|
67
|
+
source,
|
|
68
|
+
processed: currentProcessed,
|
|
69
|
+
percentage,
|
|
70
|
+
total,
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (mode === 'sequential') {
|
|
75
|
+
for (const file of files) {
|
|
76
|
+
await processOne(file)
|
|
77
|
+
}
|
|
78
|
+
} else {
|
|
79
|
+
await Promise.all(files.map((file) => this.#limit(() => processOne(file))))
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
await onEnd?.(files)
|
|
83
|
+
|
|
84
|
+
return files
|
|
85
|
+
}
|
|
86
|
+
}
|