helm-env-delta 1.13.0 → 1.14.0

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 (52) hide show
  1. package/README.md +15 -5
  2. package/dist/{configFile.d.ts → config/configFile.d.ts} +4 -4
  3. package/dist/{configFile.js → config/configFile.js} +1 -1
  4. package/dist/{configLoader.d.ts → config/configLoader.d.ts} +2 -2
  5. package/dist/{configLoader.js → config/configLoader.js} +2 -2
  6. package/dist/{configMerger.d.ts → config/configMerger.d.ts} +2 -2
  7. package/dist/{configMerger.js → config/configMerger.js} +2 -2
  8. package/dist/config/index.d.ts +8 -0
  9. package/dist/config/index.js +24 -0
  10. package/dist/consoleFormatter.d.ts +1 -1
  11. package/dist/index.js +26 -36
  12. package/dist/logger.d.ts +1 -1
  13. package/dist/{fileDiff.d.ts → pipeline/fileDiff.d.ts} +3 -3
  14. package/dist/{fileDiff.js → pipeline/fileDiff.js} +9 -9
  15. package/dist/{fileLoader.d.ts → pipeline/fileLoader.d.ts} +3 -3
  16. package/dist/{fileLoader.js → pipeline/fileLoader.js} +3 -3
  17. package/dist/{fileUpdater.d.ts → pipeline/fileUpdater.d.ts} +3 -3
  18. package/dist/{fileUpdater.js → pipeline/fileUpdater.js} +7 -7
  19. package/dist/pipeline/index.d.ts +11 -0
  20. package/dist/pipeline/index.js +26 -0
  21. package/dist/{patternUsageValidator.d.ts → pipeline/patternUsageValidator.d.ts} +1 -1
  22. package/dist/{patternUsageValidator.js → pipeline/patternUsageValidator.js} +2 -2
  23. package/dist/{stopRulesValidator.d.ts → pipeline/stopRulesValidator.d.ts} +3 -3
  24. package/dist/{stopRulesValidator.js → pipeline/stopRulesValidator.js} +4 -4
  25. package/dist/{yamlFormatter.d.ts → pipeline/yamlFormatter.d.ts} +2 -2
  26. package/dist/{yamlFormatter.js → pipeline/yamlFormatter.js} +24 -7
  27. package/dist/{consoleDiffReporter.d.ts → reporters/consoleDiffReporter.d.ts} +2 -2
  28. package/dist/{consoleDiffReporter.js → reporters/consoleDiffReporter.js} +5 -5
  29. package/dist/{htmlReporter.d.ts → reporters/htmlReporter.d.ts} +6 -6
  30. package/dist/{htmlReporter.js → reporters/htmlReporter.js} +7 -7
  31. package/dist/reporters/htmlTemplate.d.ts +1 -1
  32. package/dist/reporters/index.d.ts +14 -0
  33. package/dist/reporters/index.js +33 -0
  34. package/dist/{jsonReporter.d.ts → reporters/jsonReporter.d.ts} +3 -4
  35. package/dist/{jsonReporter.js → reporters/jsonReporter.js} +3 -3
  36. package/dist/suggestionEngine.d.ts +2 -2
  37. package/dist/suggestionEngine.js +1 -1
  38. package/dist/utils/collisionDetector.d.ts +1 -1
  39. package/dist/utils/fileFilter.d.ts +1 -2
  40. package/dist/utils/filenameTransformer.d.ts +1 -1
  41. package/dist/utils/fixedValues.d.ts +1 -1
  42. package/dist/utils/regexTransform.d.ts +1 -1
  43. package/dist/utils/regexValidator.d.ts +1 -1
  44. package/dist/utils/transformFileLoader.d.ts +1 -1
  45. package/dist/utils/transformer.d.ts +1 -1
  46. package/package.json +7 -11
  47. /package/dist/{ZodError.d.ts → config/ZodError.d.ts} +0 -0
  48. /package/dist/{ZodError.js → config/ZodError.js} +0 -0
  49. /package/dist/{configWarnings.d.ts → config/configWarnings.d.ts} +0 -0
  50. /package/dist/{configWarnings.js → config/configWarnings.js} +0 -0
  51. /package/dist/{arrayDiffer.d.ts → reporters/arrayDiffer.d.ts} +0 -0
  52. /package/dist/{arrayDiffer.js → reporters/arrayDiffer.js} +0 -0
package/README.md CHANGED
@@ -226,6 +226,14 @@ outputFormat:
226
226
 
227
227
  The repository includes ready-to-run examples:
228
228
 
229
+ ### 🟢 Example 0: Basic
230
+
231
+ The simplest possible setup — syncs changes from UAT to Production while preserving environment-specific values.
232
+
233
+ ```bash
234
+ helm-env-delta --config example/0-basic/config.yaml --dry-run --diff
235
+ ```
236
+
229
237
  ### 📁 Example 1: Config Inheritance
230
238
 
231
239
  Shows how to reuse base configuration across multiple environment pairs.
@@ -236,7 +244,7 @@ helm-env-delta --config example/1-config-inheritance/config.uat-to-prod.yaml --d
236
244
 
237
245
  ### 🚦 Example 2: Stop Rules
238
246
 
239
- Demonstrates all 5 stop rule types and how violations block execution.
247
+ Demonstrates all 7 stop rule types and how violations block execution.
240
248
 
241
249
  ```bash
242
250
  helm-env-delta --config example/2-stop-rules/config.yaml --dry-run --diff
@@ -331,7 +339,7 @@ helm-env-delta --config config.yaml --suggest --suggest-threshold 0.7
331
339
  - 🎯 Suggests transform patterns (regex find/replace) based on semantic patterns
332
340
  - 🛡️ Recommends stop rules for safety validation using pattern recognition
333
341
  - 📊 Provides confidence scores and occurrence counts for each suggestion
334
- - 🎛️ **NEW:** Configurable threshold filters suggestions by confidence level (0-1)
342
+ - 🎛️ Configurable threshold filters suggestions by confidence level (0-1)
335
343
  - 📝 Outputs copy-paste ready YAML configuration
336
344
  - ✨ **Enhanced noise filtering:**
337
345
  - Ignores UUIDs, timestamps, single-character changes
@@ -627,7 +635,7 @@ stopRules:
627
635
  path: 'image.tag'
628
636
  regex: '^v0\.'
629
637
 
630
- # NEW: Regex without path (global - scans all values)
638
+ # Regex without path (global - scans all values)
631
639
  - type: 'regex'
632
640
  regex: '^127\.' # Block localhost IPs anywhere
633
641
  ```
@@ -698,7 +706,9 @@ outputFormat:
698
706
  arraySort: # Sort arrays
699
707
  'services/**/values.yaml':
700
708
  - path: 'env'
701
- sortBy: 'name'
709
+ sortBy: 'name' # Sort object array by field
710
+ order: 'asc'
711
+ - path: 'volumes' # No sortBy → sort scalar array by value
702
712
  order: 'asc'
703
713
 
704
714
  quoteValues: # Force quoting
@@ -954,7 +964,7 @@ git push origin main
954
964
 
955
965
  ✅ **Flexibility** - Per-file patterns. Config inheritance. Regex transforms.
956
966
 
957
- ✅ **Reliability** - 1150+ tests, 84% coverage. Battle-tested.
967
+ ✅ **Reliability** - 1400+ tests, 92% coverage. Battle-tested.
958
968
 
959
969
  ---
960
970
 
@@ -71,7 +71,7 @@ declare const stopRuleSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
71
71
  }, z.core.$strict>], "type">;
