@paulpugovkin/api-docs-axios-ts-generator 1.0.6 → 1.0.8
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/package.json +3 -3
- package/src/index.js +166 -0
- package/src/index.min.js +0 -2
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@paulpugovkin/api-docs-axios-ts-generator",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Generate TypeScript interfaces and axios classes from OpenAPI documentation",
|
|
5
|
-
"main": "src/index.
|
|
5
|
+
"main": "src/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"api-docs-generator": "./
|
|
7
|
+
"api-docs-generator": "./bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"types": "src/types/index.d.ts",
|
|
10
10
|
"scripts": {
|
package/src/index.js
ADDED
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
const {program} = require("commander");
|
|
2
|
+
const path = require("path");
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
|
|
5
|
+
// Модули генератора
|
|
6
|
+
const {
|
|
7
|
+
cleanGeneratedFolder,
|
|
8
|
+
} = require("./clean-generated-folder/cleanGeneratedFolder");
|
|
9
|
+
const {
|
|
10
|
+
updateApiDocsJson,
|
|
11
|
+
} = require("./update-api-docs-json/updateApiDocsJson");
|
|
12
|
+
const {parseAndGenerate} = require("./parse-and-generate/parseAndGenerate");
|
|
13
|
+
const {
|
|
14
|
+
generateIndexFileWithOpenApi,
|
|
15
|
+
} = require("./generate-index-file-with-public-api/generateIndexFileWithPublicApi");
|
|
16
|
+
const {
|
|
17
|
+
generateMainIndexFile,
|
|
18
|
+
} = require("./generate-main-index-file/generateMainIndexFile");
|
|
19
|
+
const {generateAxiosConfig} = require("./generators/axiosConfigGenerator");
|
|
20
|
+
|
|
21
|
+
// Simple configuration loader
|
|
22
|
+
const fs = require('fs');
|
|
23
|
+
const path = require('path');
|
|
24
|
+
|
|
25
|
+
async function loadConfig(configPath, cliOptions = {}) {
|
|
26
|
+
const resolvedPath = path.resolve(configPath);
|
|
27
|
+
|
|
28
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
29
|
+
throw new Error(`Configuration file not found: ${resolvedPath}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const ext = path.extname(resolvedPath);
|
|
33
|
+
let config;
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
if (ext === '.js') {
|
|
37
|
+
const modulePath = resolvedPath;
|
|
38
|
+
config = require(modulePath);
|
|
39
|
+
} else if (ext === '.json') {
|
|
40
|
+
const content = fs.readFileSync(resolvedPath, 'utf8');
|
|
41
|
+
config = JSON.parse(content);
|
|
42
|
+
} else if (ext === '.ts') {
|
|
43
|
+
const ts = require('typescript');
|
|
44
|
+
const result = ts.transpileModule(content, {
|
|
45
|
+
compilerOptions: {
|
|
46
|
+
module: 1, // CommonJS
|
|
47
|
+
target: 99, // ESNext
|
|
48
|
+
esModuleInterop: true,
|
|
49
|
+
},
|
|
50
|
+
});
|
|
51
|
+
const modulePath = resolvedPath.replace('.ts', '.js');
|
|
52
|
+
fs.writeFileSync(modulePath, result.outputText);
|
|
53
|
+
config = require(modulePath);
|
|
54
|
+
} else {
|
|
55
|
+
throw new Error(`Unsupported configuration file format. Use .js, .json, or .ts`);
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
throw new Error(`Failed to load configuration: ${error.message}`);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Merge CLI options with config
|
|
62
|
+
return {
|
|
63
|
+
...config,
|
|
64
|
+
...cliOptions,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Основной инструмент CLI
|
|
69
|
+
program
|
|
70
|
+
.version("1.0.0")
|
|
71
|
+
.description("Generate TypeScript API client from OpenAPI documentation")
|
|
72
|
+
.option("-c, --config <path>", "Path to configuration file")
|
|
73
|
+
.option("--api-docs-url <url>", "URL to fetch the OpenAPI documentation")
|
|
74
|
+
.option("--api-docs-path <path>", "Local path to OpenAPI documentation file")
|
|
75
|
+
.option("--output-dir <dir>", "Output directory for generated files")
|
|
76
|
+
.option("--clean", "Clean output directory before generation")
|
|
77
|
+
.parse(process.argv);
|
|
78
|
+
|
|
79
|
+
// Основной вызов
|
|
80
|
+
async function main() {
|
|
81
|
+
const options = program.opts();
|
|
82
|
+
const configPath = options.config;
|
|
83
|
+
|
|
84
|
+
let config = null;
|
|
85
|
+
|
|
86
|
+
// Загрузка конфигурации из файла или использование CLI аргументов
|
|
87
|
+
if (configPath) {
|
|
88
|
+
try {
|
|
89
|
+
config = await loadConfig(configPath, {
|
|
90
|
+
apiDocsUrl: options.apiDocsUrl,
|
|
91
|
+
apiDocsPath: options.apiDocsPath,
|
|
92
|
+
outputDir: options.outputDir,
|
|
93
|
+
});
|
|
94
|
+
} catch (error) {
|
|
95
|
+
console.error(`Failed to load configuration: ${error.message}`);
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
} else {
|
|
99
|
+
// Режим обратной совместимости - использование CLI аргументов
|
|
100
|
+
const apiDocsUrl = options.apiDocsUrl;
|
|
101
|
+
const outputDir = options.outputDir || path.resolve(__dirname, "../generated");
|
|
102
|
+
|
|
103
|
+
// Проверяем, указан ли URL для API документации
|
|
104
|
+
if (!apiDocsUrl) {
|
|
105
|
+
console.error('Error: API documentation URL is required.');
|
|
106
|
+
console.error('Please specify --api-docs-url or --api-docs-path, or create a configuration file.');
|
|
107
|
+
console.error('Run "api-docs-generator --help" for more information.');
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
config = {
|
|
112
|
+
apiDocsUrl: apiDocsUrl,
|
|
113
|
+
outputDir: outputDir,
|
|
114
|
+
interfacesDir: path.join(outputDir, "interfaces"),
|
|
115
|
+
classesDir: path.join(outputDir, "classes"),
|
|
116
|
+
groupBy: "tag",
|
|
117
|
+
classMode: "multiple",
|
|
118
|
+
options: {
|
|
119
|
+
cleanOutputDir: options.clean !== undefined ? options.clean : true,
|
|
120
|
+
generateAxiosConfig: false,
|
|
121
|
+
generateIndexFiles: true,
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
console.log(`Using API Docs URL: ${config.apiDocsUrl}`);
|
|
127
|
+
console.log(`Output directory: ${config.outputDir}`);
|
|
128
|
+
|
|
129
|
+
// Определяем пути
|
|
130
|
+
const outputDir = config.outputDir;
|
|
131
|
+
const interfacesDir = config.interfacesDir || path.join(outputDir, "interfaces");
|
|
132
|
+
const classesDir = config.classesDir || path.join(outputDir, "classes");
|
|
133
|
+
const interfacesOpenApi = path.join(interfacesDir, "index.ts");
|
|
134
|
+
const classesOpenApi = path.join(classesDir, "index.ts");
|
|
135
|
+
|
|
136
|
+
// Очищаем папку, если нужно
|
|
137
|
+
if (config.options?.cleanOutputDir !== false) {
|
|
138
|
+
cleanGeneratedFolder(outputDir);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Обновляем API-документацию
|
|
142
|
+
if (config.apiDocsUrl) {
|
|
143
|
+
await updateApiDocsJson(config.apiDocsUrl, "api-docs.json");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// Генерация кода на основе спецификаций OpenAPI
|
|
147
|
+
const apiDocsPath = config.apiDocsPath || "api-docs.json";
|
|
148
|
+
await parseAndGenerate(apiDocsPath, config);
|
|
149
|
+
|
|
150
|
+
// Генерация конфигурации axios, если нужно
|
|
151
|
+
if (config.options?.generateAxiosConfig) {
|
|
152
|
+
generateAxiosConfig(config, outputDir);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Генерация файлов index.ts для интерфейсов
|
|
156
|
+
if (config.options?.generateIndexFiles !== false) {
|
|
157
|
+
await generateIndexFileWithOpenApi(interfacesDir, interfacesOpenApi);
|
|
158
|
+
await generateIndexFileWithOpenApi(classesDir, classesOpenApi);
|
|
159
|
+
await generateMainIndexFile(outputDir);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
console.log("Generation completed successfully.");
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Вызов
|
|
166
|
+
main().catch((err) => console.error("Error during generation:", err));
|
package/src/index.min.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
const fs=require('fs'),path=require('path'),{program}=require('commander'),{parseAndGenerate}=require('./parse-and-generate/parseAndGenerate'),{cleanGeneratedFolder}=require('./clean-generated-folder/cleanGeneratedFolder'),{collectGeneratedFiles}=require('./collect-genereted-files/collectGeneratedFiles'),{generateInterface}=require('./generate-interface/generateInterface'),{generateClass}=require('./generate-class/generateClass'),{generateMethod}=require('./generate-method/generateMethod'),{generateJSDoc}=require('./generate-js-doc/generateJSDoc'),{generateIndexFileWithPublicApi}=require('./generate-index-file-with-public-api/generateIndexFileWithPublicApi'),{generateMainIndexFile}=require('./generate-main-index-file/generateMainIndexFile'),{generateAxiosConfig}=require('./generators/axiosConfigGenerator'),{mapType}=require('./map-type/mapType'),{resolveType}=require('./resolve-type/resolveType'),{updateApiDocsJson}=require('./update-api-docs-json/updateApiDocsJson');program.name('api-docs-generator').description('Generate TypeScript interfaces and axios classes from OpenAPI documentation').version('1.0.5').option('-c, --config <path>','Path to configuration file').option('--api-docs-url <url>','URL to fetch OpenAPI documentation').option('--api-docs-path <path>','Local path to OpenAPI documentation file').option('--output-dir <dir>','Output directory for generated files').option('--clean','Clean output directory before generation');program.parse(process.argv);async function main(){let config;const options=program.opts();if(options.config){try{const configPath=path.resolve(options.config);if(!fs.existsSync(configPath)){console.error(`Configuration file not found: ${configPath}`);process.exit(1);}const configContent=fs.readFileSync(configPath,'utf8');const ext=path.extname(configPath);if(ext==='.js'){const modulePath=path.resolve(configPath);config=eval(`require('${modulePath.replace(/\\/g,'\\\\')}')`);}else if(ext==='.json'){config=JSON.parse(configContent);}else if(ext==='.ts'){const ts=require('typescript');const result=ts.transpileModule(configContent,{compilerOptions:{module:1,target:99,esModuleInterop:!0}});const modulePath=path.resolve(configPath.replace('.ts','.js'));fs.writeFileSync(modulePath,result);config=eval(`require('${modulePath.replace(/\\/g,'\\\\')}')`);}else{console.error('Unsupported configuration file format. Use .js, .json, or .ts');process.exit(1);}}catch(error){console.error(`Failed to load configuration: ${error.message}`);process.exit(1);}}else{const apiDocsUrl=options.apiDocsUrl;if(!apiDocsUrl){console.error('Error: API documentation URL is required.');console.error('Please specify --api-docs-url or --api-docs-path, or create a configuration file.');console.error('Run "api-docs-generator --help" for more information.');process.exit(1);}const outputDir=options.outputDir||path.resolve(__dirname,"../generated");config={apiDocsUrl:apiDocsUrl,outputDir:outputDir,interfacesDir:path.join(outputDir,"interfaces"),classesDir:path.join(outputDir,"classes"),groupBy:"tag",classMode:"multiple",options:{cleanOutputDir:options.clean!==undefined?options.clean:!0,generateAxiosConfig:!1,allowAxiosConfigSpread:!0}};}await cleanGeneratedFolder(config);const apiDocs=await updateApiDocsJson(config);const schemaData=apiDocs.paths?apiDocs.paths:apiDocs.components?.schemas||{};const generatedFiles=await collectGeneratedFiles(config);const interfaces=generatedFiles.filter(f=>f.endsWith('.ts')&&!f.includes('index'));const classes=generatedFiles.filter(f=>f.endsWith('.ts')&&!f.includes('index'));await generateInterface(schemaData,interfaces,config);await generateClass(schemaData,classes,config);await generateJSDoc(schemaData,classes,config);await generateMethod(schemaData,classes,config);await generateIndexFileWithPublicApi(config);await generateMainIndexFile(config);await generateAxiosConfig(config);console.log('✓ API client generated successfully!');console.log(` Output directory: ${config.outputDir}`);}main().catch(error=>{console.error('Error:',error.message);process.exit(1);});
|