ts-openapi-codegen 2.0.0-beta.2 → 2.0.0-beta.4

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 (91) hide show
  1. package/dist/cli/{generate/runGenerateOpenApi.d.ts → generateOpenApiClient/generateOpenApiClient.d.ts} +2 -2
  2. package/dist/cli/generateOpenApiClient/generateOpenApiClient.d.ts.map +1 -0
  3. package/dist/cli/{generate/runGenerateOpenApi.js → generateOpenApiClient/generateOpenApiClient.js} +32 -11
  4. package/dist/cli/index.js +20 -2
  5. package/dist/cli/previewChanges/previewChanges.d.ts +8 -0
  6. package/dist/cli/previewChanges/previewChanges.d.ts.map +1 -0
  7. package/dist/cli/previewChanges/previewChanges.js +182 -0
  8. package/dist/cli/previewChanges/utils/compareFiles.d.ts +6 -0
  9. package/dist/cli/previewChanges/utils/compareFiles.d.ts.map +1 -0
  10. package/dist/cli/previewChanges/utils/compareFiles.js +50 -0
  11. package/dist/cli/previewChanges/utils/formatDiff.d.ts +6 -0
  12. package/dist/cli/previewChanges/utils/formatDiff.d.ts.map +1 -0
  13. package/dist/cli/previewChanges/utils/formatDiff.js +30 -0
  14. package/dist/cli/previewChanges/utils/isDirectoryEmpty.d.ts +5 -0
  15. package/dist/cli/previewChanges/utils/isDirectoryEmpty.d.ts.map +1 -0
  16. package/dist/cli/previewChanges/utils/isDirectoryEmpty.js +17 -0
  17. package/dist/cli/previewChanges/utils/readDirectoryRecursive.d.ts +5 -0
  18. package/dist/cli/previewChanges/utils/readDirectoryRecursive.d.ts.map +1 -0
  19. package/dist/cli/previewChanges/utils/readDirectoryRecursive.js +28 -0
  20. package/dist/cli/previewChanges/utils/updateOutputPaths.d.ts +10 -0
  21. package/dist/cli/previewChanges/utils/updateOutputPaths.d.ts.map +1 -0
  22. package/dist/cli/previewChanges/utils/updateOutputPaths.js +106 -0
  23. package/dist/cli/schemas/base.d.ts +17 -0
  24. package/dist/cli/schemas/base.d.ts.map +1 -0
  25. package/dist/cli/schemas/base.js +19 -0
  26. package/dist/cli/schemas/checkConfig.d.ts +6 -0
  27. package/dist/cli/schemas/checkConfig.d.ts.map +1 -0
  28. package/dist/cli/schemas/checkConfig.js +5 -0
  29. package/dist/cli/schemas/generate.d.ts +32 -0
  30. package/dist/cli/schemas/generate.d.ts.map +1 -0
  31. package/dist/cli/schemas/generate.js +56 -0
  32. package/dist/cli/schemas/index.d.ts +7 -0
  33. package/dist/cli/schemas/index.d.ts.map +1 -0
  34. package/dist/cli/schemas/index.js +21 -0
  35. package/dist/cli/schemas/init.d.ts +8 -0
  36. package/dist/cli/schemas/init.d.ts.map +1 -0
  37. package/dist/cli/schemas/init.js +9 -0
  38. package/dist/cli/schemas/updateConfig.d.ts +6 -0
  39. package/dist/cli/schemas/updateConfig.d.ts.map +1 -0
  40. package/dist/cli/schemas/updateConfig.js +5 -0
  41. package/dist/cli/validation/errorFormatter.d.ts +6 -0
  42. package/dist/cli/validation/errorFormatter.d.ts.map +1 -0
  43. package/dist/cli/validation/errorFormatter.js +113 -0
  44. package/dist/cli/validation/index.d.ts +3 -0
  45. package/dist/cli/validation/index.d.ts.map +1 -0
  46. package/dist/cli/validation/index.js +18 -0
  47. package/dist/cli/validation/validateCLIOptions.d.ts +27 -0
  48. package/dist/cli/validation/validateCLIOptions.d.ts.map +1 -0
  49. package/dist/cli/validation/validateCLIOptions.js +38 -0
  50. package/dist/common/TRawOptions.d.ts +4 -37
  51. package/dist/common/TRawOptions.d.ts.map +1 -1
  52. package/dist/common/VersionedSchema/AllVersionedSchemas/AllMigrationPlans.d.ts.map +1 -1
  53. package/dist/common/VersionedSchema/AllVersionedSchemas/AllMigrationPlans.js +9 -11
  54. package/dist/common/VersionedSchema/AllVersionedSchemas/UnifiedOptionsSchemaV1.d.ts.map +1 -1
  55. package/dist/common/VersionedSchema/AllVersionedSchemas/UnifiedOptionsSchemaV1.js +5 -6
  56. package/dist/common/VersionedSchema/AllVersionedSchemas/UnifiedOptionsSchemaV2.d.ts.map +1 -1
  57. package/dist/common/VersionedSchema/AllVersionedSchemas/UnifiedOptionsSchemaV2.js +5 -6
  58. package/dist/common/VersionedSchema/MultiOptionsVersioned/MultiOptionsMigrationPlan.d.ts.map +1 -1
  59. package/dist/common/VersionedSchema/MultiOptionsVersioned/MultiOptionsMigrationPlan.js +9 -16
  60. package/dist/common/VersionedSchema/OptionsVersioned/OptionsMigrationPlans.d.ts.map +1 -1
  61. package/dist/common/VersionedSchema/OptionsVersioned/OptionsMigrationPlans.js +2 -5
  62. package/dist/common/VersionedSchema/Utils/createFieldTransformationMigration.d.ts +32 -0
  63. package/dist/common/VersionedSchema/Utils/createFieldTransformationMigration.d.ts.map +1 -0
  64. package/dist/common/VersionedSchema/Utils/createFieldTransformationMigration.js +40 -0
  65. package/dist/common/VersionedSchema/Utils/getLatestVersionFromMigrationPlans.d.ts +16 -0
  66. package/dist/common/VersionedSchema/Utils/getLatestVersionFromMigrationPlans.d.ts.map +1 -0
  67. package/dist/common/VersionedSchema/Utils/getLatestVersionFromMigrationPlans.js +23 -0
  68. package/dist/common/schemas/configSchemas.d.ts +91 -0
  69. package/dist/common/schemas/configSchemas.d.ts.map +1 -0
  70. package/dist/common/schemas/configSchemas.js +131 -0
  71. package/dist/common/utils/fileSystemHelpers.d.ts +3 -1
  72. package/dist/common/utils/fileSystemHelpers.d.ts.map +1 -1
  73. package/dist/common/utils/fileSystemHelpers.js +3 -0
  74. package/dist/core/OpenApiClient.d.ts.map +1 -1
  75. package/dist/core/OpenApiClient.js +36 -1
  76. package/dist/core/__tests__/WriteClient.test.js +0 -4
  77. package/dist/core/utils/__mocks__/templates.d.ts.map +1 -1
  78. package/dist/core/utils/__mocks__/templates.js +0 -4
  79. package/dist/core/utils/__tests__/registerHandlebarTemplates.test.js +2 -0
  80. package/dist/core/utils/registerHandlebarTemplates.d.ts +1 -5
  81. package/dist/core/utils/registerHandlebarTemplates.d.ts.map +1 -1
  82. package/dist/core/utils/registerHandlebarTemplates.js +9 -10
  83. package/dist/core/utils/writeClientSchemas.d.ts.map +1 -1
  84. package/dist/core/utils/writeClientSchemas.js +22 -31
  85. package/dist/templatesCompiled/client/core/request-executor.js +1 -1
  86. package/dist/templatesCompiled/client/partials/parameters.js +1 -1
  87. package/dist/templatesCompiled/client/partials/serviceOption.d.ts +1 -4
  88. package/dist/templatesCompiled/client/partials/serviceOption.d.ts.map +1 -1
  89. package/dist/templatesCompiled/client/partials/serviceOption.js +28 -48
  90. package/package.json +4 -2
  91. package/dist/cli/generate/runGenerateOpenApi.d.ts.map +0 -1
