@helpers4/version 2.0.0-alpha.9 → 2.0.0-beta.3

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/README.md CHANGED
@@ -14,8 +14,10 @@ A set of helpers for working with URLs.
14
14
  <!-- AUTOMATIC-METHODS -->
15
15
  - compare
16
16
  - increment
17
+ - isPrerelease
17
18
  - parse
18
19
  - satisfiesRange
20
+ - stringify
19
21
  - stripV
20
22
  <!-- /AUTOMATIC-METHODS -->
21
23
 
@@ -23,9 +25,12 @@ A set of helpers for working with URLs.
23
25
 
24
26
  <!-- AUTOMATIC-SIBLINGS -->
25
27
  - [array](../array)
28
+ - [ci](../ci)
29
+ - [commit](../commit)
26
30
  - [date](../date)
27
31
  - [function](../function)
28
- - [math](../math)
32
+ - [id](../id)
33
+ - [markdown](../markdown)
29
34
  - [number](../number)
30
35
  - [object](../object)
31
36
  - [observable](../observable)
@@ -41,15 +46,18 @@ A set of helpers for working with URLs.
41
46
  | Name | Package | Source Code | Description |
42
47
  |------|---------|-------------|-------------|
43
48
  | array | [@helpers4/array](https://www.npmjs.com/package/@helpers4/array) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/array) | Array manipulation utilities |
44
- | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | date utilities |
49
+ | ci | [@helpers4/ci](https://www.npmjs.com/package/@helpers4/ci) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/ci) | CI/CD workflow status utilities |
50
+ | commit | [@helpers4/commit](https://www.npmjs.com/package/@helpers4/commit) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/commit) | Conventional Commits parsing and analysis |
51
+ | date | [@helpers4/date](https://www.npmjs.com/package/@helpers4/date) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/date) | Date and time utility functions |
45
52
  | function | [@helpers4/function](https://www.npmjs.com/package/@helpers4/function) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/function) | Function utilities and type guards |
46
- | math | [@helpers4/math](https://www.npmjs.com/package/@helpers4/math) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/math) | math utilities |
47
- | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | number utilities |
53
+ | id | [@helpers4/id](https://www.npmjs.com/package/@helpers4/id) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/id) | Unique identifier generation utilities |
54
+ | markdown | [@helpers4/markdown](https://www.npmjs.com/package/@helpers4/markdown) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/markdown) | Markdown formatting and escaping utilities |
55
+ | number | [@helpers4/number](https://www.npmjs.com/package/@helpers4/number) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/number) | Number utility functions and validation |
48
56
  | object | [@helpers4/object](https://www.npmjs.com/package/@helpers4/object) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/object) | Object manipulation utilities |
49
57
  | observable | [@helpers4/observable](https://www.npmjs.com/package/@helpers4/observable) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/observable) | Observable utilities and combinators |
50
58
  | promise | [@helpers4/promise](https://www.npmjs.com/package/@helpers4/promise) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/promise) | Promise utilities and error handling |
51
59
  | string | [@helpers4/string](https://www.npmjs.com/package/@helpers4/string) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/string) | String manipulation and formatting utilities |
52
- | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | type utilities |
60
+ | type | [@helpers4/type](https://www.npmjs.com/package/@helpers4/type) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/type) | Type checking and validation utilities |
53
61
  | url | [@helpers4/url](https://www.npmjs.com/package/@helpers4/url) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/url) | URL parsing and manipulation utilities |
54
62
  | version | [@helpers4/version](https://www.npmjs.com/package/@helpers4/version) | [Source](https://github.com/helpers4/helpers4/tree/main/helpers/version) | Version string manipulation utilities |
55
63
  <!-- /AUTOMATIC-CATEGORIES-TABLE -->
package/lib/index.d.ts CHANGED
@@ -38,6 +38,8 @@ declare function compare(version1: string, version2: string): number;
38
38
  * @since 1.9.0
39
39
  */
40
40
  declare function increment(version: string, type: 'major' | 'minor' | 'patch'): string;
41
+ declare function increment(version: undefined, type: 'major' | 'minor' | 'patch'): undefined;
42
+ declare function increment(version: null, type: 'major' | 'minor' | 'patch'): null;
41
43
 
42
44
  /**
43
45
  * This file is part of helpers4.
@@ -79,6 +81,42 @@ interface ParsedVersion {
79
81
  * @since 2.0.0
80
82
  */
81
83
  declare function parse(version: string): ParsedVersion;
84
+ declare function parse(version: undefined): undefined;
85
+ declare function parse(version: null): null;
86
+
87
+ /**
88
+ * This file is part of helpers4.
89
+ * Copyright (C) 2025 baxyz
90
+ * SPDX-License-Identifier: LGPL-3.0-or-later
91
+ */
92
+
93
+ /**
94
+ * Returns `true` when the version string has a prerelease suffix
95
+ * (i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).
96
+ *
97
+ * @param version - A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).
98
+ * @returns `true` if the version is a prerelease, `false` otherwise.
99
+ * @example
100
+ * isPrerelease('2.0.0-alpha.1') // true
101
+ * isPrerelease('1.0.0-rc.0') // true
102
+ * isPrerelease('1.0.0') // false
103
+ * isPrerelease('2.1.0') // false
104
+ * @since next
105
+ */
106
+ declare function isPrerelease(version: string): boolean;
107
+ /**
108
+ * Returns `true` when the parsed version has at least one prerelease identifier.
109
+ *
110
+ * @param version - A {@link ParsedVersion} object (as returned by {@link parse}).
111
+ * @returns `true` if `version.prerelease` is non-empty, `false` otherwise.
112
+ * @example
113
+ * isPrerelease(parse('2.0.0-alpha.1')) // true
114
+ * isPrerelease(parse('1.0.0')) // false
115
+ * @since next
116
+ */
117
+ declare function isPrerelease(version: ParsedVersion): boolean;
118
+ declare function isPrerelease(version: undefined): undefined;
119
+ declare function isPrerelease(version: null): null;
82
120
 
83
121
  /**
84
122
  * This file is part of helpers4.
@@ -94,6 +132,35 @@ declare function parse(version: string): ParsedVersion;
94
132
  */
95
133
  declare function satisfiesRange(version: string, range: string): boolean;
96
134
 
135
+ /**
136
+ * This file is part of helpers4.
137
+ * Copyright (C) 2025 baxyz
138
+ * SPDX-License-Identifier: LGPL-3.0-or-later
139
+ */
140
+
141
+ /**
142
+ * Reconstruct a semantic version string from a {@link ParsedVersion} object.
143
+ *
144
+ * This is the inverse of {@link parse}:
145
+ * `stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.
146
+ *
147
+ * @param parsed - A parsed semantic version object.
148
+ * @returns The reconstructed version string (without leading `v`).
149
+ * @example
150
+ * stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })
151
+ * // => '1.2.3'
152
+ * @example
153
+ * stringify({ major: 2, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] })
154
+ * // => '2.0.0-alpha.1'
155
+ * @example
156
+ * stringify({ major: 1, minor: 0, patch: 0, prerelease: ['beta'], build: ['exp', 'sha', '5114f85'] })
157
+ * // => '1.0.0-beta+exp.sha.5114f85'
158
+ * @since next
159
+ */
160
+ declare function stringify(parsed: ParsedVersion): string;
161
+ declare function stringify(parsed: undefined): undefined;
162
+ declare function stringify(parsed: null): null;
163
+
97
164
  /**
98
165
  * This file is part of helpers4.
99
166
  * Copyright (C) 2025 baxyz
@@ -121,5 +188,5 @@ declare function stripV(version: string): string;
121
188
  declare function stripV(version: null): null;
122
189
  declare function stripV(version: undefined): undefined;
123
190
 
124
- export { compare, increment, parse, satisfiesRange, stripV };
191
+ export { compare, increment, isPrerelease, parse, satisfiesRange, stringify, stripV };
125
192
  export type { ParsedVersion };
package/lib/index.js CHANGED
@@ -1,23 +1,6 @@
1
1
  //#region helpers/version/parse.ts
2
- /**
3
- * Parses a semantic version string into its components according to SemVer 2.0.0 specification
4
- *
5
- * Supports:
6
- * - Core version: MAJOR.MINOR.PATCH
7
- * - Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92
8
- * - Build metadata: +build, +sha.abc123, +20130313144700
9
- * - Optional 'v' prefix (commonly used in git tags)
10
- *
11
- * @param version - Version string to parse
12
- * @returns Parsed version object with major, minor, patch, prerelease, and build
13
- * @example
14
- * parse('1.2.3') // { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }
15
- * parse('v1.0.0-alpha.1') // { major: 1, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }
16
- * parse('2.0.0+build.123') // { major: 2, minor: 0, patch: 0, prerelease: [], build: ['build', '123'] }
17
- * parse('1.0.0-beta+exp.sha.5114f85') // { major: 1, minor: 0, patch: 0, prerelease: ['beta'], build: ['exp', 'sha', '5114f85'] }
18
- * @since 2.0.0
19
- */
20
2
  function parse(version) {
3
+ if (version === void 0 || version === null) return version;
21
4
  const [versionWithPrerelease, buildString] = version.replace(/^v/, "").split("+");
22
5
  const build = buildString ? buildString.split(".") : [];
23
6
  const [coreVersion, prereleaseString] = versionWithPrerelease.split("-");
@@ -105,22 +88,10 @@ function compare(version1, version2) {
105
88
  }
106
89
  //#endregion
107
90
  //#region helpers/version/increment.ts
108
- /**
109
- * This file is part of helpers4.
110
- * Copyright (C) 2025 baxyz
111
- * SPDX-License-Identifier: LGPL-3.0-or-later
112
- */
113
- /**
114
- * Increments a semantic version
115
- * @param version - The version to increment
116
- * @param type - The increment type ('major', 'minor', 'patch')
117
- * @returns Incremented version string
118
- * @since 1.9.0
119
- */
120
91
  function increment(version, type) {
121
- const normalize = (v) => v.replace(/^v/, "");
92
+ if (version === void 0 || version === null) return version;
122
93
  const hasV = version.startsWith("v");
123
- const parts = normalize(version).split(".").map(Number);
94
+ const parts = version.replace(/^v/, "").split(".").map(Number);
124
95
  while (parts.length < 3) parts.push(0);
125
96
  let [major, minor, patch] = parts;
126
97
  switch (type) {
@@ -142,6 +113,13 @@ function increment(version, type) {
142
113
  return hasV ? `v${result}` : result;
143
114
  }
144
115
  //#endregion
116
+ //#region helpers/version/isPrerelease.ts
117
+ function isPrerelease(version) {
118
+ if (version === void 0 || version === null) return version;
119
+ if (typeof version === "string") return version.split("+")[0].includes("-");
120
+ return version.prerelease.length > 0;
121
+ }
122
+ //#endregion
145
123
  //#region helpers/version/satisfiesRange.ts
146
124
  /**
147
125
  * This file is part of helpers4.
@@ -156,21 +134,20 @@ function increment(version, type) {
156
134
  * @since 1.9.0
157
135
  */
158
136
  function satisfiesRange(version, range) {
159
- const normalize = (v) => v.replace(/^v/, "");
160
- const normalizedVersion = normalize(version);
161
- if (!range.match(/[~^<>=]/)) return normalizedVersion === normalize(range);
162
- if (range.startsWith(">=")) return compareVersionsSimple(normalizedVersion, normalize(range.slice(2))) >= 0;
163
- if (range.startsWith(">")) return compareVersionsSimple(normalizedVersion, normalize(range.slice(1))) > 0;
164
- if (range.startsWith("<=")) return compareVersionsSimple(normalizedVersion, normalize(range.slice(2))) <= 0;
165
- if (range.startsWith("<")) return compareVersionsSimple(normalizedVersion, normalize(range.slice(1))) < 0;
137
+ const normalizedVersion = version.replace(/^v/, "");
138
+ if (!range.match(/[~^<>=]/)) return normalizedVersion === range.replace(/^v/, "");
139
+ if (range.startsWith(">=")) return compareVersionsSimple(normalizedVersion, range.slice(2).replace(/^v/, "")) >= 0;
140
+ if (range.startsWith(">")) return compareVersionsSimple(normalizedVersion, range.slice(1).replace(/^v/, "")) > 0;
141
+ if (range.startsWith("<=")) return compareVersionsSimple(normalizedVersion, range.slice(2).replace(/^v/, "")) <= 0;
142
+ if (range.startsWith("<")) return compareVersionsSimple(normalizedVersion, range.slice(1).replace(/^v/, "")) < 0;
166
143
  if (range.startsWith("^")) {
167
- const targetVersion = normalize(range.slice(1));
144
+ const targetVersion = range.slice(1).replace(/^v/, "");
168
145
  const [targetMajor] = targetVersion.split(".").map(Number);
169
146
  const [versionMajor] = normalizedVersion.split(".").map(Number);
170
147
  return versionMajor === targetMajor && compareVersionsSimple(normalizedVersion, targetVersion) >= 0;
171
148
  }
172
149
  if (range.startsWith("~")) {
173
- const targetVersion = normalize(range.slice(1));
150
+ const targetVersion = range.slice(1).replace(/^v/, "");
174
151
  const [targetMajor, targetMinor] = targetVersion.split(".").map(Number);
175
152
  const [versionMajor, versionMinor] = normalizedVersion.split(".").map(Number);
176
153
  return versionMajor === targetMajor && versionMinor === targetMinor && compareVersionsSimple(normalizedVersion, targetVersion) >= 0;
@@ -189,11 +166,17 @@ function compareVersionsSimple(version1, version2) {
189
166
  return 0;
190
167
  }
191
168
  //#endregion
169
+ //#region helpers/version/stringify.ts
170
+ function stringify(parsed) {
171
+ if (parsed === void 0 || parsed === null) return parsed;
172
+ return `${`${parsed.major}.${parsed.minor}.${parsed.patch}`}${parsed.prerelease.length > 0 ? `-${parsed.prerelease.join(".")}` : ""}${parsed.build.length > 0 ? `+${parsed.build.join(".")}` : ""}`;
173
+ }
174
+ //#endregion
192
175
  //#region helpers/version/stripV.ts
193
176
  function stripV(version) {
194
177
  return typeof version === "string" && version.startsWith("v") ? version.slice(1) : version;
195
178
  }
196
179
  //#endregion
197
- export { compare, increment, parse, satisfiesRange, stripV };
180
+ export { compare, increment, isPrerelease, parse, satisfiesRange, stringify, stripV };
198
181
 
199
182
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/version/parse.ts","../../../helpers/version/compare.ts","../../../helpers/version/increment.ts","../../../helpers/version/satisfiesRange.ts","../../../helpers/version/stripV.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Represents a parsed semantic version according to SemVer 2.0.0 specification\n * @since 2.0.0\n */\nexport interface ParsedVersion {\n /** Major version number */\n major: number;\n /** Minor version number */\n minor: number;\n /** Patch version number */\n patch: number;\n /** Pre-release identifiers (e.g., ['alpha', '1'] for -alpha.1) */\n prerelease: string[];\n /** Build metadata identifiers (e.g., ['build', '123'] for +build.123) */\n build: string[];\n}\n\n/**\n * Parses a semantic version string into its components according to SemVer 2.0.0 specification\n *\n * Supports:\n * - Core version: MAJOR.MINOR.PATCH\n * - Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92\n * - Build metadata: +build, +sha.abc123, +20130313144700\n * - Optional 'v' prefix (commonly used in git tags)\n *\n * @param version - Version string to parse\n * @returns Parsed version object with major, minor, patch, prerelease, and build\n * @example\n * parse('1.2.3') // { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }\n * parse('v1.0.0-alpha.1') // { major: 1, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }\n * parse('2.0.0+build.123') // { major: 2, minor: 0, patch: 0, prerelease: [], build: ['build', '123'] }\n * parse('1.0.0-beta+exp.sha.5114f85') // { major: 1, minor: 0, patch: 0, prerelease: ['beta'], build: ['exp', 'sha', '5114f85'] }\n * @since 2.0.0\n */\nexport function parse(version: string): ParsedVersion {\n // Remove optional 'v' prefix\n const normalized = version.replace(/^v/, '');\n\n // Split build metadata first (everything after +)\n const [versionWithPrerelease, buildString] = normalized.split('+');\n const build = buildString ? buildString.split('.') : [];\n\n // Split prerelease (everything after -)\n const [coreVersion, prereleaseString] = versionWithPrerelease.split('-');\n const prerelease = prereleaseString ? prereleaseString.split('.') : [];\n\n // Parse core version\n const parts = coreVersion.split('.').map(Number);\n\n return {\n major: parts[0] || 0,\n minor: parts[1] || 0,\n patch: parts[2] || 0,\n prerelease,\n build,\n };\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { parse } from './parse';\n\n/**\n * Compares two prerelease identifier arrays according to SemVer spec\n * Rules:\n * - Numeric identifiers are compared as integers\n * - Alphanumeric identifiers are compared lexically (ASCII)\n * - Numeric identifiers have lower precedence than alphanumeric\n * - A larger set of prerelease fields has higher precedence if all preceding are equal\n * @param pre1 - First prerelease array\n * @param pre2 - Second prerelease array\n * @returns -1, 0, or 1\n */\nfunction comparePrerelease(pre1: string[], pre2: string[]): number {\n // No prerelease has higher precedence than prerelease\n // e.g., 1.0.0 > 1.0.0-alpha\n if (pre1.length === 0 && pre2.length === 0) return 0;\n if (pre1.length === 0) return 1; // No prerelease > prerelease\n if (pre2.length === 0) return -1; // prerelease < no prerelease\n\n const maxLength = Math.max(pre1.length, pre2.length);\n\n for (let i = 0; i < maxLength; i++) {\n // A larger set has higher precedence if all preceding are equal\n if (i >= pre1.length) return -1;\n if (i >= pre2.length) return 1;\n\n const id1 = pre1[i];\n const id2 = pre2[i];\n\n const isNum1 = /^\\d+$/.test(id1);\n const isNum2 = /^\\d+$/.test(id2);\n\n // Both numeric: compare as integers\n if (isNum1 && isNum2) {\n const num1 = parseInt(id1, 10);\n const num2 = parseInt(id2, 10);\n if (num1 < num2) return -1;\n if (num1 > num2) return 1;\n // num1 === num2, continue to next identifier\n }\n // Numeric has lower precedence than alphanumeric\n else if (isNum1) {\n return -1;\n } else if (isNum2) {\n return 1;\n }\n // Both alphanumeric: compare lexically (ASCII sort)\n else {\n if (id1 < id2) return -1;\n if (id1 > id2) return 1;\n // id1 === id2, continue to next identifier\n }\n }\n\n return 0;\n}\n\n/**\n * Compares two semantic version strings according to SemVer 2.0.0 specification\n *\n * Supports:\n * - Core version: MAJOR.MINOR.PATCH\n * - Pre-release: -alpha, -beta.1, -rc.1, etc.\n * - Build metadata: +build, +sha.abc123 (ignored in comparison per spec)\n * - Optional 'v' prefix\n *\n * @param version1 - First version string\n * @param version2 - Second version string\n * @returns -1 if version1 < version2, 0 if equal, 1 if version1 > version2\n * @example\n * compare('1.0.0', '2.0.0') // -1\n * compare('1.0.0-alpha', '1.0.0') // -1 (prerelease < release)\n * compare('1.0.0-alpha', '1.0.0-beta') // -1\n * compare('1.0.0-alpha.1', '1.0.0-alpha.2') // -1\n * compare('1.0.0+build1', '1.0.0+build2') // 0 (build metadata ignored)\n * @since 1.9.0\n */\nexport function compare(version1: string, version2: string): number {\n const v1 = parse(version1);\n const v2 = parse(version2);\n\n // Compare major, minor, patch\n if (v1.major !== v2.major) return v1.major < v2.major ? -1 : 1;\n if (v1.minor !== v2.minor) return v1.minor < v2.minor ? -1 : 1;\n if (v1.patch !== v2.patch) return v1.patch < v2.patch ? -1 : 1;\n\n // Compare prerelease (build metadata is ignored per SemVer spec)\n return comparePrerelease(v1.prerelease, v2.prerelease);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Increments a semantic version\n * @param version - The version to increment\n * @param type - The increment type ('major', 'minor', 'patch')\n * @returns Incremented version string\n * @since 1.9.0\n */\nexport function increment(\n version: string,\n type: 'major' | 'minor' | 'patch'\n): string {\n const normalize = (v: string) => v.replace(/^v/, '');\n const hasV = version.startsWith('v');\n const normalizedVersion = normalize(version);\n\n const parts = normalizedVersion.split('.').map(Number);\n\n // Ensure we have at least major.minor.patch\n while (parts.length < 3) {\n parts.push(0);\n }\n\n let [major, minor, patch] = parts;\n\n switch (type) {\n case 'major':\n major++;\n minor = 0;\n patch = 0;\n break;\n case 'minor':\n minor++;\n patch = 0;\n break;\n case 'patch':\n patch++;\n break;\n default:\n throw new Error(`Invalid increment type: ${type}`);\n }\n\n const result = `${major}.${minor}.${patch}`;\n return hasV ? `v${result}` : result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Checks if a version satisfies a range (simple implementation)\n * @param version - Version to check\n * @param range - Range pattern (e.g., \">=1.0.0\", \"~1.2.0\", \"^1.0.0\")\n * @returns True if version satisfies the range\n * @since 1.9.0\n */\nexport function satisfiesRange(version: string, range: string): boolean {\n const normalize = (v: string) => v.replace(/^v/, '');\n const normalizedVersion = normalize(version);\n\n // Handle exact match\n if (!range.match(/[~^<>=]/)) {\n return normalizedVersion === normalize(range);\n }\n\n // Handle >= operator\n if (range.startsWith('>=')) {\n const targetVersion = normalize(range.slice(2));\n return compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n }\n\n // Handle > operator\n if (range.startsWith('>')) {\n const targetVersion = normalize(range.slice(1));\n return compareVersionsSimple(normalizedVersion, targetVersion) > 0;\n }\n\n // Handle <= operator\n if (range.startsWith('<=')) {\n const targetVersion = normalize(range.slice(2));\n return compareVersionsSimple(normalizedVersion, targetVersion) <= 0;\n }\n\n // Handle < operator\n if (range.startsWith('<')) {\n const targetVersion = normalize(range.slice(1));\n return compareVersionsSimple(normalizedVersion, targetVersion) < 0;\n }\n\n // Handle caret range (^1.2.3 allows patch and minor updates)\n if (range.startsWith('^')) {\n const targetVersion = normalize(range.slice(1));\n const [targetMajor] = targetVersion.split('.').map(Number);\n const [versionMajor] = normalizedVersion.split('.').map(Number);\n\n return versionMajor === targetMajor &&\n compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n }\n\n // Handle tilde range (~1.2.3 allows patch updates)\n if (range.startsWith('~')) {\n const targetVersion = normalize(range.slice(1));\n const [targetMajor, targetMinor] = targetVersion.split('.').map(Number);\n const [versionMajor, versionMinor] = normalizedVersion.split('.').map(Number);\n\n return versionMajor === targetMajor &&\n versionMinor === targetMinor &&\n compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n } else {\n // Unsupported range format\n return false;\n }\n}\n\nfunction compareVersionsSimple(version1: string, version2: string): number {\n const parts1 = version1.split('.').map(Number);\n const parts2 = version2.split('.').map(Number);\n\n const maxLength = Math.max(parts1.length, parts2.length);\n\n for (let i = 0; i < maxLength; i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 < part2) return -1;\n if (part1 > part2) return 1;\n }\n\n return 0;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Strip the leading \"v\" from a version string if it exists.\n * \n * @param version - The version string to process\n * @returns The version string without leading \"v\", or the original value if it's not a string or doesn't start with \"v\"\n * \n * @example\n * ```typescript\n * stripV(\"v1.2.3\") // \"1.2.3\"\n * stripV(\"1.2.3\") // \"1.2.3\"\n * stripV(\"v20.1.0\") // \"20.1.0\"\n * stripV(null) // null\n * stripV(undefined) // undefined\n * stripV(\"\") // \"\"\n * stripV(\"1.0.0-beta\") // \"1.0.0-beta\"\n * ```\n * @since 1.9.0\n */\nexport function stripV(version: string): string;\nexport function stripV(version: null): null;\nexport function stripV(version: undefined): undefined;\nexport function stripV(version: string | null | undefined): string | null | undefined {\n return typeof version === \"string\" && version.startsWith(\"v\") ? version.slice(1) : version;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../helpers/version/parse.ts","../../../helpers/version/compare.ts","../../../helpers/version/increment.ts","../../../helpers/version/isPrerelease.ts","../../../helpers/version/satisfiesRange.ts","../../../helpers/version/stringify.ts","../../../helpers/version/stripV.ts"],"sourcesContent":["/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Represents a parsed semantic version according to SemVer 2.0.0 specification\n * @since 2.0.0\n */\nexport interface ParsedVersion {\n /** Major version number */\n major: number;\n /** Minor version number */\n minor: number;\n /** Patch version number */\n patch: number;\n /** Pre-release identifiers (e.g., ['alpha', '1'] for -alpha.1) */\n prerelease: string[];\n /** Build metadata identifiers (e.g., ['build', '123'] for +build.123) */\n build: string[];\n}\n\n/**\n * Parses a semantic version string into its components according to SemVer 2.0.0 specification\n *\n * Supports:\n * - Core version: MAJOR.MINOR.PATCH\n * - Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92\n * - Build metadata: +build, +sha.abc123, +20130313144700\n * - Optional 'v' prefix (commonly used in git tags)\n *\n * @param version - Version string to parse\n * @returns Parsed version object with major, minor, patch, prerelease, and build\n * @example\n * parse('1.2.3') // { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }\n * parse('v1.0.0-alpha.1') // { major: 1, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }\n * parse('2.0.0+build.123') // { major: 2, minor: 0, patch: 0, prerelease: [], build: ['build', '123'] }\n * parse('1.0.0-beta+exp.sha.5114f85') // { major: 1, minor: 0, patch: 0, prerelease: ['beta'], build: ['exp', 'sha', '5114f85'] }\n * @since 2.0.0\n */\nexport function parse(version: string): ParsedVersion;\nexport function parse(version: undefined): undefined;\nexport function parse(version: null): null;\nexport function parse(version: string | undefined | null): ParsedVersion | undefined | null {\n if (version === undefined || version === null) return version;\n // Remove optional 'v' prefix\n const normalized = version.replace(/^v/, '');\n\n // Split build metadata first (everything after +)\n const [versionWithPrerelease, buildString] = normalized.split('+');\n const build = buildString ? buildString.split('.') : [];\n\n // Split prerelease (everything after -)\n const [coreVersion, prereleaseString] = versionWithPrerelease.split('-');\n const prerelease = prereleaseString ? prereleaseString.split('.') : [];\n\n // Parse core version\n const parts = coreVersion.split('.').map(Number);\n\n return {\n major: parts[0] || 0,\n minor: parts[1] || 0,\n patch: parts[2] || 0,\n prerelease,\n build,\n };\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport { parse } from './parse';\n\n/**\n * Compares two prerelease identifier arrays according to SemVer spec\n * Rules:\n * - Numeric identifiers are compared as integers\n * - Alphanumeric identifiers are compared lexically (ASCII)\n * - Numeric identifiers have lower precedence than alphanumeric\n * - A larger set of prerelease fields has higher precedence if all preceding are equal\n * @param pre1 - First prerelease array\n * @param pre2 - Second prerelease array\n * @returns -1, 0, or 1\n */\nfunction comparePrerelease(pre1: string[], pre2: string[]): number {\n // No prerelease has higher precedence than prerelease\n // e.g., 1.0.0 > 1.0.0-alpha\n if (pre1.length === 0 && pre2.length === 0) return 0;\n if (pre1.length === 0) return 1; // No prerelease > prerelease\n if (pre2.length === 0) return -1; // prerelease < no prerelease\n\n const maxLength = Math.max(pre1.length, pre2.length);\n\n for (let i = 0; i < maxLength; i++) {\n // A larger set has higher precedence if all preceding are equal\n if (i >= pre1.length) return -1;\n if (i >= pre2.length) return 1;\n\n const id1 = pre1[i];\n const id2 = pre2[i];\n\n const isNum1 = /^\\d+$/.test(id1);\n const isNum2 = /^\\d+$/.test(id2);\n\n // Both numeric: compare as integers\n if (isNum1 && isNum2) {\n const num1 = parseInt(id1, 10);\n const num2 = parseInt(id2, 10);\n if (num1 < num2) return -1;\n if (num1 > num2) return 1;\n // num1 === num2, continue to next identifier\n }\n // Numeric has lower precedence than alphanumeric\n else if (isNum1) {\n return -1;\n } else if (isNum2) {\n return 1;\n }\n // Both alphanumeric: compare lexically (ASCII sort)\n else {\n if (id1 < id2) return -1;\n if (id1 > id2) return 1;\n // id1 === id2, continue to next identifier\n }\n }\n\n return 0;\n}\n\n/**\n * Compares two semantic version strings according to SemVer 2.0.0 specification\n *\n * Supports:\n * - Core version: MAJOR.MINOR.PATCH\n * - Pre-release: -alpha, -beta.1, -rc.1, etc.\n * - Build metadata: +build, +sha.abc123 (ignored in comparison per spec)\n * - Optional 'v' prefix\n *\n * @param version1 - First version string\n * @param version2 - Second version string\n * @returns -1 if version1 < version2, 0 if equal, 1 if version1 > version2\n * @example\n * compare('1.0.0', '2.0.0') // -1\n * compare('1.0.0-alpha', '1.0.0') // -1 (prerelease < release)\n * compare('1.0.0-alpha', '1.0.0-beta') // -1\n * compare('1.0.0-alpha.1', '1.0.0-alpha.2') // -1\n * compare('1.0.0+build1', '1.0.0+build2') // 0 (build metadata ignored)\n * @since 1.9.0\n */\nexport function compare(version1: string, version2: string): number {\n const v1 = parse(version1);\n const v2 = parse(version2);\n\n // Compare major, minor, patch\n if (v1.major !== v2.major) return v1.major < v2.major ? -1 : 1;\n if (v1.minor !== v2.minor) return v1.minor < v2.minor ? -1 : 1;\n if (v1.patch !== v2.patch) return v1.patch < v2.patch ? -1 : 1;\n\n // Compare prerelease (build metadata is ignored per SemVer spec)\n return comparePrerelease(v1.prerelease, v2.prerelease);\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Increments a semantic version\n * @param version - The version to increment\n * @param type - The increment type ('major', 'minor', 'patch')\n * @returns Incremented version string\n * @since 1.9.0\n */\nexport function increment(version: string, type: 'major' | 'minor' | 'patch'): string;\nexport function increment(version: undefined, type: 'major' | 'minor' | 'patch'): undefined;\nexport function increment(version: null, type: 'major' | 'minor' | 'patch'): null;\nexport function increment(\n version: string | undefined | null,\n type: 'major' | 'minor' | 'patch'\n): string | undefined | null {\n if (version === undefined || version === null) return version;\n const hasV = version.startsWith('v');\n const normalizedVersion = version.replace(/^v/, '');\n\n const parts = normalizedVersion.split('.').map(Number);\n\n // Ensure we have at least major.minor.patch\n while (parts.length < 3) {\n parts.push(0);\n }\n\n let [major, minor, patch] = parts;\n\n switch (type) {\n case 'major':\n major++;\n minor = 0;\n patch = 0;\n break;\n case 'minor':\n minor++;\n patch = 0;\n break;\n case 'patch':\n patch++;\n break;\n default:\n throw new Error(`Invalid increment type: ${type}`);\n }\n\n const result = `${major}.${minor}.${patch}`;\n return hasV ? `v${result}` : result;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport type { ParsedVersion } from './parse';\n\n/**\n * Returns `true` when the version string has a prerelease suffix\n * (i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).\n *\n * @param version - A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).\n * @returns `true` if the version is a prerelease, `false` otherwise.\n * @example\n * isPrerelease('2.0.0-alpha.1') // true\n * isPrerelease('1.0.0-rc.0') // true\n * isPrerelease('1.0.0') // false\n * isPrerelease('2.1.0') // false\n * @since next\n */\nexport function isPrerelease(version: string): boolean;\n/**\n * Returns `true` when the parsed version has at least one prerelease identifier.\n *\n * @param version - A {@link ParsedVersion} object (as returned by {@link parse}).\n * @returns `true` if `version.prerelease` is non-empty, `false` otherwise.\n * @example\n * isPrerelease(parse('2.0.0-alpha.1')) // true\n * isPrerelease(parse('1.0.0')) // false\n * @since next\n */\nexport function isPrerelease(version: ParsedVersion): boolean;\nexport function isPrerelease(version: undefined): undefined;\nexport function isPrerelease(version: null): null;\nexport function isPrerelease(version: string | ParsedVersion | undefined | null): boolean | undefined | null {\n if (version === undefined || version === null) return version;\n if (typeof version === 'string') return version.split('+')[0].includes('-');\n return version.prerelease.length > 0;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Checks if a version satisfies a range (simple implementation)\n * @param version - Version to check\n * @param range - Range pattern (e.g., \">=1.0.0\", \"~1.2.0\", \"^1.0.0\")\n * @returns True if version satisfies the range\n * @since 1.9.0\n */\nexport function satisfiesRange(version: string, range: string): boolean {\n const normalizedVersion = version.replace(/^v/, '');\n\n // Handle exact match\n if (!range.match(/[~^<>=]/)) {\n return normalizedVersion === range.replace(/^v/, '');\n }\n\n // Handle >= operator\n if (range.startsWith('>=')) {\n const targetVersion = range.slice(2).replace(/^v/, '');\n return compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n }\n\n // Handle > operator\n if (range.startsWith('>')) {\n const targetVersion = range.slice(1).replace(/^v/, '');\n return compareVersionsSimple(normalizedVersion, targetVersion) > 0;\n }\n\n // Handle <= operator\n if (range.startsWith('<=')) {\n const targetVersion = range.slice(2).replace(/^v/, '');\n return compareVersionsSimple(normalizedVersion, targetVersion) <= 0;\n }\n\n // Handle < operator\n if (range.startsWith('<')) {\n const targetVersion = range.slice(1).replace(/^v/, '');\n return compareVersionsSimple(normalizedVersion, targetVersion) < 0;\n }\n\n // Handle caret range (^1.2.3 allows patch and minor updates)\n if (range.startsWith('^')) {\n const targetVersion = range.slice(1).replace(/^v/, '');\n const [targetMajor] = targetVersion.split('.').map(Number);\n const [versionMajor] = normalizedVersion.split('.').map(Number);\n\n return versionMajor === targetMajor &&\n compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n }\n\n // Handle tilde range (~1.2.3 allows patch updates)\n if (range.startsWith('~')) {\n const targetVersion = range.slice(1).replace(/^v/, '');\n const [targetMajor, targetMinor] = targetVersion.split('.').map(Number);\n const [versionMajor, versionMinor] = normalizedVersion.split('.').map(Number);\n\n return versionMajor === targetMajor &&\n versionMinor === targetMinor &&\n compareVersionsSimple(normalizedVersion, targetVersion) >= 0;\n } else {\n // Unsupported range format\n return false;\n }\n}\n\nfunction compareVersionsSimple(version1: string, version2: string): number {\n const parts1 = version1.split('.').map(Number);\n const parts2 = version2.split('.').map(Number);\n\n const maxLength = Math.max(parts1.length, parts2.length);\n\n for (let i = 0; i < maxLength; i++) {\n const part1 = parts1[i] || 0;\n const part2 = parts2[i] || 0;\n\n if (part1 < part2) return -1;\n if (part1 > part2) return 1;\n }\n\n return 0;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\nimport type { ParsedVersion } from './parse';\n\n/**\n * Reconstruct a semantic version string from a {@link ParsedVersion} object.\n *\n * This is the inverse of {@link parse}:\n * `stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.\n *\n * @param parsed - A parsed semantic version object.\n * @returns The reconstructed version string (without leading `v`).\n * @example\n * stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })\n * // => '1.2.3'\n * @example\n * stringify({ major: 2, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] })\n * // => '2.0.0-alpha.1'\n * @example\n * stringify({ major: 1, minor: 0, patch: 0, prerelease: ['beta'], build: ['exp', 'sha', '5114f85'] })\n * // => '1.0.0-beta+exp.sha.5114f85'\n * @since next\n */\nexport function stringify(parsed: ParsedVersion): string;\nexport function stringify(parsed: undefined): undefined;\nexport function stringify(parsed: null): null;\nexport function stringify(parsed: ParsedVersion | undefined | null): string | undefined | null {\n if (parsed === undefined || parsed === null) return parsed;\n const base = `${parsed.major}.${parsed.minor}.${parsed.patch}`;\n const prerelease = parsed.prerelease.length > 0 ? `-${parsed.prerelease.join('.')}` : '';\n const build = parsed.build.length > 0 ? `+${parsed.build.join('.')}` : '';\n return `${base}${prerelease}${build}`;\n}\n","/**\n * This file is part of helpers4.\n * Copyright (C) 2025 baxyz\n * SPDX-License-Identifier: LGPL-3.0-or-later\n */\n\n/**\n * Strip the leading \"v\" from a version string if it exists.\n * \n * @param version - The version string to process\n * @returns The version string without leading \"v\", or the original value if it's not a string or doesn't start with \"v\"\n * \n * @example\n * ```typescript\n * stripV(\"v1.2.3\") // \"1.2.3\"\n * stripV(\"1.2.3\") // \"1.2.3\"\n * stripV(\"v20.1.0\") // \"20.1.0\"\n * stripV(null) // null\n * stripV(undefined) // undefined\n * stripV(\"\") // \"\"\n * stripV(\"1.0.0-beta\") // \"1.0.0-beta\"\n * ```\n * @since 1.9.0\n */\nexport function stripV(version: string): string;\nexport function stripV(version: null): null;\nexport function stripV(version: undefined): undefined;\nexport function stripV(version: string | null | undefined): string | null | undefined {\n return typeof version === \"string\" && version.startsWith(\"v\") ? version.slice(1) : version;\n}\n"],"mappings":"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"}
package/llms.txt ADDED
@@ -0,0 +1,485 @@
1
+ # @helpers4/version
2
+
3
+ > Tree-shakable TypeScript utility functions for the `version` domain.
4
+ > Package: `@helpers4/version` — Version: 2.0.0-beta.3
5
+ > License: LGPL-3.0-or-later
6
+
7
+ ## Installation
8
+
9
+ ```sh
10
+ npm install @helpers4/version
11
+ # or
12
+ pnpm add @helpers4/version
13
+ ```
14
+
15
+ ## Usage
16
+
17
+ ```typescript
18
+ import { compare, increment, isPrerelease, ... } from '@helpers4/version';
19
+ ```
20
+
21
+ ## Functions
22
+
23
+ | Function | Description |
24
+ |---|---|
25
+ | `compare` | Compares two semantic version strings according to SemVer 2.0.0 specification Supports: - Core vers |
26
+ | `increment` | Increments a semantic version |
27
+ | `isPrerelease` | Returns `true` when the version string has a prerelease suffix (i.e. contains a `-` after the core ` |
28
+ | `parse` | Parses a semantic version string into its components according to SemVer 2.0.0 specification Suppor |
29
+ | `satisfiesRange` | Checks if a version satisfies a range (simple implementation) |
30
+ | `stringify` | Reconstruct a semantic version string from a ParsedVersion object. This is the inverse of parse: `s |
31
+ | `stripV` | Strip the leading "v" from a version string if it exists. |
32
+
33
+ ---
34
+
35
+ ## API Reference
36
+
37
+ ### `compare`
38
+
39
+ Compares two semantic version strings according to SemVer 2.0.0 specification
40
+
41
+ Supports:
42
+ - Core version: MAJOR.MINOR.PATCH
43
+ - Pre-release: -alpha, -beta.1, -rc.1, etc.
44
+ - Build metadata: +build, +sha.abc123 (ignored in comparison per spec)
45
+ - Optional 'v' prefix
46
+
47
+ ```typescript
48
+ import { compare } from '@helpers4/version';
49
+
50
+ compare(version1: string, version2: string): number
51
+ ```
52
+
53
+ **Parameters:**
54
+
55
+ - `version1: string` — First version string
56
+ - `version2: string` — Second version string
57
+
58
+ **Returns:** `number` — -1 if version1 < version2, 0 if equal, 1 if version1 > version2
59
+
60
+ **Examples:**
61
+
62
+ *Compare two semver versions*
63
+
64
+ Returns -1, 0, or 1 based on SemVer ordering.
65
+
66
+ ```typescript
67
+ compare('1.0.0', '2.0.0') // => -1
68
+ compare('1.0.0', '1.0.0') // => 0
69
+ compare('2.0.0', '1.0.0') // => 1
70
+ ```
71
+
72
+ *Prerelease is lower than release*
73
+
74
+ A prerelease version is always less than the release.
75
+
76
+ ```typescript
77
+ compare('1.0.0-alpha', '1.0.0')
78
+ // => -1
79
+ ```
80
+
81
+ ---
82
+
83
+ ### `increment`
84
+
85
+ Increments a semantic version
86
+
87
+ ```typescript
88
+ import { increment } from '@helpers4/version';
89
+
90
+ increment(version: string, type: "major" | "minor" | "patch"): string
91
+ ```
92
+
93
+ **Parameters:**
94
+
95
+ - `version: string` — The version to increment
96
+ - `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')
97
+
98
+ **Returns:** `string` — Incremented version string
99
+
100
+ ```typescript
101
+ import { increment } from '@helpers4/version';
102
+
103
+ increment(version: undefined, type: "major" | "minor" | "patch"): undefined
104
+ ```
105
+
106
+ **Parameters:**
107
+
108
+ - `version: undefined` — The version to increment
109
+ - `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')
110
+
111
+ **Returns:** `undefined` — Incremented version string
112
+
113
+ ```typescript
114
+ import { increment } from '@helpers4/version';
115
+
116
+ increment(version: null, type: "major" | "minor" | "patch"): null
117
+ ```
118
+
119
+ **Parameters:**
120
+
121
+ - `version: null` — The version to increment
122
+ - `type: "major" | "minor" | "patch"` — The increment type ('major', 'minor', 'patch')
123
+
124
+ **Returns:** `null` — Incremented version string
125
+
126
+ **Examples:**
127
+
128
+ *Increment the patch version*
129
+
130
+ Bumps the patch number while keeping major and minor.
131
+
132
+ ```typescript
133
+ increment('1.2.3', 'patch')
134
+ // => '1.2.4'
135
+ ```
136
+
137
+ *Increment the minor version*
138
+
139
+ Bumps the minor number and resets patch to 0.
140
+
141
+ ```typescript
142
+ increment('1.2.3', 'minor')
143
+ // => '1.3.0'
144
+ ```
145
+
146
+ *Preserve the v prefix*
147
+
148
+ The v prefix is preserved if present in the input.
149
+
150
+ ```typescript
151
+ increment('v1.0.0', 'major')
152
+ // => 'v2.0.0'
153
+ ```
154
+
155
+ ---
156
+
157
+ ### `isPrerelease`
158
+
159
+ Returns `true` when the version string has a prerelease suffix
160
+ (i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).
161
+
162
+ ```typescript
163
+ import { isPrerelease } from '@helpers4/version';
164
+
165
+ isPrerelease(version: string): boolean
166
+ ```
167
+
168
+ **Parameters:**
169
+
170
+ - `version: string` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).
171
+
172
+ **Returns:** `boolean` — `true` if the version is a prerelease, `false` otherwise.
173
+
174
+ ```typescript
175
+ import { isPrerelease } from '@helpers4/version';
176
+
177
+ isPrerelease(version: ParsedVersion): boolean
178
+ ```
179
+
180
+ **Parameters:**
181
+
182
+ - `version: ParsedVersion` — A ParsedVersion object (as returned by parse).
183
+
184
+ **Returns:** `boolean` — `true` if `version.prerelease` is non-empty, `false` otherwise.
185
+
186
+ ```typescript
187
+ import { isPrerelease } from '@helpers4/version';
188
+
189
+ isPrerelease(version: undefined): undefined
190
+ ```
191
+
192
+ **Parameters:**
193
+
194
+ - `version: undefined` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).
195
+
196
+ **Returns:** `undefined` — `true` if the version is a prerelease, `false` otherwise.
197
+
198
+ ```typescript
199
+ import { isPrerelease } from '@helpers4/version';
200
+
201
+ isPrerelease(version: null): null
202
+ ```
203
+
204
+ **Parameters:**
205
+
206
+ - `version: null` — A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`).
207
+
208
+ **Returns:** `null` — `true` if the version is a prerelease, `false` otherwise.
209
+
210
+ **Examples:**
211
+
212
+ *Detect a prerelease version*
213
+
214
+ Returns true for any version string that contains a prerelease suffix.
215
+
216
+ ```typescript
217
+ isPrerelease('2.0.0-alpha.1') // true
218
+ isPrerelease('1.0.0-rc.0') // true
219
+ ```
220
+
221
+ *Stable versions return false*
222
+
223
+ Returns false when the version has no prerelease suffix.
224
+
225
+ ```typescript
226
+ isPrerelease('1.0.0') // false
227
+ isPrerelease('2.1.3') // false
228
+ ```
229
+
230
+ *Accept a ParsedVersion object*
231
+
232
+ Works with the result of parse() — checks the prerelease array instead of string matching.
233
+
234
+ ```typescript
235
+ isPrerelease(parse('2.0.0-alpha.1')) // true
236
+ isPrerelease(parse('1.0.0')) // false
237
+ ```
238
+
239
+ ---
240
+
241
+ ### `parse`
242
+
243
+ Parses a semantic version string into its components according to SemVer 2.0.0 specification
244
+
245
+ Supports:
246
+ - Core version: MAJOR.MINOR.PATCH
247
+ - Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92
248
+ - Build metadata: +build, +sha.abc123, +20130313144700
249
+ - Optional 'v' prefix (commonly used in git tags)
250
+
251
+ ```typescript
252
+ import { parse } from '@helpers4/version';
253
+
254
+ parse(version: string): ParsedVersion
255
+ ```
256
+
257
+ **Parameters:**
258
+
259
+ - `version: string` — Version string to parse
260
+
261
+ **Returns:** `ParsedVersion` — Parsed version object with major, minor, patch, prerelease, and build
262
+
263
+ ```typescript
264
+ import { parse } from '@helpers4/version';
265
+
266
+ parse(version: undefined): undefined
267
+ ```
268
+
269
+ **Parameters:**
270
+
271
+ - `version: undefined` — Version string to parse
272
+
273
+ **Returns:** `undefined` — Parsed version object with major, minor, patch, prerelease, and build
274
+
275
+ ```typescript
276
+ import { parse } from '@helpers4/version';
277
+
278
+ parse(version: null): null
279
+ ```
280
+
281
+ **Parameters:**
282
+
283
+ - `version: null` — Version string to parse
284
+
285
+ **Returns:** `null` — Parsed version object with major, minor, patch, prerelease, and build
286
+
287
+ **Examples:**
288
+
289
+ *Parse a semver string*
290
+
291
+ Breaks a semantic version string into its components.
292
+
293
+ ```typescript
294
+ parse('1.2.3')
295
+ // => { major: 1, minor: 2, patch: 3, prerelease: [], build: [] }
296
+ ```
297
+
298
+ *Parse a prerelease version*
299
+
300
+ Handles prerelease identifiers and optional v prefix.
301
+
302
+ ```typescript
303
+ parse('v2.0.0-alpha.1')
304
+ // => { major: 2, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }
305
+ ```
306
+
307
+ ---
308
+
309
+ ### `satisfiesRange`
310
+
311
+ Checks if a version satisfies a range (simple implementation)
312
+
313
+ ```typescript
314
+ import { satisfiesRange } from '@helpers4/version';
315
+
316
+ satisfiesRange(version: string, range: string): boolean
317
+ ```
318
+
319
+ **Parameters:**
320
+
321
+ - `version: string` — Version to check
322
+ - `range: string` — Range pattern (e.g., ">=1.0.0", "~1.2.0", "^1.0.0")
323
+
324
+ **Returns:** `boolean` — True if version satisfies the range
325
+
326
+ **Examples:**
327
+
328
+ *Check caret range*
329
+
330
+ Caret (^) allows patch and minor updates within the same major.
331
+
332
+ ```typescript
333
+ satisfiesRange('1.2.3', '^1.0.0')
334
+ // => true
335
+ ```
336
+
337
+ *Check greater-than-or-equal range*
338
+
339
+ The >= operator checks if the version is at least the specified value.
340
+
341
+ ```typescript
342
+ satisfiesRange('2.0.0', '>=1.5.0')
343
+ // => true
344
+ ```
345
+
346
+ *Out of range*
347
+
348
+ Returns false when the version does not satisfy the range.
349
+
350
+ ```typescript
351
+ satisfiesRange('0.9.0', '>=1.0.0')
352
+ // => false
353
+ ```
354
+
355
+ ---
356
+
357
+ ### `stringify`
358
+
359
+ Reconstruct a semantic version string from a ParsedVersion object.
360
+
361
+ This is the inverse of parse:
362
+ `stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.
363
+
364
+ ```typescript
365
+ import { stringify } from '@helpers4/version';
366
+
367
+ stringify(parsed: ParsedVersion): string
368
+ ```
369
+
370
+ **Parameters:**
371
+
372
+ - `parsed: ParsedVersion` — A parsed semantic version object.
373
+
374
+ **Returns:** `string` — The reconstructed version string (without leading `v`).
375
+
376
+ ```typescript
377
+ import { stringify } from '@helpers4/version';
378
+
379
+ stringify(parsed: undefined): undefined
380
+ ```
381
+
382
+ **Parameters:**
383
+
384
+ - `parsed: undefined` — A parsed semantic version object.
385
+
386
+ **Returns:** `undefined` — The reconstructed version string (without leading `v`).
387
+
388
+ ```typescript
389
+ import { stringify } from '@helpers4/version';
390
+
391
+ stringify(parsed: null): null
392
+ ```
393
+
394
+ **Parameters:**
395
+
396
+ - `parsed: null` — A parsed semantic version object.
397
+
398
+ **Returns:** `null` — The reconstructed version string (without leading `v`).
399
+
400
+ **Examples:**
401
+
402
+ *Reconstruct a stable version*
403
+
404
+ Converts a ParsedVersion object back to a version string.
405
+
406
+ ```typescript
407
+ stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })
408
+ // => '1.2.3'
409
+ ```
410
+
411
+ *Round-trip with parse*
412
+
413
+ stringify(parse(v)) returns the original version string (without leading v).
414
+
415
+ ```typescript
416
+ stringify(parse('2.0.0-alpha.1'))
417
+ // => '2.0.0-alpha.1'
418
+
419
+ stringify(parse('1.0.0-beta+exp.sha.5114f85'))
420
+ // => '1.0.0-beta+exp.sha.5114f85'
421
+ ```
422
+
423
+ ---
424
+
425
+ ### `stripV`
426
+
427
+ Strip the leading "v" from a version string if it exists.
428
+
429
+ ```typescript
430
+ import { stripV } from '@helpers4/version';
431
+
432
+ stripV(version: string): string
433
+ ```
434
+
435
+ **Parameters:**
436
+
437
+ - `version: string` — The version string to process
438
+
439
+ **Returns:** `string` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"
440
+
441
+ ```typescript
442
+ import { stripV } from '@helpers4/version';
443
+
444
+ stripV(version: null): null
445
+ ```
446
+
447
+ **Parameters:**
448
+
449
+ - `version: null` — The version string to process
450
+
451
+ **Returns:** `null` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"
452
+
453
+ ```typescript
454
+ import { stripV } from '@helpers4/version';
455
+
456
+ stripV(version: undefined): undefined
457
+ ```
458
+
459
+ **Parameters:**
460
+
461
+ - `version: undefined` — The version string to process
462
+
463
+ **Returns:** `undefined` — The version string without leading "v", or the original value if it's not a string or doesn't start with "v"
464
+
465
+ **Examples:**
466
+
467
+ *Remove v prefix from a version string*
468
+
469
+ Strips the leading "v" from a git tag-style version string.
470
+
471
+ ```typescript
472
+ stripV('v1.2.3')
473
+ // => '1.2.3'
474
+ ```
475
+
476
+ *No-op when there is no v prefix*
477
+
478
+ Returns the string unchanged when it does not start with "v".
479
+
480
+ ```typescript
481
+ stripV('1.2.3')
482
+ // => '1.2.3'
483
+ ```
484
+
485
+ ---
package/meta/api.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "category": "version",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.3",
4
4
  "functions": [
5
5
  {
6
6
  "name": "compare",
@@ -68,6 +68,46 @@
68
68
  "type": "string",
69
69
  "description": "Incremented version string"
70
70
  }
71
+ },
72
+ {
73
+ "signature": "increment(version: undefined, type: \"major\" | \"minor\" | \"patch\"): undefined",
74
+ "description": "Increments a semantic version",
75
+ "params": [
76
+ {
77
+ "name": "version",
78
+ "type": "undefined",
79
+ "description": "The version to increment"
80
+ },
81
+ {
82
+ "name": "type",
83
+ "type": "\"major\" | \"minor\" | \"patch\"",
84
+ "description": "The increment type ('major', 'minor', 'patch')"
85
+ }
86
+ ],
87
+ "returns": {
88
+ "type": "undefined",
89
+ "description": "Incremented version string"
90
+ }
91
+ },
92
+ {
93
+ "signature": "increment(version: null, type: \"major\" | \"minor\" | \"patch\"): null",
94
+ "description": "Increments a semantic version",
95
+ "params": [
96
+ {
97
+ "name": "version",
98
+ "type": "null",
99
+ "description": "The version to increment"
100
+ },
101
+ {
102
+ "name": "type",
103
+ "type": "\"major\" | \"minor\" | \"patch\"",
104
+ "description": "The increment type ('major', 'minor', 'patch')"
105
+ }
106
+ ],
107
+ "returns": {
108
+ "type": "null",
109
+ "description": "Incremented version string"
110
+ }
71
111
  }
72
112
  ],
73
113
  "examples": [
@@ -89,6 +129,92 @@
89
129
  ],
90
130
  "sourceFile": "increment.ts"
91
131
  },
132
+ {
133
+ "name": "isPrerelease",
134
+ "kind": "function",
135
+ "description": "Returns `true` when the version string has a prerelease suffix\n(i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).",
136
+ "since": "next",
137
+ "signatures": [
138
+ {
139
+ "signature": "isPrerelease(version: string): boolean",
140
+ "description": "Returns `true` when the version string has a prerelease suffix\n(i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).",
141
+ "params": [
142
+ {
143
+ "name": "version",
144
+ "type": "string",
145
+ "description": "A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`)."
146
+ }
147
+ ],
148
+ "returns": {
149
+ "type": "boolean",
150
+ "description": "`true` if the version is a prerelease, `false` otherwise."
151
+ }
152
+ },
153
+ {
154
+ "signature": "isPrerelease(version: ParsedVersion): boolean",
155
+ "description": "Returns `true` when the parsed version has at least one prerelease identifier.",
156
+ "params": [
157
+ {
158
+ "name": "version",
159
+ "type": "ParsedVersion",
160
+ "description": "A ParsedVersion object (as returned by parse)."
161
+ }
162
+ ],
163
+ "returns": {
164
+ "type": "boolean",
165
+ "description": "`true` if `version.prerelease` is non-empty, `false` otherwise."
166
+ }
167
+ },
168
+ {
169
+ "signature": "isPrerelease(version: undefined): undefined",
170
+ "description": "Returns `true` when the version string has a prerelease suffix\n(i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).",
171
+ "params": [
172
+ {
173
+ "name": "version",
174
+ "type": "undefined",
175
+ "description": "A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`)."
176
+ }
177
+ ],
178
+ "returns": {
179
+ "type": "undefined",
180
+ "description": "`true` if the version is a prerelease, `false` otherwise."
181
+ }
182
+ },
183
+ {
184
+ "signature": "isPrerelease(version: null): null",
185
+ "description": "Returns `true` when the version string has a prerelease suffix\n(i.e. contains a `-` after the core `MAJOR.MINOR.PATCH`).",
186
+ "params": [
187
+ {
188
+ "name": "version",
189
+ "type": "null",
190
+ "description": "A semantic version string (e.g. `'2.0.0-alpha.1'`, `'1.0.0'`)."
191
+ }
192
+ ],
193
+ "returns": {
194
+ "type": "null",
195
+ "description": "`true` if the version is a prerelease, `false` otherwise."
196
+ }
197
+ }
198
+ ],
199
+ "examples": [
200
+ {
201
+ "title": "Detect a prerelease version",
202
+ "description": "Returns true for any version string that contains a prerelease suffix.",
203
+ "code": "isPrerelease('2.0.0-alpha.1') // true\nisPrerelease('1.0.0-rc.0') // true"
204
+ },
205
+ {
206
+ "title": "Stable versions return false",
207
+ "description": "Returns false when the version has no prerelease suffix.",
208
+ "code": "isPrerelease('1.0.0') // false\nisPrerelease('2.1.3') // false"
209
+ },
210
+ {
211
+ "title": "Accept a ParsedVersion object",
212
+ "description": "Works with the result of parse() — checks the prerelease array instead of string matching.",
213
+ "code": "isPrerelease(parse('2.0.0-alpha.1')) // true\nisPrerelease(parse('1.0.0')) // false"
214
+ }
215
+ ],
216
+ "sourceFile": "isPrerelease.ts"
217
+ },
92
218
  {
93
219
  "name": "parse",
94
220
  "kind": "function",
@@ -109,6 +235,36 @@
109
235
  "type": "ParsedVersion",
110
236
  "description": "Parsed version object with major, minor, patch, prerelease, and build"
111
237
  }
238
+ },
239
+ {
240
+ "signature": "parse(version: undefined): undefined",
241
+ "description": "Parses a semantic version string into its components according to SemVer 2.0.0 specification\n\nSupports:\n- Core version: MAJOR.MINOR.PATCH\n- Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92\n- Build metadata: +build, +sha.abc123, +20130313144700\n- Optional 'v' prefix (commonly used in git tags)",
242
+ "params": [
243
+ {
244
+ "name": "version",
245
+ "type": "undefined",
246
+ "description": "Version string to parse"
247
+ }
248
+ ],
249
+ "returns": {
250
+ "type": "undefined",
251
+ "description": "Parsed version object with major, minor, patch, prerelease, and build"
252
+ }
253
+ },
254
+ {
255
+ "signature": "parse(version: null): null",
256
+ "description": "Parses a semantic version string into its components according to SemVer 2.0.0 specification\n\nSupports:\n- Core version: MAJOR.MINOR.PATCH\n- Pre-release: -alpha, -beta.1, -rc.1, -0.3.7, -x.7.z.92\n- Build metadata: +build, +sha.abc123, +20130313144700\n- Optional 'v' prefix (commonly used in git tags)",
257
+ "params": [
258
+ {
259
+ "name": "version",
260
+ "type": "null",
261
+ "description": "Version string to parse"
262
+ }
263
+ ],
264
+ "returns": {
265
+ "type": "null",
266
+ "description": "Parsed version object with major, minor, patch, prerelease, and build"
267
+ }
112
268
  }
113
269
  ],
114
270
  "examples": [
@@ -123,16 +279,14 @@
123
279
  "code": "parse('v2.0.0-alpha.1')\n// => { major: 2, minor: 0, patch: 0, prerelease: ['alpha', '1'], build: [] }"
124
280
  }
125
281
  ],
126
- "sourceFile": "parse.ts"
127
- },
128
- {
129
- "name": "ParsedVersion",
130
- "kind": "interface",
131
- "description": "Represents a parsed semantic version according to SemVer 2.0.0 specification",
132
- "since": "2.0.0",
133
- "signatures": [],
134
- "examples": [],
135
- "sourceFile": "parse.ts"
282
+ "sourceFile": "parse.ts",
283
+ "relatedTypes": [
284
+ {
285
+ "name": "ParsedVersion",
286
+ "description": "Represents a parsed semantic version according to SemVer 2.0.0 specification",
287
+ "typeDefinition": "interface ParsedVersion {\n build: string[];\n major: number;\n minor: number;\n patch: number;\n prerelease: string[];\n}"
288
+ }
289
+ ]
136
290
  },
137
291
  {
138
292
  "name": "satisfiesRange",
@@ -180,6 +334,72 @@
180
334
  ],
181
335
  "sourceFile": "satisfiesRange.ts"
182
336
  },
337
+ {
338
+ "name": "stringify",
339
+ "kind": "function",
340
+ "description": "Reconstruct a semantic version string from a ParsedVersion object.\n\nThis is the inverse of parse:\n`stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.",
341
+ "since": "next",
342
+ "signatures": [
343
+ {
344
+ "signature": "stringify(parsed: ParsedVersion): string",
345
+ "description": "Reconstruct a semantic version string from a ParsedVersion object.\n\nThis is the inverse of parse:\n`stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.",
346
+ "params": [
347
+ {
348
+ "name": "parsed",
349
+ "type": "ParsedVersion",
350
+ "description": "A parsed semantic version object."
351
+ }
352
+ ],
353
+ "returns": {
354
+ "type": "string",
355
+ "description": "The reconstructed version string (without leading `v`)."
356
+ }
357
+ },
358
+ {
359
+ "signature": "stringify(parsed: undefined): undefined",
360
+ "description": "Reconstruct a semantic version string from a ParsedVersion object.\n\nThis is the inverse of parse:\n`stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.",
361
+ "params": [
362
+ {
363
+ "name": "parsed",
364
+ "type": "undefined",
365
+ "description": "A parsed semantic version object."
366
+ }
367
+ ],
368
+ "returns": {
369
+ "type": "undefined",
370
+ "description": "The reconstructed version string (without leading `v`)."
371
+ }
372
+ },
373
+ {
374
+ "signature": "stringify(parsed: null): null",
375
+ "description": "Reconstruct a semantic version string from a ParsedVersion object.\n\nThis is the inverse of parse:\n`stringify(parse(v)) === stripV(v)` for any valid SemVer string `v`.",
376
+ "params": [
377
+ {
378
+ "name": "parsed",
379
+ "type": "null",
380
+ "description": "A parsed semantic version object."
381
+ }
382
+ ],
383
+ "returns": {
384
+ "type": "null",
385
+ "description": "The reconstructed version string (without leading `v`)."
386
+ }
387
+ }
388
+ ],
389
+ "examples": [
390
+ {
391
+ "title": "Reconstruct a stable version",
392
+ "description": "Converts a ParsedVersion object back to a version string.",
393
+ "code": "stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })\n// => '1.2.3'"
394
+ },
395
+ {
396
+ "title": "Round-trip with parse",
397
+ "description": "stringify(parse(v)) returns the original version string (without leading v).",
398
+ "code": "stringify(parse('2.0.0-alpha.1'))\n// => '2.0.0-alpha.1'\n\nstringify(parse('1.0.0-beta+exp.sha.5114f85'))\n// => '1.0.0-beta+exp.sha.5114f85'"
399
+ }
400
+ ],
401
+ "sourceFile": "stringify.ts"
402
+ },
183
403
  {
184
404
  "name": "stripV",
185
405
  "kind": "function",
@@ -0,0 +1,6 @@
1
+ {
2
+ "category": "version",
3
+ "label": "Version",
4
+ "smallDescription": "Version string manipulation utilities",
5
+ "description": "Utilities for working with version strings including parsing, validation, and version string transformation"
6
+ }
@@ -36,6 +36,26 @@
36
36
  }
37
37
  ]
38
38
  },
39
+ {
40
+ "name": "isPrerelease",
41
+ "examples": [
42
+ {
43
+ "title": "Detect a prerelease version",
44
+ "description": "Returns true for any version string that contains a prerelease suffix.",
45
+ "code": "isPrerelease('2.0.0-alpha.1') // true\nisPrerelease('1.0.0-rc.0') // true"
46
+ },
47
+ {
48
+ "title": "Stable versions return false",
49
+ "description": "Returns false when the version has no prerelease suffix.",
50
+ "code": "isPrerelease('1.0.0') // false\nisPrerelease('2.1.3') // false"
51
+ },
52
+ {
53
+ "title": "Accept a ParsedVersion object",
54
+ "description": "Works with the result of parse() — checks the prerelease array instead of string matching.",
55
+ "code": "isPrerelease(parse('2.0.0-alpha.1')) // true\nisPrerelease(parse('1.0.0')) // false"
56
+ }
57
+ ]
58
+ },
39
59
  {
40
60
  "name": "parse",
41
61
  "examples": [
@@ -71,6 +91,21 @@
71
91
  }
72
92
  ]
73
93
  },
94
+ {
95
+ "name": "stringify",
96
+ "examples": [
97
+ {
98
+ "title": "Reconstruct a stable version",
99
+ "description": "Converts a ParsedVersion object back to a version string.",
100
+ "code": "stringify({ major: 1, minor: 2, patch: 3, prerelease: [], build: [] })\n// => '1.2.3'"
101
+ },
102
+ {
103
+ "title": "Round-trip with parse",
104
+ "description": "stringify(parse(v)) returns the original version string (without leading v).",
105
+ "code": "stringify(parse('2.0.0-alpha.1'))\n// => '2.0.0-alpha.1'\n\nstringify(parse('1.0.0-beta+exp.sha.5114f85'))\n// => '1.0.0-beta+exp.sha.5114f85'"
106
+ }
107
+ ]
108
+ },
74
109
  {
75
110
  "name": "stripV",
76
111
  "examples": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@helpers4/version",
3
- "version": "2.0.0-alpha.9",
3
+ "version": "2.0.0-beta.3",
4
4
  "description": "A set of helpers in TS/JS, compatible with tree-shaking, for version.",
5
5
  "author": "baxyz <baxy@etik.com>",
6
6
  "license": "LGPL-3.0",
@@ -21,6 +21,7 @@
21
21
  "./meta/api.json": "./meta/api.json",
22
22
  "./meta/examples.json": "./meta/examples.json",
23
23
  "./meta/licenses.json": "./meta/licenses.json",
24
+ "./llms.txt": "./llms.txt",
24
25
  "./package.json": "./package.json"
25
26
  },
26
27
  "keywords": [
@@ -28,8 +29,10 @@
28
29
  "version",
29
30
  "compare",
30
31
  "increment",
32
+ "isPrerelease",
31
33
  "parse",
32
34
  "satisfiesRange",
35
+ "stringify",
33
36
  "stripV"
34
37
  ],
35
38
  "files": [
@@ -37,6 +40,7 @@
37
40
  "lib/index.d.ts",
38
41
  "lib/index.js.map",
39
42
  "meta/",
43
+ "llms.txt",
40
44
  "LICENSE.md",
41
45
  "package.json",
42
46
  "README.md"