fork-version 5.1.2 → 5.1.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Fork Version
2
2
 
3
+ ## [5.1.4](https://github.com/eglavin/fork-version/compare/v5.1.3...v5.1.4) (2026-04-18)
4
+
5
+
6
+ ### Refactor
7
+
8
+ * add defineFileManager function ([6e0f437](https://github.com/eglavin/fork-version/commit/6e0f4371824a232f85880a80b218d13b3decb25f))
9
+
10
+
11
+ ## [5.1.3](https://github.com/eglavin/fork-version/compare/v5.1.2...v5.1.3) (2026-04-18)
12
+
13
+
14
+ ### Bug Fixes
15
+
16
+ * filter unrelated prerelease tags to ensure out of order prereleases are handled bumped correctly ([1440272](https://github.com/eglavin/fork-version/commit/1440272dd55900945fae66539637d14b9b702b9b))
17
+
18
+
3
19
  ## [5.1.2](https://github.com/eglavin/fork-version/compare/v5.1.1...v5.1.2) (2026-04-13)
4
20
 
5
21
 
package/README.md CHANGED
@@ -574,6 +574,9 @@ Example `test.json` file:
574
574
 
575
575
  Example Custom File Manager implementation:
576
576
 
577
+ - [Using a class to define a file manager](./examples/custom-file-manager/fork.config.ts)
578
+ - [Using the defineFileManager function](./examples/custom-file-manager/fork.config.defineFileManager.ts)
579
+
577
580
  ```ts
578
581
  // fork.config.ts
579
582
  import { readFile, writeFile } from "node:fs/promises";
@@ -61,6 +61,12 @@ interface IFileManager {
61
61
  */
62
62
  isSupportedFile(filePath: string): boolean;
63
63
  }
64
+ /**
65
+ * Helper function to define a custom file manager with proper typing.
66
+ *
67
+ * [Fork-Version - Custom File Managers](https://github.com/eglavin/fork-version#custom-file-updaters)
68
+ */
69
+ declare function defineFileManager(fileManager: IFileManager): IFileManager;
64
70
  declare class FileManager {
65
71
  #private;
66
72
  constructor(config: ForkConfig, logger: Logger);
@@ -90,4 +96,4 @@ declare class FileManager {
90
96
  write(fileState: FileState, newVersion: string): Promise<void>;
91
97
  }
92
98
  //#endregion
93
- export { FileManager, FileState, IFileManager, MissingPropertyException };
99
+ export { FileManager, FileState, IFileManager, MissingPropertyException, defineFileManager };
@@ -22,6 +22,14 @@ var MissingPropertyException = class extends Error {
22
22
  this.propertyName = propertyName;
23
23
  }
24
24
  };
25
+ /**
26
+ * Helper function to define a custom file manager with proper typing.
27
+ *
28
+ * [Fork-Version - Custom File Managers](https://github.com/eglavin/fork-version#custom-file-updaters)
29
+ */
30
+ function defineFileManager(fileManager) {
31
+ return fileManager;
32
+ }
25
33
  var FileManager = class {
26
34
  #config;
27
35
  #logger;
@@ -97,4 +105,4 @@ var FileManager = class {
97
105
  }
98
106
  };
99
107
  //#endregion
100
- export { FileManager, MissingPropertyException };
108
+ export { FileManager, MissingPropertyException, defineFileManager };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { ParserOptions, createParserOptions } from "./commit-parser/options.js";
2
2
  import { Logger } from "./services/logger.js";
3
- import { FileManager, FileState, IFileManager, MissingPropertyException } from "./files/file-manager.js";
3
+ import { FileManager, FileState, IFileManager, MissingPropertyException, defineFileManager } from "./files/file-manager.js";
4
4
  import { ChangelogPresetConfig, ChangelogPresetConfigType, Config, ForkConfig } from "./config/types.js";
5
5
  import { Git } from "./services/git.js";
6
6
  import { inspect } from "./commands/inspect.js";
@@ -18,4 +18,4 @@ import { NextVersion, getNextVersion } from "./process/get-next-version.js";
18
18
  import { updateChangelog } from "./process/changelog.js";
19
19
  import { commitChanges } from "./process/commit.js";
20
20
  import { tagChanges } from "./process/tag.js";
21
- export { type ChangelogPresetConfig, type ChangelogPresetConfigType, type Commit, type CommitMerge, type CommitNote, CommitParser, type CommitReference, type CommitRevert, type CommitsSinceTag, type Config, type CurrentVersion, FileManager, type FileState, type ForkConfig, ForkConfigJSONSchema, ForkConfigJSSchema, Git, type IFileManager, Logger, MissingPropertyException, type NextVersion, type ParserOptions, commitChanges, createParserOptions, defineConfig, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
21
+ export { type ChangelogPresetConfig, type ChangelogPresetConfigType, type Commit, type CommitMerge, type CommitNote, CommitParser, type CommitReference, type CommitRevert, type CommitsSinceTag, type Config, type CurrentVersion, FileManager, type FileState, type ForkConfig, ForkConfigJSONSchema, ForkConfigJSSchema, Git, type IFileManager, Logger, MissingPropertyException, type NextVersion, type ParserOptions, commitChanges, createParserOptions, defineConfig, defineFileManager, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
package/dist/index.js CHANGED
@@ -14,6 +14,6 @@ import { ForkConfigJSONSchema, ForkConfigJSSchema } from "./config/schema.js";
14
14
  import { defineConfig } from "./config/define-config.js";
15
15
  import { Git } from "./services/git.js";
16
16
  import { getUserConfig } from "./config/user-config.js";
17
- import { FileManager, MissingPropertyException } from "./files/file-manager.js";
17
+ import { FileManager, MissingPropertyException, defineFileManager } from "./files/file-manager.js";
18
18
  import { Logger } from "./services/logger.js";
19
- export { CommitParser, FileManager, ForkConfigJSONSchema, ForkConfigJSSchema, Git, Logger, MissingPropertyException, commitChanges, createParserOptions, defineConfig, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
19
+ export { CommitParser, FileManager, ForkConfigJSONSchema, ForkConfigJSSchema, Git, Logger, MissingPropertyException, commitChanges, createParserOptions, defineConfig, defineFileManager, filterRevertedCommits, getCommitsSinceTag, getCurrentVersion, getNextVersion, getUserConfig, inspect, main, tagChanges, updateChangelog, validateConfig };
@@ -5,6 +5,7 @@ import { Commit } from "../commit-parser/types.js";
5
5
 
6
6
  //#region src/process/get-commits.d.ts
7
7
  interface CommitsSinceTag {
8
+ tags: string[];
8
9
  latestTag: string | undefined;
9
10
  latestTagVersion: string | undefined;
10
11
  commits: Commit[];
@@ -5,7 +5,8 @@ import { cleanTag } from "../utils/clean-tag.js";
5
5
  async function getCommitsSinceTag(config, logger, git) {
6
6
  const commitParser = new CommitParser(config.commitParserOptions);
7
7
  if (config.debug) commitParser.setLogger(logger);
8
- const latestTag = await git.getMostRecentTag(config.tagPrefix);
8
+ const tags = await git.getTags(config.tagPrefix, config.preRelease);
9
+ const latestTag = tags.length > 0 ? tags[0] : void 0;
9
10
  if (!latestTag) logger.warn("No previous tag found, using all commits");
10
11
  const foundCommits = await git.getCommits(latestTag, "HEAD");
11
12
  const commits = foundCommits.reduce((acc, commit) => {
@@ -16,6 +17,7 @@ async function getCommitsSinceTag(config, logger, git) {
16
17
  const filteredCommits = filterRevertedCommits(commits);
17
18
  logger.debug(`Found ${foundCommits.length} commits since tag: ${latestTag ?? "none"} (${commits.length} parsed, ${filteredCommits.length} after filtering reverts)`);
18
19
  return {
20
+ tags,
19
21
  latestTag,
20
22
  latestTagVersion: cleanTag(latestTag, config.tagPrefix),
21
23
  commits: filteredCommits
@@ -107,16 +107,7 @@ declare class Git {
107
107
  * await git.getTags("v"); // ["v1.0.2", "v1.0.1", "v1.0.0"]
108
108
  * ```
109
109
  */
110
- getTags(tagPrefix: string | undefined): Promise<string[]>;
111
- /**
112
- * Returns the most recent tag from the commit history, or `undefined` if no valid semver tags are found
113
- *
114
- * @example
115
- * ```ts
116
- * await git.getMostRecentTag("v"); // "1.2.3"
117
- * ```
118
- */
119
- getMostRecentTag(tagPrefix: string | undefined): Promise<string | undefined>;
110
+ getTags(tagPrefix?: string, preRelease?: string | boolean): Promise<string[]>;
120
111
  /**
121
112
  * Get commit history in a parsable format
122
113
  *
@@ -1,4 +1,4 @@
1
- import { escapeRegex } from "../utils/escape-regex.js";
1
+ import { cleanTag } from "../utils/clean-tag.js";
2
2
  import semver from "semver";
3
3
  import { execFile } from "node:child_process";
4
4
  //#region src/services/git.ts
@@ -16,7 +16,6 @@ var Git = class {
16
16
  this.getBranchName = this.getBranchName.bind(this);
17
17
  this.getRemoteUrl = this.getRemoteUrl.bind(this);
18
18
  this.getTags = this.getTags.bind(this);
19
- this.getMostRecentTag = this.getMostRecentTag.bind(this);
20
19
  this.getCommits = this.getCommits.bind(this);
21
20
  }
22
21
  async #execGit(command, args) {
@@ -143,6 +142,44 @@ var Git = class {
143
142
  }
144
143
  }
145
144
  /**
145
+ * Determine if a tag should be included based on the preRelease configuration.
146
+ *
147
+ * Example prerelease tags:
148
+ * - `1.2.3-alpha.0`
149
+ * - `1.2.3-beta.0`
150
+ * - `1.2.3-0`
151
+ *
152
+ * @example
153
+ * ```ts
154
+ * const tags = ["1.0.1-0", "1.0.1-alpha.0", "1.0.0"];
155
+ *
156
+ * shouldIncludeTag("1.0.1-0", true); // true
157
+ * shouldIncludeTag("1.0.1-alpha.0", true); // false
158
+ * shouldIncludeTag("1.0.0", true); // true
159
+ *
160
+ * shouldIncludeTag("1.0.1-0", "alpha"); // false
161
+ * shouldIncludeTag("1.0.1-alpha.0", "alpha"); // true
162
+ * shouldIncludeTag("1.0.0", "alpha"); // true
163
+ *
164
+ * shouldIncludeTag("1.0.1-0", false); // true
165
+ * shouldIncludeTag("1.0.1-alpha.0", false); // true
166
+ * shouldIncludeTag("1.0.0", false); // true
167
+ * ```
168
+ *
169
+ * @param tag The tag to evaluate (without prefix)
170
+ * @param preRelease The preRelease configuration value (Example: `true`, `false`, or a string like `"beta"`)
171
+ * @returns `true` if the tag should be included, `false` otherwise
172
+ */
173
+ #shouldIncludeTag(tag, preRelease) {
174
+ if (!tag || !semver.valid(tag)) return false;
175
+ if (!preRelease) return true;
176
+ const prereleaseParts = semver.prerelease(tag);
177
+ if (!prereleaseParts) return true;
178
+ if (typeof preRelease === "string") return prereleaseParts[0] === preRelease;
179
+ if (preRelease === true) return prereleaseParts.length === 1;
180
+ return false;
181
+ }
182
+ /**
146
183
  * `getTags` returns valid semver version tags in order of the commit history
147
184
  *
148
185
  * Using `git log` to get the commit history, we then parse the tags from the
@@ -163,7 +200,7 @@ var Git = class {
163
200
  * await git.getTags("v"); // ["v1.0.2", "v1.0.1", "v1.0.0"]
164
201
  * ```
165
202
  */
166
- async getTags(tagPrefix) {
203
+ async getTags(tagPrefix, preRelease) {
167
204
  const logOutput = await this.log("--decorate", "--no-color", "--date-order");
168
205
  /**
169
206
  * Search for tags in the following formats:
@@ -171,31 +208,19 @@ var Git = class {
171
208
  */
172
209
  const TAG_REGEX = /tag:\s*(?<tag>.+?)[,)]/gi;
173
210
  const tags = [];
174
- const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
175
211
  let tagMatch = null;
176
212
  while (tagMatch = TAG_REGEX.exec(logOutput)) {
177
213
  const { tag = "" } = tagMatch.groups ?? {};
178
214
  if (tagPrefix) {
179
215
  if (tag.startsWith(tagPrefix)) {
180
- const tagWithoutPrefix = tag.replace(new RegExp(`^${escapedTagPrefix}`), "");
181
- if (semver.valid(tagWithoutPrefix)) tags.push(tag);
216
+ const tagWithoutPrefix = cleanTag(tag, tagPrefix);
217
+ if (this.#shouldIncludeTag(tagWithoutPrefix, preRelease)) tags.push(tag);
182
218
  }
183
- } else if (/^\d/.test(tag) && semver.valid(tag)) tags.push(tag);
219
+ } else if (/^\d/.test(tag) && this.#shouldIncludeTag(tag, preRelease)) tags.push(tag);
184
220
  }
185
221
  return tags;
186
222
  }
187
223
  /**
188
- * Returns the most recent tag from the commit history, or `undefined` if no valid semver tags are found
189
- *
190
- * @example
191
- * ```ts
192
- * await git.getMostRecentTag("v"); // "1.2.3"
193
- * ```
194
- */
195
- async getMostRecentTag(tagPrefix) {
196
- return (await this.getTags(tagPrefix))[0] || void 0;
197
- }
198
- /**
199
224
  * Get commit history in a parsable format
200
225
  *
201
226
  * An array of strings with commit details is returned in the following format:
@@ -13,8 +13,7 @@ import semver from "semver";
13
13
  */
14
14
  function cleanTag(tag, tagPrefix) {
15
15
  if (!tag) return void 0;
16
- const escapedTagPrefix = tagPrefix ? escapeRegex(tagPrefix) : void 0;
17
- const tagWithoutPrefix = escapedTagPrefix ? tag.replace(new RegExp(`^${escapedTagPrefix}`), "") : tag;
16
+ const tagWithoutPrefix = tagPrefix ? tag.replace(new RegExp(`^${escapeRegex(tagPrefix)}`), "") : tag;
18
17
  return semver.clean(tagWithoutPrefix) ?? void 0;
19
18
  }
20
19
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fork-version",
3
- "version": "5.1.2",
3
+ "version": "5.1.4",
4
4
  "license": "MIT",
5
5
  "description": "Fork-Version automates version control tasks such as determining, updating, and committing versions, files, and changelogs, simplifying the process when adhering to the conventional commit standard.",
6
6
  "keywords": [