@@ -3,5 +3,5 @@ import { OptionValues } from 'commander';
3
3
  * Запускает генерацию OpenAPI клиента
4
4
  * Поддерживает как конфиг-файл, так и параметры из CLI
5
5
  */
6
- export declare function runGenerateOpenApi(options: OptionValues): Promise<void>;
7
- //# sourceMappingURL=runGenerateOpenApi.d.ts.map
6
+ export declare function generateOpenApiClient(options: OptionValues): Promise<void>;
7
+ //# sourceMappingURL=generateOpenApiClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateOpenApiClient.d.ts","sourceRoot":"","sources":["../../../src/cli/generateOpenApiClient/generateOpenApiClient.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAgBzC;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA8DhF"}
@@ -33,34 +33,55 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.runGenerateOpenApi = runGenerateOpenApi;
36
+ exports.generateOpenApiClient = generateOpenApiClient;
37
37
  const Consts_1 = require("../../common/Consts");
38
38
  const defaultOptions_1 = require("../../common/defaultOptions");
39
39
  const Enums_1 = require("../../common/Enums");
40
+ const LoggerMessages_1 = require("../../common/LoggerMessages");
40
41
  const convertArrayToObject_1 = require("../../common/utils/convertArrayToObject");
41
42
  const loadConfigIfExists_1 = require("../../common/utils/loadConfigIfExists");
42
43
  const AllMigrationPlans_1 = require("../../common/VersionedSchema/AllVersionedSchemas/AllMigrationPlans");
