fix: исправлен путь к шаблонам, добавлена валидация результата генерации
- путь к шаблонам теперь корректен при установке через npm (resolve(__dirname, 'templates')) - проверка существования директории шаблонов перед генерацией - проверка что файлы реально созданы после генерации - добавлена мета-информация в package.json (автор, репозиторий) - переименован AI-PROJECT-OVERVIEW.md в AGENTS.md - версия 1.0.5
This commit is contained in:
14
package.json
14
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@gromlab/api-codegen",
|
"name": "@gromlab/api-codegen",
|
||||||
"version": "1.0.3",
|
"version": "1.0.5",
|
||||||
"description": "CLI tool to generate TypeScript API client from OpenAPI specification",
|
"description": "CLI tool to generate TypeScript API client from OpenAPI specification",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"bin": {
|
"bin": {
|
||||||
@@ -57,6 +57,14 @@
|
|||||||
"generator",
|
"generator",
|
||||||
"cli"
|
"cli"
|
||||||
],
|
],
|
||||||
"author": "",
|
"author": "S.Gromov",
|
||||||
"license": "MIT"
|
"license": "MIT",
|
||||||
|
"homepage": "https://gromlab.ru/gromov/api-codegen",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://gromlab.ru/gromov/api-codegen.git"
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://gromlab.ru/gromov/api-codegen/issues"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
import { generateApi as swaggerGenerateApi } from 'swagger-typescript-api';
|
import { generateApi as swaggerGenerateApi } from 'swagger-typescript-api';
|
||||||
import { resolve } from 'path';
|
import { resolve, join } from 'path';
|
||||||
import { fileURLToPath } from 'url';
|
import { fileURLToPath } from 'url';
|
||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
import { existsSync } from 'fs';
|
||||||
import type { GeneratorConfig } from './config.js';
|
import type { GeneratorConfig } from './config.js';
|
||||||
import { ensureDir, readJsonFile } from './utils/file.js';
|
import { ensureDir, readJsonFile } from './utils/file.js';
|
||||||
|
|
||||||
@@ -16,7 +17,9 @@ export async function generate(config: GeneratorConfig): Promise<void> {
|
|||||||
await ensureDir(config.outputPath);
|
await ensureDir(config.outputPath);
|
||||||
|
|
||||||
// Путь к кастомным шаблонам
|
// Путь к кастомным шаблонам
|
||||||
const templatesPath = resolve(__dirname, '../src/templates');
|
// В dev-режиме (bun run src/cli.ts): __dirname = .../src, шаблоны в ./templates
|
||||||
|
// В собранной версии (dist/cli.js): __dirname = .../dist, шаблоны в ./templates (скопированы при сборке)
|
||||||
|
const templatesPath = resolve(__dirname, 'templates');
|
||||||
|
|
||||||
// Проверяем тип входного пути
|
// Проверяем тип входного пути
|
||||||
const isUrl = config.inputPath.startsWith('http://') || config.inputPath.startsWith('https://');
|
const isUrl = config.inputPath.startsWith('http://') || config.inputPath.startsWith('https://');
|
||||||
@@ -45,11 +48,22 @@ export async function generate(config: GeneratorConfig): Promise<void> {
|
|||||||
: 'Api';
|
: 'Api';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Проверяем, что директория с шаблонами существует
|
||||||
|
if (!existsSync(templatesPath)) {
|
||||||
|
throw new Error(
|
||||||
|
`Templates directory not found: ${templatesPath}. ` +
|
||||||
|
`Make sure the package is built correctly (run "bun run build").`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const outputDir = resolve(config.outputPath);
|
||||||
|
const outputFileName = `${fileName}.ts`;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await swaggerGenerateApi({
|
const { files } = await swaggerGenerateApi({
|
||||||
...(isUrl ? { url } : { input: inputPath }),
|
...(isUrl ? { url } : { input: inputPath }),
|
||||||
output: resolve(config.outputPath),
|
output: outputDir,
|
||||||
fileName: `${fileName}.ts`,
|
fileName: outputFileName,
|
||||||
httpClientType: 'fetch',
|
httpClientType: 'fetch',
|
||||||
modular: false,
|
modular: false,
|
||||||
templates: templatesPath,
|
templates: templatesPath,
|
||||||
@@ -112,10 +126,26 @@ export async function generate(config: GeneratorConfig): Promise<void> {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
// Генерация успешна
|
// Проверяем, что файлы были сгенерированы
|
||||||
|
if (!files || files.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
'Generation completed but no files were produced. ' +
|
||||||
|
'Check that the OpenAPI specification is valid.'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем, что выходной файл существует на диске
|
||||||
|
const outputFilePath = join(outputDir, outputFileName);
|
||||||
|
if (!existsSync(outputFilePath)) {
|
||||||
|
throw new Error(
|
||||||
|
`Generation completed but output file was not created: ${outputFilePath}`
|
||||||
|
);
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('❌ Generation failed:', error);
|
if (error instanceof Error && error.message.startsWith('Generation completed')) {
|
||||||
throw error;
|
throw error;
|
||||||
|
}
|
||||||
|
throw new Error(`Generation failed: ${error instanceof Error ? error.message : error}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
|
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
|
||||||
import { execa } from 'execa';
|
import { execa } from 'execa';
|
||||||
|
import { readFileSync } from 'fs';
|
||||||
import { setupTest } from '../helpers/setup.js';
|
import { setupTest } from '../helpers/setup.js';
|
||||||
import { FIXTURES } from '../helpers/fixtures.js';
|
import { FIXTURES } from '../helpers/fixtures.js';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
@@ -8,6 +9,7 @@ import { fileURLToPath } from 'url';
|
|||||||
import { dirname } from 'path';
|
import { dirname } from 'path';
|
||||||
|
|
||||||
const __filename = fileURLToPath(import.meta.url);
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const pkg = JSON.parse(readFileSync(join(dirname(__filename), '../../package.json'), 'utf-8'));
|
||||||
const __dirname = dirname(__filename);
|
const __dirname = dirname(__filename);
|
||||||
const CLI_PATH = join(__dirname, '../../src/cli.ts');
|
const CLI_PATH = join(__dirname, '../../src/cli.ts');
|
||||||
|
|
||||||
@@ -70,7 +72,7 @@ describe('CLI', () => {
|
|||||||
test('должен отображать версию с --version', async () => {
|
test('должен отображать версию с --version', async () => {
|
||||||
const { stdout } = await execa('bun', ['run', CLI_PATH, '--version']);
|
const { stdout } = await execa('bun', ['run', CLI_PATH, '--version']);
|
||||||
|
|
||||||
expect(stdout).toContain('1.0.0');
|
expect(stdout).toContain(pkg.version);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('должен отображать help с --help', async () => {
|
test('должен отображать help с --help', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user