@kubb/fabric-core 0.1.0 → 0.1.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.
- package/dist/App-DZuROf6f.d.ts +292 -0
- package/dist/App-zyf9KG3p.d.cts +292 -0
- package/dist/chunk-CUT6urMc.cjs +30 -0
- package/dist/defineApp-D3B0bU-z.d.cts +14 -0
- package/dist/defineApp-DJVMk9lc.d.ts +14 -0
- package/dist/index.cjs +217 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -5
- package/dist/index.d.ts +10 -5
- package/dist/index.js +204 -63
- package/dist/index.js.map +1 -1
- package/dist/parsers/typescript.cjs +5 -5
- package/dist/parsers/typescript.d.cts +3 -51
- package/dist/parsers/typescript.d.ts +3 -51
- package/dist/parsers/typescript.js +2 -2
- package/dist/parsers.cjs +7 -0
- package/dist/parsers.d.cts +14 -0
- package/dist/parsers.d.ts +14 -0
- package/dist/parsers.js +4 -0
- package/dist/plugins.cjs +76 -0
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +28 -0
- package/dist/plugins.d.ts +28 -0
- package/dist/plugins.js +71 -0
- package/dist/plugins.js.map +1 -0
- package/dist/tsxParser-C741ZKCN.js +26 -0
- package/dist/tsxParser-C741ZKCN.js.map +1 -0
- package/dist/tsxParser-HDf_3TMc.cjs +37 -0
- package/dist/tsxParser-HDf_3TMc.cjs.map +1 -0
- package/dist/types.d.cts +2 -2
- package/dist/types.d.ts +2 -2
- package/dist/{parser-CWB_OBtr.js → typescriptParser-BBGeFKlP.js} +51 -98
- package/dist/typescriptParser-BBGeFKlP.js.map +1 -0
- package/dist/typescriptParser-BBbbmG5W.cjs +171 -0
- package/dist/typescriptParser-BBbbmG5W.cjs.map +1 -0
- package/dist/typescriptParser-C-sBy1iR.d.cts +50 -0
- package/dist/typescriptParser-CtMmz0UV.d.ts +50 -0
- package/package.json +13 -6
- package/src/App.ts +91 -0
- package/src/FileManager.ts +14 -193
- package/src/FileProcessor.ts +89 -0
- package/src/createFile.ts +167 -0
- package/src/defineApp.ts +49 -74
- package/src/index.ts +3 -1
- package/src/parsers/createParser.ts +8 -0
- package/src/parsers/defaultParser.ts +10 -0
- package/src/parsers/index.ts +5 -0
- package/src/parsers/tsxParser.ts +11 -0
- package/src/parsers/types.ts +22 -0
- package/src/parsers/{typescript.ts → typescriptParser.ts} +8 -4
- package/src/plugins/createPlugin.ts +10 -0
- package/src/plugins/fsPlugin.ts +112 -0
- package/src/plugins/index.ts +3 -0
- package/src/plugins/types.ts +15 -0
- package/src/types.ts +4 -1
- package/src/utils/AsyncEventEmitter.ts +37 -0
- package/src/utils/EventEmitter.ts +23 -0
- package/src/utils/getRelativePath.ts +32 -0
- package/src/utils/trimExtName.ts +3 -0
- package/dist/KubbFile-BrN7Wwp6.d.cts +0 -119
- package/dist/KubbFile-BzVkcu9M.d.ts +0 -119
- package/dist/defineApp-Bg7JewJQ.d.ts +0 -62
- package/dist/defineApp-DKW3IRO8.d.cts +0 -62
- package/dist/parser-CWB_OBtr.js.map +0 -1
- package/dist/parser-D64DdV1v.d.cts +0 -21
- package/dist/parser-QF8j8-pj.cjs +0 -260
- package/dist/parser-QF8j8-pj.cjs.map +0 -1
- package/dist/parser-yYqnryUV.d.ts +0 -21
- package/dist/parsers/tsx.cjs +0 -3
- package/dist/parsers/tsx.d.cts +0 -8
- package/dist/parsers/tsx.d.ts +0 -8
- package/dist/parsers/tsx.js +0 -3
- package/src/fs.ts +0 -167
- package/src/parsers/parser.ts +0 -56
- package/src/parsers/tsx.ts +0 -8
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
const require_chunk = require('./chunk-CUT6urMc.cjs');
|
|
2
|
+
let node_path = require("node:path");
|
|
3
|
+
node_path = require_chunk.__toESM(node_path);
|
|
4
|
+
let typescript = require("typescript");
|
|
5
|
+
typescript = require_chunk.__toESM(typescript);
|
|
6
|
+
|
|
7
|
+
//#region src/utils/trimExtName.ts
|
|
8
|
+
function trimExtName(text) {
|
|
9
|
+
return text.replace(/\.[^/.]+$/, "");
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/parsers/createParser.ts
|
|
14
|
+
function createParser(parser) {
|
|
15
|
+
return {
|
|
16
|
+
type: "parser",
|
|
17
|
+
...parser
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
//#endregion
|
|
22
|
+
//#region src/utils/getRelativePath.ts
|
|
23
|
+
function slash(path$1, platform = "linux") {
|
|
24
|
+
const isWindowsPath = /^\\\\\?\\/.test(path$1);
|
|
25
|
+
const normalizedPath = (0, node_path.normalize)(path$1);
|
|
26
|
+
if (["linux", "mac"].includes(platform) && !isWindowsPath) return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
27
|
+
return normalizedPath.replaceAll(/\\/g, "/").replace("../", "");
|
|
28
|
+
}
|
|
29
|
+
function getRelativePath(rootDir, filePath, platform = "linux") {
|
|
30
|
+
if (!rootDir || !filePath) throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ""} ${filePath || ""}`);
|
|
31
|
+
const slashedPath = slash((0, node_path.relative)(rootDir, filePath), platform);
|
|
32
|
+
if (slashedPath.startsWith("../")) return slashedPath;
|
|
33
|
+
return `./${slashedPath}`;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/parsers/typescriptParser.ts
|
|
38
|
+
const { factory } = typescript.default;
|
|
39
|
+
/**
|
|
40
|
+
* Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}
|
|
41
|
+
*/
|
|
42
|
+
const escapeNewLines = (code) => code.replace(/\n\n/g, "\n/* :newline: */");
|
|
43
|
+
/**
|
|
44
|
+
* Reverses {@link escapeNewLines} and restores new lines
|
|
45
|
+
*/
|
|
46
|
+
const restoreNewLines = (code) => code.replace(/\/\* :newline: \*\//g, "\n");
|
|
47
|
+
/**
|
|
48
|
+
* Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
|
|
49
|
+
* Ensures consistent output across environments.
|
|
50
|
+
* Also works as a formatter when `source` is provided without `elements`.
|
|
51
|
+
*/
|
|
52
|
+
function print(elements = [], { source = "", baseName = "print.tsx", scriptKind = typescript.default.ScriptKind.TSX } = {}) {
|
|
53
|
+
const sourceFile = typescript.default.createSourceFile(baseName, escapeNewLines(source), typescript.default.ScriptTarget.ES2022, true, scriptKind);
|
|
54
|
+
const printer = typescript.default.createPrinter({
|
|
55
|
+
omitTrailingSemicolon: true,
|
|
56
|
+
newLine: typescript.default.NewLineKind.LineFeed,
|
|
57
|
+
removeComments: false,
|
|
58
|
+
noEmitHelpers: true
|
|
59
|
+
});
|
|
60
|
+
let output;
|
|
61
|
+
if (elements.length > 0) {
|
|
62
|
+
const nodes = elements.filter(Boolean).sort((a, b) => {
|
|
63
|
+
var _a$pos, _b$pos;
|
|
64
|
+
return ((_a$pos = a.pos) !== null && _a$pos !== void 0 ? _a$pos : 0) - ((_b$pos = b.pos) !== null && _b$pos !== void 0 ? _b$pos : 0);
|
|
65
|
+
});
|
|
66
|
+
output = printer.printList(typescript.default.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile);
|
|
67
|
+
} else output = printer.printFile(sourceFile);
|
|
68
|
+
return restoreNewLines(output).replace(/\r\n/g, "\n");
|
|
69
|
+
}
|
|
70
|
+
function createImport({ name, path: path$1, root, isTypeOnly = false, isNameSpace = false }) {
|
|
71
|
+
const resolvePath = root ? getRelativePath(root, path$1) : path$1;
|
|
72
|
+
if (!Array.isArray(name)) {
|
|
73
|
+
let importPropertyName = factory.createIdentifier(name);
|
|
74
|
+
let importName;
|
|
75
|
+
if (isNameSpace) {
|
|
76
|
+
importPropertyName = void 0;
|
|
77
|
+
importName = factory.createNamespaceImport(factory.createIdentifier(name));
|
|
78
|
+
}
|
|
79
|
+
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, importPropertyName, importName), factory.createStringLiteral(resolvePath), void 0);
|
|
80
|
+
}
|
|
81
|
+
return factory.createImportDeclaration(void 0, factory.createImportClause(isTypeOnly, void 0, factory.createNamedImports(name.map((item) => {
|
|
82
|
+
if (typeof item === "object") {
|
|
83
|
+
const obj = item;
|
|
84
|
+
if (obj.name) return factory.createImportSpecifier(false, factory.createIdentifier(obj.propertyName), factory.createIdentifier(obj.name));
|
|
85
|
+
return factory.createImportSpecifier(false, void 0, factory.createIdentifier(obj.propertyName));
|
|
86
|
+
}
|
|
87
|
+
return factory.createImportSpecifier(false, void 0, factory.createIdentifier(item));
|
|
88
|
+
}))), factory.createStringLiteral(resolvePath), void 0);
|
|
89
|
+
}
|
|
90
|
+
function createExport({ path: path$1, asAlias, isTypeOnly = false, name }) {
|
|
91
|
+
if (name && !Array.isArray(name) && !asAlias) console.warn(`When using name as string, asAlias should be true ${name}`);
|
|
92
|
+
if (!Array.isArray(name)) {
|
|
93
|
+
const parsedName = (name === null || name === void 0 ? void 0 : name.match(/^\d/)) ? `_${name === null || name === void 0 ? void 0 : name.slice(1)}` : name;
|
|
94
|
+
return factory.createExportDeclaration(void 0, isTypeOnly, asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : void 0, factory.createStringLiteral(path$1), void 0);
|
|
95
|
+
}
|
|
96
|
+
return factory.createExportDeclaration(void 0, isTypeOnly, factory.createNamedExports(name.map((propertyName) => {
|
|
97
|
+
return factory.createExportSpecifier(false, void 0, typeof propertyName === "string" ? factory.createIdentifier(propertyName) : propertyName);
|
|
98
|
+
})), factory.createStringLiteral(path$1), void 0);
|
|
99
|
+
}
|
|
100
|
+
const typescriptParser = createParser({
|
|
101
|
+
name: "typescript",
|
|
102
|
+
extNames: [".ts", ".js"],
|
|
103
|
+
install() {},
|
|
104
|
+
async parse(file, options = { extname: ".ts" }) {
|
|
105
|
+
const source = file.sources.map((item) => item.value).join("\n\n");
|
|
106
|
+
const importNodes = file.imports.map((item) => {
|
|
107
|
+
const importPath = item.root ? getRelativePath(item.root, item.path) : item.path;
|
|
108
|
+
const hasExtname = !!node_path.default.extname(importPath);
|
|
109
|
+
return createImport({
|
|
110
|
+
name: item.name,
|
|
111
|
+
path: options.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,
|
|
112
|
+
isTypeOnly: item.isTypeOnly
|
|
113
|
+
});
|
|
114
|
+
}).filter(Boolean);
|
|
115
|
+
const exportNodes = file.exports.map((item) => {
|
|
116
|
+
const exportPath = item.path;
|
|
117
|
+
const hasExtname = !!node_path.default.extname(exportPath);
|
|
118
|
+
return createExport({
|
|
119
|
+
name: item.name,
|
|
120
|
+
path: options.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),
|
|
121
|
+
isTypeOnly: item.isTypeOnly,
|
|
122
|
+
asAlias: item.asAlias
|
|
123
|
+
});
|
|
124
|
+
}).filter(Boolean);
|
|
125
|
+
return [
|
|
126
|
+
file.banner,
|
|
127
|
+
print([...importNodes, ...exportNodes]),
|
|
128
|
+
source,
|
|
129
|
+
file.footer
|
|
130
|
+
].join("\n");
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
//#endregion
|
|
135
|
+
Object.defineProperty(exports, 'createExport', {
|
|
136
|
+
enumerable: true,
|
|
137
|
+
get: function () {
|
|
138
|
+
return createExport;
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
Object.defineProperty(exports, 'createImport', {
|
|
142
|
+
enumerable: true,
|
|
143
|
+
get: function () {
|
|
144
|
+
return createImport;
|
|
145
|
+
}
|
|
146
|
+
});
|
|
147
|
+
Object.defineProperty(exports, 'createParser', {
|
|
148
|
+
enumerable: true,
|
|
149
|
+
get: function () {
|
|
150
|
+
return createParser;
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
Object.defineProperty(exports, 'print', {
|
|
154
|
+
enumerable: true,
|
|
155
|
+
get: function () {
|
|
156
|
+
return print;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
Object.defineProperty(exports, 'trimExtName', {
|
|
160
|
+
enumerable: true,
|
|
161
|
+
get: function () {
|
|
162
|
+
return trimExtName;
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
Object.defineProperty(exports, 'typescriptParser', {
|
|
166
|
+
enumerable: true,
|
|
167
|
+
get: function () {
|
|
168
|
+
return typescriptParser;
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
//# sourceMappingURL=typescriptParser-BBbbmG5W.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typescriptParser-BBbbmG5W.cjs","names":["path","ts","output: string","path","importPropertyName: ts.Identifier | undefined","importName: ts.NamedImportBindings | undefined"],"sources":["../src/utils/trimExtName.ts","../src/parsers/createParser.ts","../src/utils/getRelativePath.ts","../src/parsers/typescriptParser.ts"],"sourcesContent":["export function trimExtName(text: string): string {\n return text.replace(/\\.[^/.]+$/, '')\n}\n","import type { Parser, UserParser } from './types.ts'\n\nexport function createParser<TOptions = any[], TMeta extends object = any>(parser: UserParser<TOptions, TMeta>): Parser<TOptions, TMeta> {\n return {\n type: 'parser',\n ...parser,\n }\n}\n","import { normalize, relative } from 'node:path'\n\nfunction slash(path: string, platform: 'windows' | 'mac' | 'linux' = 'linux') {\n const isWindowsPath = /^\\\\\\\\\\?\\\\/.test(path)\n const normalizedPath = normalize(path)\n\n if (['linux', 'mac'].includes(platform) && !isWindowsPath) {\n // linux and mac\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n }\n\n // windows\n return normalizedPath.replaceAll(/\\\\/g, '/').replace('../', '')\n}\n\nexport function getRelativePath(rootDir?: string | null, filePath?: string | null, platform: 'windows' | 'mac' | 'linux' = 'linux'): string {\n if (!rootDir || !filePath) {\n throw new Error(`Root and file should be filled in when retrieving the relativePath, ${rootDir || ''} ${filePath || ''}`)\n }\n\n const relativePath = relative(rootDir, filePath)\n\n // On Windows, paths are separated with a \"\\\"\n // However, web browsers use \"/\" no matter the platform\n const slashedPath = slash(relativePath, platform)\n\n if (slashedPath.startsWith('../')) {\n return slashedPath\n }\n\n return `./${slashedPath}`\n}\n","import ts from 'typescript'\nimport { getRelativePath } from '../utils/getRelativePath.ts'\nimport { trimExtName } from '../utils/trimExtName.ts'\nimport path from 'node:path'\nimport { createParser } from './createParser.ts'\n\nconst { factory } = ts\n\ntype PrintOptions = {\n source?: string\n baseName?: string\n scriptKind?: ts.ScriptKind\n}\n\n/**\n * Escaped new lines in code with block comments so they can be restored by {@link restoreNewLines}\n */\nconst escapeNewLines = (code: string) => code.replace(/\\n\\n/g, '\\n/* :newline: */')\n\n/**\n * Reverses {@link escapeNewLines} and restores new lines\n */\nconst restoreNewLines = (code: string) => code.replace(/\\/\\* :newline: \\*\\//g, '\\n')\n\n/**\n * Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.\n * Ensures consistent output across environments.\n * Also works as a formatter when `source` is provided without `elements`.\n */\nexport function print(elements: Array<ts.Node> = [], { source = '', baseName = 'print.tsx', scriptKind = ts.ScriptKind.TSX }: PrintOptions = {}): string {\n const sourceFile = ts.createSourceFile(baseName, escapeNewLines(source), ts.ScriptTarget.ES2022, true, scriptKind)\n\n const printer = ts.createPrinter({\n omitTrailingSemicolon: true,\n newLine: ts.NewLineKind.LineFeed,\n removeComments: false,\n noEmitHelpers: true,\n })\n\n let output: string\n\n if (elements.length > 0) {\n // Print only provided nodes\n const nodes = elements.filter(Boolean).sort((a, b) => (a.pos ?? 0) - (b.pos ?? 0))\n output = printer.printList(ts.ListFormat.MultiLine, factory.createNodeArray(nodes), sourceFile)\n } else {\n // Format the whole file\n output = printer.printFile(sourceFile)\n }\n\n return restoreNewLines(output).replace(/\\r\\n/g, '\\n')\n}\n\nexport function createImport({\n name,\n path,\n root,\n isTypeOnly = false,\n isNameSpace = false,\n}: {\n name: string | Array<string | { propertyName: string; name?: string }>\n path: string\n root?: string\n isTypeOnly?: boolean\n isNameSpace?: boolean\n}) {\n const resolvePath = root ? getRelativePath(root, path) : path\n\n if (!Array.isArray(name)) {\n let importPropertyName: ts.Identifier | undefined = factory.createIdentifier(name)\n let importName: ts.NamedImportBindings | undefined\n\n if (isNameSpace) {\n importPropertyName = undefined\n importName = factory.createNamespaceImport(factory.createIdentifier(name))\n }\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(isTypeOnly, importPropertyName, importName),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n }\n\n return factory.createImportDeclaration(\n undefined,\n factory.createImportClause(\n isTypeOnly,\n undefined,\n factory.createNamedImports(\n name.map((item) => {\n if (typeof item === 'object') {\n const obj = item as { propertyName: string; name?: string }\n if (obj.name) {\n return factory.createImportSpecifier(false, factory.createIdentifier(obj.propertyName), factory.createIdentifier(obj.name))\n }\n\n return factory.createImportSpecifier(false, undefined, factory.createIdentifier(obj.propertyName))\n }\n\n return factory.createImportSpecifier(false, undefined, factory.createIdentifier(item))\n }),\n ),\n ),\n factory.createStringLiteral(resolvePath),\n undefined,\n )\n}\n\nexport function createExport({\n path,\n asAlias,\n isTypeOnly = false,\n name,\n}: {\n path: string\n asAlias?: boolean\n isTypeOnly?: boolean\n name?: string | Array<ts.Identifier | string>\n}) {\n if (name && !Array.isArray(name) && !asAlias) {\n console.warn(`When using name as string, asAlias should be true ${name}`)\n }\n\n if (!Array.isArray(name)) {\n const parsedName = name?.match(/^\\d/) ? `_${name?.slice(1)}` : name\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n asAlias && parsedName ? factory.createNamespaceExport(factory.createIdentifier(parsedName)) : undefined,\n factory.createStringLiteral(path),\n undefined,\n )\n }\n\n return factory.createExportDeclaration(\n undefined,\n isTypeOnly,\n factory.createNamedExports(\n name.map((propertyName) => {\n return factory.createExportSpecifier(false, undefined, typeof propertyName === 'string' ? factory.createIdentifier(propertyName) : propertyName)\n }),\n ),\n factory.createStringLiteral(path),\n undefined,\n )\n}\n\nexport const typescriptParser = createParser({\n name: 'typescript',\n extNames: ['.ts', '.js'],\n install() {},\n async parse(file, options = { extname: '.ts' }) {\n const source = file.sources.map((item) => item.value).join('\\n\\n')\n\n const importNodes = file.imports\n .map((item) => {\n const importPath = item.root ? getRelativePath(item.root, item.path) : item.path\n const hasExtname = !!path.extname(importPath)\n\n return createImport({\n name: item.name,\n path: options.extname && hasExtname ? `${trimExtName(importPath)}${options.extname}` : item.root ? trimExtName(importPath) : importPath,\n isTypeOnly: item.isTypeOnly,\n })\n })\n .filter(Boolean)\n\n const exportNodes = file.exports\n .map((item) => {\n const exportPath = item.path\n\n const hasExtname = !!path.extname(exportPath)\n\n return createExport({\n name: item.name,\n path: options.extname && hasExtname ? `${trimExtName(item.path)}${options.extname}` : trimExtName(item.path),\n isTypeOnly: item.isTypeOnly,\n asAlias: item.asAlias,\n })\n })\n .filter(Boolean)\n\n return [file.banner, print([...importNodes, ...exportNodes]), source, file.footer].join('\\n')\n },\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { o as Parser } from "./App-zyf9KG3p.cjs";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
|
|
4
|
+
//#region src/parsers/typescriptParser.d.ts
|
|
5
|
+
type PrintOptions = {
|
|
6
|
+
source?: string;
|
|
7
|
+
baseName?: string;
|
|
8
|
+
scriptKind?: ts.ScriptKind;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
|
|
12
|
+
* Ensures consistent output across environments.
|
|
13
|
+
* Also works as a formatter when `source` is provided without `elements`.
|
|
14
|
+
*/
|
|
15
|
+
declare function print(elements?: Array<ts.Node>, {
|
|
16
|
+
source,
|
|
17
|
+
baseName,
|
|
18
|
+
scriptKind
|
|
19
|
+
}?: PrintOptions): string;
|
|
20
|
+
declare function createImport({
|
|
21
|
+
name,
|
|
22
|
+
path,
|
|
23
|
+
root,
|
|
24
|
+
isTypeOnly,
|
|
25
|
+
isNameSpace
|
|
26
|
+
}: {
|
|
27
|
+
name: string | Array<string | {
|
|
28
|
+
propertyName: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
}>;
|
|
31
|
+
path: string;
|
|
32
|
+
root?: string;
|
|
33
|
+
isTypeOnly?: boolean;
|
|
34
|
+
isNameSpace?: boolean;
|
|
35
|
+
}): ts.ImportDeclaration;
|
|
36
|
+
declare function createExport({
|
|
37
|
+
path,
|
|
38
|
+
asAlias,
|
|
39
|
+
isTypeOnly,
|
|
40
|
+
name
|
|
41
|
+
}: {
|
|
42
|
+
path: string;
|
|
43
|
+
asAlias?: boolean;
|
|
44
|
+
isTypeOnly?: boolean;
|
|
45
|
+
name?: string | Array<ts.Identifier | string>;
|
|
46
|
+
}): ts.ExportDeclaration;
|
|
47
|
+
declare const typescriptParser: Parser<[], any>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { typescriptParser as i, createImport as n, print as r, createExport as t };
|
|
50
|
+
//# sourceMappingURL=typescriptParser-C-sBy1iR.d.cts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { o as Parser } from "./App-DZuROf6f.js";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
|
|
4
|
+
//#region src/parsers/typescriptParser.d.ts
|
|
5
|
+
type PrintOptions = {
|
|
6
|
+
source?: string;
|
|
7
|
+
baseName?: string;
|
|
8
|
+
scriptKind?: ts.ScriptKind;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Convert AST TypeScript/TSX nodes to a string based on the TypeScript printer.
|
|
12
|
+
* Ensures consistent output across environments.
|
|
13
|
+
* Also works as a formatter when `source` is provided without `elements`.
|
|
14
|
+
*/
|
|
15
|
+
declare function print(elements?: Array<ts.Node>, {
|
|
16
|
+
source,
|
|
17
|
+
baseName,
|
|
18
|
+
scriptKind
|
|
19
|
+
}?: PrintOptions): string;
|
|
20
|
+
declare function createImport({
|
|
21
|
+
name,
|
|
22
|
+
path,
|
|
23
|
+
root,
|
|
24
|
+
isTypeOnly,
|
|
25
|
+
isNameSpace
|
|
26
|
+
}: {
|
|
27
|
+
name: string | Array<string | {
|
|
28
|
+
propertyName: string;
|
|
29
|
+
name?: string;
|
|
30
|
+
}>;
|
|
31
|
+
path: string;
|
|
32
|
+
root?: string;
|
|
33
|
+
isTypeOnly?: boolean;
|
|
34
|
+
isNameSpace?: boolean;
|
|
35
|
+
}): ts.ImportDeclaration;
|
|
36
|
+
declare function createExport({
|
|
37
|
+
path,
|
|
38
|
+
asAlias,
|
|
39
|
+
isTypeOnly,
|
|
40
|
+
name
|
|
41
|
+
}: {
|
|
42
|
+
path: string;
|
|
43
|
+
asAlias?: boolean;
|
|
44
|
+
isTypeOnly?: boolean;
|
|
45
|
+
name?: string | Array<ts.Identifier | string>;
|
|
46
|
+
}): ts.ExportDeclaration;
|
|
47
|
+
declare const typescriptParser: Parser<[], any>;
|
|
48
|
+
//#endregion
|
|
49
|
+
export { typescriptParser as i, createImport as n, print as r, createExport as t };
|
|
50
|
+
//# sourceMappingURL=typescriptParser-CtMmz0UV.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kubb/fabric-core",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Core functionality for Kubb's plugin-based code generation system, providing the foundation for transforming OpenAPI specifications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -26,14 +26,18 @@
|
|
|
26
26
|
"import": "./dist/index.js",
|
|
27
27
|
"require": "./dist/index.cjs"
|
|
28
28
|
},
|
|
29
|
-
"./parsers
|
|
30
|
-
"import": "./dist/parsers
|
|
31
|
-
"require": "./dist/parsers
|
|
29
|
+
"./parsers": {
|
|
30
|
+
"import": "./dist/parsers.js",
|
|
31
|
+
"require": "./dist/parsers.cjs"
|
|
32
32
|
},
|
|
33
33
|
"./parsers/typescript": {
|
|
34
34
|
"import": "./dist/parsers/typescript.js",
|
|
35
35
|
"require": "./dist/parsers/typescript.cjs"
|
|
36
36
|
},
|
|
37
|
+
"./plugins": {
|
|
38
|
+
"import": "./dist/plugins.js",
|
|
39
|
+
"require": "./dist/plugins.cjs"
|
|
40
|
+
},
|
|
37
41
|
"./types": {
|
|
38
42
|
"import": "./dist/types.js",
|
|
39
43
|
"require": "./dist/types.cjs"
|
|
@@ -45,11 +49,14 @@
|
|
|
45
49
|
"types": "./dist/index.d.cts",
|
|
46
50
|
"typesVersions": {
|
|
47
51
|
"*": {
|
|
52
|
+
"parsers": [
|
|
53
|
+
"./dist/parsers.d.ts"
|
|
54
|
+
],
|
|
48
55
|
"parsers/typescript": [
|
|
49
56
|
"./dist/parsers/typescript.d.ts"
|
|
50
57
|
],
|
|
51
|
-
"
|
|
52
|
-
"./dist/
|
|
58
|
+
"plugins": [
|
|
59
|
+
"./dist/plugins.d.ts"
|
|
53
60
|
],
|
|
54
61
|
"types": [
|
|
55
62
|
"./dist/types.d.ts"
|
package/src/App.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type * as KubbFile from './KubbFile.ts'
|
|
2
|
+
import type { Plugin } from './plugins/types.ts'
|
|
3
|
+
import type { Parser } from './parsers/types.ts'
|
|
4
|
+
import type { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'
|
|
5
|
+
import type { FileManager } from './FileManager.ts'
|
|
6
|
+
|
|
7
|
+
export type Component = any
|
|
8
|
+
|
|
9
|
+
export type AppEvents = {
|
|
10
|
+
/**
|
|
11
|
+
* Called in the beginning of the app lifecycle.
|
|
12
|
+
*/
|
|
13
|
+
start: [{ app: App }]
|
|
14
|
+
/**
|
|
15
|
+
* Called in the end of the app lifecycle.
|
|
16
|
+
*/
|
|
17
|
+
end: [{ app: App }]
|
|
18
|
+
/**
|
|
19
|
+
* Called when being rendered
|
|
20
|
+
*/
|
|
21
|
+
render: [{ app: App }]
|
|
22
|
+
/**
|
|
23
|
+
* Called once before processing any files.
|
|
24
|
+
*/
|
|
25
|
+
'process:start': [{ files: KubbFile.ResolvedFile[] }]
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Called for each file when processing begins.
|
|
29
|
+
*/
|
|
30
|
+
'file:start': [{ file: KubbFile.ResolvedFile; index: number; total: number }]
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Called for each file when processing finishes.
|
|
34
|
+
*/
|
|
35
|
+
'file:end': [{ file: KubbFile.ResolvedFile; index: number; total: number }]
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Called periodically (or after each file) to indicate progress.
|
|
39
|
+
* Useful for progress bars or logging.
|
|
40
|
+
*/
|
|
41
|
+
'process:progress': [
|
|
42
|
+
{
|
|
43
|
+
processed: number
|
|
44
|
+
total: number
|
|
45
|
+
percentage: number
|
|
46
|
+
source: string
|
|
47
|
+
file: KubbFile.ResolvedFile
|
|
48
|
+
},
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Called once all files have been processed successfully.
|
|
53
|
+
*/
|
|
54
|
+
'process:end': [{ files: KubbFile.ResolvedFile[] }]
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export type AppContext<TOptions = unknown> = {
|
|
58
|
+
options?: TOptions
|
|
59
|
+
events: AsyncEventEmitter<AppEvents>
|
|
60
|
+
fileManager: FileManager
|
|
61
|
+
installedPlugins: Set<Plugin>
|
|
62
|
+
installedParsers: Set<Parser>
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export type Install<TOptions = any[] | object | undefined> = TOptions extends any[]
|
|
66
|
+
? (app: App, context: AppContext, ...options: TOptions) => void
|
|
67
|
+
: TOptions extends object
|
|
68
|
+
? (app: App, context: AppContext, options?: TOptions) => void
|
|
69
|
+
: (app: App, context: AppContext) => void
|
|
70
|
+
|
|
71
|
+
export type Override<TOptions = any[] | object | undefined, TAppExtension extends Record<string, any> = {}> = TOptions extends any[]
|
|
72
|
+
? (app: App, context: AppContext, ...options: TOptions) => Partial<TAppExtension>
|
|
73
|
+
: TOptions extends object
|
|
74
|
+
? (app: App, context: AppContext, options?: TOptions) => Partial<TAppExtension>
|
|
75
|
+
: (app: App, context: AppContext) => Partial<TAppExtension>
|
|
76
|
+
|
|
77
|
+
export interface App {
|
|
78
|
+
_component: Component
|
|
79
|
+
render(): Promise<void>
|
|
80
|
+
renderToString(): Promise<string>
|
|
81
|
+
files: Array<KubbFile.ResolvedFile>
|
|
82
|
+
use<TOptions extends any[] | object = any, TMeta extends object = object, TAppExtension extends Record<string, any> = {}>(
|
|
83
|
+
pluginOrParser: Plugin<TOptions, TAppExtension> | Parser<TOptions, TMeta>,
|
|
84
|
+
...options: TOptions extends any[] ? NoInfer<TOptions> : [NoInfer<TOptions>]
|
|
85
|
+
): this & TAppExtension
|
|
86
|
+
use<TOptions extends any[] | object = any, TMeta extends object = object, TAppExtension extends Record<string, any> = {}>(
|
|
87
|
+
pluginOrParser: Plugin<TOptions, TAppExtension> | Parser<TOptions, TMeta>,
|
|
88
|
+
): this & TAppExtension
|
|
89
|
+
addFile(...files: Array<KubbFile.File>): Promise<void>
|
|
90
|
+
waitUntilExit(): Promise<void>
|
|
91
|
+
}
|
package/src/FileManager.ts
CHANGED
|
@@ -1,25 +1,13 @@
|
|
|
1
|
-
import pLimit from 'p-limit'
|
|
2
|
-
|
|
3
1
|
import type * as KubbFile from './KubbFile.ts'
|
|
4
|
-
import { parseFile } from './parsers/parser.ts'
|
|
5
2
|
import { Cache } from './utils/Cache.ts'
|
|
6
|
-
import { trimExtName
|
|
7
|
-
import { createHash } from 'node:crypto'
|
|
8
|
-
import path from 'node:path'
|
|
3
|
+
import { trimExtName } from './utils/trimExtName.ts'
|
|
9
4
|
import { orderBy } from 'natural-orderby'
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
dryRun?: boolean
|
|
15
|
-
}
|
|
5
|
+
import { createFile } from './createFile.ts'
|
|
6
|
+
import { FileProcessor, type ProcessFilesProps } from './FileProcessor.ts'
|
|
7
|
+
import { AsyncEventEmitter } from './utils/AsyncEventEmitter.ts'
|
|
8
|
+
import type { AppEvents } from './App.ts'
|
|
16
9
|
|
|
17
|
-
function
|
|
18
|
-
const str = JSON.stringify(obj, Object.keys(obj).sort())
|
|
19
|
-
return createHash('sha256').update(str).digest('hex')
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {
|
|
10
|
+
function mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>, b: KubbFile.File<TMeta>): KubbFile.File<TMeta> {
|
|
23
11
|
return {
|
|
24
12
|
...a,
|
|
25
13
|
sources: [...(a.sources || []), ...(b.sources || [])],
|
|
@@ -28,167 +16,16 @@ export function mergeFile<TMeta extends object = object>(a: KubbFile.File<TMeta>
|
|
|
28
16
|
}
|
|
29
17
|
}
|
|
30
18
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function combineExports(exports: Array<KubbFile.Export>): Array<KubbFile.Export> {
|
|
36
|
-
return orderBy(exports, [
|
|
37
|
-
(v) => !!Array.isArray(v.name),
|
|
38
|
-
(v) => !v.isTypeOnly,
|
|
39
|
-
(v) => v.path,
|
|
40
|
-
(v) => !!v.name,
|
|
41
|
-
(v) => (Array.isArray(v.name) ? orderBy(v.name) : v.name),
|
|
42
|
-
]).reduce(
|
|
43
|
-
(prev, curr) => {
|
|
44
|
-
const name = curr.name
|
|
45
|
-
const prevByPath = prev.findLast((imp) => imp.path === curr.path)
|
|
46
|
-
const prevByPathAndIsTypeOnly = prev.findLast((imp) => imp.path === curr.path && isDeepEqual(imp.name, name) && imp.isTypeOnly)
|
|
47
|
-
|
|
48
|
-
if (prevByPathAndIsTypeOnly) {
|
|
49
|
-
// we already have an export that has the same path but uses `isTypeOnly` (export type ...)
|
|
50
|
-
return prev
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const uniquePrev = prev.findLast(
|
|
54
|
-
(imp) => imp.path === curr.path && isDeepEqual(imp.name, name) && imp.isTypeOnly === curr.isTypeOnly && imp.asAlias === curr.asAlias,
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
// we already have an item that was unique enough or name field is empty or prev asAlias is set but current has no changes
|
|
58
|
-
if (uniquePrev || (Array.isArray(name) && !name.length) || (prevByPath?.asAlias && !curr.asAlias)) {
|
|
59
|
-
return prev
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (!prevByPath) {
|
|
63
|
-
return [
|
|
64
|
-
...prev,
|
|
65
|
-
{
|
|
66
|
-
...curr,
|
|
67
|
-
name: Array.isArray(name) ? [...new Set(name)] : name,
|
|
68
|
-
},
|
|
69
|
-
]
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// merge all names when prev and current both have the same isTypeOnly set
|
|
73
|
-
if (prevByPath && Array.isArray(prevByPath.name) && Array.isArray(curr.name) && prevByPath.isTypeOnly === curr.isTypeOnly) {
|
|
74
|
-
prevByPath.name = [...new Set([...prevByPath.name, ...curr.name])]
|
|
75
|
-
|
|
76
|
-
return prev
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
return [...prev, curr]
|
|
80
|
-
},
|
|
81
|
-
[] as Array<KubbFile.Export>,
|
|
82
|
-
)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
export function combineImports(imports: Array<KubbFile.Import>, exports: Array<KubbFile.Export>, source?: string): Array<KubbFile.Import> {
|
|
86
|
-
return orderBy(imports, [
|
|
87
|
-
(v) => !!Array.isArray(v.name),
|
|
88
|
-
(v) => !v.isTypeOnly,
|
|
89
|
-
(v) => v.path,
|
|
90
|
-
(v) => !!v.name,
|
|
91
|
-
(v) => (Array.isArray(v.name) ? orderBy(v.name) : v.name),
|
|
92
|
-
]).reduce(
|
|
93
|
-
(prev, curr) => {
|
|
94
|
-
let name = Array.isArray(curr.name) ? [...new Set(curr.name)] : curr.name
|
|
95
|
-
|
|
96
|
-
const hasImportInSource = (importName: string) => {
|
|
97
|
-
if (!source) {
|
|
98
|
-
return true
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
const checker = (name?: string) => {
|
|
102
|
-
return name && source.includes(name)
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
return checker(importName) || exports.some(({ name }) => (Array.isArray(name) ? name.some(checker) : checker(name)))
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
if (curr.path === curr.root) {
|
|
109
|
-
// root and path are the same file, remove the "./" import
|
|
110
|
-
return prev
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
// merge all names and check if the importName is being used in the generated source and if not filter those imports out
|
|
114
|
-
if (Array.isArray(name)) {
|
|
115
|
-
name = name.filter((item) => (typeof item === 'string' ? hasImportInSource(item) : hasImportInSource(item.propertyName)))
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const prevByPath = prev.findLast((imp) => imp.path === curr.path && imp.isTypeOnly === curr.isTypeOnly)
|
|
119
|
-
const uniquePrev = prev.findLast((imp) => imp.path === curr.path && isDeepEqual(imp.name, name) && imp.isTypeOnly === curr.isTypeOnly)
|
|
120
|
-
const prevByPathNameAndIsTypeOnly = prev.findLast((imp) => imp.path === curr.path && isDeepEqual(imp.name, name) && imp.isTypeOnly)
|
|
121
|
-
|
|
122
|
-
if (prevByPathNameAndIsTypeOnly) {
|
|
123
|
-
// we already have an export that has the same path but uses `isTypeOnly` (import type ...)
|
|
124
|
-
return prev
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// already unique enough or name is empty
|
|
128
|
-
if (uniquePrev || (Array.isArray(name) && !name.length)) {
|
|
129
|
-
return prev
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
// new item, append name
|
|
133
|
-
if (!prevByPath) {
|
|
134
|
-
return [
|
|
135
|
-
...prev,
|
|
136
|
-
{
|
|
137
|
-
...curr,
|
|
138
|
-
name,
|
|
139
|
-
},
|
|
140
|
-
]
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// merge all names when prev and current both have the same isTypeOnly set
|
|
144
|
-
if (prevByPath && Array.isArray(prevByPath.name) && Array.isArray(name) && prevByPath.isTypeOnly === curr.isTypeOnly) {
|
|
145
|
-
prevByPath.name = [...new Set([...prevByPath.name, ...name])]
|
|
146
|
-
|
|
147
|
-
return prev
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// no import was found in the source, ignore import
|
|
151
|
-
if (!Array.isArray(name) && name && !hasImportInSource(name)) {
|
|
152
|
-
return prev
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return [...prev, curr]
|
|
156
|
-
},
|
|
157
|
-
[] as Array<KubbFile.Import>,
|
|
158
|
-
)
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Helper to create a file with name and id set
|
|
163
|
-
*/
|
|
164
|
-
export function createFile<TMeta extends object = object>(file: KubbFile.File<TMeta>): KubbFile.ResolvedFile<TMeta> {
|
|
165
|
-
const extname = path.extname(file.baseName) as KubbFile.Extname
|
|
166
|
-
if (!extname) {
|
|
167
|
-
throw new Error(`No extname found for ${file.baseName}`)
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const source = file.sources.map((item) => item.value).join('\n\n')
|
|
171
|
-
const exports = file.exports?.length ? combineExports(file.exports) : []
|
|
172
|
-
const imports = file.imports?.length && source ? combineImports(file.imports, exports, source) : []
|
|
173
|
-
const sources = file.sources?.length ? combineSources(file.sources) : []
|
|
174
|
-
|
|
175
|
-
return {
|
|
176
|
-
...file,
|
|
177
|
-
id: hashObject({ path: file.path }),
|
|
178
|
-
name: trimExtName(file.baseName),
|
|
179
|
-
extname,
|
|
180
|
-
imports: imports,
|
|
181
|
-
exports: exports,
|
|
182
|
-
sources: sources,
|
|
183
|
-
meta: file.meta || ({} as TMeta),
|
|
184
|
-
}
|
|
19
|
+
type Options = {
|
|
20
|
+
events?: AsyncEventEmitter<AppEvents>
|
|
185
21
|
}
|
|
186
22
|
|
|
187
23
|
export class FileManager {
|
|
188
24
|
#cache = new Cache<KubbFile.ResolvedFile>()
|
|
189
|
-
|
|
25
|
+
processor: FileProcessor
|
|
190
26
|
|
|
191
|
-
constructor() {
|
|
27
|
+
constructor({ events = new AsyncEventEmitter<AppEvents>() }: Options = {}) {
|
|
28
|
+
this.processor = new FileProcessor({ events })
|
|
192
29
|
return this
|
|
193
30
|
}
|
|
194
31
|
|
|
@@ -237,7 +74,7 @@ export class FileManager {
|
|
|
237
74
|
this.#cache.clear()
|
|
238
75
|
}
|
|
239
76
|
|
|
240
|
-
|
|
77
|
+
get files(): Array<KubbFile.ResolvedFile> {
|
|
241
78
|
const cachedKeys = this.#cache.keys()
|
|
242
79
|
|
|
243
80
|
// order by path length and if file is a barrel file
|
|
@@ -248,23 +85,7 @@ export class FileManager {
|
|
|
248
85
|
return files.filter(Boolean)
|
|
249
86
|
}
|
|
250
87
|
|
|
251
|
-
async
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const promises = files.map((resolvedFile) => {
|
|
255
|
-
return this.#limit(async () => {
|
|
256
|
-
const extname = extension ? extension[resolvedFile.extname] || undefined : resolvedFile.extname
|
|
257
|
-
|
|
258
|
-
if (!dryRun) {
|
|
259
|
-
const source = await parseFile(resolvedFile, { extname })
|
|
260
|
-
|
|
261
|
-
await write(resolvedFile.path, source, { sanity: false })
|
|
262
|
-
}
|
|
263
|
-
})
|
|
264
|
-
})
|
|
265
|
-
|
|
266
|
-
await Promise.all(promises)
|
|
267
|
-
|
|
268
|
-
return files
|
|
88
|
+
async write(options: ProcessFilesProps): Promise<KubbFile.ResolvedFile[]> {
|
|
89
|
+
return this.processor.run(this.files, options)
|
|
269
90
|
}
|
|
270
91
|
}
|