43
44
  const AllVersionedSchemas_1 = require("../../common/VersionedSchema/AllVersionedSchemas/AllVersionedSchemas");
44
45
  const migrateDataToLatestSchemaVersion_1 = require("../../common/VersionedSchema/Utils/migrateDataToLatestSchemaVersion");
45
46
  const OpenAPI = __importStar(require("../../core"));
47
+ const generate_1 = require("../schemas/generate");
48
+ const validation_1 = require("../validation");
46
49
  /**
47
50
  * Запускает генерацию OpenAPI клиента
48
51
  * Поддерживает как конфиг-файл, так и параметры из CLI
49
52
  */
50
- async function runGenerateOpenApi(options) {
53
+ async function generateOpenApiClient(options) {
51
54
  const { openapiConfig, ...clientOptions } = options;
52
55
  try {
53
- const hasMinimumRequiredOptions = !!clientOptions.input && !!clientOptions.output;
56
+ // Валидация опций через Zod
57
+ const validationResult = (0, validation_1.validateCLIOptions)(generate_1.generateOptionsSchema, {
58
+ openapiConfig,
59
+ ...clientOptions,
60
+ });
61
+ if (!validationResult.success) {
62
+ Consts_1.APP_LOGGER.error(validationResult.error);
63
+ process.exit(1);
64
+ }
65
+ const validatedOptions = validationResult.data;
66
+ // Если есть минимальные опции (input и output), используем их
67
+ const hasMinimumRequiredOptions = !!validatedOptions.input && !!validatedOptions.output;
54
68
  if (hasMinimumRequiredOptions) {
55
- const { error: defaultValuesError, value } = defaultOptions_1.defaultOptions.validate(clientOptions);
69
+ // Используем старую Joi валидацию для обратной совместимости
70
+ // В будущем можно заменить на Zod
71
+ const { error: defaultValuesError, value } = defaultOptions_1.defaultOptions.validate({
72
+ input: validatedOptions.input,
73
+ output: validatedOptions.output,
74
+ ...clientOptions,
75
+ });
56
76
  if (defaultValuesError) {
57
77
  await OpenAPI.generate(value);
58
78
  process.exit(0);
59
79
  }
60
80
  }
61
- const configData = (0, loadConfigIfExists_1.loadConfigIfExists)(openapiConfig);
81
+ const configData = (0, loadConfigIfExists_1.loadConfigIfExists)(validatedOptions.openapiConfig);
62
82
  if (!configData) {
63
- Consts_1.APP_LOGGER.error('The configuration file is missing');
83
+ Consts_1.APP_LOGGER.error(LoggerMessages_1.LOGGER_MESSAGES.CONFIG.FILE_MISSING);
84
+ process.exit(1);
64
85
  }
65
86
  const preparedOptions = (0, convertArrayToObject_1.convertArrayToObject)(configData);
66
87
  // Use unified migration system for all schema types
@@ -71,15 +92,15 @@ async function runGenerateOpenApi(options) {
71
92
  migrationMode: Enums_1.EMigrationMode.GENERATE_OPENAPI,
72
93
  });
73
94
  if (!migratedOptions) {
74
- Consts_1.APP_LOGGER.error("Couldn't convert the set of options to the current version");
75
- }
76
- else {
77
- const { value } = migratedOptions;
78
- await OpenAPI.generate(value);
95
+ Consts_1.APP_LOGGER.error(LoggerMessages_1.LOGGER_MESSAGES.CONFIG.CONVERSION_FAILED);
96
+ process.exit(1);
79
97
  }
98
+ const { value } = migratedOptions;
99
+ await OpenAPI.generate(value);
80
100
  process.exit(0);
81
101
  }
82
102
  catch (error) {
83
103
  Consts_1.APP_LOGGER.error(error.message);
104
+ process.exit(1);
84
105
  }
85
106
  }
package/dist/cli/index.js CHANGED
@@ -14,9 +14,10 @@ const HttpClient_enum_1 = require("../core/types/enums/HttpClient.enum");
14
14
  const ValidationLibrary_enum_1 = require("../core/types/enums/ValidationLibrary.enum");
15
15
  const checkConfig_1 = require("./checkAndUpdateConfig/checkConfig");
16
16
  const updateConfig_1 = require("./checkAndUpdateConfig/updateConfig");
17
- const runGenerateOpenApi_1 = require("./generate/runGenerateOpenApi");
17
+ const generateOpenApiClient_1 = require("./generateOpenApiClient/generateOpenApiClient");
18
18
  const Enums_2 = require("./initOpenApiConfig/Enums");
19
19
  const runInitOpenapiConfig_1 = require("./initOpenApiConfig/runInitOpenapiConfig");
20
+ const previewChanges_1 = require("./previewChanges/previewChanges");
20
21
  const utils_1 = require("./utils");