72
72
  declare const arraySortRuleSchema: z.ZodObject<{
73
73
  path: z.ZodString;
74
- sortBy: z.ZodString;
74
+ sortBy: z.ZodOptional<z.ZodString>;
75
75
  order: z.ZodDefault<z.ZodEnum<{
76
76
  asc: "asc";
77
77
  desc: "desc";
@@ -120,7 +120,7 @@ declare const baseConfigSchema: z.ZodObject<{
120
120
  }, z.core.$strip>>>>;
121
121
  arraySort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
122
122
  path: z.ZodString;
123
- sortBy: z.ZodString;
123
+ sortBy: z.ZodOptional<z.ZodString>;
124
124
  order: z.ZodDefault<z.ZodEnum<{
125
125
  asc: "asc";
126
126
  desc: "desc";
@@ -243,7 +243,7 @@ declare const finalConfigSchema: z.ZodObject<{
243
243
  }, z.core.$strip>>>>;
244
244
  arraySort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
245
245
  path: z.ZodString;
246
- sortBy: z.ZodString;
246
+ sortBy: z.ZodOptional<z.ZodString>;
247
247
  order: z.ZodDefault<z.ZodEnum<{
248
248
  asc: "asc";
249
249
  desc: "desc";
@@ -318,7 +318,7 @@ declare const formatOnlyConfigSchema: z.ZodObject<{
318
318
  }, z.core.$strip>>>>;
319
319
  arraySort: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodArray<z.ZodObject<{
320
320
  path: z.ZodString;
321
- sortBy: z.ZodString;
321
+ sortBy: z.ZodOptional<z.ZodString>;
322
322
  order: z.ZodDefault<z.ZodEnum<{
323
323
  asc: "asc";
324
324
  desc: "desc";
@@ -76,7 +76,7 @@ const stopRuleSchema = zod_1.z.discriminatedUnion('type', [
76
76
  ]);
77
77
  const arraySortRuleSchema = zod_1.z.object({
78
78
  path: zod_1.z.string().min(1),
79
- sortBy: zod_1.z.string().min(1),
79
+ sortBy: zod_1.z.string().min(1).optional(),
80
80
  order: zod_1.z.enum(['asc', 'desc']).default('asc')
81
81
  });
82
82
  const keySortRuleSchema = zod_1.z.object({ path: zod_1.z.string().min(1) });
@@ -1,6 +1,6 @@
1
1
  import { type FinalConfig, type FormatOnlyConfig } from './configFile';
2
2
  declare const ConfigLoaderErrorClass: {
3
- new (message: string, options?: import("./utils").ErrorOptions): {
3
+ new (message: string, options?: import("../utils").ErrorOptions): {
4
4
  [key: string]: unknown;
5
5
  readonly code?: string;
6
6
  readonly path?: string;
@@ -21,5 +21,5 @@ export type Config = FinalConfig;
21
21
  export type LoadConfigOptions = {
22
22
  formatOnly?: boolean;
23
23
  };
24
- export declare const loadConfigFile: (configPath: string, quiet?: boolean, logger?: import("./logger").Logger, options?: LoadConfigOptions) => FinalConfig | FormatOnlyConfig;
24
+ export declare const loadConfigFile: (configPath: string, quiet?: boolean, logger?: import("../logger").Logger, options?: LoadConfigOptions) => FinalConfig | FormatOnlyConfig;
25
25
  export {};
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.loadConfigFile = exports.isConfigLoaderError = exports.ConfigLoaderError = void 0;
7
7
  const node_path_1 = __importDefault(require("node:path"));
8
- const package_json_1 = __importDefault(require("../package.json"));
8
+ const package_json_1 = __importDefault(require("../../package.json"));
9
+ const utils_1 = require("../utils");
9
10
  const configFile_1 = require("./configFile");
10
11
  const configMerger_1 = require("./configMerger");
11
- const utils_1 = require("./utils");
12
12
  const ConfigLoaderErrorClass = (0, utils_1.createErrorClass)('Config Loader Error', {
13
13
  VERSION_REQUIREMENT: 'Installed version does not meet the required version'
14
14
  }, (message, options) => {
@@ -1,6 +1,6 @@
1
1
  import { type BaseConfig } from './configFile';
2
2
  declare const ConfigMergerErrorClass: {
3
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
3
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
4
4
  [key: string]: unknown;
5
5
  readonly code?: string;
6
6
  readonly path?: string;
@@ -18,5 +18,5 @@ export declare class ConfigMergerError extends ConfigMergerErrorClass {
18
18
  }
19
19
  export declare const isConfigMergerError: (error: unknown) => error is ConfigMergerError;
20
20
  export declare const mergeConfigs: (parent: BaseConfig, child: BaseConfig) => BaseConfig;
21
- export declare const resolveConfigWithExtends: (configPath: string, visited?: Set<string>, depth?: number, logger?: import("./logger").Logger) => BaseConfig;
21
+ export declare const resolveConfigWithExtends: (configPath: string, visited?: Set<string>, depth?: number, logger?: import("../logger").Logger) => BaseConfig;
22
22
  export {};
@@ -40,9 +40,9 @@ exports.resolveConfigWithExtends = exports.mergeConfigs = exports.isConfigMerger
40
40
  const node_fs_1 = require("node:fs");
41
41
  const node_path_1 = __importDefault(require("node:path"));
42
42
  const YAML = __importStar(require("yaml"));
43
+ const constants_1 = require("../constants");
44
+ const errors_1 = require("../utils/errors");
43
45
  const configFile_1 = require("./configFile");
44
- const constants_1 = require("./constants");
45
- const errors_1 = require("./utils/errors");
46
46
  const ConfigMergerErrorClass = (0, errors_1.createErrorClass)('Config Merger Error', {
47
47
  CIRCULAR_DEPENDENCY: 'Circular dependency detected in extends chain',
48
48
  MAX_DEPTH_EXCEEDED: 'Extends chain exceeds maximum depth',
@@ -0,0 +1,8 @@
1
+ export { isZodValidationError, ZodValidationError } from './ZodError';
2
+ export type { ArraySortRule, BaseConfig, Config, FinalConfig, FixedValueConfig, FixedValueRule, FormatOnlyConfig, KeySortRule, NumericRule, OutputFormat, RegexFileKeyRule, RegexFileRule, RegexRule, SemverDowngradeRule, SemverMajorUpgradeRule, StopRule, TransformConfig, TransformRule, TransformRules, VersionFormatRule } from './configFile';
3
+ export { ConfigValidationError, isConfigValidationError, parseBaseConfig, parseConfig, parseFinalConfig, parseFormatOnlyConfig } from './configFile';
4
+ export type { LoadConfigOptions } from './configLoader';
5
+ export { ConfigLoaderError, isConfigLoaderError, loadConfigFile } from './configLoader';
6
+ export { ConfigMergerError, isConfigMergerError, mergeConfigs, resolveConfigWithExtends } from './configMerger';
7
+ export type { WarningResult } from './configWarnings';
8
+ export { validateConfigWarnings } from './configWarnings';
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validateConfigWarnings = exports.resolveConfigWithExtends = exports.mergeConfigs = exports.isConfigMergerError = exports.ConfigMergerError = exports.loadConfigFile = exports.isConfigLoaderError = exports.ConfigLoaderError = exports.parseFormatOnlyConfig = exports.parseFinalConfig = exports.parseConfig = exports.parseBaseConfig = exports.isConfigValidationError = exports.ConfigValidationError = exports.ZodValidationError = exports.isZodValidationError = void 0;
4
+ var ZodError_1 = require("./ZodError");
5
+ Object.defineProperty(exports, "isZodValidationError", { enumerable: true, get: function () { return ZodError_1.isZodValidationError; } });
6
+ Object.defineProperty(exports, "ZodValidationError", { enumerable: true, get: function () { return ZodError_1.ZodValidationError; } });
7
+ var configFile_1 = require("./configFile");
8
+ Object.defineProperty(exports, "ConfigValidationError", { enumerable: true, get: function () { return configFile_1.ConfigValidationError; } });
9
+ Object.defineProperty(exports, "isConfigValidationError", { enumerable: true, get: function () { return configFile_1.isConfigValidationError; } });
10
+ Object.defineProperty(exports, "parseBaseConfig", { enumerable: true, get: function () { return configFile_1.parseBaseConfig; } });
11
+ Object.defineProperty(exports, "parseConfig", { enumerable: true, get: function () { return configFile_1.parseConfig; } });
12
+ Object.defineProperty(exports, "parseFinalConfig", { enumerable: true, get: function () { return configFile_1.parseFinalConfig; } });
13
+ Object.defineProperty(exports, "parseFormatOnlyConfig", { enumerable: true, get: function () { return configFile_1.parseFormatOnlyConfig; } });
14
+ var configLoader_1 = require("./configLoader");
15
+ Object.defineProperty(exports, "ConfigLoaderError", { enumerable: true, get: function () { return configLoader_1.ConfigLoaderError; } });
16
+ Object.defineProperty(exports, "isConfigLoaderError", { enumerable: true, get: function () { return configLoader_1.isConfigLoaderError; } });
17
+ Object.defineProperty(exports, "loadConfigFile", { enumerable: true, get: function () { return configLoader_1.loadConfigFile; } });
18
+ var configMerger_1 = require("./configMerger");
19
+ Object.defineProperty(exports, "ConfigMergerError", { enumerable: true, get: function () { return configMerger_1.ConfigMergerError; } });
20
+ Object.defineProperty(exports, "isConfigMergerError", { enumerable: true, get: function () { return configMerger_1.isConfigMergerError; } });
21
+ Object.defineProperty(exports, "mergeConfigs", { enumerable: true, get: function () { return configMerger_1.mergeConfigs; } });
22
+ Object.defineProperty(exports, "resolveConfigWithExtends", { enumerable: true, get: function () { return configMerger_1.resolveConfigWithExtends; } });
23
+ var configWarnings_1 = require("./configWarnings");
24
+ Object.defineProperty(exports, "validateConfigWarnings", { enumerable: true, get: function () { return configWarnings_1.validateConfigWarnings; } });
@@ -1,4 +1,4 @@
1
- import { StopRuleViolation } from './stopRulesValidator';
1
+ import { StopRuleViolation } from './pipeline/stopRulesValidator';
2
2
  export type BoxStyle = 'success' | 'warning' | 'error' | 'info';
3
3
  export type ProgressStyle = 'loading' | 'success' | 'info';
4
4
  export type ViolationMode = 'error' | 'warning' | 'force';
package/dist/index.js CHANGED
@@ -44,19 +44,11 @@ const chalk_1 = __importDefault(require("chalk"));
44
44
  const YAML = __importStar(require("yaml"));
45
45
  const package_json_1 = __importDefault(require("../package.json"));
46
46
  const commandLine_1 = require("./commandLine");
47
- const configLoader_1 = require("./configLoader");
48
- const configMerger_1 = require("./configMerger");
49
- const configWarnings_1 = require("./configWarnings");
50
- const consoleDiffReporter_1 = require("./consoleDiffReporter");
47
+ const config_1 = require("./config");
51
48
  const consoleFormatter_1 = require("./consoleFormatter");
52
- const fileDiff_1 = require("./fileDiff");
53
- const fileLoader_1 = require("./fileLoader");
54
- const fileUpdater_1 = require("./fileUpdater");
55
- const htmlReporter_1 = require("./htmlReporter");
56
- const jsonReporter_1 = require("./jsonReporter");
57
49
  const logger_1 = require("./logger");
58
- const patternUsageValidator_1 = require("./patternUsageValidator");
59
- const stopRulesValidator_1 = require("./stopRulesValidator");
50
+ const pipeline_1 = require("./pipeline");
51
+ const reporters_1 = require("./reporters");
60
52
  const suggestionEngine_1 = require("./suggestionEngine");
61
53
  const collisionDetector_1 = require("./utils/collisionDetector");
62
54
  const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
@@ -64,8 +56,6 @@ const fileFilter_1 = require("./utils/fileFilter");
64
56
  const filenameTransformer_1 = require("./utils/filenameTransformer");
65
57
  const fileType_1 = require("./utils/fileType");
66
58
  const versionChecker_1 = require("./utils/versionChecker");
67
- const yamlFormatter_1 = require("./yamlFormatter");
68
- const ZodError_1 = require("./ZodError");
69
59
  const main = async () => {
70
60
  const command = (0, commandLine_1.parseCommandLine)();
71
61
  if (command.noColor)
@@ -86,7 +76,7 @@ const main = async () => {
86
76
  (0, node_fs_1.mkdirSync)(configDirectory, { recursive: true });
87
77
  (0, node_fs_1.writeFileSync)(firstRunMarker, new Date().toISOString());
88
78
  }
89
- const config = (0, configLoader_1.loadConfigFile)(command.config, command.quiet, logger, { formatOnly: command.formatOnly });
79
+ const config = (0, config_1.loadConfigFile)(command.config, command.quiet, logger, { formatOnly: command.formatOnly });
90
80
  if (command.showConfig) {
91
81
  console.log(chalk_1.default.cyan('\n⚙️ Resolved Configuration:\n'));
92
82
  console.log(YAML.stringify(config, { indent: 2 }));
@@ -99,7 +89,7 @@ const main = async () => {
99
89
  }
100
90
  const validationConfig = config;
101
91
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Validating configuration...', 'info'));
102
- const warningResult = (0, configWarnings_1.validateConfigWarnings)(validationConfig);
92
+ const warningResult = (0, config_1.validateConfigWarnings)(validationConfig);
103
93
  let hasAnyWarnings = warningResult.hasWarnings;
104
94
  if (warningResult.hasWarnings) {
105
95
  console.warn(chalk_1.default.yellow('\n⚠️ Configuration Warnings (non-fatal):\n'));
@@ -107,7 +97,7 @@ const main = async () => {
107
97
  console.warn(chalk_1.default.yellow(` • ${warning}`));
108
98
  }
109
99
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Loading files for validation...', 'loading'));
110
- const sourceResult = await (0, fileLoader_1.loadFiles)({
100
+ const sourceResult = await (0, pipeline_1.loadFiles)({
111
101
  baseDirectory: validationConfig.source,
112
102
  include: validationConfig.include,
113
103
  exclude: validationConfig.exclude,
@@ -115,7 +105,7 @@ const main = async () => {
115
105
  skipExclude: true
116
106
  }, logger);
117
107
  let sourceFiles = sourceResult.fileMap;
118
- const destinationResult = await (0, fileLoader_1.loadFiles)({
108
+ const destinationResult = await (0, pipeline_1.loadFiles)({
119
109
  baseDirectory: validationConfig.destination,
120
110
  include: validationConfig.include,
121
111
  exclude: validationConfig.exclude,
@@ -129,7 +119,7 @@ const main = async () => {
129
119
  }
130
120
  logger.progress(`Loaded ${sourceFiles.size} source, ${destinationFiles.size} destination file(s)`, 'success');
131
121
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Validating pattern usage...', 'info'));
132
- const usageResult = (0, patternUsageValidator_1.validatePatternUsage)(validationConfig, sourceFiles, destinationFiles);
122
+ const usageResult = (0, pipeline_1.validatePatternUsage)(validationConfig, sourceFiles, destinationFiles);
133
123
  hasAnyWarnings = hasAnyWarnings || usageResult.hasWarnings;
134
124
  if (usageResult.hasWarnings) {
135
125
  console.warn(chalk_1.default.yellow('\n⚠️ Pattern Usage Warnings (non-fatal):\n'));
@@ -160,7 +150,7 @@ const main = async () => {
160
150
  return;
161
151
  }
162
152
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Loading destination files...', 'loading'));
163
- const destinationResult = await (0, fileLoader_1.loadFiles)({
153
+ const destinationResult = await (0, pipeline_1.loadFiles)({
164
154
  baseDirectory: config.destination,
165
155
  include: config.include,
166
156
  exclude: config.exclude
@@ -186,7 +176,7 @@ const main = async () => {
186
176
  if ((0, commentOnlyDetector_1.isCommentOnlyContent)(content))
187
177
  continue;
188
178
  try {
189
- const formatted = (0, yamlFormatter_1.formatYaml)(content, relativePath, config.outputFormat);
179
+ const formatted = (0, pipeline_1.formatYaml)(content, relativePath, config.outputFormat);
190
180
  if (formatted !== content) {
191
181
  const absolutePath = node_path_1.default.join(config.destination, relativePath);
192
182
  if (command.dryRun)
@@ -220,7 +210,7 @@ const main = async () => {
220
210
  }
221
211
  const syncConfig = config;
222
212
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Loading files...', 'loading'));
223
- const sourceResult = await (0, fileLoader_1.loadFiles)({
213
+ const sourceResult = await (0, pipeline_1.loadFiles)({
224
214
  baseDirectory: syncConfig.source,
225
215
  include: syncConfig.include,
226
216
  exclude: syncConfig.exclude,
@@ -234,7 +224,7 @@ const main = async () => {
234
224
  (0, collisionDetector_1.validateNoCollisions)(collisions);
235
225
  if (logger.shouldShow('debug'))
236
226
  logger.debug('Filename collision check: passed');
237
- const destinationResult = await (0, fileLoader_1.loadFiles)({
227
+ const destinationResult = await (0, pipeline_1.loadFiles)({
238
228
  baseDirectory: syncConfig.destination,
239
229
  include: syncConfig.include,
240
230
  exclude: syncConfig.exclude
@@ -260,12 +250,12 @@ const main = async () => {
260
250
  return;
261
251
  }
262
252
  logger.log('\n' + (0, consoleFormatter_1.formatProgressMessage)('Computing differences...', 'info'));
263
- const rawDiffResult = (0, fileDiff_1.computeFileDiff)(sourceFiles, destinationFiles, syncConfig, logger, originalPaths);
253
+ const rawDiffResult = (0, pipeline_1.computeFileDiff)(sourceFiles, destinationFiles, syncConfig, logger, originalPaths);
264
254
  const diffResult = (0, fileFilter_1.filterDiffResultByMode)(rawDiffResult, command.mode);
265
255
  if (logger.shouldShow('debug'))
266
256
  logger.debug('Diff pipeline: parse → transforms → skipPath → normalize → compare');
267
257
  if (command.diff && !command.quiet)
268
- (0, consoleDiffReporter_1.showConsoleDiff)(diffResult, syncConfig);
258
+ (0, reporters_1.showConsoleDiff)(diffResult, syncConfig);
269
259
  else {
270
260
  logger.log(` New files: ${diffResult.addedFiles.length}`);
271
261
  logger.log(` Deleted files: ${diffResult.deletedFiles.length}`);
@@ -296,7 +286,7 @@ const main = async () => {
296
286
  }
297
287
  }
298
288
  const configFileDirectory = node_path_1.default.dirname(node_path_1.default.resolve(command.config));
299
- const validationResult = (0, stopRulesValidator_1.validateStopRules)(diffResult, syncConfig.stopRules, configFileDirectory, logger);
289
+ const validationResult = (0, pipeline_1.validateStopRules)(diffResult, syncConfig.stopRules, configFileDirectory, logger);
300
290
  if (validationResult.violations.length > 0)
301
291
  if (command.force)
302
292
  for (const violation of validationResult.violations)
@@ -324,36 +314,36 @@ const main = async () => {
324
314
  if (syncConfig.confirmationDelay > 0)
325
315
  await new Promise((resolve) => setTimeout(resolve, syncConfig.confirmationDelay));
326
316
  }
327
- const formattedFiles = await (0, fileUpdater_1.updateFiles)(diffResult, sourceFiles, destinationFiles, syncConfig, command.dryRun, command.skipFormat, logger);
317
+ const formattedFiles = await (0, pipeline_1.updateFiles)(diffResult, sourceFiles, destinationFiles, syncConfig, command.dryRun, command.skipFormat, logger);
328
318
  if (command.diffHtml && !command.quiet)
329
- await (0, htmlReporter_1.generateHtmlReport)(diffResult, formattedFiles, syncConfig, command.dryRun, logger, command.dryRun ? validationResult : undefined);
319
+ await (0, reporters_1.generateHtmlReport)(diffResult, formattedFiles, syncConfig, command.dryRun, logger, command.dryRun ? validationResult : undefined);
330
320
  if (command.diffJson)
331
- (0, jsonReporter_1.generateJsonReport)(diffResult, formattedFiles, validationResult, syncConfig, command.dryRun, package_json_1.default.version);
321
+ (0, reporters_1.generateJsonReport)(diffResult, formattedFiles, validationResult, syncConfig, command.dryRun, package_json_1.default.version);
332
322
  };
333
323
  (async () => {
334
324
  try {
335
325
  await main();
336
326
  }
337
327
  catch (error) {
338
- if ((0, configMerger_1.isConfigMergerError)(error))
328
+ if ((0, config_1.isConfigMergerError)(error))
339
329
  console.error(error.message);
340
- else if ((0, configLoader_1.isConfigLoaderError)(error))
330
+ else if ((0, config_1.isConfigLoaderError)(error))
341
331
  console.error(error.message);
342
- else if ((0, ZodError_1.isZodValidationError)(error))
332
+ else if ((0, config_1.isZodValidationError)(error))
343
333
  console.error(error.message);
344
- else if ((0, fileLoader_1.isFileLoaderError)(error))
334
+ else if ((0, pipeline_1.isFileLoaderError)(error))
345
335
  console.error(error.message);
346
336
  else if ((0, filenameTransformer_1.isFilenameTransformerError)(error))
347
337
  console.error(error.message);
348
338
  else if ((0, collisionDetector_1.isCollisionDetectorError)(error))
349
339
  console.error(error.message);
350
- else if ((0, fileDiff_1.isFileDiffError)(error))
340
+ else if ((0, pipeline_1.isFileDiffError)(error))
351
341
  console.error(error.message);
352
- else if ((0, fileUpdater_1.isFileUpdaterError)(error))
342
+ else if ((0, pipeline_1.isFileUpdaterError)(error))
353
343
  console.error(error.message);
354
- else if ((0, htmlReporter_1.isHtmlReporterError)(error))
344
+ else if ((0, reporters_1.isHtmlReporterError)(error))
355
345
  console.error(error.message);
356
- else if ((0, jsonReporter_1.isJsonReporterError)(error))
346
+ else if ((0, reporters_1.isJsonReporterError)(error))
357
347
  console.error(error.message);
358
348
  else if ((0, suggestionEngine_1.isSuggestionEngineError)(error))
359
349
  console.error(error.message);
package/dist/logger.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { FileOperation, ProgressStyle, ViolationMode } from './consoleFormatter';
2
- import { StopRuleViolation } from './stopRulesValidator';
2
+ import { StopRuleViolation } from './pipeline/stopRulesValidator';
3
3
  export type VerbosityLevel = 'quiet' | 'normal' | 'verbose';
4
4
  export type OutputCategory = 'critical' | 'normal' | 'debug' | 'special';
5
5
  export type LoggerOptions = {
@@ -1,4 +1,4 @@
1
- import { Config, FixedValueConfig, TransformConfig } from './configFile';
1
+ import { Config, FixedValueConfig, TransformConfig } from '../config';
2
2
  import { FileMap } from './fileLoader';
3
3
  export interface FileDiffResult {
4
4
  addedFiles: AddedFile[];
@@ -36,7 +36,7 @@ export interface ProcessYamlOptions {
36
36
  fixedValues?: FixedValueConfig;
37
37
  }
38
38
  declare const FileDiffErrorClass: {
39
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
39
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
40
40
  [key: string]: unknown;
41
41
  readonly code?: string;
42
42
  readonly path?: string;
@@ -54,5 +54,5 @@ export declare class FileDiffError extends FileDiffErrorClass {
54
54
  }
55
55
  export declare const isFileDiffError: (error: unknown) => error is FileDiffError;
56
56
  export declare const getSkipPathsForFile: (filePath: string, skipPath?: Record<string, string[]>) => string[];
57
- export declare const computeFileDiff: (sourceFiles: FileMap, destinationFiles: FileMap, config: Config, logger?: import("./logger").Logger, originalPaths?: Map<string, string>) => FileDiffResult;
57
+ export declare const computeFileDiff: (sourceFiles: FileMap, destinationFiles: FileMap, config: Config, logger?: import("../logger").Logger, originalPaths?: Map<string, string>) => FileDiffResult;
58
58
  export {};
@@ -5,15 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.computeFileDiff = exports.getSkipPathsForFile = exports.isFileDiffError = exports.FileDiffError = void 0;
7
7
  const yaml_1 = __importDefault(require("yaml"));
8
- const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
9
- const deepEqual_1 = require("./utils/deepEqual");
10
- const errors_1 = require("./utils/errors");
11
- const fileType_1 = require("./utils/fileType");
12
- const fixedValues_1 = require("./utils/fixedValues");
13
- const jsonPath_1 = require("./utils/jsonPath");
14
- const patternMatcher_1 = require("./utils/patternMatcher");
15
- const serialization_1 = require("./utils/serialization");
16
- const transformer_1 = require("./utils/transformer");
8
+ const commentOnlyDetector_1 = require("../utils/commentOnlyDetector");
9
+ const deepEqual_1 = require("../utils/deepEqual");
10
+ const errors_1 = require("../utils/errors");
11
+ const fileType_1 = require("../utils/fileType");
12
+ const fixedValues_1 = require("../utils/fixedValues");
13
+ const jsonPath_1 = require("../utils/jsonPath");
14
+ const patternMatcher_1 = require("../utils/patternMatcher");
15
+ const serialization_1 = require("../utils/serialization");
16
+ const transformer_1 = require("../utils/transformer");
17
17
  const yamlFormatter_1 = require("./yamlFormatter");
18
18
  const FileDiffErrorClass = (0, errors_1.createErrorClass)('File Diff Error', {
19
19
  YAML_PARSE_ERROR: 'YAML file could not be parsed'
@@ -1,4 +1,4 @@
1
- import type { TransformConfig } from './configFile';
1
+ import type { TransformConfig } from '../config';
2
2
  export interface FileLoaderOptions {
3
3
  baseDirectory: string;
4
4
  include: string[];
@@ -12,7 +12,7 @@ export interface FileLoaderResult {
12
12
  originalPaths: Map<string, string>;
13
13
  }
14
14
  declare const FileLoaderErrorClass: {
15
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
15
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
16
16
  [key: string]: unknown;
17
17
  readonly code?: string;
18
18
  readonly path?: string;
@@ -29,5 +29,5 @@ declare const FileLoaderErrorClass: {
29
29
  export declare class FileLoaderError extends FileLoaderErrorClass {
30
30
  }
31
31
  export declare const isFileLoaderError: (error: unknown) => error is FileLoaderError;
32
- export declare const loadFiles: (options: FileLoaderOptions, logger?: import("./logger").Logger) => Promise<FileLoaderResult>;
32
+ export declare const loadFiles: (options: FileLoaderOptions, logger?: import("../logger").Logger) => Promise<FileLoaderResult>;
33
33
  export {};
@@ -7,9 +7,9 @@ exports.loadFiles = exports.isFileLoaderError = exports.FileLoaderError = void 0
7
7
  const promises_1 = require("node:fs/promises");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const tinyglobby_1 = require("tinyglobby");
10
- const errors_1 = require("./utils/errors");
11
- const filenameTransformer_1 = require("./utils/filenameTransformer");
12
- const patternMatcher_1 = require("./utils/patternMatcher");
10
+ const errors_1 = require("../utils/errors");
11
+ const filenameTransformer_1 = require("../utils/filenameTransformer");
12
+ const patternMatcher_1 = require("../utils/patternMatcher");
13
13
  const FileLoaderErrorClass = (0, errors_1.createErrorClass)('File Loader Error', {
14
14
  ENOENT: 'File or directory not found',
15
15
  EACCES: 'Permission denied',
@@ -1,7 +1,7 @@
1
- import { Config } from './configFile';
1
+ import { Config } from '../config';
2
+ import { Logger } from '../logger';
2
3
  import { ChangedFile, FileDiffResult } from './fileDiff';
3
4
  import { FileMap } from './fileLoader';
4
- import { Logger } from './logger';
5
5
  export interface FileUpdateError {
6
6
  operation: 'add' | 'update' | 'delete';
7
7
  path: string;
@@ -25,7 +25,7 @@ export interface UpdateFileOptions {
25
25
  logger: Logger;
26
26
  }
27
27
  declare const FileUpdaterErrorClass: {
28
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
28
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
29
29
  [key: string]: unknown;
30
30
  readonly code?: string;
31
31
  readonly path?: string;
@@ -7,13 +7,13 @@ exports.updateFiles = exports.isFileUpdaterError = exports.FileUpdaterError = vo
7
7
  const promises_1 = require("node:fs/promises");
8
8
  const node_path_1 = __importDefault(require("node:path"));
9
9
  const yaml_1 = __importDefault(require("yaml"));
10
- const consoleFormatter_1 = require("./consoleFormatter");
11
- const arrayMerger_1 = require("./utils/arrayMerger");
12
- const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
13
- const errors_1 = require("./utils/errors");
14
- const fileType_1 = require("./utils/fileType");
15
- const fixedValues_1 = require("./utils/fixedValues");
16
- const transformer_1 = require("./utils/transformer");
10
+ const consoleFormatter_1 = require("../consoleFormatter");
11
+ const arrayMerger_1 = require("../utils/arrayMerger");
12
+ const commentOnlyDetector_1 = require("../utils/commentOnlyDetector");
13
+ const errors_1 = require("../utils/errors");
14
+ const fileType_1 = require("../utils/fileType");
15
+ const fixedValues_1 = require("../utils/fixedValues");
16
+ const transformer_1 = require("../utils/transformer");
17
17
  const yamlFormatter_1 = require("./yamlFormatter");
18
18
  const FileUpdaterErrorClass = (0, errors_1.createErrorClass)('File Updater Error', {
19
19
  WRITE_FAILED: 'File write operation failed',
@@ -0,0 +1,11 @@
1
+ export type { FileLoaderOptions, FileLoaderResult, FileMap } from './fileLoader';
2
+ export { FileLoaderError, isFileLoaderError, loadFiles } from './fileLoader';
3
+ export type { AddedFile, ChangedFile, FileDiffResult, ProcessYamlOptions } from './fileDiff';
4
+ export { computeFileDiff, FileDiffError, getSkipPathsForFile, isFileDiffError } from './fileDiff';
5
+ export type { FileOperationOptions, FileUpdateError, UpdateFileOptions } from './fileUpdater';
6
+ export { FileUpdaterError, isFileUpdaterError, updateFiles } from './fileUpdater';
7
+ export { formatYaml, isYamlFormatterError, YamlFormatterError } from './yamlFormatter';
8
+ export type { StopRuleViolation, ValidationContext, ValidationResult } from './stopRulesValidator';
9
+ export { isStopRulesValidatorError, StopRulesValidatorError, validateStopRules } from './stopRulesValidator';
10
+ export type { PatternUsageResult, PatternUsageWarning } from './patternUsageValidator';
11
+ export { validatePatternUsage } from './patternUsageValidator';
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatePatternUsage = exports.validateStopRules = exports.StopRulesValidatorError = exports.isStopRulesValidatorError = exports.YamlFormatterError = exports.isYamlFormatterError = exports.formatYaml = exports.updateFiles = exports.isFileUpdaterError = exports.FileUpdaterError = exports.isFileDiffError = exports.getSkipPathsForFile = exports.FileDiffError = exports.computeFileDiff = exports.loadFiles = exports.isFileLoaderError = exports.FileLoaderError = void 0;
4
+ var fileLoader_1 = require("./fileLoader");
5
+ Object.defineProperty(exports, "FileLoaderError", { enumerable: true, get: function () { return fileLoader_1.FileLoaderError; } });
6
+ Object.defineProperty(exports, "isFileLoaderError", { enumerable: true, get: function () { return fileLoader_1.isFileLoaderError; } });
7
+ Object.defineProperty(exports, "loadFiles", { enumerable: true, get: function () { return fileLoader_1.loadFiles; } });
8
+ var fileDiff_1 = require("./fileDiff");
9
+ Object.defineProperty(exports, "computeFileDiff", { enumerable: true, get: function () { return fileDiff_1.computeFileDiff; } });
10
+ Object.defineProperty(exports, "FileDiffError", { enumerable: true, get: function () { return fileDiff_1.FileDiffError; } });
11
+ Object.defineProperty(exports, "getSkipPathsForFile", { enumerable: true, get: function () { return fileDiff_1.getSkipPathsForFile; } });
12
+ Object.defineProperty(exports, "isFileDiffError", { enumerable: true, get: function () { return fileDiff_1.isFileDiffError; } });
13
+ var fileUpdater_1 = require("./fileUpdater");
14
+ Object.defineProperty(exports, "FileUpdaterError", { enumerable: true, get: function () { return fileUpdater_1.FileUpdaterError; } });
15
+ Object.defineProperty(exports, "isFileUpdaterError", { enumerable: true, get: function () { return fileUpdater_1.isFileUpdaterError; } });
16
+ Object.defineProperty(exports, "updateFiles", { enumerable: true, get: function () { return fileUpdater_1.updateFiles; } });
17
+ var yamlFormatter_1 = require("./yamlFormatter");
18
+ Object.defineProperty(exports, "formatYaml", { enumerable: true, get: function () { return yamlFormatter_1.formatYaml; } });
19
+ Object.defineProperty(exports, "isYamlFormatterError", { enumerable: true, get: function () { return yamlFormatter_1.isYamlFormatterError; } });
20
+ Object.defineProperty(exports, "YamlFormatterError", { enumerable: true, get: function () { return yamlFormatter_1.YamlFormatterError; } });
21
+ var stopRulesValidator_1 = require("./stopRulesValidator");
22
+ Object.defineProperty(exports, "isStopRulesValidatorError", { enumerable: true, get: function () { return stopRulesValidator_1.isStopRulesValidatorError; } });
23
+ Object.defineProperty(exports, "StopRulesValidatorError", { enumerable: true, get: function () { return stopRulesValidator_1.StopRulesValidatorError; } });
24
+ Object.defineProperty(exports, "validateStopRules", { enumerable: true, get: function () { return stopRulesValidator_1.validateStopRules; } });
25
+ var patternUsageValidator_1 = require("./patternUsageValidator");
26
+ Object.defineProperty(exports, "validatePatternUsage", { enumerable: true, get: function () { return patternUsageValidator_1.validatePatternUsage; } });
@@ -1,4 +1,4 @@
1
- import type { FinalConfig } from './configFile';
1
+ import type { FinalConfig } from '../config';
2
2
  import type { FileMap } from './fileLoader';
3
3
  export interface PatternUsageResult {
4
4
  warnings: PatternUsageWarning[];
@@ -5,8 +5,8 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.validatePatternUsage = void 0;
7
7
  const yaml_1 = __importDefault(require("yaml"));
8
- const jsonPath_1 = require("./utils/jsonPath");
9
- const patternMatcher_1 = require("./utils/patternMatcher");
8
+ const jsonPath_1 = require("../utils/jsonPath");
9
+ const patternMatcher_1 = require("../utils/patternMatcher");
10
10
  const validatePatternUsage = (config, sourceFiles, destinationFiles) => {
11
11
  const warnings = [
12
12
  ...validateExcludePatterns(config, sourceFiles, destinationFiles),
@@ -1,7 +1,7 @@
1
- import type { StopRule } from './configFile';
1
+ import type { StopRule } from '../config';
2
2
  import type { FileDiffResult } from './fileDiff';
3
3
  declare const StopRulesValidatorErrorClass: {
4
- new (message: string, options?: import("./utils").ErrorOptions): {
4
+ new (message: string, options?: import("../utils").ErrorOptions): {
5
5
  [key: string]: unknown;
6
6
  readonly code?: string;
7
7
  readonly path?: string;
@@ -37,5 +37,5 @@ export interface ValidationContext {
37
37
  filePath: string;
38
38
  configDirectory?: string;
39
39
  }
40
- export declare const validateStopRules: (diffResult: FileDiffResult, stopRulesConfig?: Record<string, StopRule[]>, configDirectory?: string, logger?: import("./logger").Logger) => ValidationResult;
40
+ export declare const validateStopRules: (diffResult: FileDiffResult, stopRulesConfig?: Record<string, StopRule[]>, configDirectory?: string, logger?: import("../logger").Logger) => ValidationResult;
41
41
  export {};
@@ -1,10 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateStopRules = exports.isStopRulesValidatorError = exports.StopRulesValidatorError = void 0;
4
- const utils_1 = require("./utils");
5
- const errors_1 = require("./utils/errors");
6
- const jsonPath_1 = require("./utils/jsonPath");
7
- const patternMatcher_1 = require("./utils/patternMatcher");
4
+ const utils_1 = require("../utils");
5
+ const errors_1 = require("../utils/errors");
6
+ const jsonPath_1 = require("../utils/jsonPath");
7
+ const patternMatcher_1 = require("../utils/patternMatcher");
8
8
  const StopRulesValidatorErrorClass = (0, errors_1.createErrorClass)('Stop Rules Validator Error', {}, (message, options) => {
9
9
  let fullMessage = `Stop Rules Validator Error: ${message}`;
10
10
  if (options.code)
@@ -1,6 +1,6 @@
1
- import { OutputFormat } from './configFile';
1
+ import { OutputFormat } from '../config';
2
2
  export declare const YamlFormatterError: {
3
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
3
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
4
4
  [key: string]: unknown;
5
5
  readonly code?: string;
6
6
  readonly path?: string;
@@ -5,12 +5,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.formatYaml = exports.isYamlFormatterError = exports.YamlFormatterError = void 0;
7
7
  const yaml_1 = __importDefault(require("yaml"));
8
- const constants_1 = require("./constants");
9
- const commentOnlyDetector_1 = require("./utils/commentOnlyDetector");
10
- const errors_1 = require("./utils/errors");
11
- const jsonPath_1 = require("./utils/jsonPath");
12
- const patternMatcher_1 = require("./utils/patternMatcher");
13
- const yamlTypeGuards_1 = require("./utils/yamlTypeGuards");
8
+ const constants_1 = require("../constants");
9
+ const commentOnlyDetector_1 = require("../utils/commentOnlyDetector");
10
+ const errors_1 = require("../utils/errors");
11
+ const jsonPath_1 = require("../utils/jsonPath");
12
+ const patternMatcher_1 = require("../utils/patternMatcher");
13
+ const yamlTypeGuards_1 = require("../utils/yamlTypeGuards");
14
14
  exports.YamlFormatterError = (0, errors_1.createErrorClass)('YAML Formatter Error', {
15
15
  YAML_PARSE_ERROR: 'YAML file could not be parsed',
16
16
  YAML_FORMAT_ERROR: 'Failed to apply formatting',
@@ -308,6 +308,13 @@ const isPotentialMatch = (currentPath, targetPath) => {
308
308
  const sortYamlSeq = (seq, sortByField, order) => {
309
309
  if (!seq.items || seq.items.length === 0)
310
310
  return;
311
+ const firstItem = seq.items.find((item) => item != undefined);
312
+ if (firstItem !== undefined) {
313
+ if (sortByField === undefined && (0, yamlTypeGuards_1.isYamlMap)(firstItem))
314
+ return;
315
+ if (sortByField !== undefined && (0, yamlTypeGuards_1.isScalar)(firstItem))
316
+ return;
317
+ }
311
318
  const itemsWithSortKeys = [];
312
319
  for (const item of seq.items) {
313
320
  const sortKey = extractSortKey(item, sortByField);
@@ -319,6 +326,16 @@ const sortYamlSeq = (seq, sortByField, order) => {
319
326
  seq.items = [...itemsWithKeys, ...itemsWithoutKeys].map((entry) => entry.item);
320
327
  };
321
328
  const extractSortKey = (item, sortByField) => {
329
+ if (sortByField === undefined) {
330
+ if ((0, yamlTypeGuards_1.isScalar)(item)) {
331
+ const value = item.value;
332
+ if (typeof value === 'string')
333
+ return value;
334
+ if (typeof value === 'number')
335
+ return value;
336
+ }
337
+ return undefined;
338
+ }
322
339
  if (!(0, yamlTypeGuards_1.isYamlMap)(item))
323
340
  return undefined;
324
341
  for (const pair of item.items) {
@@ -343,7 +360,7 @@ const compareSortKeys = (a, b, order) => {
343
360
  return 1;
344
361
  if (b === undefined)
345
362
  return -1;
346
- let result = 0;
363
+ let result;
347
364
  if (typeof a === 'string' && typeof b === 'string')
348
365
  result = a.toLowerCase().localeCompare(b.toLowerCase());
349
366
  else if (typeof a === 'number' && typeof b === 'number')
@@ -1,3 +1,3 @@
1
- import { Config } from './configFile';
2
- import { FileDiffResult } from './fileDiff';
1
+ import { Config } from '../config';
2
+ import { FileDiffResult } from '../pipeline';
3
3
  export declare const showConsoleDiff: (diffResult: FileDiffResult, config: Config) => void;
@@ -5,10 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.showConsoleDiff = void 0;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
- const fileDiff_1 = require("./fileDiff");
9
- const diffGenerator_1 = require("./utils/diffGenerator");
10
- const fileType_1 = require("./utils/fileType");
11
- const serialization_1 = require("./utils/serialization");
8
+ const pipeline_1 = require("../pipeline");
9
+ const diffGenerator_1 = require("../utils/diffGenerator");
10
+ const fileType_1 = require("../utils/fileType");
11
+ const serialization_1 = require("../utils/serialization");
12
12
  const colorizeUnifiedDiff = (diff) => {
13
13
  return diff
14
14
  .split('\n')
@@ -40,7 +40,7 @@ const formatDeletedFiles = (files) => {
40
40
  const formatChangedFile = (file, config) => {
41
41
  const isYaml = (0, fileType_1.isYamlFile)(file.path);
42
42
  const separator = chalk_1.default.yellow('━'.repeat(60));
43
- const skipPaths = (0, fileDiff_1.getSkipPathsForFile)(file.path, config.skipPath);
43
+ const skipPaths = (0, pipeline_1.getSkipPathsForFile)(file.path, config.skipPath);
44
44
  const skipPathInfo = skipPaths.length > 0
45
45
  ? chalk_1.default.dim(`SkipPath patterns applied: ${skipPaths.join(', ')}`)
46
46
  : chalk_1.default.dim('No skipPath patterns applied');
@@ -1,9 +1,9 @@
1
- import { Config } from './configFile';
2
- import { FileDiffResult } from './fileDiff';
3
- import type { ValidationResult } from './stopRulesValidator';
4
- export type { DiffStats, ReportMetadata } from './reporters/htmlTemplate';
1
+ import { Config } from '../config';
2
+ import type { ValidationResult } from '../pipeline';
3
+ import { FileDiffResult } from '../pipeline';
4
+ export type { DiffStats, ReportMetadata } from './htmlTemplate';
5
5
  declare const HtmlReporterErrorClass: {
6
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
6
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
7
7
  [key: string]: unknown;
8
8
  readonly code?: string;
9
9
  readonly path?: string;
@@ -20,4 +20,4 @@ declare const HtmlReporterErrorClass: {
20
20
  export declare class HtmlReporterError extends HtmlReporterErrorClass {
21
21
  }
22
22
  export declare const isHtmlReporterError: (error: unknown) => error is HtmlReporterError;
23
- export declare const generateHtmlReport: (diffResult: FileDiffResult, formattedFiles: string[], config: Config, dryRun: boolean, logger?: import("./logger").Logger, validationResult?: ValidationResult) => Promise<void>;
23
+ export declare const generateHtmlReport: (diffResult: FileDiffResult, formattedFiles: string[], config: Config, dryRun: boolean, logger?: import("../logger").Logger, validationResult?: ValidationResult) => Promise<void>;
@@ -9,13 +9,13 @@ const promises_1 = require("node:fs/promises");
9
9
  const node_os_1 = require("node:os");
10
10
  const node_path_1 = __importDefault(require("node:path"));
11
11
  const diff2html_1 = require("diff2html");
12
- const browserLauncher_1 = require("./reporters/browserLauncher");
13
- const htmlTemplate_1 = require("./reporters/htmlTemplate");
14
- const treeRenderer_1 = require("./reporters/treeRenderer");
15
- const diffGenerator_1 = require("./utils/diffGenerator");
16
- const errors_1 = require("./utils/errors");
17
- const fileType_1 = require("./utils/fileType");
18
- const serialization_1 = require("./utils/serialization");
12
+ const diffGenerator_1 = require("../utils/diffGenerator");
13
+ const errors_1 = require("../utils/errors");
14
+ const fileType_1 = require("../utils/fileType");
15
+ const serialization_1 = require("../utils/serialization");
16
+ const browserLauncher_1 = require("./browserLauncher");
17
+ const htmlTemplate_1 = require("./htmlTemplate");
18
+ const treeRenderer_1 = require("./treeRenderer");
19
19
  const HtmlReporterErrorClass = (0, errors_1.createErrorClass)('HTML Reporter Error', {
20
20
  WRITE_FAILED: 'Failed to write HTML report file',
21
21
  BROWSER_OPEN_FAILED: 'Failed to open report in browser',
@@ -1,4 +1,4 @@
1
- import { FileDiffResult } from '../fileDiff';
1
+ import { FileDiffResult } from '../pipeline';
2
2
  export interface HtmlStopRuleViolation {
3
3
  file: string;
4
4
  rule: {
@@ -0,0 +1,14 @@
1
+ export type { ArrayDiffResult } from './arrayDiffer';
2
+ export { diffArrays, findArrayPaths, hasArrays } from './arrayDiffer';
3
+ export { showConsoleDiff } from './consoleDiffReporter';
4
+ export type { DiffStats, ReportMetadata } from './htmlReporter';
5
+ export { generateHtmlReport, HtmlReporterError, isHtmlReporterError } from './htmlReporter';
6
+ export type { AddedFileDetail, ChangedFileDetail, FieldChange, JsonReport, JsonReportFiles, JsonReportMetadata, JsonReportSummary, StopRuleViolationJson } from './jsonReporter';
7
+ export { generateJsonReport, isJsonReporterError, JsonReporterError } from './jsonReporter';
8
+ export type { HtmlStopRuleViolation } from './htmlTemplate';
9
+ export { generateHtmlTemplate } from './htmlTemplate';
10
+ export { DIFF2HTML_STYLES, HTML_STYLES, TAB_SCRIPT } from './htmlStyles';
11
+ export type { TreeNode } from './treeBuilder';
12
+ export { buildFileTree } from './treeBuilder';
13
+ export { escapeHtml, renderSidebarTree, renderTreeview } from './treeRenderer';
14
+ export { BrowserLauncherError, isBrowserLauncherError, openInBrowser } from './browserLauncher';
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.openInBrowser = exports.isBrowserLauncherError = exports.BrowserLauncherError = exports.renderTreeview = exports.renderSidebarTree = exports.escapeHtml = exports.buildFileTree = exports.TAB_SCRIPT = exports.HTML_STYLES = exports.DIFF2HTML_STYLES = exports.generateHtmlTemplate = exports.JsonReporterError = exports.isJsonReporterError = exports.generateJsonReport = exports.isHtmlReporterError = exports.HtmlReporterError = exports.generateHtmlReport = exports.showConsoleDiff = exports.hasArrays = exports.findArrayPaths = exports.diffArrays = void 0;
4
+ var arrayDiffer_1 = require("./arrayDiffer");
5
+ Object.defineProperty(exports, "diffArrays", { enumerable: true, get: function () { return arrayDiffer_1.diffArrays; } });
6
+ Object.defineProperty(exports, "findArrayPaths", { enumerable: true, get: function () { return arrayDiffer_1.findArrayPaths; } });
7
+ Object.defineProperty(exports, "hasArrays", { enumerable: true, get: function () { return arrayDiffer_1.hasArrays; } });
8
+ var consoleDiffReporter_1 = require("./consoleDiffReporter");
9
+ Object.defineProperty(exports, "showConsoleDiff", { enumerable: true, get: function () { return consoleDiffReporter_1.showConsoleDiff; } });
10
+ var htmlReporter_1 = require("./htmlReporter");
11
+ Object.defineProperty(exports, "generateHtmlReport", { enumerable: true, get: function () { return htmlReporter_1.generateHtmlReport; } });
12
+ Object.defineProperty(exports, "HtmlReporterError", { enumerable: true, get: function () { return htmlReporter_1.HtmlReporterError; } });
13
+ Object.defineProperty(exports, "isHtmlReporterError", { enumerable: true, get: function () { return htmlReporter_1.isHtmlReporterError; } });
14
+ var jsonReporter_1 = require("./jsonReporter");
15
+ Object.defineProperty(exports, "generateJsonReport", { enumerable: true, get: function () { return jsonReporter_1.generateJsonReport; } });
16
+ Object.defineProperty(exports, "isJsonReporterError", { enumerable: true, get: function () { return jsonReporter_1.isJsonReporterError; } });
17
+ Object.defineProperty(exports, "JsonReporterError", { enumerable: true, get: function () { return jsonReporter_1.JsonReporterError; } });
18
+ var htmlTemplate_1 = require("./htmlTemplate");
19
+ Object.defineProperty(exports, "generateHtmlTemplate", { enumerable: true, get: function () { return htmlTemplate_1.generateHtmlTemplate; } });
20
+ var htmlStyles_1 = require("./htmlStyles");
21
+ Object.defineProperty(exports, "DIFF2HTML_STYLES", { enumerable: true, get: function () { return htmlStyles_1.DIFF2HTML_STYLES; } });
22
+ Object.defineProperty(exports, "HTML_STYLES", { enumerable: true, get: function () { return htmlStyles_1.HTML_STYLES; } });
23
+ Object.defineProperty(exports, "TAB_SCRIPT", { enumerable: true, get: function () { return htmlStyles_1.TAB_SCRIPT; } });
24
+ var treeBuilder_1 = require("./treeBuilder");
25
+ Object.defineProperty(exports, "buildFileTree", { enumerable: true, get: function () { return treeBuilder_1.buildFileTree; } });
26
+ var treeRenderer_1 = require("./treeRenderer");
27
+ Object.defineProperty(exports, "escapeHtml", { enumerable: true, get: function () { return treeRenderer_1.escapeHtml; } });
28
+ Object.defineProperty(exports, "renderSidebarTree", { enumerable: true, get: function () { return treeRenderer_1.renderSidebarTree; } });
29
+ Object.defineProperty(exports, "renderTreeview", { enumerable: true, get: function () { return treeRenderer_1.renderTreeview; } });
30
+ var browserLauncher_1 = require("./browserLauncher");
31
+ Object.defineProperty(exports, "BrowserLauncherError", { enumerable: true, get: function () { return browserLauncher_1.BrowserLauncherError; } });
32
+ Object.defineProperty(exports, "isBrowserLauncherError", { enumerable: true, get: function () { return browserLauncher_1.isBrowserLauncherError; } });
33
+ Object.defineProperty(exports, "openInBrowser", { enumerable: true, get: function () { return browserLauncher_1.openInBrowser; } });
@@ -1,8 +1,7 @@
1
- import { Config } from './configFile';
2
- import { FileDiffResult } from './fileDiff';
3
- import { ValidationResult } from './stopRulesValidator';
1
+ import { Config } from '../config';
2
+ import { FileDiffResult, ValidationResult } from '../pipeline';
4
3
  declare const JsonReporterErrorClass: {
5
- new (message: string, options?: import("./utils/errors").ErrorOptions): {
4
+ new (message: string, options?: import("../utils/errors").ErrorOptions): {
6
5
  [key: string]: unknown;
7
6
  readonly code?: string;
8
7
  readonly path?: string;
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.generateJsonReport = exports.isJsonReporterError = exports.JsonReporterError = void 0;
4
- const deepEqual_1 = require("./utils/deepEqual");
5
- const diffGenerator_1 = require("./utils/diffGenerator");
6
- const errors_1 = require("./utils/errors");
4
+ const deepEqual_1 = require("../utils/deepEqual");
5
+ const diffGenerator_1 = require("../utils/diffGenerator");
6
+ const errors_1 = require("../utils/errors");
7
7
  const JsonReporterErrorClass = (0, errors_1.createErrorClass)('JSON Reporter Error', {});
8
8
  class JsonReporterError extends JsonReporterErrorClass {
9
9
  }
@@ -1,5 +1,5 @@
1
- import { Config, StopRule } from './configFile';
2
- import { FileDiffResult } from './fileDiff';
1
+ import { Config, StopRule } from './config';
2
+ import { FileDiffResult } from './pipeline';
3
3
  export interface ValuePair {
4
4
  oldValue: string;
5
5
  targetValue: string;
@@ -316,7 +316,7 @@ const shouldIgnoreValue = (oldValue, targetValue) => {
316
316
  const calculateTransformConfidence = (occurrence) => {
317
317
  const fileCount = occurrence.files.size;
318
318
  const occurrenceCount = occurrence.examples.length;
319
- let confidence = 0;
319
+ let confidence;
320
320
  if (fileCount === 1)
321
321
  confidence =
322
322
  occurrenceCount >= suggestionConstants_1.FILTER_THRESHOLDS.MIN_SINGLE_FILE_OCCURRENCES
@@ -1,4 +1,4 @@
1
- import type { TransformConfig } from '../configFile';
1
+ import type { TransformConfig } from '../config';
2
2
  declare const CollisionDetectorErrorClass: {
3
3
  new (message: string, options?: import("./errors").ErrorOptions): {
4
4
  [key: string]: unknown;
@@ -1,5 +1,4 @@
1
- import type { FileDiffResult } from '../fileDiff';
2
- import type { FileMap } from '../fileLoader';
1
+ import type { FileDiffResult, FileMap } from '../pipeline';
3
2
  export type ChangeMode = 'new' | 'modified' | 'deleted' | 'all';
4
3
  export type FilterLogicalOperator = 'AND' | 'OR' | 'NONE';
5
4
  export interface ParsedFilter {
@@ -1,4 +1,4 @@
1
- import type { TransformConfig, TransformRule } from '../configFile';
1
+ import type { TransformConfig, TransformRule } from '../config';
2
2
  export declare const FilenameTransformerError: {
3
3
  new (message: string, options?: import("./errors").ErrorOptions): {
4
4
  [key: string]: unknown;
@@ -1,4 +1,4 @@
1
- import type { FixedValueConfig, FixedValueRule } from '../configFile';
1
+ import type { FixedValueConfig, FixedValueRule } from '../config';
2
2
  export declare const getFixedValuesForFile: (filePath: string, fixedValues?: FixedValueConfig) => FixedValueRule[];
3
3
  export declare const setValueAtPath: (object: unknown, pathParts: string[], value: unknown) => boolean;
4
4
  export declare const applyFixedValues: (data: unknown, rules: FixedValueRule[]) => void;
@@ -1,2 +1,2 @@
1
- import type { TransformRule } from '../configFile';
1
+ import type { TransformRule } from '../config';
2
2
  export declare const applyRegexRulesSequentially: (value: string, rules: TransformRule[], throwOnError?: boolean) => string;
@@ -1,4 +1,4 @@
1
- import type { StopRule } from '../configFile';
1
+ import type { StopRule } from '../config';
2
2
  export interface StopRuleViolation {
3
3
  file: string;
4
4
  rule: StopRule;
@@ -1,4 +1,4 @@
1
- import type { TransformRule } from '../configFile';
1
+ import type { TransformRule } from '../config';
2
2
  export declare const TransformFileLoaderError: {
3
3
  new (message: string, options?: import("./errors").ErrorOptions): {
4
4
  [key: string]: unknown;
@@ -1,4 +1,4 @@
1
- import type { TransformConfig, TransformRule } from '../configFile';
1
+ import type { TransformConfig, TransformRule } from '../config';
2
2
  declare const TransformerErrorClass: {
3
3
  new (message: string, options?: import("./errors").ErrorOptions): {
4
4
  [key: string]: unknown;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "helm-env-delta",
3
- "version": "1.13.0",
3
+ "version": "1.14.0",
4
4
  "description": "HelmEnvDelta – environment-aware YAML delta and sync for GitOps",
5
5
  "author": "BCsabaEngine",
6
6
  "license": "ISC",
@@ -40,9 +40,9 @@
40
40
  "test:coverage": "vitest run --coverage",
41
41
  "test:perf": "vitest bench --run",
42
42
  "test:perf:json": "vitest bench --run --reporter=json --outputFile=benchmark-results.json",
43
- "test:all": "npm test && npm run test:perf",
43
+ "test:all": "node --run test && node --run test:perf",
44
44
  "clean": "tsc --build --clean",
45
- "build": "tsc --build --clean && tsc --build --force",
45
+ "build": "tsc --build --clean && tsc --build",
46
46
  "format:check": "prettier --check .",
47
47
  "format:fix": "prettier --write . | grep -v 'unchanged' | sed G",
48
48
  "lint:check": "eslint .",
@@ -63,17 +63,13 @@
63
63
  "sync",
64
64
  "automation"
65
65
  ],
66
- "overrides": {
67
- "mkdirp": "3.0.1"
68
- },
69
66
  "devDependencies": {
70
- "@types/hogan.js": "^3.0.5",
71
- "@types/node": "^25.2.3",
67
+ "@eslint/js": "^10.0.1",
68
+ "@types/node": "^25.3.0",
72
69
  "@types/picomatch": "^4.0.2",
73
- "@typescript-eslint/eslint-plugin": "^8.55.0",
74
- "@typescript-eslint/parser": "^8.55.0",
70
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
75
71
  "@vitest/coverage-v8": "^4.0.18",
76
- "eslint": "^9.39.2",
72
+ "eslint": "^10.0.2",
77
73
  "eslint-config-prettier": "^10.1.8",
78
74
  "eslint-plugin-simple-import-sort": "^12.1.1",
79
75
  "eslint-plugin-unicorn": "^63.0.0",
File without changes
File without changes