21
22
  const packageDetails = JSON.parse(fs_1.default.readFileSync((0, pathHelpers_1.joinHelper)(__dirname, '../../package.json'), 'utf-8'));
22
23
  const APP_NAME = packageDetails.name || 'ts-openapi-codegen-cli';
@@ -61,7 +62,7 @@ program
61
62
  await updateNotifier.checkAndNotify();
62
63
  })
63
64
  .action(async (options) => {
64
- await (0, runGenerateOpenApi_1.runGenerateOpenApi)(options);
65
+ await (0, generateOpenApiClient_1.generateOpenApiClient)(options);
65
66
  });
66
67
  /**
67
68
  * check - Команда для проверки конфигурационного файла
@@ -106,6 +107,23 @@ program
106
107
  .action(async (options) => {
107
108
  await (0, runInitOpenapiConfig_1.runInitOpenapiConfig)(options);
108
109
  });
110
+ /**
111
+ * preview-changes - Команда для предпросмотра изменений перед генерацией
112
+ */
113
+ program
114
+ .command('preview-changes')
115
+ .description('Preview changes that will be made to generated code before applying them')
116
+ .addHelpText('before', (0, utils_1.getCLIName)(APP_NAME))
117
+ .option('-ocn, --openapi-config <value>', 'The path to the configuration file, listing the options', Consts_1.DEFAULT_OPENAPI_CONFIG_FILENAME)
118
+ .option('-gd, --generated-dir <value>', 'Directory with previously generated code (default: "generated")', './generated')
119
+ .option('-pd, --preview-dir <value>', 'Temporary directory for preview generation (default: "generated-preview")', './generated-preview')
120
+ .option('-dd, --diff-dir <value>', 'Directory to save diff files (default: "generated-diff")', './generated-diff')
121
+ .hook('preAction', async () => {
122
+ await updateNotifier.checkAndNotify();
123
+ })
124
+ .action(async (options) => {
125
+ await (0, previewChanges_1.previewChanges)(options);
126
+ });
109
127
  program.exitOverride();
110
128
  // TODO: Включить позже!
111
129
  // program.showSuggestionAfterError(false);
@@ -0,0 +1,8 @@
1
+ import { OptionValues } from 'commander';
2
+ /**
3
+ * Основная функция для предпросмотра изменений
4
+ *
5
+ * TODO: Добавить проверку опций команды перед выполнением
6
+ */
7
+ export declare function previewChanges(options: OptionValues): Promise<void>;
8
+ //# sourceMappingURL=previewChanges.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"previewChanges.d.ts","sourceRoot":"","sources":["../../../src/cli/previewChanges/previewChanges.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AA0BzC;;;;GAIG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CA0IzE"}
@@ -0,0 +1,182 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.previewChanges = previewChanges;
37
+ const Consts_1 = require("../../common/Consts");
38
+ const Enums_1 = require("../../common/Enums");
39
+ const convertArrayToObject_1 = require("../../common/utils/convertArrayToObject");
40
+ const fileSystemHelpers_1 = require("../../common/utils/fileSystemHelpers");
41
+ const loadConfigIfExists_1 = require("../../common/utils/loadConfigIfExists");
42
+ const pathHelpers_1 = require("../../common/utils/pathHelpers");
43
+ const AllMigrationPlans_1 = require("../../common/VersionedSchema/AllVersionedSchemas/AllMigrationPlans");
44
+ const AllVersionedSchemas_1 = require("../../common/VersionedSchema/AllVersionedSchemas/AllVersionedSchemas");
45
+ const migrateDataToLatestSchemaVersion_1 = require("../../common/VersionedSchema/Utils/migrateDataToLatestSchemaVersion");
46
+ const OpenAPI = __importStar(require("../../core"));
47
+ const compareFiles_1 = require("./utils/compareFiles");
48
+ const formatDiff_1 = require("./utils/formatDiff");
49
+ const isDirectoryEmpty_1 = require("./utils/isDirectoryEmpty");
50
+ const readDirectoryRecursive_1 = require("./utils/readDirectoryRecursive");
51
+ const updateOutputPaths_1 = require("./utils/updateOutputPaths");
52
+ /**
53
+ * Основная функция для предпросмотра изменений
54
+ *
55
+ * TODO: Добавить проверку опций команды перед выполнением
56
+ */
57
+ async function previewChanges(options) {
58
+ const { openapiConfig, generatedDir = 'generated', previewDir = 'generated-preview', diffDir = 'generated-diff' } = options;
59
+ const resolvedGeneratedDir = (0, pathHelpers_1.resolveHelper)(process.cwd(), generatedDir);
60
+ const resolvedPreviewDir = (0, pathHelpers_1.resolveHelper)(process.cwd(), previewDir);
61
+ const resolvedDiffDir = (0, pathHelpers_1.resolveHelper)(process.cwd(), diffDir);
62
+ let previewDirCreated = false;
63
+ try {
64
+ // 1. Проверка директории со сгенерированным кодом
65
+ if (await (0, isDirectoryEmpty_1.isDirectoryEmpty)(resolvedGeneratedDir)) {
66
+ Consts_1.APP_LOGGER.info(`Directory "${generatedDir}" is empty or does not exist. Nothing to compare.`);
67
+ process.exit(0);
68
+ }
69
+ // 2. Создание временной директории для preview
70
+ await fileSystemHelpers_1.fileSystemHelpers.mkdir(resolvedPreviewDir);
71
+ previewDirCreated = true;
72
+ // 3. Загрузка конфигурации
73
+ const configData = (0, loadConfigIfExists_1.loadConfigIfExists)(openapiConfig);
74
+ if (!configData) {
75
+ Consts_1.APP_LOGGER.error('The configuration file is missing');
76
+ process.exit(1);
77
+ }
78
+ const preparedOptions = (0, convertArrayToObject_1.convertArrayToObject)(configData);
79
+ // Миграция опций
80
+ const migratedOptions = (0, migrateDataToLatestSchemaVersion_1.migrateDataToLatestSchemaVersion)({
81
+ rawInput: preparedOptions,
82
+ migrationPlans: AllMigrationPlans_1.allMigrationPlans,
83
+ versionedSchemas: AllVersionedSchemas_1.allVersionedSchemas,
84
+ migrationMode: Enums_1.EMigrationMode.GENERATE_OPENAPI,
85
+ });
86
+ if (!migratedOptions) {
87
+ Consts_1.APP_LOGGER.error("Couldn't convert the set of options to the current version");
88
+ process.exit(1);
89
+ }
90
+ // 4. Обновление путей output для генерации в preview директорию
91
+ const migratedValue = migratedOptions.value;
92
+ const previewOptions = (0, updateOutputPaths_1.updateOutputPaths)(migratedValue, previewDir, generatedDir);
93
+ // 5. Генерация кода в preview директорию
94
+ Consts_1.APP_LOGGER.info(`Generating code to preview directory: ${previewDir}`);
95
+ await OpenAPI.generate(previewOptions);
96
+ // 6. Сравнение файлов
97
+ Consts_1.APP_LOGGER.info('Comparing files...');
98
+ const oldFiles = await (0, readDirectoryRecursive_1.readDirectoryRecursive)(resolvedGeneratedDir);
99
+ const newFiles = await (0, readDirectoryRecursive_1.readDirectoryRecursive)(resolvedPreviewDir);
100
+ const allFiles = new Set([...oldFiles, ...newFiles]);
101
+ const changes = [];
102
+ for (const file of allFiles) {
103
+ const oldPath = (0, pathHelpers_1.joinHelper)(resolvedGeneratedDir, file);
104
+ const newPath = (0, pathHelpers_1.joinHelper)(resolvedPreviewDir, file);
105
+ const oldExists = await fileSystemHelpers_1.fileSystemHelpers.exists(oldPath);
106
+ const newExists = await fileSystemHelpers_1.fileSystemHelpers.exists(newPath);
107
+ if (oldExists && newExists) {
108
+ // Файл существует в обеих директориях - сравниваем
109
+ const fileDiff = await (0, compareFiles_1.compareFiles)(oldPath, newPath);
110
+ if (fileDiff) {
111
+ changes.push({
112
+ file,
113
+ status: 'modified',
114
+ diff: fileDiff,
115
+ });
116
+ }
117
+ else {
118
+ Consts_1.APP_LOGGER.info(`File "${file}" has no changes`);
119
+ }
120
+ }
121
+ else if (!oldExists && newExists) {
122
+ // Новый файл
123
+ changes.push({
124
+ file,
125
+ status: 'added',
126
+ });
127
+ }
128
+ else if (oldExists && !newExists) {
129
+ // Удаленный файл
130
+ changes.push({
131
+ file,
132
+ status: 'removed',
133
+ });
134
+ }
135
+ }
136
+ // 7. Сохранение результатов в diff директорию
137
+ if (changes.length > 0) {
138
+ await fileSystemHelpers_1.fileSystemHelpers.mkdir(resolvedDiffDir);
139
+ for (const change of changes) {
140
+ const diffFilePath = (0, pathHelpers_1.joinHelper)(resolvedDiffDir, `${change.file}.md`);
141
+ const diffDirPath = (0, pathHelpers_1.dirNameHelper)(diffFilePath);
142
+ await fileSystemHelpers_1.fileSystemHelpers.mkdir(diffDirPath);
143
+ let diffContent = '';
144
+ if (change.status === 'added') {
145
+ diffContent = (0, formatDiff_1.formatDiff)(change.file, change.status);
146
+ }
147
+ else if (change.status === 'removed') {
148
+ diffContent = (0, formatDiff_1.formatDiff)(change.file, change.status);
149
+ }
150
+ else if (change.diff) {
151
+ diffContent = (0, formatDiff_1.formatDiff)(change.file, change.status, change.diff);
152
+ }
153
+ await fileSystemHelpers_1.fileSystemHelpers.writeFile(diffFilePath, diffContent, 'utf-8');
154
+ Consts_1.APP_LOGGER.info(`Diff saved: ${diffFilePath}`);
155
+ }
156
+ Consts_1.APP_LOGGER.info(`\nTotal changes: ${changes.length}`);
157
+ Consts_1.APP_LOGGER.info(`Diff files saved to: ${diffDir}`);
158
+ }
159
+ else {
160
+ Consts_1.APP_LOGGER.info('No changes detected. All files are identical.');
161
+ }
162
+ // 8. Удаление временной директории preview
163
+ Consts_1.APP_LOGGER.info(`Cleaning up preview directory: ${previewDir}`);
164
+ await fileSystemHelpers_1.fileSystemHelpers.rmdir(resolvedPreviewDir);
165
+ previewDirCreated = false;
166
+ process.exit(0);
167
+ }
168
+ catch (error) {
169
+ // Очистка preview директории в случае ошибки
170
+ if (previewDirCreated) {
171
+ try {
172
+ Consts_1.APP_LOGGER.info(`Cleaning up preview directory after error: ${previewDir}`);
173
+ await fileSystemHelpers_1.fileSystemHelpers.rmdir(resolvedPreviewDir);
174
+ }
175
+ catch (cleanupError) {
176
+ Consts_1.APP_LOGGER.error(`Failed to cleanup preview directory: ${cleanupError.message}`);
177
+ }
178
+ }
179
+ Consts_1.APP_LOGGER.error(error.message);
180
+ process.exit(1);
181
+ }
182
+ }
@@ -0,0 +1,6 @@
1
+ import * as diff from 'diff';
2
+ /**
3
+ * Сравнивает два файла и возвращает diff
4
+ */
5
+ export declare function compareFiles(oldPath: string, newPath: string): Promise<diff.Change[] | null>;
6
+ //# sourceMappingURL=compareFiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compareFiles.d.ts","sourceRoot":"","sources":["../../../../src/cli/previewChanges/utils/compareFiles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B;;GAEG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAUlG"}
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.compareFiles = compareFiles;
37
+ const diff = __importStar(require("diff"));
38
+ const fileSystemHelpers_1 = require("../../../common/utils/fileSystemHelpers");
39
+ /**
40
+ * Сравнивает два файла и возвращает diff
41
+ */
42
+ async function compareFiles(oldPath, newPath) {
43
+ const oldContent = await fileSystemHelpers_1.fileSystemHelpers.readFile(oldPath, 'utf-8');
44
+ const newContent = await fileSystemHelpers_1.fileSystemHelpers.readFile(newPath, 'utf-8');
45
+ const fileDiff = diff.diffLines(oldContent, newContent);
46
+ if (fileDiff.some(part => part.added || part.removed)) {
47
+ return fileDiff;
48
+ }
49
+ return null;
50
+ }
@@ -0,0 +1,6 @@
1
+ import * as diff from 'diff';
2
+ /**
3
+ * Форматирует diff для сохранения в markdown файл
4
+ */
5
+ export declare function formatDiff(filePath: string, status: 'added' | 'modified' | 'removed', fileDiff?: diff.Change[]): string;
6
+ //# sourceMappingURL=formatDiff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatDiff.d.ts","sourceRoot":"","sources":["../../../../src/cli/previewChanges/utils/formatDiff.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B;;GAEG;AACH,wBAAgB,UAAU,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,EACxC,QAAQ,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,GACzB,MAAM,CAyBR"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatDiff = formatDiff;
4
+ /**
5
+ * Форматирует diff для сохранения в markdown файл
6
+ */
7
+ function formatDiff(filePath, status, fileDiff) {
8
+ const lines = [`# ${filePath}`, '', `**Status:** ${status.toUpperCase()}`, ''];
9
+ if (status === 'added') {
10
+ lines.push('This is a new file.');
11
+ }
12
+ else if (status === 'removed') {
13
+ lines.push('This file was deleted.');
14
+ }
15
+ else if (fileDiff) {
16
+ lines.push('## Changes', '');
17
+ lines.push('```diff');
18
+ fileDiff.forEach(part => {
19
+ const prefix = part.added ? '+' : part.removed ? '-' : ' ';
20
+ const lines_ = part.value.split('\n');
21
+ lines_.forEach(line => {
22
+ if (line || lines_.length > 1) {
23
+ lines.push(`${prefix} ${line}`);
24
+ }
25
+ });
26
+ });
27
+ lines.push('```');
28
+ }
29
+ return lines.join('\n');
30
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Проверяет, пуста ли директория
3
+ */
4
+ export declare function isDirectoryEmpty(dirPath: string): Promise<boolean>;
5
+ //# sourceMappingURL=isDirectoryEmpty.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isDirectoryEmpty.d.ts","sourceRoot":"","sources":["../../../../src/cli/previewChanges/utils/isDirectoryEmpty.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAWxE"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isDirectoryEmpty = isDirectoryEmpty;
4
+ const fileSystemHelpers_1 = require("../../../common/utils/fileSystemHelpers");
5
+ /**
6
+ * Проверяет, пуста ли директория
7
+ */
8
+ async function isDirectoryEmpty(dirPath) {
9
+ if (!(await fileSystemHelpers_1.fileSystemHelpers.exists(dirPath))) {
10
+ return true;
11
+ }
12
+ if (!fileSystemHelpers_1.fileSystemHelpers.isDirectory(dirPath)) {
13
+ return true;
14
+ }
15
+ const entries = await fileSystemHelpers_1.fileSystemHelpers.readdir(dirPath);
16
+ return entries.length === 0;
17
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Рекурсивно читает все файлы в директории
3
+ */
4
+ export declare function readDirectoryRecursive(dirPath: string, basePath?: string): Promise<string[]>;
5
+ //# sourceMappingURL=readDirectoryRecursive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readDirectoryRecursive.d.ts","sourceRoot":"","sources":["../../../../src/cli/previewChanges/utils/readDirectoryRecursive.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAgB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAqB3G"}
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readDirectoryRecursive = readDirectoryRecursive;
4
+ const fileSystemHelpers_1 = require("../../../common/utils/fileSystemHelpers");
5
+ const pathHelpers_1 = require("../../../common/utils/pathHelpers");
6
+ /**
7
+ * Рекурсивно читает все файлы в директории
8
+ */
9
+ async function readDirectoryRecursive(dirPath, basePath = dirPath) {
10
+ const files = [];
11
+ const entries = await fileSystemHelpers_1.fileSystemHelpers.readdir(dirPath);
12
+ for (const entry of entries) {
13
+ const fullPath = (0, pathHelpers_1.joinHelper)(dirPath, entry);
14
+ let relativePath = (0, pathHelpers_1.relativeHelper)(basePath, fullPath);
15
+ // Убираем префикс ./ если он есть
16
+ if (relativePath.startsWith('./')) {
17
+ relativePath = relativePath.substring(2);
18
+ }
19
+ if (fileSystemHelpers_1.fileSystemHelpers.isDirectory(fullPath)) {
20
+ const subFiles = await readDirectoryRecursive(fullPath, basePath);
21
+ files.push(...subFiles);
22
+ }
23
+ else if (fileSystemHelpers_1.fileSystemHelpers.isPathToFile(fullPath)) {
24
+ files.push(relativePath);
25
+ }
26
+ }
27
+ return files;
28
+ }
@@ -0,0 +1,10 @@
1
+ import { TRawOptions } from '../../../common/TRawOptions';
2
+ /**
3
+ * Обновляет пути output в опциях для генерации в preview директорию
4
+ * Удаляет generatedDir из путей и заменяет на previewDir
5
+ *
6
+ * Пример: generatedDir = "./test/generated", output = "./test/generated/api"
7
+ * Результат: output = "./generated-preview/api"
8
+ */
9
+ export declare function updateOutputPaths(options: TRawOptions, previewDir: string, generatedDir: string): TRawOptions;
10
+ //# sourceMappingURL=updateOutputPaths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"updateOutputPaths.d.ts","sourceRoot":"","sources":["../../../../src/cli/previewChanges/utils/updateOutputPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAG1D;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAC7B,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,GACrB,WAAW,CAuIb"}
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updateOutputPaths = updateOutputPaths;
4
+ const pathHelpers_1 = require("../../../common/utils/pathHelpers");
5
+ /**
6
+ * Обновляет пути output в опциях для генерации в preview директорию
7
+ * Удаляет generatedDir из путей и заменяет на previewDir
8
+ *
9
+ * Пример: generatedDir = "./test/generated", output = "./test/generated/api"
10
+ * Результат: output = "./generated-preview/api"
11
+ */
12
+ function updateOutputPaths(options, previewDir, generatedDir) {
13
+ const resolvedGeneratedDir = (0, pathHelpers_1.resolveHelper)(process.cwd(), generatedDir);
14
+ // const resolvedPreviewDir = resolveHelper(process.cwd(), previewDir);
15
+ /**
16
+ * Заменяет путь, удаляя generatedDir и добавляя previewDir
17
+ * Если путь находится внутри generatedDir, сохраняется относительная структура
18
+ */
19
+ const replacePath = (oldPath) => {
20
+ const resolvedOldPath = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldPath);
21
+ let relativePath = (0, pathHelpers_1.relativeHelper)(resolvedGeneratedDir, resolvedOldPath);
22
+ // Убираем префикс ./ если он есть
23
+ if (relativePath.startsWith('./')) {
24
+ relativePath = relativePath.substring(2);
25
+ }
26
+ // Если путь пустой или равен текущей директории, возвращаем previewDir
27
+ if (!relativePath || relativePath === '' || relativePath === './') {
28
+ return previewDir;
29
+ }
30
+ // Используем previewDir (относительный путь) вместо resolvedPreviewDir
31
+ return (0, pathHelpers_1.joinHelper)(previewDir, relativePath);
32
+ };
33
+ /**
34
+ * Обновляет output* пути относительно нового output
35
+ * Если output* был указан явно, сохраняем его относительную структуру от старого output
36
+ */
37
+ const updateRelativePaths = (newOutput, oldOutput, oldOutputCore, oldOutputServices, oldOutputModels, oldOutputSchemas) => {
38
+ const resolvedOldOutput = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldOutput);
39
+ const resolvedNewOutput = (0, pathHelpers_1.resolveHelper)(process.cwd(), newOutput);
40
+ const result = {};
41
+ // Для каждого output* пути, если он был указан, сохраняем относительную структуру
42
+ if (oldOutputCore) {
43
+ const resolvedOldCore = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldOutputCore);
44
+ let relativeCore = (0, pathHelpers_1.relativeHelper)(resolvedOldOutput, resolvedOldCore);
45
+ if (relativeCore.startsWith('./')) {
46
+ relativeCore = relativeCore.substring(2);
47
+ }
48
+ // Если относительный путь пустой, используем стандартное имя 'core'
49
+ result.outputCore = relativeCore && relativeCore !== '' && relativeCore !== './'
50
+ ? (0, pathHelpers_1.joinHelper)(resolvedNewOutput, relativeCore)
51
+ : (0, pathHelpers_1.joinHelper)(resolvedNewOutput, 'core');
52
+ }
53
+ if (oldOutputServices) {
54
+ const resolvedOldServices = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldOutputServices);
55
+ let relativeServices = (0, pathHelpers_1.relativeHelper)(resolvedOldOutput, resolvedOldServices);
56
+ if (relativeServices.startsWith('./')) {
57
+ relativeServices = relativeServices.substring(2);
58
+ }
59
+ result.outputServices = relativeServices && relativeServices !== '' && relativeServices !== './'
60
+ ? (0, pathHelpers_1.joinHelper)(resolvedNewOutput, relativeServices)
61
+ : (0, pathHelpers_1.joinHelper)(resolvedNewOutput, 'services');
62
+ }
63
+ if (oldOutputModels) {
64
+ const resolvedOldModels = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldOutputModels);
65
+ let relativeModels = (0, pathHelpers_1.relativeHelper)(resolvedOldOutput, resolvedOldModels);
66
+ if (relativeModels.startsWith('./')) {
67
+ relativeModels = relativeModels.substring(2);
68
+ }
69
+ result.outputModels = relativeModels && relativeModels !== '' && relativeModels !== './'
70
+ ? (0, pathHelpers_1.joinHelper)(resolvedNewOutput, relativeModels)
71
+ : (0, pathHelpers_1.joinHelper)(resolvedNewOutput, 'models');
72
+ }
73
+ if (oldOutputSchemas) {
74
+ const resolvedOldSchemas = (0, pathHelpers_1.resolveHelper)(process.cwd(), oldOutputSchemas);
75
+ let relativeSchemas = (0, pathHelpers_1.relativeHelper)(resolvedOldOutput, resolvedOldSchemas);
76
+ if (relativeSchemas.startsWith('./')) {
77
+ relativeSchemas = relativeSchemas.substring(2);
78
+ }
79
+ result.outputSchemas = relativeSchemas && relativeSchemas !== '' && relativeSchemas !== './'
80
+ ? (0, pathHelpers_1.joinHelper)(resolvedNewOutput, relativeSchemas)
81
+ : (0, pathHelpers_1.joinHelper)(resolvedNewOutput, 'schemas');
82
+ }
83
+ return result;
84
+ };
85
+ if (options.items && Array.isArray(options.items)) {
86
+ return {
87
+ ...options,
88
+ items: options.items.map(item => {
89
+ const newOutput = replacePath(item.output);
90
+ const relativePaths = updateRelativePaths(newOutput, item.output, item.outputCore, item.outputServices, item.outputModels, item.outputSchemas);
91
+ return {
92
+ ...item,
93
+ output: newOutput,
94
+ ...relativePaths,
95
+ };
96
+ }),
97
+ };
98
+ }
99
+ const newOutput = replacePath(options.output || '');
100
+ const relativePaths = updateRelativePaths(newOutput, options.output || '', options.outputCore, options.outputServices, options.outputModels, options.outputSchemas);
101
+ return {
102
+ ...options,
103
+ output: newOutput,
104
+ ...relativePaths,
105
+ };
106
+ }