@savvy-web/changesets 0.4.2 → 0.5.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.
- package/README.md +16 -0
- package/cjs/changelog.cjs +131 -36
- package/cjs/changelog.d.cts +52 -3
- package/cjs/index.cjs +262 -42
- package/cjs/index.d.cts +1726 -175
- package/cjs/markdownlint.cjs +156 -2
- package/cjs/markdownlint.d.cts +127 -21
- package/cjs/remark.cjs +225 -9
- package/cjs/remark.d.cts +106 -37
- package/esm/160.js +45 -39
- package/esm/260.js +2 -1
- package/esm/273.js +2 -1
- package/esm/622.js +2 -2
- package/esm/{795.js → 725.js} +2 -5
- package/esm/855.js +5 -0
- package/esm/891.js +147 -0
- package/esm/bin/savvy-changesets.js +5 -3
- package/esm/changelog.d.ts +52 -3
- package/esm/index.d.ts +1726 -175
- package/esm/index.js +27 -5
- package/esm/markdownlint.d.ts +127 -21
- package/esm/markdownlint.js +152 -2
- package/esm/remark.d.ts +106 -37
- package/esm/remark.js +76 -3
- package/package.json +1 -1
- package/esm/689.js +0 -1
package/cjs/index.d.cts
CHANGED
|
@@ -20,124 +20,311 @@ import { ModCompWithPackage } from '@changesets/types';
|
|
|
20
20
|
import { NewChangesetWithCommit } from '@changesets/types';
|
|
21
21
|
import type { Root } from 'mdast';
|
|
22
22
|
import { Schema } from 'effect';
|
|
23
|
+
import type { Table } from 'mdast';
|
|
23
24
|
import { VersionType as VersionType_2 } from '@changesets/types';
|
|
24
25
|
import { YieldableError } from 'effect/Cause';
|
|
25
26
|
|
|
26
27
|
/**
|
|
27
|
-
* Static class wrapper for category operations.
|
|
28
|
+
* Static class wrapper for section category operations.
|
|
28
29
|
*
|
|
29
30
|
* Provides methods for resolving conventional commit types to changelog
|
|
30
|
-
* section categories
|
|
31
|
+
* section categories, validating section headings, and accessing the
|
|
32
|
+
* canonical set of 13 section categories used throughout the pipeline.
|
|
31
33
|
*
|
|
32
|
-
* @
|
|
34
|
+
* @remarks
|
|
35
|
+
* This class wraps the pure functions and constants from the internal
|
|
36
|
+
* `categories/` module. Each {@link SectionCategory} is defined by the
|
|
37
|
+
* {@link SectionCategorySchema} Effect Schema, which provides runtime
|
|
38
|
+
* validation at system boundaries. The class itself is stateless; all
|
|
39
|
+
* methods and properties are `static`.
|
|
40
|
+
*
|
|
41
|
+
* Categories control how changelog entries are grouped and ordered.
|
|
42
|
+
* Lower priority numbers appear first in the output. The 13 built-in
|
|
43
|
+
* categories cover all conventional commit types plus special cases
|
|
44
|
+
* like dependency updates and breaking changes.
|
|
45
|
+
*
|
|
46
|
+
* @example Looking up categories from commit metadata
|
|
33
47
|
* ```typescript
|
|
34
48
|
* import { Categories } from "\@savvy-web/changesets";
|
|
35
49
|
* import type { SectionCategory } from "\@savvy-web/changesets";
|
|
36
50
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
51
|
+
* // Resolve a conventional commit type to its category
|
|
52
|
+
* const feature: SectionCategory = Categories.fromCommitType("feat");
|
|
53
|
+
* // feature.heading === "Features"
|
|
54
|
+
* // feature.priority === 2
|
|
55
|
+
*
|
|
56
|
+
* // Breaking changes always win regardless of commit type
|
|
57
|
+
* const breaking: SectionCategory = Categories.fromCommitType("fix", undefined, true);
|
|
58
|
+
* // breaking.heading === "Breaking Changes"
|
|
59
|
+
* // breaking.priority === 1
|
|
60
|
+
*
|
|
61
|
+
* // The special scope "deps" on "chore" maps to Dependencies
|
|
62
|
+
* const deps: SectionCategory = Categories.fromCommitType("chore", "deps");
|
|
63
|
+
* // deps.heading === "Dependencies"
|
|
64
|
+
* ```
|
|
65
|
+
*
|
|
66
|
+
* @example Validating section headings
|
|
67
|
+
* ```typescript
|
|
68
|
+
* import { Categories } from "\@savvy-web/changesets";
|
|
69
|
+
*
|
|
70
|
+
* const headings: readonly string[] = Categories.allHeadings();
|
|
71
|
+
* // ["Breaking Changes", "Features", "Bug Fixes", ...]
|
|
72
|
+
*
|
|
73
|
+
* const valid: boolean = Categories.isValidHeading("Bug Fixes");
|
|
74
|
+
* // true
|
|
75
|
+
*
|
|
76
|
+
* const unknown: boolean = Categories.isValidHeading("Miscellaneous");
|
|
77
|
+
* // false
|
|
78
|
+
* ```
|
|
79
|
+
*
|
|
80
|
+
* @example Reverse-lookup from heading text
|
|
81
|
+
* ```typescript
|
|
82
|
+
* import { Categories } from "\@savvy-web/changesets";
|
|
83
|
+
* import type { SectionCategory } from "\@savvy-web/changesets";
|
|
40
84
|
*
|
|
41
|
-
* const
|
|
42
|
-
*
|
|
85
|
+
* const category: SectionCategory | undefined = Categories.fromHeading("Features");
|
|
86
|
+
* if (category) {
|
|
87
|
+
* const commitTypes: readonly string[] = category.commitTypes;
|
|
88
|
+
* // ["feat"]
|
|
89
|
+
* }
|
|
43
90
|
* ```
|
|
44
91
|
*
|
|
45
|
-
* @see {@link SectionCategory} for the category shape
|
|
92
|
+
* @see {@link SectionCategory} for the category shape (heading, priority, commitTypes, description)
|
|
93
|
+
* @see {@link SectionCategorySchema} for the Effect Schema that validates category data
|
|
46
94
|
*
|
|
47
95
|
* @public
|
|
48
96
|
*/
|
|
49
97
|
export declare class Categories {
|
|
50
98
|
private constructor();
|
|
51
|
-
/**
|
|
99
|
+
/**
|
|
100
|
+
* Breaking changes -- backward-incompatible changes (priority 1).
|
|
101
|
+
*
|
|
102
|
+
* @remarks
|
|
103
|
+
* Mapped from any commit type when the `breaking` flag is `true`.
|
|
104
|
+
* Always appears first in changelog output.
|
|
105
|
+
*/
|
|
52
106
|
static readonly BREAKING_CHANGES: SectionCategory;
|
|
53
|
-
/**
|
|
107
|
+
/**
|
|
108
|
+
* Features -- new functionality (priority 2).
|
|
109
|
+
*
|
|
110
|
+
* @remarks
|
|
111
|
+
* Mapped from the `feat` commit type.
|
|
112
|
+
*/
|
|
54
113
|
static readonly FEATURES: SectionCategory;
|
|
55
|
-
/**
|
|
114
|
+
/**
|
|
115
|
+
* Bug Fixes -- bug corrections (priority 3).
|
|
116
|
+
*
|
|
117
|
+
* @remarks
|
|
118
|
+
* Mapped from the `fix` commit type.
|
|
119
|
+
*/
|
|
56
120
|
static readonly BUG_FIXES: SectionCategory;
|
|
57
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Performance -- performance improvements (priority 4).
|
|
123
|
+
*
|
|
124
|
+
* @remarks
|
|
125
|
+
* Mapped from the `perf` commit type.
|
|
126
|
+
*/
|
|
58
127
|
static readonly PERFORMANCE: SectionCategory;
|
|
59
|
-
/**
|
|
128
|
+
/**
|
|
129
|
+
* Documentation -- documentation changes (priority 5).
|
|
130
|
+
*
|
|
131
|
+
* @remarks
|
|
132
|
+
* Mapped from the `docs` commit type.
|
|
133
|
+
*/
|
|
60
134
|
static readonly DOCUMENTATION: SectionCategory;
|
|
61
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Refactoring -- code restructuring (priority 6).
|
|
137
|
+
*
|
|
138
|
+
* @remarks
|
|
139
|
+
* Mapped from the `refactor` commit type.
|
|
140
|
+
*/
|
|
62
141
|
static readonly REFACTORING: SectionCategory;
|
|
63
|
-
/**
|
|
142
|
+
/**
|
|
143
|
+
* Tests -- test additions or modifications (priority 7).
|
|
144
|
+
*
|
|
145
|
+
* @remarks
|
|
146
|
+
* Mapped from the `test` commit type.
|
|
147
|
+
*/
|
|
64
148
|
static readonly TESTS: SectionCategory;
|
|
65
|
-
/**
|
|
149
|
+
/**
|
|
150
|
+
* Build System -- build configuration changes (priority 8).
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Mapped from the `build` commit type.
|
|
154
|
+
*/
|
|
66
155
|
static readonly BUILD_SYSTEM: SectionCategory;
|
|
67
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* CI -- continuous integration changes (priority 9).
|
|
158
|
+
*
|
|
159
|
+
* @remarks
|
|
160
|
+
* Mapped from the `ci` commit type.
|
|
161
|
+
*/
|
|
68
162
|
static readonly CI: SectionCategory;
|
|
69
|
-
/**
|
|
163
|
+
/**
|
|
164
|
+
* Dependencies -- dependency updates (priority 10).
|
|
165
|
+
*
|
|
166
|
+
* @remarks
|
|
167
|
+
* Mapped from `chore(deps)` and similar dependency-scoped commits.
|
|
168
|
+
*/
|
|
70
169
|
static readonly DEPENDENCIES: SectionCategory;
|
|
71
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* Maintenance -- general maintenance (priority 11).
|
|
172
|
+
*
|
|
173
|
+
* @remarks
|
|
174
|
+
* Mapped from the `chore` commit type (without the `deps` scope).
|
|
175
|
+
*/
|
|
72
176
|
static readonly MAINTENANCE: SectionCategory;
|
|
73
|
-
/**
|
|
177
|
+
/**
|
|
178
|
+
* Reverts -- reverted changes (priority 12).
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* Mapped from the `revert` commit type.
|
|
182
|
+
*/
|
|
74
183
|
static readonly REVERTS: SectionCategory;
|
|
75
|
-
/**
|
|
184
|
+
/**
|
|
185
|
+
* Other -- uncategorized changes (priority 13).
|
|
186
|
+
*
|
|
187
|
+
* @remarks
|
|
188
|
+
* Fallback category for unrecognized commit types. Always appears
|
|
189
|
+
* last in changelog output.
|
|
190
|
+
*/
|
|
76
191
|
static readonly OTHER: SectionCategory;
|
|
77
|
-
/**
|
|
192
|
+
/**
|
|
193
|
+
* All 13 categories ordered by priority (ascending, 1-13).
|
|
194
|
+
*
|
|
195
|
+
* @remarks
|
|
196
|
+
* This array is frozen and sorted from highest priority (Breaking Changes)
|
|
197
|
+
* to lowest (Other). Useful for iterating over categories in display order.
|
|
198
|
+
*/
|
|
78
199
|
static readonly ALL: readonly SectionCategory[];
|
|
79
200
|
/**
|
|
80
|
-
* Resolve a conventional commit type to its category.
|
|
201
|
+
* Resolve a conventional commit type to its section category.
|
|
81
202
|
*
|
|
82
203
|
* @remarks
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
204
|
+
* Resolution follows a precedence chain:
|
|
205
|
+
*
|
|
206
|
+
* 1. If `breaking` is `true`, always returns {@link Categories.BREAKING_CHANGES}
|
|
207
|
+
* 2. If `type` is `"chore"` and `scope` is `"deps"`, returns {@link Categories.DEPENDENCIES}
|
|
208
|
+
* 3. Otherwise, looks up `type` in the `commitTypes` arrays of all categories
|
|
209
|
+
* 4. Falls back to {@link Categories.OTHER} for unrecognized types
|
|
87
210
|
*
|
|
88
|
-
* @param type - The commit type (e.g., "feat"
|
|
89
|
-
* @param scope - Optional scope (e.g., "deps"
|
|
90
|
-
* @param breaking - Whether the commit
|
|
91
|
-
* @returns The resolved
|
|
211
|
+
* @param type - The conventional commit type (e.g., `"feat"`, `"fix"`, `"chore"`)
|
|
212
|
+
* @param scope - Optional commit scope (e.g., `"deps"` from `chore(deps):`)
|
|
213
|
+
* @param breaking - Whether the commit includes a breaking change indicator (`!`)
|
|
214
|
+
* @returns The resolved {@link SectionCategory}
|
|
92
215
|
*/
|
|
93
216
|
static fromCommitType(type: string, scope?: string, breaking?: boolean): SectionCategory;
|
|
94
217
|
/**
|
|
95
218
|
* Look up a category by its section heading text.
|
|
96
|
-
* Comparison is case-insensitive.
|
|
97
219
|
*
|
|
98
|
-
* @
|
|
99
|
-
*
|
|
220
|
+
* @remarks
|
|
221
|
+
* Comparison is case-insensitive. For example, both `"Bug Fixes"` and
|
|
222
|
+
* `"bug fixes"` will match {@link Categories.BUG_FIXES}.
|
|
223
|
+
*
|
|
224
|
+
* @param heading - The heading text (e.g., `"Features"`, `"Bug Fixes"`)
|
|
225
|
+
* @returns The matching {@link SectionCategory}, or `undefined` if the heading
|
|
226
|
+
* does not correspond to any known category
|
|
100
227
|
*/
|
|
101
228
|
static fromHeading(heading: string): SectionCategory | undefined;
|
|
102
229
|
/**
|
|
103
|
-
* Get all valid section heading strings.
|
|
230
|
+
* Get all valid section heading strings in priority order.
|
|
104
231
|
*
|
|
105
|
-
* @
|
|
232
|
+
* @remarks
|
|
233
|
+
* Returns the `heading` field from each category in {@link Categories.ALL},
|
|
234
|
+
* preserving priority order. Useful for building validation sets or
|
|
235
|
+
* rendering category pickers.
|
|
236
|
+
*
|
|
237
|
+
* @returns Readonly array of heading strings (e.g., `["Breaking Changes", "Features", ...]`)
|
|
106
238
|
*/
|
|
107
239
|
static allHeadings(): readonly string[];
|
|
108
240
|
/**
|
|
109
241
|
* Check whether a heading string matches a known category.
|
|
110
|
-
* Comparison is case-insensitive.
|
|
111
242
|
*
|
|
112
|
-
* @
|
|
113
|
-
*
|
|
243
|
+
* @remarks
|
|
244
|
+
* Comparison is case-insensitive. Equivalent to
|
|
245
|
+
* `Categories.fromHeading(heading) !== undefined`.
|
|
246
|
+
*
|
|
247
|
+
* @param heading - The heading text to validate
|
|
248
|
+
* @returns `true` if the heading matches a known category, `false` otherwise
|
|
114
249
|
*/
|
|
115
250
|
static isValidHeading(heading: string): boolean;
|
|
116
251
|
}
|
|
117
252
|
|
|
118
253
|
/**
|
|
119
|
-
* Static class wrapper for changelog operations.
|
|
254
|
+
* Static class wrapper for changelog formatting operations.
|
|
120
255
|
*
|
|
121
256
|
* Delegates to the Changesets-compatible `getReleaseLine` and
|
|
122
|
-
* `getDependencyReleaseLine` functions
|
|
257
|
+
* `getDependencyReleaseLine` functions. Internally, these use the
|
|
258
|
+
* {@link ChangelogService} Effect service layer, which coordinates
|
|
259
|
+
* the {@link GitHubService} (for commit/PR metadata) and
|
|
260
|
+
* {@link MarkdownService} (for AST manipulation) to produce
|
|
261
|
+
* structured changelog entries.
|
|
123
262
|
*
|
|
124
|
-
* @
|
|
263
|
+
* @remarks
|
|
264
|
+
* This class provides the same formatting capabilities as the
|
|
265
|
+
* `\@savvy-web/changesets/changelog` subpath export, but through a
|
|
266
|
+
* class-based API rather than the Changesets default-export convention.
|
|
267
|
+
* The underlying formatter parses conventional commit prefixes from the
|
|
268
|
+
* changeset summary to determine the section category (via
|
|
269
|
+
* {@link Categories}), resolves GitHub metadata (authors, PR links,
|
|
270
|
+
* commit hashes), and produces markdown output grouped by category.
|
|
271
|
+
*
|
|
272
|
+
* The `options` parameter must include a `repo` field in `"owner/repo"`
|
|
273
|
+
* format (e.g., `"savvy-web/changesets"`) so that GitHub links can be
|
|
274
|
+
* constructed. Additional options are defined by {@link ChangesetOptionsSchema}.
|
|
275
|
+
*
|
|
276
|
+
* @example Formatting a single changeset release line
|
|
125
277
|
* ```typescript
|
|
126
278
|
* import { Changelog } from "\@savvy-web/changesets";
|
|
127
279
|
*
|
|
128
280
|
* const changeset = {
|
|
129
281
|
* id: "brave-pandas-learn",
|
|
130
|
-
* summary: "feat: add
|
|
282
|
+
* summary: "feat: add token refresh endpoint",
|
|
131
283
|
* releases: [{ name: "\@savvy-web/auth", type: "minor" as const }],
|
|
132
|
-
* commit: "
|
|
284
|
+
* commit: "abc1234567890abcdef1234567890abcdef123456",
|
|
133
285
|
* };
|
|
134
286
|
*
|
|
135
|
-
* const line = await Changelog.formatReleaseLine(changeset, "minor", {
|
|
287
|
+
* const line: string = await Changelog.formatReleaseLine(changeset, "minor", {
|
|
136
288
|
* repo: "savvy-web/auth",
|
|
137
289
|
* });
|
|
290
|
+
* // line contains a markdown bullet under the "Features" section heading
|
|
291
|
+
* ```
|
|
292
|
+
*
|
|
293
|
+
* @example Formatting dependency update lines
|
|
294
|
+
* ```typescript
|
|
295
|
+
* import { Changelog } from "\@savvy-web/changesets";
|
|
296
|
+
*
|
|
297
|
+
* const changesets = [
|
|
298
|
+
* {
|
|
299
|
+
* id: "cool-dogs-fly",
|
|
300
|
+
* summary: "chore(deps): update effect to 3.20.0",
|
|
301
|
+
* releases: [{ name: "\@savvy-web/core", type: "patch" as const }],
|
|
302
|
+
* commit: "def4567890abcdef1234567890abcdef456789ab",
|
|
303
|
+
* },
|
|
304
|
+
* ];
|
|
305
|
+
*
|
|
306
|
+
* const dependenciesUpdated = [
|
|
307
|
+
* {
|
|
308
|
+
* name: "\@savvy-web/utils",
|
|
309
|
+
* type: "patch" as const,
|
|
310
|
+
* oldVersion: "1.2.0",
|
|
311
|
+
* newVersion: "1.2.1",
|
|
312
|
+
* changesets: ["cool-dogs-fly"],
|
|
313
|
+
* packageJson: { name: "\@savvy-web/utils", version: "1.2.1" },
|
|
314
|
+
* },
|
|
315
|
+
* ];
|
|
316
|
+
*
|
|
317
|
+
* const depLines: string = await Changelog.formatDependencyReleaseLine(
|
|
318
|
+
* changesets,
|
|
319
|
+
* dependenciesUpdated,
|
|
320
|
+
* { repo: "savvy-web/core" },
|
|
321
|
+
* );
|
|
322
|
+
* // depLines contains a markdown table of dependency changes
|
|
138
323
|
* ```
|
|
139
324
|
*
|
|
140
|
-
* @see {@link
|
|
325
|
+
* @see {@link ChangelogService} for the underlying Effect service
|
|
326
|
+
* @see {@link Categories} for how commit types map to section headings
|
|
327
|
+
* @see {@link ChangesetOptionsSchema} for the full options schema
|
|
141
328
|
*
|
|
142
329
|
* @public
|
|
143
330
|
*/
|
|
@@ -146,30 +333,67 @@ export declare class Changelog {
|
|
|
146
333
|
/**
|
|
147
334
|
* Format a single changeset into a changelog release line.
|
|
148
335
|
*
|
|
149
|
-
* @
|
|
150
|
-
*
|
|
151
|
-
*
|
|
152
|
-
* @
|
|
336
|
+
* @remarks
|
|
337
|
+
* Parses the changeset summary for a conventional commit prefix
|
|
338
|
+
* (e.g., `"feat: ..."`, `"fix!: ..."`), resolves the corresponding
|
|
339
|
+
* {@link SectionCategory}, and produces a markdown bullet item with
|
|
340
|
+
* optional GitHub metadata (author, PR link, commit hash).
|
|
341
|
+
*
|
|
342
|
+
* @param changeset - The changeset to format, including its `id`, `summary`,
|
|
343
|
+
* `releases` array, and optional `commit` hash
|
|
344
|
+
* @param versionType - The semantic version bump type (`"major"`, `"minor"`, or `"patch"`)
|
|
345
|
+
* @param options - Configuration object; must include `repo` in `"owner/repo"` format.
|
|
346
|
+
* Pass `null` to use defaults (no GitHub link resolution).
|
|
347
|
+
* @returns A promise resolving to the formatted markdown string
|
|
153
348
|
*/
|
|
154
349
|
static formatReleaseLine(changeset: NewChangesetWithCommit, versionType: VersionType_2, options: Record<string, unknown> | null): Promise<string>;
|
|
155
350
|
/**
|
|
156
|
-
* Format dependency update release lines.
|
|
351
|
+
* Format dependency update release lines into a markdown table.
|
|
352
|
+
*
|
|
353
|
+
* @remarks
|
|
354
|
+
* Generates a structured dependency table showing package names,
|
|
355
|
+
* version transitions, and dependency types. The table is placed
|
|
356
|
+
* under the "Dependencies" section heading in the changelog.
|
|
157
357
|
*
|
|
158
|
-
* @param changesets -
|
|
159
|
-
* @param dependenciesUpdated -
|
|
160
|
-
*
|
|
161
|
-
* @
|
|
358
|
+
* @param changesets - The changesets that triggered the dependency updates
|
|
359
|
+
* @param dependenciesUpdated - Array of updated dependencies with their
|
|
360
|
+
* old/new versions and package metadata
|
|
361
|
+
* @param options - Configuration object; must include `repo` in `"owner/repo"` format.
|
|
362
|
+
* Pass `null` to use defaults.
|
|
363
|
+
* @returns A promise resolving to the formatted markdown string containing
|
|
364
|
+
* the dependency update table
|
|
162
365
|
*/
|
|
163
366
|
static formatDependencyReleaseLine(changesets: NewChangesetWithCommit[], dependenciesUpdated: ModCompWithPackage[], options: Record<string, unknown> | null): Promise<string>;
|
|
164
367
|
}
|
|
165
368
|
|
|
166
369
|
/**
|
|
167
|
-
*
|
|
370
|
+
* Effect service tag for changelog formatting.
|
|
371
|
+
*
|
|
372
|
+
* Provides dependency-injected access to the two Changesets API formatter
|
|
373
|
+
* functions: `formatReleaseLine` and `formatDependencyReleaseLine`.
|
|
168
374
|
*
|
|
169
375
|
* @remarks
|
|
170
|
-
* This service tag
|
|
171
|
-
*
|
|
172
|
-
* the
|
|
376
|
+
* This is an abstract service tag — it has no default `Layer`. The concrete
|
|
377
|
+
* implementation is the `\@savvy-web/changesets/changelog` subpath export,
|
|
378
|
+
* which wires the formatting logic through `Effect.runPromise` for the
|
|
379
|
+
* Changesets CLI. For direct Effect usage, build your own layer or use
|
|
380
|
+
* the class-based `Changelog` wrapper.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```typescript
|
|
384
|
+
* import { Effect } from "effect";
|
|
385
|
+
* import type { ChangesetOptions } from "\@savvy-web/changesets";
|
|
386
|
+
* import { ChangelogService, GitHubLive, MarkdownLive } from "\@savvy-web/changesets";
|
|
387
|
+
*
|
|
388
|
+
* const program = Effect.gen(function* () {
|
|
389
|
+
* const changelog = yield* ChangelogService;
|
|
390
|
+
* const line = yield* changelog.formatReleaseLine(changeset, "minor", options);
|
|
391
|
+
* return line;
|
|
392
|
+
* });
|
|
393
|
+
* ```
|
|
394
|
+
*
|
|
395
|
+
* @see {@link ChangelogServiceShape} for the service interface
|
|
396
|
+
* @see {@link ChangelogServiceBase} for the api-extractor base class
|
|
173
397
|
*
|
|
174
398
|
* @public
|
|
175
399
|
*/
|
|
@@ -191,12 +415,37 @@ export declare const ChangelogServiceBase: Context.TagClass<ChangelogService, "C
|
|
|
191
415
|
/**
|
|
192
416
|
* Service interface for changelog formatting.
|
|
193
417
|
*
|
|
194
|
-
*
|
|
418
|
+
* Describes the two operations a `ChangelogService` implementation must
|
|
419
|
+
* provide: formatting individual release lines and formatting dependency
|
|
420
|
+
* update tables.
|
|
421
|
+
*
|
|
422
|
+
* @remarks
|
|
423
|
+
* Both methods return `Effect.Effect` values that require additional
|
|
424
|
+
* services in their environment (`R` channel). `formatReleaseLine` needs
|
|
425
|
+
* both {@link GitHubService} (for commit metadata) and {@link MarkdownService}
|
|
426
|
+
* (for markdown parsing), while `formatDependencyReleaseLine` only needs
|
|
427
|
+
* {@link GitHubService}.
|
|
428
|
+
*
|
|
429
|
+
* @public
|
|
195
430
|
*/
|
|
196
431
|
export declare interface ChangelogServiceShape {
|
|
197
|
-
/**
|
|
432
|
+
/**
|
|
433
|
+
* Format a single changeset into a markdown release line.
|
|
434
|
+
*
|
|
435
|
+
* @param changeset - The changeset to format, including its commit hash and summary
|
|
436
|
+
* @param versionType - The semantic version bump type (`major`, `minor`, or `patch`)
|
|
437
|
+
* @param options - Validated changeset configuration options (must include `repo`)
|
|
438
|
+
* @returns An `Effect` that resolves to a formatted markdown string
|
|
439
|
+
*/
|
|
198
440
|
readonly formatReleaseLine: (changeset: NewChangesetWithCommit, versionType: VersionType_2, options: ChangesetOptions) => Effect.Effect<string, never, GitHubService | MarkdownService>;
|
|
199
|
-
/**
|
|
441
|
+
/**
|
|
442
|
+
* Format dependency update release lines as a markdown table.
|
|
443
|
+
*
|
|
444
|
+
* @param changesets - The changesets that triggered the dependency updates
|
|
445
|
+
* @param dependenciesUpdated - The list of updated dependencies with version info
|
|
446
|
+
* @param options - Validated changeset configuration options (must include `repo`)
|
|
447
|
+
* @returns An `Effect` that resolves to a formatted markdown table string, or empty string if no updates
|
|
448
|
+
*/
|
|
200
449
|
readonly formatDependencyReleaseLine: (changesets: NewChangesetWithCommit[], dependenciesUpdated: ModCompWithPackage[], options: ChangesetOptions) => Effect.Effect<string, never, GitHubService>;
|
|
201
450
|
}
|
|
202
451
|
|
|
@@ -204,43 +453,116 @@ export declare interface ChangelogServiceShape {
|
|
|
204
453
|
* Class-based API wrapper for changelog transformation.
|
|
205
454
|
*
|
|
206
455
|
* Provides a static class interface that runs all remark transform
|
|
207
|
-
* plugins against CHANGELOG markdown content
|
|
456
|
+
* plugins against CHANGELOG markdown content as the post-processing
|
|
457
|
+
* layer of the three-layer pipeline.
|
|
458
|
+
*
|
|
459
|
+
* @internal
|
|
208
460
|
*/
|
|
209
461
|
/**
|
|
210
|
-
* Static class for
|
|
462
|
+
* Static class for post-processing CHANGELOG.md files.
|
|
211
463
|
*
|
|
212
|
-
*
|
|
213
|
-
*
|
|
214
|
-
*
|
|
464
|
+
* Implements the third layer of the three-layer pipeline by running
|
|
465
|
+
* six remark transform plugins in a fixed order to clean up, normalize,
|
|
466
|
+
* and enhance changelog output produced by the formatter layer.
|
|
215
467
|
*
|
|
216
|
-
* @
|
|
468
|
+
* @remarks
|
|
469
|
+
* The six plugins run in this order:
|
|
470
|
+
*
|
|
471
|
+
* 1. **MergeSectionsPlugin** -- merges duplicate section headings (e.g., two
|
|
472
|
+
* "Features" sections from separate changesets are combined into one)
|
|
473
|
+
* 2. **ReorderSectionsPlugin** -- reorders sections by category priority
|
|
474
|
+
* (Breaking Changes first, Other last) using the {@link Categories} priority values
|
|
475
|
+
* 3. **DeduplicateItemsPlugin** -- removes duplicate list items within a section
|
|
476
|
+
* 4. **ContributorFootnotesPlugin** -- converts inline contributor mentions
|
|
477
|
+
* into footnote references for cleaner formatting
|
|
478
|
+
* 5. **IssueLinkRefsPlugin** -- converts inline issue/PR links into markdown
|
|
479
|
+
* reference-style links collected at the bottom of the document
|
|
480
|
+
* 6. **NormalizeFormatPlugin** -- applies consistent formatting (spacing,
|
|
481
|
+
* trailing newlines, heading levels)
|
|
482
|
+
*
|
|
483
|
+
* The transformer operates on the full CHANGELOG.md content (all versions),
|
|
484
|
+
* not just the latest release block. It is idempotent -- running it multiple
|
|
485
|
+
* times produces the same output.
|
|
486
|
+
*
|
|
487
|
+
* @example Transform changelog content in memory
|
|
217
488
|
* ```typescript
|
|
218
489
|
* import { ChangelogTransformer } from "\@savvy-web/changesets";
|
|
219
490
|
*
|
|
220
|
-
*
|
|
221
|
-
*
|
|
491
|
+
* const rawChangelog = [
|
|
492
|
+
* "# Changelog",
|
|
493
|
+
* "",
|
|
494
|
+
* "## 1.2.0",
|
|
495
|
+
* "",
|
|
496
|
+
* "### Features",
|
|
497
|
+
* "",
|
|
498
|
+
* "- Added new auth endpoint",
|
|
499
|
+
* "",
|
|
500
|
+
* "### Features",
|
|
501
|
+
* "",
|
|
502
|
+
* "- Added rate limiting",
|
|
503
|
+
* ].join("\n");
|
|
504
|
+
*
|
|
505
|
+
* const cleaned: string = ChangelogTransformer.transformContent(rawChangelog);
|
|
506
|
+
* // Duplicate "Features" sections are merged into one
|
|
507
|
+
* ```
|
|
508
|
+
*
|
|
509
|
+
* @example Transform a CHANGELOG.md file in-place
|
|
510
|
+
* ```typescript
|
|
511
|
+
* import { ChangelogTransformer } from "\@savvy-web/changesets";
|
|
222
512
|
*
|
|
223
|
-
* //
|
|
513
|
+
* // Reads, transforms, and writes back to the same path
|
|
224
514
|
* ChangelogTransformer.transformFile("CHANGELOG.md");
|
|
225
515
|
* ```
|
|
226
516
|
*
|
|
517
|
+
* @example Check for changes without writing (dry-run pattern)
|
|
518
|
+
* ```typescript
|
|
519
|
+
* import { readFileSync } from "node:fs";
|
|
520
|
+
* import { ChangelogTransformer } from "\@savvy-web/changesets";
|
|
521
|
+
*
|
|
522
|
+
* const original: string = readFileSync("CHANGELOG.md", "utf-8");
|
|
523
|
+
* const transformed: string = ChangelogTransformer.transformContent(original);
|
|
524
|
+
*
|
|
525
|
+
* if (original !== transformed) {
|
|
526
|
+
* console.error("CHANGELOG.md needs transformation");
|
|
527
|
+
* process.exitCode = 1;
|
|
528
|
+
* }
|
|
529
|
+
* ```
|
|
530
|
+
*
|
|
531
|
+
* @see {@link Categories} for the priority order used by ReorderSectionsPlugin
|
|
532
|
+
* @see {@link ChangesetLinter} for the pre-validation layer (layer 1)
|
|
533
|
+
* @see {@link Changelog} for the formatter layer (layer 2)
|
|
534
|
+
*
|
|
227
535
|
* @public
|
|
228
536
|
*/
|
|
229
537
|
export declare class ChangelogTransformer {
|
|
230
538
|
private constructor();
|
|
231
539
|
/**
|
|
232
|
-
* Transform CHANGELOG markdown content by running all transform plugins.
|
|
540
|
+
* Transform CHANGELOG markdown content by running all six transform plugins.
|
|
541
|
+
*
|
|
542
|
+
* @remarks
|
|
543
|
+
* The input is parsed with `remark-parse` and `remark-gfm` (for table
|
|
544
|
+
* support), processed through all six plugins in order, and stringified
|
|
545
|
+
* back to markdown. The operation is synchronous and idempotent.
|
|
233
546
|
*
|
|
234
|
-
* @param content - Raw CHANGELOG markdown string
|
|
235
|
-
*
|
|
547
|
+
* @param content - Raw CHANGELOG markdown string (may contain multiple
|
|
548
|
+
* version blocks, GFM tables, footnotes, and reference links)
|
|
549
|
+
* @returns The transformed markdown string with sections merged, reordered,
|
|
550
|
+
* deduplicated, and normalized
|
|
236
551
|
*/
|
|
237
552
|
static transformContent(content: string): string;
|
|
238
553
|
/**
|
|
239
554
|
* Transform a CHANGELOG file in-place.
|
|
240
555
|
*
|
|
241
|
-
*
|
|
556
|
+
* @remarks
|
|
557
|
+
* Reads the file synchronously, runs all transform plugins via
|
|
558
|
+
* {@link ChangelogTransformer.transformContent}, and writes the result
|
|
559
|
+
* back to the same path. The file is overwritten atomically (single
|
|
560
|
+
* `writeFileSync` call).
|
|
561
|
+
*
|
|
562
|
+
* This is the method used by the Effect CLI's `transform` subcommand
|
|
563
|
+
* when invoked without the `--dry-run` or `--check` flags.
|
|
242
564
|
*
|
|
243
|
-
* @param filePath -
|
|
565
|
+
* @param filePath - Absolute or relative path to the CHANGELOG.md file
|
|
244
566
|
*/
|
|
245
567
|
static transformFile(filePath: string): void;
|
|
246
568
|
}
|
|
@@ -248,60 +570,142 @@ export declare class ChangelogTransformer {
|
|
|
248
570
|
/**
|
|
249
571
|
* Inferred type for {@link ChangesetSchema}.
|
|
250
572
|
*
|
|
573
|
+
* @remarks
|
|
574
|
+
* Use this interface when you need to type a variable or parameter as a
|
|
575
|
+
* decoded changeset object. It is structurally equivalent to the output
|
|
576
|
+
* of `Schema.decodeUnknownSync(ChangesetSchema)(...)`.
|
|
577
|
+
*
|
|
251
578
|
* @public
|
|
252
579
|
*/
|
|
253
580
|
export declare interface Changeset extends Schema.Schema.Type<typeof ChangesetSchema> {
|
|
254
581
|
}
|
|
255
582
|
|
|
256
583
|
/**
|
|
257
|
-
* Static class for linting changeset files.
|
|
584
|
+
* Static class for linting changeset markdown files.
|
|
258
585
|
*
|
|
259
586
|
* Runs the four remark-lint rules (heading-hierarchy, required-sections,
|
|
260
587
|
* content-structure, uncategorized-content) against changeset markdown
|
|
261
|
-
* and returns structured
|
|
588
|
+
* and returns structured {@link LintMessage} diagnostics.
|
|
262
589
|
*
|
|
263
|
-
* @
|
|
590
|
+
* @remarks
|
|
591
|
+
* This class implements the pre-validation layer of the three-layer
|
|
592
|
+
* pipeline. It validates that changeset markdown conforms to the
|
|
593
|
+
* expected structure before the changelog formatter processes it.
|
|
594
|
+
*
|
|
595
|
+
* YAML frontmatter (the `---` delimited block at the top of changeset
|
|
596
|
+
* files containing package bump declarations) is automatically stripped
|
|
597
|
+
* before validation, since frontmatter is managed by Changesets itself
|
|
598
|
+
* and is not part of the markdown structure being validated.
|
|
599
|
+
*
|
|
600
|
+
* The class provides three granularity levels:
|
|
601
|
+
*
|
|
602
|
+
* - {@link ChangesetLinter.validateContent} -- validate a markdown string directly
|
|
603
|
+
* - {@link ChangesetLinter.validateFile} -- validate a single file by path
|
|
604
|
+
* - {@link ChangesetLinter.validate} -- validate all changeset files in a directory
|
|
605
|
+
*
|
|
606
|
+
* @example Validate a single file and report errors
|
|
607
|
+
* ```typescript
|
|
608
|
+
* import { ChangesetLinter } from "\@savvy-web/changesets";
|
|
609
|
+
* import type { LintMessage } from "\@savvy-web/changesets";
|
|
610
|
+
*
|
|
611
|
+
* const messages: LintMessage[] = ChangesetLinter.validateFile(
|
|
612
|
+
* ".changeset/brave-pandas-learn.md",
|
|
613
|
+
* );
|
|
614
|
+
*
|
|
615
|
+
* if (messages.length > 0) {
|
|
616
|
+
* for (const msg of messages) {
|
|
617
|
+
* console.error(`${msg.file}:${msg.line}:${msg.column} [${msg.rule}] ${msg.message}`);
|
|
618
|
+
* }
|
|
619
|
+
* process.exitCode = 1;
|
|
620
|
+
* }
|
|
621
|
+
* ```
|
|
622
|
+
*
|
|
623
|
+
* @example Validate all changesets in a directory
|
|
264
624
|
* ```typescript
|
|
265
625
|
* import { ChangesetLinter } from "\@savvy-web/changesets";
|
|
266
626
|
* import type { LintMessage } from "\@savvy-web/changesets";
|
|
267
627
|
*
|
|
268
|
-
* const
|
|
269
|
-
*
|
|
270
|
-
*
|
|
628
|
+
* const allMessages: LintMessage[] = ChangesetLinter.validate(".changeset");
|
|
629
|
+
*
|
|
630
|
+
* const errorsByFile = new Map<string, LintMessage[]>();
|
|
631
|
+
* for (const msg of allMessages) {
|
|
632
|
+
* const existing = errorsByFile.get(msg.file) ?? [];
|
|
633
|
+
* existing.push(msg);
|
|
634
|
+
* errorsByFile.set(msg.file, existing);
|
|
635
|
+
* }
|
|
636
|
+
*
|
|
637
|
+
* for (const [file, msgs] of errorsByFile) {
|
|
638
|
+
* console.error(`${file}: ${msgs.length} issue(s)`);
|
|
271
639
|
* }
|
|
272
640
|
* ```
|
|
273
641
|
*
|
|
642
|
+
* @example Validate markdown content directly (useful in tests)
|
|
643
|
+
* ```typescript
|
|
644
|
+
* import { ChangesetLinter } from "\@savvy-web/changesets";
|
|
645
|
+
* import type { LintMessage } from "\@savvy-web/changesets";
|
|
646
|
+
*
|
|
647
|
+
* const content = [
|
|
648
|
+
* "---",
|
|
649
|
+
* '"\@savvy-web/core": patch',
|
|
650
|
+
* "---",
|
|
651
|
+
* "",
|
|
652
|
+
* "## Bug Fixes",
|
|
653
|
+
* "",
|
|
654
|
+
* "Fixed an edge case in token validation.",
|
|
655
|
+
* ].join("\n");
|
|
656
|
+
*
|
|
657
|
+
* const messages: LintMessage[] = ChangesetLinter.validateContent(content);
|
|
658
|
+
* // messages.length === 0 (valid changeset)
|
|
659
|
+
* ```
|
|
660
|
+
*
|
|
661
|
+
* @see {@link LintMessage} for the diagnostic message shape
|
|
662
|
+
* @see {@link Categories} for the valid section headings checked by the rules
|
|
663
|
+
*
|
|
274
664
|
* @public
|
|
275
665
|
*/
|
|
276
666
|
export declare class ChangesetLinter {
|
|
277
667
|
private constructor();
|
|
278
668
|
/**
|
|
279
|
-
* Validate a single changeset file.
|
|
669
|
+
* Validate a single changeset file by path.
|
|
280
670
|
*
|
|
281
|
-
*
|
|
671
|
+
* @remarks
|
|
672
|
+
* Reads the file synchronously, strips YAML frontmatter, and runs all
|
|
673
|
+
* four lint rules. The file path is preserved in each returned
|
|
674
|
+
* {@link LintMessage} for error reporting.
|
|
282
675
|
*
|
|
283
|
-
* @param filePath -
|
|
284
|
-
* @returns Array of
|
|
676
|
+
* @param filePath - Absolute or relative path to the changeset `.md` file
|
|
677
|
+
* @returns Array of {@link LintMessage} diagnostics (empty if the file is valid)
|
|
285
678
|
*/
|
|
286
679
|
static validateFile(filePath: string): LintMessage[];
|
|
287
680
|
/**
|
|
288
681
|
* Validate a markdown string directly.
|
|
289
682
|
*
|
|
290
|
-
*
|
|
683
|
+
* @remarks
|
|
684
|
+
* Strips YAML frontmatter (if present) and runs all four lint rules
|
|
685
|
+
* against the remaining content. This method is useful for validating
|
|
686
|
+
* changeset content that is already in memory, such as in test suites
|
|
687
|
+
* or editor integrations.
|
|
291
688
|
*
|
|
292
|
-
* @param content - Raw markdown content (may include frontmatter)
|
|
293
|
-
* @param filePath - File path for error reporting
|
|
294
|
-
*
|
|
689
|
+
* @param content - Raw markdown content (may include YAML frontmatter)
|
|
690
|
+
* @param filePath - File path for error reporting; defaults to `"<input>"`
|
|
691
|
+
* when validating in-memory content
|
|
692
|
+
* @returns Array of {@link LintMessage} diagnostics (empty if the content is valid)
|
|
295
693
|
*/
|
|
296
694
|
static validateContent(content: string, filePath?: string): LintMessage[];
|
|
297
695
|
/**
|
|
298
696
|
* Validate all changeset `.md` files in a directory.
|
|
299
697
|
*
|
|
300
|
-
*
|
|
301
|
-
*
|
|
698
|
+
* @remarks
|
|
699
|
+
* Scans the directory for `*.md` files (excluding `README.md`) and runs
|
|
700
|
+
* {@link ChangesetLinter.validateFile} on each. Results are aggregated
|
|
701
|
+
* into a single array. The directory is read synchronously.
|
|
702
|
+
*
|
|
703
|
+
* This is the method used by the Effect CLI's `lint` and `check`
|
|
704
|
+
* subcommands to validate the `.changeset/` directory.
|
|
302
705
|
*
|
|
303
|
-
* @param dir -
|
|
304
|
-
*
|
|
706
|
+
* @param dir - Path to the directory containing changeset files
|
|
707
|
+
* (typically `.changeset/`)
|
|
708
|
+
* @returns Aggregated array of {@link LintMessage} diagnostics from all files
|
|
305
709
|
*/
|
|
306
710
|
static validate(dir: string): LintMessage[];
|
|
307
711
|
}
|
|
@@ -309,6 +713,9 @@ export declare class ChangesetLinter {
|
|
|
309
713
|
/**
|
|
310
714
|
* Inferred type for {@link ChangesetOptionsSchema}.
|
|
311
715
|
*
|
|
716
|
+
* @remarks
|
|
717
|
+
* The `repo` field is always present; all other fields are optional.
|
|
718
|
+
*
|
|
312
719
|
* @public
|
|
313
720
|
*/
|
|
314
721
|
export declare interface ChangesetOptions extends Schema.Schema.Type<typeof ChangesetOptionsSchema> {
|
|
@@ -317,6 +724,34 @@ export declare interface ChangesetOptions extends Schema.Schema.Type<typeof Chan
|
|
|
317
724
|
/**
|
|
318
725
|
* Schema for changeset configuration options.
|
|
319
726
|
*
|
|
727
|
+
* @remarks
|
|
728
|
+
* The `repo` field is required; all other fields are optional with sensible
|
|
729
|
+
* defaults applied by the changelog formatter at runtime. The `versionFiles`
|
|
730
|
+
* option allows specifying additional JSON files (beyond `package.json`)
|
|
731
|
+
* whose version fields should be updated during `changeset version`.
|
|
732
|
+
*
|
|
733
|
+
* @example
|
|
734
|
+
* ```typescript
|
|
735
|
+
* import { Schema } from "effect";
|
|
736
|
+
* import { ChangesetOptionsSchema } from "@savvy-web/changesets";
|
|
737
|
+
* import type { ChangesetOptions } from "@savvy-web/changesets";
|
|
738
|
+
*
|
|
739
|
+
* const options: ChangesetOptions = Schema.decodeUnknownSync(ChangesetOptionsSchema)({
|
|
740
|
+
* repo: "savvy-web/changesets",
|
|
741
|
+
* commitLinks: true,
|
|
742
|
+
* prLinks: true,
|
|
743
|
+
* issueLinks: true,
|
|
744
|
+
* issuePrefixes: ["#", "GH-"],
|
|
745
|
+
* versionFiles: [
|
|
746
|
+
* { glob: "manifest.json", paths: ["$.version"] },
|
|
747
|
+
* ],
|
|
748
|
+
* });
|
|
749
|
+
* ```
|
|
750
|
+
*
|
|
751
|
+
* @see {@link ChangesetOptions} for the inferred TypeScript type
|
|
752
|
+
* @see {@link validateChangesetOptions} for Effect-idiomatic validation with detailed error messages
|
|
753
|
+
* @see {@link VersionFilesSchema} for the `versionFiles` entry format
|
|
754
|
+
*
|
|
320
755
|
* @public
|
|
321
756
|
*/
|
|
322
757
|
export declare const ChangesetOptionsSchema: Schema.Struct<{
|
|
@@ -340,6 +775,29 @@ export declare const ChangesetOptionsSchema: Schema.Struct<{
|
|
|
340
775
|
/**
|
|
341
776
|
* Schema for a changeset object.
|
|
342
777
|
*
|
|
778
|
+
* @remarks
|
|
779
|
+
* Represents a single changeset entry as consumed by the changelog formatter.
|
|
780
|
+
* The `summary` is the human-readable description, `id` is a unique identifier
|
|
781
|
+
* (typically the changeset filename without extension), and `commit` is the
|
|
782
|
+
* optional git SHA that introduced the changeset.
|
|
783
|
+
*
|
|
784
|
+
* @example
|
|
785
|
+
* ```typescript
|
|
786
|
+
* import { Schema } from "effect";
|
|
787
|
+
* import { ChangesetSchema } from "@savvy-web/changesets";
|
|
788
|
+
* import type { Changeset } from "@savvy-web/changesets";
|
|
789
|
+
*
|
|
790
|
+
* const changeset: Changeset = Schema.decodeUnknownSync(ChangesetSchema)({
|
|
791
|
+
* summary: "Add retry logic to API client",
|
|
792
|
+
* id: "brave-dogs-laugh",
|
|
793
|
+
* commit: "a1b2c3d",
|
|
794
|
+
* });
|
|
795
|
+
* ```
|
|
796
|
+
*
|
|
797
|
+
* @see {@link Changeset} for the inferred TypeScript type
|
|
798
|
+
* @see {@link ChangesetSummarySchema} for summary validation rules
|
|
799
|
+
* @see {@link CommitHashSchema} for commit hash format requirements
|
|
800
|
+
*
|
|
343
801
|
* @public
|
|
344
802
|
*/
|
|
345
803
|
export declare const ChangesetSchema: Schema.Struct<{
|
|
@@ -352,7 +810,26 @@ export declare const ChangesetSchema: Schema.Struct<{
|
|
|
352
810
|
}>;
|
|
353
811
|
|
|
354
812
|
/**
|
|
355
|
-
* Schema for a changeset summary (1
|
|
813
|
+
* Schema for a changeset summary (1--1000 characters).
|
|
814
|
+
*
|
|
815
|
+
* @remarks
|
|
816
|
+
* Enforces that every changeset has a non-empty summary and caps length
|
|
817
|
+
* at 1000 characters. Longer descriptions should go in the changeset body,
|
|
818
|
+
* not the summary line. Validation messages guide users toward correct usage.
|
|
819
|
+
*
|
|
820
|
+
* @example
|
|
821
|
+
* ```typescript
|
|
822
|
+
* import { Schema } from "effect";
|
|
823
|
+
* import { ChangesetSummarySchema } from "@savvy-web/changesets";
|
|
824
|
+
*
|
|
825
|
+
* // Succeeds — valid summary
|
|
826
|
+
* const summary = Schema.decodeUnknownSync(ChangesetSummarySchema)(
|
|
827
|
+
* "Fix authentication timeout in login flow"
|
|
828
|
+
* );
|
|
829
|
+
*
|
|
830
|
+
* // Throws ParseError — empty string
|
|
831
|
+
* Schema.decodeUnknownSync(ChangesetSummarySchema)("");
|
|
832
|
+
* ```
|
|
356
833
|
*
|
|
357
834
|
* @public
|
|
358
835
|
*/
|
|
@@ -361,7 +838,30 @@ export declare const ChangesetSummarySchema: Schema.filter<Schema.filter<typeof
|
|
|
361
838
|
/**
|
|
362
839
|
* Changeset file validation failure.
|
|
363
840
|
*
|
|
364
|
-
*
|
|
841
|
+
* @remarks
|
|
842
|
+
* Raised when a changeset markdown file fails structural validation
|
|
843
|
+
* (e.g., missing summary, invalid heading, malformed dependency table).
|
|
844
|
+
* Carries an array of structured issues, each with a JSON-path pointing
|
|
845
|
+
* to the problematic field and a human-readable message.
|
|
846
|
+
*
|
|
847
|
+
* @example
|
|
848
|
+
* ```typescript
|
|
849
|
+
* import { Effect } from "effect";
|
|
850
|
+
* import { ChangesetValidationError } from "@savvy-web/changesets";
|
|
851
|
+
*
|
|
852
|
+
* declare const program: Effect.Effect<void, ChangesetValidationError>;
|
|
853
|
+
*
|
|
854
|
+
* const handled = program.pipe(
|
|
855
|
+
* Effect.catchTag("ChangesetValidationError", (err) => {
|
|
856
|
+
* for (const issue of err.issues) {
|
|
857
|
+
* console.error(`${issue.path}: ${issue.message}`);
|
|
858
|
+
* }
|
|
859
|
+
* return Effect.void;
|
|
860
|
+
* }),
|
|
861
|
+
* );
|
|
862
|
+
* ```
|
|
863
|
+
*
|
|
864
|
+
* @see {@link ChangesetSchema} for the schema that drives validation
|
|
365
865
|
*
|
|
366
866
|
* @public
|
|
367
867
|
*/
|
|
@@ -380,7 +880,7 @@ export declare class ChangesetValidationError extends ChangesetValidationErrorBa
|
|
|
380
880
|
}
|
|
381
881
|
|
|
382
882
|
/**
|
|
383
|
-
* Base class for ChangesetValidationError.
|
|
883
|
+
* Base class for {@link ChangesetValidationError}.
|
|
384
884
|
*
|
|
385
885
|
* @privateRemarks
|
|
386
886
|
* This export is required for api-extractor documentation generation.
|
|
@@ -396,6 +896,34 @@ export declare const ChangesetValidationErrorBase: new <A extends Record<string,
|
|
|
396
896
|
/**
|
|
397
897
|
* Schema for a git commit hash (at least 7 lowercase hex characters).
|
|
398
898
|
*
|
|
899
|
+
* @remarks
|
|
900
|
+
* Accepts both abbreviated (7-character) and full (40-character) SHA-1 hashes.
|
|
901
|
+
* Only lowercase hexadecimal characters are allowed; uppercase letters will
|
|
902
|
+
* fail validation. This matches the output of `git rev-parse --short` and
|
|
903
|
+
* `git log --format=%h`.
|
|
904
|
+
*
|
|
905
|
+
* @example
|
|
906
|
+
* ```typescript
|
|
907
|
+
* import { Schema } from "effect";
|
|
908
|
+
* import { CommitHashSchema } from "@savvy-web/changesets";
|
|
909
|
+
*
|
|
910
|
+
* // Succeeds — abbreviated hash
|
|
911
|
+
* const short = Schema.decodeUnknownSync(CommitHashSchema)("a1b2c3d");
|
|
912
|
+
*
|
|
913
|
+
* // Succeeds — full 40-character SHA
|
|
914
|
+
* const full = Schema.decodeUnknownSync(CommitHashSchema)(
|
|
915
|
+
* "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4e5f6a1b2"
|
|
916
|
+
* );
|
|
917
|
+
*
|
|
918
|
+
* // Throws ParseError — too short
|
|
919
|
+
* Schema.decodeUnknownSync(CommitHashSchema)("a1b2c3");
|
|
920
|
+
*
|
|
921
|
+
* // Throws ParseError — uppercase not allowed
|
|
922
|
+
* Schema.decodeUnknownSync(CommitHashSchema)("A1B2C3D");
|
|
923
|
+
* ```
|
|
924
|
+
*
|
|
925
|
+
* @see {@link ChangesetSchema} which uses this for the optional `commit` field
|
|
926
|
+
*
|
|
399
927
|
* @public
|
|
400
928
|
*/
|
|
401
929
|
export declare const CommitHashSchema: Schema.filter<typeof Schema.String>;
|
|
@@ -403,7 +931,27 @@ export declare const CommitHashSchema: Schema.filter<typeof Schema.String>;
|
|
|
403
931
|
/**
|
|
404
932
|
* Invalid or missing configuration.
|
|
405
933
|
*
|
|
934
|
+
* @remarks
|
|
935
|
+
* Raised when the changeset configuration (typically from `.changeset/config.json`)
|
|
936
|
+
* is missing required fields, has invalid values, or cannot be parsed. The `field`
|
|
937
|
+
* property identifies which configuration field is problematic, and `reason`
|
|
938
|
+
* provides an actionable message.
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```typescript
|
|
942
|
+
* import { Effect } from "effect";
|
|
943
|
+
* import { ConfigurationError, validateChangesetOptions } from "@savvy-web/changesets";
|
|
944
|
+
*
|
|
945
|
+
* const program = validateChangesetOptions({ repo: "invalid" }).pipe(
|
|
946
|
+
* Effect.catchTag("ConfigurationError", (err) => {
|
|
947
|
+
* console.error(`Field "${err.field}": ${err.reason}`);
|
|
948
|
+
* return Effect.fail(err);
|
|
949
|
+
* }),
|
|
950
|
+
* );
|
|
951
|
+
* ```
|
|
952
|
+
*
|
|
406
953
|
* @see {@link ChangesetOptionsSchema} for the expected configuration shape
|
|
954
|
+
* @see {@link validateChangesetOptions} for the validation function that produces this error
|
|
407
955
|
*
|
|
408
956
|
* @public
|
|
409
957
|
*/
|
|
@@ -417,7 +965,7 @@ export declare class ConfigurationError extends ConfigurationErrorBase<{
|
|
|
417
965
|
}
|
|
418
966
|
|
|
419
967
|
/**
|
|
420
|
-
* Base class for ConfigurationError.
|
|
968
|
+
* Base class for {@link ConfigurationError}.
|
|
421
969
|
*
|
|
422
970
|
* @privateRemarks
|
|
423
971
|
* This export is required for api-extractor documentation generation.
|
|
@@ -431,70 +979,464 @@ export declare const ConfigurationErrorBase: new <A extends Record<string, any>
|
|
|
431
979
|
} & Readonly<A>;
|
|
432
980
|
|
|
433
981
|
/**
|
|
434
|
-
* Inferred type for {@link
|
|
982
|
+
* Inferred type for {@link DependencyActionSchema}.
|
|
435
983
|
*
|
|
436
|
-
* @
|
|
437
|
-
|
|
438
|
-
export declare type DependencyType = typeof DependencyTypeSchema.Type;
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Schema for npm dependency types.
|
|
984
|
+
* @remarks
|
|
985
|
+
* One of `"added"`, `"updated"`, or `"removed"`.
|
|
442
986
|
*
|
|
443
987
|
* @public
|
|
444
988
|
*/
|
|
445
|
-
export declare
|
|
989
|
+
export declare type DependencyAction = typeof DependencyActionSchema.Type;
|
|
446
990
|
|
|
447
991
|
/**
|
|
448
|
-
*
|
|
992
|
+
* Valid dependency table actions.
|
|
449
993
|
*
|
|
450
|
-
* @
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
*
|
|
994
|
+
* @remarks
|
|
995
|
+
* Represents the three possible operations on a dependency: `"added"` for
|
|
996
|
+
* new dependencies, `"updated"` for version changes, and `"removed"` for
|
|
997
|
+
* deletions. Used in the "Action" column of dependency tables.
|
|
998
|
+
*
|
|
999
|
+
* @example
|
|
1000
|
+
* ```typescript
|
|
1001
|
+
* import { Schema } from "effect";
|
|
1002
|
+
* import { DependencyActionSchema } from "@savvy-web/changesets";
|
|
1003
|
+
* import type { DependencyAction } from "@savvy-web/changesets";
|
|
1004
|
+
*
|
|
1005
|
+
* const action: DependencyAction = Schema.decodeUnknownSync(DependencyActionSchema)("updated");
|
|
1006
|
+
* ```
|
|
457
1007
|
*
|
|
458
1008
|
* @public
|
|
459
1009
|
*/
|
|
460
|
-
export declare const
|
|
461
|
-
/** Package name (must be non-empty). */
|
|
462
|
-
name: Schema.refine<string, typeof Schema.String>;
|
|
463
|
-
/** npm dependency type. */
|
|
464
|
-
type: Schema.Literal<["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]>;
|
|
465
|
-
/** Previous version string. */
|
|
466
|
-
oldVersion: typeof Schema.String;
|
|
467
|
-
/** New version string. */
|
|
468
|
-
newVersion: typeof Schema.String;
|
|
469
|
-
}>;
|
|
1010
|
+
export declare const DependencyActionSchema: Schema.Literal<["added", "updated", "removed"]>;
|
|
470
1011
|
|
|
471
1012
|
/**
|
|
472
|
-
*
|
|
1013
|
+
* Static class for dependency table manipulation.
|
|
1014
|
+
*
|
|
1015
|
+
* Wraps the internal utility functions that operate on dependency tables --
|
|
1016
|
+
* the structured markdown tables that appear in the "Dependencies" section
|
|
1017
|
+
* of changelogs. Each row in a dependency table represents a single package
|
|
1018
|
+
* change with its name, type, action, and version transition.
|
|
473
1019
|
*
|
|
474
1020
|
* @remarks
|
|
475
|
-
*
|
|
476
|
-
* strategy should be applied. Rate-limited responses (403/429) and
|
|
477
|
-
* server errors (5xx) are considered retryable.
|
|
1021
|
+
* The typical workflow for processing dependency tables is:
|
|
478
1022
|
*
|
|
479
|
-
* @
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
1023
|
+
* 1. **Parse** an mdast `Table` node into typed {@link DependencyTableRow} objects
|
|
1024
|
+
* 2. **Collapse** duplicate rows (same package updated multiple times) into single entries
|
|
1025
|
+
* 3. **Sort** rows by dependency type, then alphabetically by package name
|
|
1026
|
+
* 4. **Serialize** back to an mdast `Table` node or directly to a markdown string
|
|
1027
|
+
*
|
|
1028
|
+
* The {@link DependencyTable.aggregate} method combines the collapse and sort
|
|
1029
|
+
* steps into a single call, which is the most common usage pattern.
|
|
1030
|
+
*
|
|
1031
|
+
* Each {@link DependencyTableRow} is validated by the {@link DependencyTableRowSchema}
|
|
1032
|
+
* Effect Schema at system boundaries, ensuring that dependency names, types,
|
|
1033
|
+
* actions, and version strings conform to expected formats.
|
|
1034
|
+
*
|
|
1035
|
+
* @example Parse, aggregate, and serialize a dependency table
|
|
1036
|
+
* ```typescript
|
|
1037
|
+
* import { DependencyTable } from "\@savvy-web/changesets";
|
|
1038
|
+
* import type { DependencyTableRow } from "\@savvy-web/changesets";
|
|
1039
|
+
* import type { Table } from "mdast";
|
|
1040
|
+
*
|
|
1041
|
+
* // Given an mdast Table node from a parsed CHANGELOG
|
|
1042
|
+
* declare const tableNode: Table;
|
|
1043
|
+
*
|
|
1044
|
+
* // Parse into typed rows
|
|
1045
|
+
* const rows: DependencyTableRow[] = DependencyTable.parse(tableNode);
|
|
1046
|
+
*
|
|
1047
|
+
* // Collapse duplicates and sort by type, then name
|
|
1048
|
+
* const aggregated: DependencyTableRow[] = DependencyTable.aggregate(rows);
|
|
1049
|
+
*
|
|
1050
|
+
* // Serialize back to an mdast Table node for further AST manipulation
|
|
1051
|
+
* const outputNode: Table = DependencyTable.serialize(aggregated);
|
|
1052
|
+
*
|
|
1053
|
+
* // Or serialize directly to a markdown string
|
|
1054
|
+
* const markdown: string = DependencyTable.toMarkdown(aggregated);
|
|
1055
|
+
* ```
|
|
1056
|
+
*
|
|
1057
|
+
* @example Step-by-step collapse and sort
|
|
1058
|
+
* ```typescript
|
|
1059
|
+
* import { DependencyTable } from "\@savvy-web/changesets";
|
|
1060
|
+
* import type { DependencyTableRow } from "\@savvy-web/changesets";
|
|
1061
|
+
*
|
|
1062
|
+
* declare const rows: DependencyTableRow[];
|
|
1063
|
+
*
|
|
1064
|
+
* // Collapse duplicate entries (same package appears multiple times)
|
|
1065
|
+
* const collapsed: DependencyTableRow[] = DependencyTable.collapse(rows);
|
|
1066
|
+
*
|
|
1067
|
+
* // Sort by dependency type, then alphabetically by name
|
|
1068
|
+
* const sorted: DependencyTableRow[] = DependencyTable.sort(collapsed);
|
|
1069
|
+
* ```
|
|
1070
|
+
*
|
|
1071
|
+
* @see {@link DependencyTableRow} for the row shape (dependency, type, action, from, to)
|
|
1072
|
+
* @see {@link DependencyTableRowSchema} for the Effect Schema that validates row data
|
|
1073
|
+
* @see {@link DependencyTableSchema} for the non-empty array schema
|
|
1074
|
+
*
|
|
1075
|
+
* @public
|
|
1076
|
+
*/
|
|
1077
|
+
export declare class DependencyTable {
|
|
1078
|
+
private constructor();
|
|
1079
|
+
/**
|
|
1080
|
+
* Parse an mdast `Table` node into typed dependency table rows.
|
|
1081
|
+
*
|
|
1082
|
+
* @remarks
|
|
1083
|
+
* Extracts the text content from each table cell and maps it to the
|
|
1084
|
+
* corresponding {@link DependencyTableRow} fields. The first row is
|
|
1085
|
+
* treated as the header and skipped. Rows that do not have the expected
|
|
1086
|
+
* number of columns are ignored.
|
|
1087
|
+
*
|
|
1088
|
+
* @param tableNode - An mdast `Table` node from a parsed markdown AST
|
|
1089
|
+
* @returns Array of {@link DependencyTableRow} objects, one per data row
|
|
1090
|
+
*/
|
|
1091
|
+
static parse(tableNode: Table): DependencyTableRow[];
|
|
1092
|
+
/**
|
|
1093
|
+
* Serialize typed dependency table rows into an mdast `Table` node.
|
|
1094
|
+
*
|
|
1095
|
+
* @remarks
|
|
1096
|
+
* Produces a well-formed mdast `Table` with a header row
|
|
1097
|
+
* (`Dependency | Type | Action | From | To`) followed by one data row
|
|
1098
|
+
* per input entry. The resulting node can be inserted into a remark AST
|
|
1099
|
+
* for further processing or stringification.
|
|
1100
|
+
*
|
|
1101
|
+
* @param rows - Array of {@link DependencyTableRow} objects to serialize
|
|
1102
|
+
* @returns An mdast `Table` node ready for AST insertion
|
|
1103
|
+
*/
|
|
1104
|
+
static serialize(rows: DependencyTableRow[]): Table;
|
|
1105
|
+
/**
|
|
1106
|
+
* Serialize typed dependency table rows directly to a markdown string.
|
|
1107
|
+
*
|
|
1108
|
+
* @remarks
|
|
1109
|
+
* Convenience method that combines {@link DependencyTable.serialize} with
|
|
1110
|
+
* remark stringification. Produces a GFM-compatible markdown table string.
|
|
1111
|
+
*
|
|
1112
|
+
* @param rows - Array of {@link DependencyTableRow} objects to render
|
|
1113
|
+
* @returns A markdown string containing the formatted table
|
|
1114
|
+
*/
|
|
1115
|
+
static toMarkdown(rows: DependencyTableRow[]): string;
|
|
1116
|
+
/**
|
|
1117
|
+
* Collapse duplicate dependency rows into single entries.
|
|
1118
|
+
*
|
|
1119
|
+
* @remarks
|
|
1120
|
+
* When a package appears in multiple rows (e.g., updated in separate
|
|
1121
|
+
* changesets), this method merges them by keeping the earliest `from`
|
|
1122
|
+
* version and the latest `to` version, producing a single row that
|
|
1123
|
+
* represents the net change.
|
|
1124
|
+
*
|
|
1125
|
+
* @param rows - Array of {@link DependencyTableRow} objects, possibly with duplicates
|
|
1126
|
+
* @returns A new array with duplicate packages collapsed into single rows
|
|
1127
|
+
*/
|
|
1128
|
+
static collapse(rows: DependencyTableRow[]): DependencyTableRow[];
|
|
1129
|
+
/**
|
|
1130
|
+
* Sort dependency rows by action, type, and package name.
|
|
1131
|
+
*
|
|
1132
|
+
* @remarks
|
|
1133
|
+
* Applies a three-level stable sort:
|
|
1134
|
+
* 1. **Action** — `removed` first, then `updated`, then `added`
|
|
1135
|
+
* 2. **Type** — alphabetically (e.g., `config` before `dependency`)
|
|
1136
|
+
* 3. **Dependency name** — alphabetically within each action+type group
|
|
1137
|
+
*
|
|
1138
|
+
* @param rows - Array of {@link DependencyTableRow} objects to sort
|
|
1139
|
+
* @returns A new array sorted by action, type, then name
|
|
1140
|
+
*/
|
|
1141
|
+
static sort(rows: DependencyTableRow[]): DependencyTableRow[];
|
|
1142
|
+
/**
|
|
1143
|
+
* Collapse duplicate rows and then sort the result.
|
|
1144
|
+
*
|
|
1145
|
+
* @remarks
|
|
1146
|
+
* Equivalent to calling {@link DependencyTable.collapse} followed by
|
|
1147
|
+
* {@link DependencyTable.sort}. This is the recommended method for
|
|
1148
|
+
* preparing dependency table data for final output, as it produces
|
|
1149
|
+
* a clean, deduplicated, and consistently ordered table.
|
|
1150
|
+
*
|
|
1151
|
+
* @param rows - Array of {@link DependencyTableRow} objects to aggregate
|
|
1152
|
+
* @returns A new array with duplicates collapsed and rows sorted
|
|
1153
|
+
*/
|
|
1154
|
+
static aggregate(rows: DependencyTableRow[]): DependencyTableRow[];
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
/**
|
|
1158
|
+
* Inferred type for {@link DependencyTableRowSchema}.
|
|
1159
|
+
*
|
|
1160
|
+
* @public
|
|
1161
|
+
*/
|
|
1162
|
+
export declare interface DependencyTableRow extends Schema.Schema.Type<typeof DependencyTableRowSchema> {
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
/**
|
|
1166
|
+
* Schema for a single dependency table row.
|
|
1167
|
+
*
|
|
1168
|
+
* @remarks
|
|
1169
|
+
* Represents one row of a dependency update table in a CHANGELOG.
|
|
1170
|
+
* Each row captures the dependency name, its type, the change action,
|
|
1171
|
+
* and the "from" and "to" version strings. For added dependencies the
|
|
1172
|
+
* `from` field is an em dash; for removed dependencies the `to` field
|
|
1173
|
+
* is an em dash.
|
|
1174
|
+
*
|
|
1175
|
+
* @example
|
|
1176
|
+
* ```typescript
|
|
1177
|
+
* import { Schema } from "effect";
|
|
1178
|
+
* import { DependencyTableRowSchema } from "@savvy-web/changesets";
|
|
1179
|
+
* import type { DependencyTableRow } from "@savvy-web/changesets";
|
|
1180
|
+
*
|
|
1181
|
+
* const row: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
|
|
1182
|
+
* dependency: "effect",
|
|
1183
|
+
* type: "dependency",
|
|
1184
|
+
* action: "updated",
|
|
1185
|
+
* from: "3.18.0",
|
|
1186
|
+
* to: "3.19.1",
|
|
1187
|
+
* });
|
|
1188
|
+
*
|
|
1189
|
+
* // Newly added dependency — "from" is em dash
|
|
1190
|
+
* const addedRow: DependencyTableRow = Schema.decodeUnknownSync(DependencyTableRowSchema)({
|
|
1191
|
+
* dependency: "@effect/cli",
|
|
1192
|
+
* type: "dependency",
|
|
1193
|
+
* action: "added",
|
|
1194
|
+
* from: "\u2014",
|
|
1195
|
+
* to: "0.50.0",
|
|
1196
|
+
* });
|
|
1197
|
+
* ```
|
|
1198
|
+
*
|
|
1199
|
+
* @see {@link DependencyTableRow} for the inferred TypeScript type
|
|
1200
|
+
* @see {@link DependencyTableSchema} for a non-empty array of rows
|
|
1201
|
+
*
|
|
1202
|
+
* @public
|
|
1203
|
+
*/
|
|
1204
|
+
export declare const DependencyTableRowSchema: Schema.Struct<{
|
|
1205
|
+
/** Package or toolchain name. */
|
|
1206
|
+
dependency: Schema.filter<typeof Schema.String>;
|
|
1207
|
+
/** Dependency type. */
|
|
1208
|
+
type: Schema.Literal<["dependency", "devDependency", "peerDependency", "optionalDependency", "workspace", "config"]>;
|
|
1209
|
+
/** Change action. */
|
|
1210
|
+
action: Schema.Literal<["added", "updated", "removed"]>;
|
|
1211
|
+
/** Previous version (em dash for added). */
|
|
1212
|
+
from: Schema.filter<typeof Schema.String>;
|
|
1213
|
+
/** New version (em dash for removed). */
|
|
1214
|
+
to: Schema.filter<typeof Schema.String>;
|
|
1215
|
+
}>;
|
|
1216
|
+
|
|
1217
|
+
/**
|
|
1218
|
+
* Schema for a dependency table (non-empty array of rows).
|
|
1219
|
+
*
|
|
1220
|
+
* @remarks
|
|
1221
|
+
* Validates that the table contains at least one row. Used to represent
|
|
1222
|
+
* the full dependency update table in a changeset or CHANGELOG entry.
|
|
1223
|
+
*
|
|
1224
|
+
* @example
|
|
1225
|
+
* ```typescript
|
|
1226
|
+
* import { Schema } from "effect";
|
|
1227
|
+
* import { DependencyTableSchema } from "@savvy-web/changesets";
|
|
1228
|
+
*
|
|
1229
|
+
* const table = Schema.decodeUnknownSync(DependencyTableSchema)([
|
|
1230
|
+
* {
|
|
1231
|
+
* dependency: "effect",
|
|
1232
|
+
* type: "dependency",
|
|
1233
|
+
* action: "updated",
|
|
1234
|
+
* from: "3.18.0",
|
|
1235
|
+
* to: "3.19.1",
|
|
1236
|
+
* },
|
|
1237
|
+
* {
|
|
1238
|
+
* dependency: "typescript",
|
|
1239
|
+
* type: "config",
|
|
1240
|
+
* action: "updated",
|
|
1241
|
+
* from: "5.6.0",
|
|
1242
|
+
* to: "5.7.2",
|
|
1243
|
+
* },
|
|
1244
|
+
* ]);
|
|
1245
|
+
*
|
|
1246
|
+
* // Throws ParseError — empty array
|
|
1247
|
+
* Schema.decodeUnknownSync(DependencyTableSchema)([]);
|
|
1248
|
+
* ```
|
|
1249
|
+
*
|
|
1250
|
+
* @see {@link DependencyTableRowSchema} for the individual row schema
|
|
1251
|
+
*
|
|
1252
|
+
* @public
|
|
1253
|
+
*/
|
|
1254
|
+
export declare const DependencyTableSchema: Schema.filter<Schema.Array$<Schema.Struct<{
|
|
1255
|
+
/** Package or toolchain name. */
|
|
1256
|
+
dependency: Schema.filter<typeof Schema.String>;
|
|
1257
|
+
/** Dependency type. */
|
|
1258
|
+
type: Schema.Literal<["dependency", "devDependency", "peerDependency", "optionalDependency", "workspace", "config"]>;
|
|
1259
|
+
/** Change action. */
|
|
1260
|
+
action: Schema.Literal<["added", "updated", "removed"]>;
|
|
1261
|
+
/** Previous version (em dash for added). */
|
|
1262
|
+
from: Schema.filter<typeof Schema.String>;
|
|
1263
|
+
/** New version (em dash for removed). */
|
|
1264
|
+
to: Schema.filter<typeof Schema.String>;
|
|
1265
|
+
}>>>;
|
|
1266
|
+
|
|
1267
|
+
/**
|
|
1268
|
+
* Inferred type for {@link DependencyTableTypeSchema}.
|
|
1269
|
+
*
|
|
1270
|
+
* @remarks
|
|
1271
|
+
* One of `"dependency"`, `"devDependency"`, `"peerDependency"`,
|
|
1272
|
+
* `"optionalDependency"`, `"workspace"`, or `"config"`.
|
|
1273
|
+
*
|
|
1274
|
+
* @public
|
|
1275
|
+
*/
|
|
1276
|
+
export declare type DependencyTableType = typeof DependencyTableTypeSchema.Type;
|
|
1277
|
+
|
|
1278
|
+
/**
|
|
1279
|
+
* Extended dependency types for table format.
|
|
1280
|
+
*
|
|
1281
|
+
* @remarks
|
|
1282
|
+
* Unlike {@link DependencyTypeSchema} (which uses plural npm field names like
|
|
1283
|
+
* `"dependencies"`), this schema uses singular forms (`"dependency"`) and adds
|
|
1284
|
+
* two additional types: `"workspace"` for monorepo workspace references and
|
|
1285
|
+
* `"config"` for configuration toolchain updates (e.g., ESLint, TypeScript).
|
|
1286
|
+
*
|
|
1287
|
+
* @example
|
|
1288
|
+
* ```typescript
|
|
1289
|
+
* import { Schema } from "effect";
|
|
1290
|
+
* import { DependencyTableTypeSchema } from "@savvy-web/changesets";
|
|
1291
|
+
* import type { DependencyTableType } from "@savvy-web/changesets";
|
|
1292
|
+
*
|
|
1293
|
+
* const tableType: DependencyTableType = Schema.decodeUnknownSync(
|
|
1294
|
+
* DependencyTableTypeSchema
|
|
1295
|
+
* )("workspace");
|
|
1296
|
+
* ```
|
|
1297
|
+
*
|
|
1298
|
+
* @see {@link DependencyTypeSchema} for the plural npm-field variant
|
|
1299
|
+
*
|
|
1300
|
+
* @public
|
|
1301
|
+
*/
|
|
1302
|
+
export declare const DependencyTableTypeSchema: Schema.Literal<["dependency", "devDependency", "peerDependency", "optionalDependency", "workspace", "config"]>;
|
|
1303
|
+
|
|
1304
|
+
/**
|
|
1305
|
+
* Inferred type for {@link DependencyTypeSchema}.
|
|
1306
|
+
*
|
|
1307
|
+
* @remarks
|
|
1308
|
+
* One of `"dependencies"`, `"devDependencies"`, `"peerDependencies"`,
|
|
1309
|
+
* or `"optionalDependencies"`.
|
|
1310
|
+
*
|
|
1311
|
+
* @public
|
|
1312
|
+
*/
|
|
1313
|
+
export declare type DependencyType = typeof DependencyTypeSchema.Type;
|
|
1314
|
+
|
|
1315
|
+
/**
|
|
1316
|
+
* Schema for npm dependency types.
|
|
1317
|
+
*
|
|
1318
|
+
* @remarks
|
|
1319
|
+
* Represents the four standard `package.json` dependency fields using their
|
|
1320
|
+
* plural key names as they appear in the manifest. For the singular,
|
|
1321
|
+
* table-oriented variant that includes `workspace` and `config` types,
|
|
1322
|
+
* see {@link DependencyTableTypeSchema}.
|
|
1323
|
+
*
|
|
1324
|
+
* @example
|
|
1325
|
+
* ```typescript
|
|
1326
|
+
* import { Schema } from "effect";
|
|
1327
|
+
* import { DependencyTypeSchema } from "@savvy-web/changesets";
|
|
1328
|
+
* import type { DependencyType } from "@savvy-web/changesets";
|
|
1329
|
+
*
|
|
1330
|
+
* const depType: DependencyType = Schema.decodeUnknownSync(DependencyTypeSchema)(
|
|
1331
|
+
* "devDependencies"
|
|
1332
|
+
* );
|
|
1333
|
+
* ```
|
|
1334
|
+
*
|
|
1335
|
+
* @see {@link DependencyTableTypeSchema} for the extended singular-form variant
|
|
1336
|
+
*
|
|
1337
|
+
* @public
|
|
1338
|
+
*/
|
|
1339
|
+
export declare const DependencyTypeSchema: Schema.Literal<["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]>;
|
|
1340
|
+
|
|
1341
|
+
/**
|
|
1342
|
+
* Inferred type for {@link DependencyUpdateSchema}.
|
|
1343
|
+
*
|
|
1344
|
+
* @remarks
|
|
1345
|
+
* Use this interface when you need to type a variable or parameter as a
|
|
1346
|
+
* decoded dependency update object.
|
|
1347
|
+
*
|
|
1348
|
+
* @public
|
|
1349
|
+
*/
|
|
1350
|
+
export declare interface DependencyUpdate extends Schema.Schema.Type<typeof DependencyUpdateSchema> {
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1353
|
+
/**
|
|
1354
|
+
* Schema for a dependency update entry.
|
|
1355
|
+
*
|
|
1356
|
+
* @remarks
|
|
1357
|
+
* Represents a single dependency version change as reported by
|
|
1358
|
+
* the Changesets API. Captures the package name, which dependency
|
|
1359
|
+
* field it belongs to, and the old and new version strings.
|
|
1360
|
+
*
|
|
1361
|
+
* @example
|
|
1362
|
+
* ```typescript
|
|
1363
|
+
* import { Schema } from "effect";
|
|
1364
|
+
* import { DependencyUpdateSchema } from "@savvy-web/changesets";
|
|
1365
|
+
* import type { DependencyUpdate } from "@savvy-web/changesets";
|
|
1366
|
+
*
|
|
1367
|
+
* const update: DependencyUpdate = Schema.decodeUnknownSync(DependencyUpdateSchema)({
|
|
1368
|
+
* name: "effect",
|
|
1369
|
+
* type: "dependencies",
|
|
1370
|
+
* oldVersion: "3.18.0",
|
|
1371
|
+
* newVersion: "3.19.1",
|
|
1372
|
+
* });
|
|
1373
|
+
* ```
|
|
1374
|
+
*
|
|
1375
|
+
* @see {@link DependencyUpdate} for the inferred TypeScript type
|
|
1376
|
+
* @see {@link DependencyTableRowSchema} for the table-formatted variant
|
|
1377
|
+
*
|
|
1378
|
+
* @public
|
|
1379
|
+
*/
|
|
1380
|
+
export declare const DependencyUpdateSchema: Schema.Struct<{
|
|
1381
|
+
/** Package name (must be non-empty). */
|
|
1382
|
+
name: Schema.refine<string, typeof Schema.String>;
|
|
1383
|
+
/** npm dependency type. */
|
|
1384
|
+
type: Schema.Literal<["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]>;
|
|
1385
|
+
/** Previous version string. */
|
|
1386
|
+
oldVersion: typeof Schema.String;
|
|
1387
|
+
/** New version string. */
|
|
1388
|
+
newVersion: typeof Schema.String;
|
|
1389
|
+
}>;
|
|
1390
|
+
|
|
1391
|
+
/**
|
|
1392
|
+
* GitHub API request failure.
|
|
1393
|
+
*
|
|
1394
|
+
* @remarks
|
|
1395
|
+
* Raised when a call to the GitHub API (via `\@changesets/get-github-info`)
|
|
1396
|
+
* fails due to network issues, authentication errors, rate limiting, or
|
|
1397
|
+
* server errors. Use the {@link GitHubApiError.isRetryable | isRetryable}
|
|
1398
|
+
* property to determine whether a retry strategy should be applied.
|
|
1399
|
+
* Rate-limited responses (403/429) and server errors (5xx) are considered
|
|
1400
|
+
* retryable.
|
|
1401
|
+
*
|
|
1402
|
+
* @example
|
|
1403
|
+
* ```typescript
|
|
1404
|
+
* import { Effect, Schedule } from "effect";
|
|
1405
|
+
* import { GitHubApiError } from "@savvy-web/changesets";
|
|
1406
|
+
*
|
|
1407
|
+
* declare const program: Effect.Effect<void, GitHubApiError>;
|
|
1408
|
+
*
|
|
1409
|
+
* const withRetry = program.pipe(
|
|
1410
|
+
* Effect.catchTag("GitHubApiError", (err) => {
|
|
1411
|
+
* if (err.isRetryable) {
|
|
1412
|
+
* return Effect.retry(program, Schedule.exponential("1 second"));
|
|
1413
|
+
* }
|
|
1414
|
+
* return Effect.fail(err);
|
|
1415
|
+
* }),
|
|
1416
|
+
* );
|
|
1417
|
+
* ```
|
|
1418
|
+
*
|
|
1419
|
+
* @see {@link GitHubService} for the Effect service that may produce this error
|
|
1420
|
+
*
|
|
1421
|
+
* @public
|
|
1422
|
+
*/
|
|
1423
|
+
export declare class GitHubApiError extends GitHubApiErrorBase<{
|
|
1424
|
+
/** The API operation that failed (e.g., `"getInfo"`). */
|
|
1425
|
+
readonly operation: string;
|
|
1426
|
+
/** HTTP status code, if available. */
|
|
1427
|
+
readonly statusCode?: number | undefined;
|
|
1428
|
+
/** Human-readable failure reason. */
|
|
1429
|
+
readonly reason: string;
|
|
1430
|
+
}> {
|
|
1431
|
+
get message(): string;
|
|
1432
|
+
/** Whether this error is a rate-limit response (403 or 429). */
|
|
1433
|
+
get isRateLimited(): boolean;
|
|
1434
|
+
/** Whether this error is eligible for retry (server errors or rate limits). */
|
|
493
1435
|
get isRetryable(): boolean;
|
|
494
1436
|
}
|
|
495
1437
|
|
|
496
1438
|
/**
|
|
497
|
-
* Base class for GitHubApiError.
|
|
1439
|
+
* Base class for {@link GitHubApiError}.
|
|
498
1440
|
*
|
|
499
1441
|
* @privateRemarks
|
|
500
1442
|
* This export is required for api-extractor documentation generation.
|
|
@@ -510,6 +1452,27 @@ export declare const GitHubApiErrorBase: new <A extends Record<string, any> = {}
|
|
|
510
1452
|
/**
|
|
511
1453
|
* Structured result from the GitHub commit info API.
|
|
512
1454
|
*
|
|
1455
|
+
* @remarks
|
|
1456
|
+
* Represents the data returned by `\@changesets/get-github-info` for a
|
|
1457
|
+
* single commit. Includes the commit author's GitHub username, the
|
|
1458
|
+
* associated pull request number (if any), and pre-formatted markdown
|
|
1459
|
+
* links for use in changelog entries.
|
|
1460
|
+
*
|
|
1461
|
+
* @example
|
|
1462
|
+
* ```typescript
|
|
1463
|
+
* import type { GitHubCommitInfo } from "\@savvy-web/changesets";
|
|
1464
|
+
*
|
|
1465
|
+
* const info: GitHubCommitInfo = {
|
|
1466
|
+
* user: "octocat",
|
|
1467
|
+
* pull: 42,
|
|
1468
|
+
* links: {
|
|
1469
|
+
* commit: "[`abc1234`](https://github.com/owner/repo/commit/abc1234)",
|
|
1470
|
+
* pull: "[#42](https://github.com/owner/repo/pull/42)",
|
|
1471
|
+
* user: "[\@octocat](https://github.com/octocat)",
|
|
1472
|
+
* },
|
|
1473
|
+
* };
|
|
1474
|
+
* ```
|
|
1475
|
+
*
|
|
513
1476
|
* @public
|
|
514
1477
|
*/
|
|
515
1478
|
export declare interface GitHubCommitInfo {
|
|
@@ -531,13 +1494,48 @@ export declare interface GitHubCommitInfo {
|
|
|
531
1494
|
/**
|
|
532
1495
|
* Inferred type for {@link GitHubInfoSchema}.
|
|
533
1496
|
*
|
|
1497
|
+
* @remarks
|
|
1498
|
+
* Contains optional `user` (GitHub username), optional `pull` (PR number),
|
|
1499
|
+
* and a required `links` object with pre-formatted commit, pull, and user
|
|
1500
|
+
* links.
|
|
1501
|
+
*
|
|
534
1502
|
* @public
|
|
535
1503
|
*/
|
|
536
1504
|
export declare interface GitHubInfo extends Schema.Schema.Type<typeof GitHubInfoSchema> {
|
|
537
1505
|
}
|
|
538
1506
|
|
|
539
1507
|
/**
|
|
540
|
-
* Schema for a GitHub info response from
|
|
1508
|
+
* Schema for a GitHub info response from `\@changesets/get-github-info`.
|
|
1509
|
+
*
|
|
1510
|
+
* @remarks
|
|
1511
|
+
* Represents the structured data returned when querying GitHub for commit
|
|
1512
|
+
* metadata. The `user` and `pull` fields are optional because not every
|
|
1513
|
+
* commit is associated with a pull request or a known GitHub user (e.g.,
|
|
1514
|
+
* bot commits or squash-merged commits without a linked PR).
|
|
1515
|
+
*
|
|
1516
|
+
* The `links` object contains pre-formatted markdown or URL strings for
|
|
1517
|
+
* the commit, pull request, and user profile -- ready for insertion into
|
|
1518
|
+
* CHANGELOG entries.
|
|
1519
|
+
*
|
|
1520
|
+
* @example
|
|
1521
|
+
* ```typescript
|
|
1522
|
+
* import { Schema } from "effect";
|
|
1523
|
+
* import { GitHubInfoSchema } from "@savvy-web/changesets";
|
|
1524
|
+
* import type { GitHubInfo } from "@savvy-web/changesets";
|
|
1525
|
+
*
|
|
1526
|
+
* const info: GitHubInfo = Schema.decodeUnknownSync(GitHubInfoSchema)({
|
|
1527
|
+
* user: "octocat",
|
|
1528
|
+
* pull: 42,
|
|
1529
|
+
* links: {
|
|
1530
|
+
* commit: "[`a1b2c3d`](https://github.com/owner/repo/commit/a1b2c3d)",
|
|
1531
|
+
* pull: "[#42](https://github.com/owner/repo/pull/42)",
|
|
1532
|
+
* user: "[@octocat](https://github.com/octocat)",
|
|
1533
|
+
* },
|
|
1534
|
+
* });
|
|
1535
|
+
* ```
|
|
1536
|
+
*
|
|
1537
|
+
* @see {@link GitHubInfo} for the inferred TypeScript type
|
|
1538
|
+
* @see {@link GitHubService} for the Effect service that produces these values
|
|
541
1539
|
*
|
|
542
1540
|
* @public
|
|
543
1541
|
*/
|
|
@@ -558,17 +1556,91 @@ export declare const GitHubInfoSchema: Schema.Struct<{
|
|
|
558
1556
|
}>;
|
|
559
1557
|
|
|
560
1558
|
/**
|
|
561
|
-
*
|
|
1559
|
+
* Production layer for {@link GitHubService}.
|
|
1560
|
+
*
|
|
1561
|
+
* Delegates to `\@changesets/get-github-info` to fetch commit metadata
|
|
1562
|
+
* from the GitHub REST API. Requires a `GITHUB_TOKEN` environment variable
|
|
1563
|
+
* to be set for authenticated requests.
|
|
1564
|
+
*
|
|
1565
|
+
* @remarks
|
|
1566
|
+
* This layer is used by the `\@savvy-web/changesets/changelog` entry point
|
|
1567
|
+
* to resolve commit hashes into PR numbers and author attribution. It is
|
|
1568
|
+
* composed with {@link MarkdownLive} in the changelog formatter's
|
|
1569
|
+
* `MainLayer`.
|
|
1570
|
+
*
|
|
1571
|
+
* @example
|
|
1572
|
+
* ```typescript
|
|
1573
|
+
* import { Effect } from "effect";
|
|
1574
|
+
* import { GitHubService, GitHubLive } from "\@savvy-web/changesets";
|
|
1575
|
+
*
|
|
1576
|
+
* const program = Effect.gen(function* () {
|
|
1577
|
+
* const github = yield* GitHubService;
|
|
1578
|
+
* return yield* github.getInfo({ commit: "abc1234", repo: "owner/repo" });
|
|
1579
|
+
* });
|
|
1580
|
+
*
|
|
1581
|
+
* Effect.runPromise(program.pipe(Effect.provide(GitHubLive)));
|
|
1582
|
+
* ```
|
|
562
1583
|
*
|
|
563
1584
|
* @public
|
|
564
1585
|
*/
|
|
565
1586
|
export declare const GitHubLive: Layer.Layer<GitHubService, never, never>;
|
|
566
1587
|
|
|
567
1588
|
/**
|
|
568
|
-
*
|
|
1589
|
+
* Effect service tag for GitHub API operations.
|
|
1590
|
+
*
|
|
1591
|
+
* Provides dependency-injected access to GitHub commit metadata lookups.
|
|
1592
|
+
* Use `yield* GitHubService` inside an `Effect.gen` block to obtain the
|
|
1593
|
+
* service instance.
|
|
1594
|
+
*
|
|
1595
|
+
* @remarks
|
|
1596
|
+
* This tag follows the standard Effect `Context.Tag` pattern. Two layers
|
|
1597
|
+
* are provided out of the box:
|
|
1598
|
+
*
|
|
1599
|
+
* - {@link GitHubLive} — production layer backed by the GitHub REST API
|
|
1600
|
+
* - {@link makeGitHubTest} — factory for deterministic test layers
|
|
1601
|
+
*
|
|
1602
|
+
* @example
|
|
1603
|
+
* ```typescript
|
|
1604
|
+
* import { Effect, Layer } from "effect";
|
|
1605
|
+
* import { GitHubService, GitHubLive } from "\@savvy-web/changesets";
|
|
1606
|
+
*
|
|
1607
|
+
* const program = Effect.gen(function* () {
|
|
1608
|
+
* const github = yield* GitHubService;
|
|
1609
|
+
* const info = yield* github.getInfo({
|
|
1610
|
+
* commit: "abc1234567890",
|
|
1611
|
+
* repo: "savvy-web/changesets",
|
|
1612
|
+
* });
|
|
1613
|
+
* console.log(info.user, info.pull, info.links);
|
|
1614
|
+
* });
|
|
569
1615
|
*
|
|
1616
|
+
* // Provide the live layer and run
|
|
1617
|
+
* Effect.runPromise(program.pipe(Effect.provide(GitHubLive)));
|
|
1618
|
+
* ```
|
|
1619
|
+
*
|
|
1620
|
+
* @example Creating a test layer with canned responses
|
|
1621
|
+
* ```typescript
|
|
1622
|
+
* import { Effect } from "effect";
|
|
1623
|
+
* import type { GitHubCommitInfo } from "\@savvy-web/changesets";
|
|
1624
|
+
* import { GitHubService, makeGitHubTest } from "\@savvy-web/changesets";
|
|
1625
|
+
*
|
|
1626
|
+
* const testResponses = new Map<string, GitHubCommitInfo>([
|
|
1627
|
+
* ["abc1234", { user: "octocat", pull: 42, links: { pull: "#42", user: "\@octocat" } }],
|
|
1628
|
+
* ]);
|
|
1629
|
+
*
|
|
1630
|
+
* const TestLayer = makeGitHubTest(testResponses);
|
|
1631
|
+
*
|
|
1632
|
+
* const program = Effect.gen(function* () {
|
|
1633
|
+
* const github = yield* GitHubService;
|
|
1634
|
+
* return yield* github.getInfo({ commit: "abc1234", repo: "owner/repo" });
|
|
1635
|
+
* });
|
|
1636
|
+
*
|
|
1637
|
+
* Effect.runPromise(program.pipe(Effect.provide(TestLayer)));
|
|
1638
|
+
* ```
|
|
1639
|
+
*
|
|
1640
|
+
* @see {@link GitHubServiceShape} for the service interface
|
|
570
1641
|
* @see {@link GitHubLive} for the production layer
|
|
571
1642
|
* @see {@link makeGitHubTest} for creating test layers
|
|
1643
|
+
* @see {@link GitHubServiceBase} for the api-extractor base class
|
|
572
1644
|
*
|
|
573
1645
|
* @public
|
|
574
1646
|
*/
|
|
@@ -590,10 +1662,25 @@ export declare const GitHubServiceBase: Context.TagClass<GitHubService, "GitHubS
|
|
|
590
1662
|
/**
|
|
591
1663
|
* Service interface for GitHub API operations.
|
|
592
1664
|
*
|
|
593
|
-
*
|
|
1665
|
+
* Describes the single `getInfo` operation that resolves a commit hash to
|
|
1666
|
+
* its associated GitHub metadata (pull-request number, author, and links).
|
|
1667
|
+
*
|
|
1668
|
+
* @remarks
|
|
1669
|
+
* The `getInfo` method may fail with a {@link GitHubApiError} when the
|
|
1670
|
+
* GitHub API is unreachable or the commit is not found. Callers should
|
|
1671
|
+
* handle this error channel — the changelog formatters recover gracefully
|
|
1672
|
+
* by omitting attribution when the call fails.
|
|
1673
|
+
*
|
|
1674
|
+
* @public
|
|
594
1675
|
*/
|
|
595
1676
|
export declare interface GitHubServiceShape {
|
|
596
|
-
/**
|
|
1677
|
+
/**
|
|
1678
|
+
* Fetch commit metadata from the GitHub API.
|
|
1679
|
+
*
|
|
1680
|
+
* @param params - The commit hash and repository identifier. Must include
|
|
1681
|
+
* `commit` (full SHA-1 hash) and `repo` (in `owner/repo` format).
|
|
1682
|
+
* @returns An `Effect` that resolves to {@link GitHubCommitInfo} or fails with {@link GitHubApiError}
|
|
1683
|
+
*/
|
|
597
1684
|
readonly getInfo: (params: {
|
|
598
1685
|
commit: string;
|
|
599
1686
|
repo: string;
|
|
@@ -603,6 +1690,25 @@ export declare interface GitHubServiceShape {
|
|
|
603
1690
|
/**
|
|
604
1691
|
* Schema for a GitHub issue or PR number (positive integer).
|
|
605
1692
|
*
|
|
1693
|
+
* @remarks
|
|
1694
|
+
* Built on {@link PositiveInteger}, this schema adds GitHub-specific
|
|
1695
|
+
* annotations for documentation tooling. Issue and PR numbers in GitHub
|
|
1696
|
+
* are always positive integers starting from 1.
|
|
1697
|
+
*
|
|
1698
|
+
* @example
|
|
1699
|
+
* ```typescript
|
|
1700
|
+
* import { Schema } from "effect";
|
|
1701
|
+
* import { IssueNumberSchema } from "@savvy-web/changesets";
|
|
1702
|
+
*
|
|
1703
|
+
* // Succeeds
|
|
1704
|
+
* const prNum = Schema.decodeUnknownSync(IssueNumberSchema)(42);
|
|
1705
|
+
*
|
|
1706
|
+
* // Throws ParseError — zero is not a valid issue number
|
|
1707
|
+
* Schema.decodeUnknownSync(IssueNumberSchema)(0);
|
|
1708
|
+
* ```
|
|
1709
|
+
*
|
|
1710
|
+
* @see {@link GitHubInfoSchema} which uses this for the `pull` field
|
|
1711
|
+
*
|
|
606
1712
|
* @public
|
|
607
1713
|
*/
|
|
608
1714
|
export declare const IssueNumberSchema: Schema.refine<number, Schema.filter<typeof Schema.Number>>;
|
|
@@ -610,8 +1716,29 @@ export declare const IssueNumberSchema: Schema.refine<number, Schema.filter<type
|
|
|
610
1716
|
/**
|
|
611
1717
|
* Schema for a JSONPath expression starting with `$.`.
|
|
612
1718
|
*
|
|
1719
|
+
* @remarks
|
|
613
1720
|
* Supports property access (`$.foo.bar`), array wildcard (`$.foo[*].bar`),
|
|
614
|
-
* and array index access (`$.foo[0].bar`).
|
|
1721
|
+
* and array index access (`$.foo[0].bar`). The expression must begin with
|
|
1722
|
+
* `$.` followed by at least one property segment.
|
|
1723
|
+
*
|
|
1724
|
+
* @example
|
|
1725
|
+
* ```typescript
|
|
1726
|
+
* import { Schema } from "effect";
|
|
1727
|
+
* import { JsonPathSchema } from "@savvy-web/changesets";
|
|
1728
|
+
*
|
|
1729
|
+
* // Succeeds — simple property access
|
|
1730
|
+
* Schema.decodeUnknownSync(JsonPathSchema)("$.version");
|
|
1731
|
+
*
|
|
1732
|
+
* // Succeeds — nested property access
|
|
1733
|
+
* Schema.decodeUnknownSync(JsonPathSchema)("$.metadata.version");
|
|
1734
|
+
*
|
|
1735
|
+
* // Throws ParseError — missing "$." prefix
|
|
1736
|
+
* Schema.decodeUnknownSync(JsonPathSchema)("version");
|
|
1737
|
+
* ```
|
|
1738
|
+
*
|
|
1739
|
+
* @see {@link VersionFileConfigSchema} which uses this for the `paths` field
|
|
1740
|
+
*
|
|
1741
|
+
* @public
|
|
615
1742
|
*/
|
|
616
1743
|
export declare const JsonPathSchema: Schema.filter<typeof Schema.String>;
|
|
617
1744
|
|
|
@@ -619,38 +1746,141 @@ export declare const JsonPathSchema: Schema.filter<typeof Schema.String>;
|
|
|
619
1746
|
* Class-based API wrapper for changeset linting.
|
|
620
1747
|
*
|
|
621
1748
|
* Provides a static class interface that runs all remark-lint rules
|
|
622
|
-
* against changeset markdown files.
|
|
1749
|
+
* against changeset markdown files and returns structured diagnostics.
|
|
1750
|
+
*
|
|
1751
|
+
* @internal
|
|
623
1752
|
*/
|
|
624
1753
|
/**
|
|
625
|
-
* A single lint message
|
|
1754
|
+
* A single lint diagnostic message produced by changeset validation.
|
|
1755
|
+
*
|
|
1756
|
+
* @remarks
|
|
1757
|
+
* Each `LintMessage` corresponds to one remark-lint rule violation found
|
|
1758
|
+
* during changeset validation. Messages include source location information
|
|
1759
|
+
* (file, line, column) for integration with editors, CI reporters, and
|
|
1760
|
+
* the Effect CLI's `lint` and `check` commands.
|
|
1761
|
+
*
|
|
1762
|
+
* The four rules that produce lint messages are:
|
|
1763
|
+
*
|
|
1764
|
+
* - **heading-hierarchy** -- ensures headings follow a valid nesting order
|
|
1765
|
+
* - **required-sections** -- checks that mandatory sections are present
|
|
1766
|
+
* - **content-structure** -- validates the structure of section content
|
|
1767
|
+
* - **uncategorized-content** -- flags content outside recognized section headings
|
|
626
1768
|
*
|
|
627
1769
|
* @public
|
|
628
1770
|
*/
|
|
629
1771
|
export declare interface LintMessage {
|
|
630
|
-
/**
|
|
1772
|
+
/**
|
|
1773
|
+
* File path that was validated.
|
|
1774
|
+
*
|
|
1775
|
+
* @remarks
|
|
1776
|
+
* Set to the actual filesystem path when using {@link ChangesetLinter.validateFile}
|
|
1777
|
+
* or {@link ChangesetLinter.validate}. Defaults to `"<input>"` when using
|
|
1778
|
+
* {@link ChangesetLinter.validateContent} without an explicit path.
|
|
1779
|
+
*/
|
|
631
1780
|
file: string;
|
|
632
|
-
/**
|
|
1781
|
+
/**
|
|
1782
|
+
* Identifier of the remark-lint rule that produced this message.
|
|
1783
|
+
*
|
|
1784
|
+
* @remarks
|
|
1785
|
+
* Corresponds to one of the four built-in rules: `"heading-hierarchy"`,
|
|
1786
|
+
* `"required-sections"`, `"content-structure"`, or `"uncategorized-content"`.
|
|
1787
|
+
* Falls back to `"unknown"` if the underlying vfile message has no rule ID.
|
|
1788
|
+
*/
|
|
633
1789
|
rule: string;
|
|
634
|
-
/**
|
|
1790
|
+
/**
|
|
1791
|
+
* Line number where the issue was detected (1-based).
|
|
1792
|
+
*
|
|
1793
|
+
* @remarks
|
|
1794
|
+
* Line numbers are relative to the content after YAML frontmatter
|
|
1795
|
+
* stripping. Defaults to `1` if the underlying rule does not provide
|
|
1796
|
+
* position information.
|
|
1797
|
+
*/
|
|
635
1798
|
line: number;
|
|
636
|
-
/**
|
|
1799
|
+
/**
|
|
1800
|
+
* Column number where the issue was detected (1-based).
|
|
1801
|
+
*
|
|
1802
|
+
* @remarks
|
|
1803
|
+
* Defaults to `1` if the underlying rule does not provide position
|
|
1804
|
+
* information.
|
|
1805
|
+
*/
|
|
637
1806
|
column: number;
|
|
638
|
-
/**
|
|
1807
|
+
/**
|
|
1808
|
+
* Human-readable description of the lint violation.
|
|
1809
|
+
*
|
|
1810
|
+
* @remarks
|
|
1811
|
+
* Suitable for display in terminal output, editor diagnostics, or
|
|
1812
|
+
* CI annotations. Includes enough context to understand the issue
|
|
1813
|
+
* without referencing the source file.
|
|
1814
|
+
*/
|
|
639
1815
|
message: string;
|
|
640
1816
|
}
|
|
641
1817
|
|
|
642
1818
|
/**
|
|
643
|
-
* Create a test layer with pre-configured responses
|
|
1819
|
+
* Create a test layer for {@link GitHubService} with pre-configured responses.
|
|
1820
|
+
*
|
|
1821
|
+
* Returns a `Layer` that resolves commit hashes from the provided `Map`.
|
|
1822
|
+
* Lookups for commits not present in the map fail with a
|
|
1823
|
+
* {@link GitHubApiError}.
|
|
1824
|
+
*
|
|
1825
|
+
* @remarks
|
|
1826
|
+
* This helper is the recommended way to test code that depends on
|
|
1827
|
+
* `GitHubService` without making real API calls. Provide the layer
|
|
1828
|
+
* via `Effect.provide` in your test setup.
|
|
1829
|
+
*
|
|
1830
|
+
* @param responses - A `Map` of full commit hash to {@link GitHubCommitInfo} objects
|
|
1831
|
+
* @returns A `Layer` providing the {@link GitHubService} with deterministic responses
|
|
1832
|
+
*
|
|
1833
|
+
* @example
|
|
1834
|
+
* ```typescript
|
|
1835
|
+
* import { Effect } from "effect";
|
|
1836
|
+
* import type { GitHubCommitInfo } from "\@savvy-web/changesets";
|
|
1837
|
+
* import { GitHubService, makeGitHubTest } from "\@savvy-web/changesets";
|
|
1838
|
+
*
|
|
1839
|
+
* const responses = new Map<string, GitHubCommitInfo>([
|
|
1840
|
+
* ["abc1234", { user: "octocat", pull: 42, links: { pull: "#42", user: "\@octocat" } }],
|
|
1841
|
+
* ]);
|
|
644
1842
|
*
|
|
645
|
-
*
|
|
646
|
-
*
|
|
1843
|
+
* const TestGitHub = makeGitHubTest(responses);
|
|
1844
|
+
*
|
|
1845
|
+
* const program = Effect.gen(function* () {
|
|
1846
|
+
* const github = yield* GitHubService;
|
|
1847
|
+
* return yield* github.getInfo({ commit: "abc1234", repo: "owner/repo" });
|
|
1848
|
+
* });
|
|
1849
|
+
*
|
|
1850
|
+
* // In a Vitest test:
|
|
1851
|
+
* const result = await Effect.runPromise(program.pipe(Effect.provide(TestGitHub)));
|
|
1852
|
+
* // result.user === "octocat"
|
|
1853
|
+
* ```
|
|
647
1854
|
*
|
|
648
1855
|
* @public
|
|
649
1856
|
*/
|
|
650
1857
|
export declare function makeGitHubTest(responses: Map<string, GitHubCommitInfo>): Layer.Layer<GitHubService>;
|
|
651
1858
|
|
|
652
1859
|
/**
|
|
653
|
-
*
|
|
1860
|
+
* Production layer for {@link MarkdownService}.
|
|
1861
|
+
*
|
|
1862
|
+
* Wraps the remark-pipeline utility functions (`parseMarkdown` and
|
|
1863
|
+
* `stringifyMarkdown`) in `Effect.sync` for use in Effect programs.
|
|
1864
|
+
* Both operations are synchronous and infallible.
|
|
1865
|
+
*
|
|
1866
|
+
* @remarks
|
|
1867
|
+
* This layer is composed with {@link GitHubLive} in the
|
|
1868
|
+
* `\@savvy-web/changesets/changelog` entry point to form the `MainLayer`
|
|
1869
|
+
* that powers the Changesets API integration.
|
|
1870
|
+
*
|
|
1871
|
+
* @example
|
|
1872
|
+
* ```typescript
|
|
1873
|
+
* import { Effect, Layer } from "effect";
|
|
1874
|
+
* import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
|
|
1875
|
+
*
|
|
1876
|
+
* const program = Effect.gen(function* () {
|
|
1877
|
+
* const md = yield* MarkdownService;
|
|
1878
|
+
* const tree = yield* md.parse("**bold** text");
|
|
1879
|
+
* return yield* md.stringify(tree);
|
|
1880
|
+
* });
|
|
1881
|
+
*
|
|
1882
|
+
* Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
|
|
1883
|
+
* ```
|
|
654
1884
|
*
|
|
655
1885
|
* @public
|
|
656
1886
|
*/
|
|
@@ -659,6 +1889,28 @@ export declare const MarkdownLive: Layer.Layer<MarkdownService, never, never>;
|
|
|
659
1889
|
/**
|
|
660
1890
|
* Markdown parsing failure.
|
|
661
1891
|
*
|
|
1892
|
+
* @remarks
|
|
1893
|
+
* Raised when a markdown file cannot be parsed into an AST by the unified/remark
|
|
1894
|
+
* pipeline. Carries optional source file location information (line, column)
|
|
1895
|
+
* for diagnostic display.
|
|
1896
|
+
*
|
|
1897
|
+
* @example
|
|
1898
|
+
* ```typescript
|
|
1899
|
+
* import { Effect } from "effect";
|
|
1900
|
+
* import { MarkdownParseError } from "@savvy-web/changesets";
|
|
1901
|
+
*
|
|
1902
|
+
* declare const program: Effect.Effect<string, MarkdownParseError>;
|
|
1903
|
+
*
|
|
1904
|
+
* const handled = program.pipe(
|
|
1905
|
+
* Effect.catchTag("MarkdownParseError", (err) => {
|
|
1906
|
+
* console.error(err.message);
|
|
1907
|
+
* return Effect.succeed("");
|
|
1908
|
+
* }),
|
|
1909
|
+
* );
|
|
1910
|
+
* ```
|
|
1911
|
+
*
|
|
1912
|
+
* @see {@link MarkdownService} for the Effect service that may produce this error
|
|
1913
|
+
*
|
|
662
1914
|
* @public
|
|
663
1915
|
*/
|
|
664
1916
|
export declare class MarkdownParseError extends MarkdownParseErrorBase<{
|
|
@@ -675,7 +1927,7 @@ export declare class MarkdownParseError extends MarkdownParseErrorBase<{
|
|
|
675
1927
|
}
|
|
676
1928
|
|
|
677
1929
|
/**
|
|
678
|
-
* Base class for MarkdownParseError.
|
|
1930
|
+
* Base class for {@link MarkdownParseError}.
|
|
679
1931
|
*
|
|
680
1932
|
* @privateRemarks
|
|
681
1933
|
* This export is required for api-extractor documentation generation.
|
|
@@ -689,9 +1941,36 @@ export declare const MarkdownParseErrorBase: new <A extends Record<string, any>
|
|
|
689
1941
|
} & Readonly<A>;
|
|
690
1942
|
|
|
691
1943
|
/**
|
|
692
|
-
*
|
|
1944
|
+
* Effect service tag for markdown parsing and stringification.
|
|
1945
|
+
*
|
|
1946
|
+
* Provides dependency-injected access to markdown parse/stringify operations.
|
|
1947
|
+
* Use `yield* MarkdownService` inside an `Effect.gen` block to obtain the
|
|
1948
|
+
* service instance.
|
|
1949
|
+
*
|
|
1950
|
+
* @remarks
|
|
1951
|
+
* This tag follows the standard Effect `Context.Tag` pattern. The
|
|
1952
|
+
* {@link MarkdownLive} layer provides the default implementation backed by
|
|
1953
|
+
* the remark/unified pipeline. For testing, you can supply a custom layer
|
|
1954
|
+
* via `Layer.succeed(MarkdownService, { parse: ..., stringify: ... })`.
|
|
693
1955
|
*
|
|
1956
|
+
* @example
|
|
1957
|
+
* ```typescript
|
|
1958
|
+
* import { Effect } from "effect";
|
|
1959
|
+
* import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
|
|
1960
|
+
*
|
|
1961
|
+
* const program = Effect.gen(function* () {
|
|
1962
|
+
* const md = yield* MarkdownService;
|
|
1963
|
+
* const tree = yield* md.parse("# Hello\n\nWorld");
|
|
1964
|
+
* const output = yield* md.stringify(tree);
|
|
1965
|
+
* console.log(output); // "# Hello\n\nWorld\n"
|
|
1966
|
+
* });
|
|
1967
|
+
*
|
|
1968
|
+
* Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
|
|
1969
|
+
* ```
|
|
1970
|
+
*
|
|
1971
|
+
* @see {@link MarkdownServiceShape} for the service interface
|
|
694
1972
|
* @see {@link MarkdownLive} for the production layer
|
|
1973
|
+
* @see {@link MarkdownServiceBase} for the api-extractor base class
|
|
695
1974
|
*
|
|
696
1975
|
* @public
|
|
697
1976
|
*/
|
|
@@ -713,18 +1992,57 @@ export declare const MarkdownServiceBase: Context.TagClass<MarkdownService, "Mar
|
|
|
713
1992
|
/**
|
|
714
1993
|
* Service interface for markdown parsing and stringification.
|
|
715
1994
|
*
|
|
716
|
-
*
|
|
1995
|
+
* Describes the two operations a `MarkdownService` implementation must
|
|
1996
|
+
* provide: parsing markdown text into an mdast AST and stringifying an
|
|
1997
|
+
* mdast AST back to markdown text.
|
|
1998
|
+
*
|
|
1999
|
+
* @remarks
|
|
2000
|
+
* Both operations are infallible (no error channel) because the underlying
|
|
2001
|
+
* remark pipeline is configured to handle all valid markdown input. The
|
|
2002
|
+
* `Root` type comes from the `mdast` package and represents the root node
|
|
2003
|
+
* of a markdown abstract syntax tree.
|
|
2004
|
+
*
|
|
2005
|
+
* @public
|
|
717
2006
|
*/
|
|
718
2007
|
export declare interface MarkdownServiceShape {
|
|
719
|
-
/**
|
|
2008
|
+
/**
|
|
2009
|
+
* Parse a markdown string into an mdast abstract syntax tree.
|
|
2010
|
+
*
|
|
2011
|
+
* @param content - Raw markdown text to parse
|
|
2012
|
+
* @returns An `Effect` that resolves to an mdast `Root` node
|
|
2013
|
+
*/
|
|
720
2014
|
readonly parse: (content: string) => Effect.Effect<Root>;
|
|
721
|
-
/**
|
|
2015
|
+
/**
|
|
2016
|
+
* Stringify an mdast abstract syntax tree back to markdown text.
|
|
2017
|
+
*
|
|
2018
|
+
* @param tree - The mdast `Root` node to serialize
|
|
2019
|
+
* @returns An `Effect` that resolves to a markdown string
|
|
2020
|
+
*/
|
|
722
2021
|
readonly stringify: (tree: Root) => Effect.Effect<string>;
|
|
723
2022
|
}
|
|
724
2023
|
|
|
725
2024
|
/**
|
|
726
2025
|
* A non-empty string schema.
|
|
727
2026
|
*
|
|
2027
|
+
* @remarks
|
|
2028
|
+
* Validates that a string has at least one character. Used as the base
|
|
2029
|
+
* constraint for package names, dependency identifiers, and other fields
|
|
2030
|
+
* that must not be blank.
|
|
2031
|
+
*
|
|
2032
|
+
* @example
|
|
2033
|
+
* ```typescript
|
|
2034
|
+
* import { Schema } from "effect";
|
|
2035
|
+
* import { NonEmptyString } from "@savvy-web/changesets";
|
|
2036
|
+
*
|
|
2037
|
+
* // Succeeds — non-empty string
|
|
2038
|
+
* const name = Schema.decodeUnknownSync(NonEmptyString)("react");
|
|
2039
|
+
*
|
|
2040
|
+
* // Throws ParseError — empty string
|
|
2041
|
+
* Schema.decodeUnknownSync(NonEmptyString)("");
|
|
2042
|
+
* ```
|
|
2043
|
+
*
|
|
2044
|
+
* @see {@link ChangesetSummarySchema} for a length-bounded variant used for changeset summaries
|
|
2045
|
+
*
|
|
728
2046
|
* @public
|
|
729
2047
|
*/
|
|
730
2048
|
export declare const NonEmptyString: Schema.filter<typeof Schema.String>;
|
|
@@ -732,6 +2050,28 @@ export declare const NonEmptyString: Schema.filter<typeof Schema.String>;
|
|
|
732
2050
|
/**
|
|
733
2051
|
* A positive integer schema.
|
|
734
2052
|
*
|
|
2053
|
+
* @remarks
|
|
2054
|
+
* Validates that a number is both an integer and strictly greater than zero.
|
|
2055
|
+
* Used as the base constraint for GitHub issue numbers and similar
|
|
2056
|
+
* identifiers that must be positive whole numbers.
|
|
2057
|
+
*
|
|
2058
|
+
* @example
|
|
2059
|
+
* ```typescript
|
|
2060
|
+
* import { Schema } from "effect";
|
|
2061
|
+
* import { PositiveInteger } from "@savvy-web/changesets";
|
|
2062
|
+
*
|
|
2063
|
+
* // Succeeds — positive integer
|
|
2064
|
+
* const issueNum = Schema.decodeUnknownSync(PositiveInteger)(42);
|
|
2065
|
+
*
|
|
2066
|
+
* // Throws ParseError — zero is not positive
|
|
2067
|
+
* Schema.decodeUnknownSync(PositiveInteger)(0);
|
|
2068
|
+
*
|
|
2069
|
+
* // Throws ParseError — floats are not integers
|
|
2070
|
+
* Schema.decodeUnknownSync(PositiveInteger)(3.14);
|
|
2071
|
+
* ```
|
|
2072
|
+
*
|
|
2073
|
+
* @see {@link IssueNumberSchema} which builds on this for GitHub issue/PR numbers
|
|
2074
|
+
*
|
|
735
2075
|
* @public
|
|
736
2076
|
*/
|
|
737
2077
|
export declare const PositiveInteger: Schema.filter<Schema.filter<typeof Schema.Number>>;
|
|
@@ -739,15 +2079,35 @@ export declare const PositiveInteger: Schema.filter<Schema.filter<typeof Schema.
|
|
|
739
2079
|
/**
|
|
740
2080
|
* Schema for a GitHub repository in `owner/repo` format.
|
|
741
2081
|
*
|
|
2082
|
+
* @remarks
|
|
2083
|
+
* Validates that the string matches the `owner/repository` format used
|
|
2084
|
+
* by GitHub. Both the owner and repository segments accept alphanumeric
|
|
2085
|
+
* characters, dots, underscores, and hyphens.
|
|
2086
|
+
*
|
|
2087
|
+
* @example
|
|
2088
|
+
* ```typescript
|
|
2089
|
+
* import { Schema } from "effect";
|
|
2090
|
+
* import { RepoSchema } from "@savvy-web/changesets";
|
|
2091
|
+
*
|
|
2092
|
+
* // Succeeds
|
|
2093
|
+
* Schema.decodeUnknownSync(RepoSchema)("microsoft/vscode");
|
|
2094
|
+
*
|
|
2095
|
+
* // Throws ParseError — missing slash
|
|
2096
|
+
* Schema.decodeUnknownSync(RepoSchema)("vscode");
|
|
2097
|
+
* ```
|
|
2098
|
+
*
|
|
2099
|
+
* @see {@link ChangesetOptionsSchema} which uses this for the `repo` field
|
|
2100
|
+
*
|
|
742
2101
|
* @public
|
|
743
2102
|
*/
|
|
744
2103
|
export declare const RepoSchema: Schema.filter<typeof Schema.String>;
|
|
745
2104
|
|
|
746
2105
|
/**
|
|
747
2106
|
* A section category defines how changes are grouped in release notes.
|
|
748
|
-
* Used across all three processing layers.
|
|
749
2107
|
*
|
|
750
|
-
*
|
|
2108
|
+
* @remarks
|
|
2109
|
+
* Inferred from {@link SectionCategorySchema}. Use this type to annotate
|
|
2110
|
+
* variables and parameters that hold category data.
|
|
751
2111
|
*
|
|
752
2112
|
* @public
|
|
753
2113
|
*/
|
|
@@ -756,9 +2116,34 @@ export declare interface SectionCategory extends Schema.Schema.Type<typeof Secti
|
|
|
756
2116
|
|
|
757
2117
|
/**
|
|
758
2118
|
* Schema for a section category that defines how changes are grouped in release notes.
|
|
759
|
-
* Used across all three processing layers.
|
|
760
2119
|
*
|
|
761
|
-
*
|
|
2120
|
+
* @remarks
|
|
2121
|
+
* A section category has four fields:
|
|
2122
|
+
* - `heading` -- the display heading used in CHANGELOG output (e.g., `"Features"`, `"Bug Fixes"`)
|
|
2123
|
+
* - `priority` -- an integer controlling display order (lower = higher priority)
|
|
2124
|
+
* - `commitTypes` -- conventional commit type prefixes that map to this category (e.g., `["feat"]`)
|
|
2125
|
+
* - `description` -- a brief human-readable description for documentation
|
|
2126
|
+
*
|
|
2127
|
+
* Categories with an empty `commitTypes` array are resolved through other means:
|
|
2128
|
+
* `BREAKING_CHANGES` is resolved via the `!` suffix on any commit type, and
|
|
2129
|
+
* `OTHER` is the fallback for unrecognized types.
|
|
2130
|
+
*
|
|
2131
|
+
* @example
|
|
2132
|
+
* ```typescript
|
|
2133
|
+
* import { Schema } from "effect";
|
|
2134
|
+
* import { SectionCategorySchema } from "@savvy-web/changesets";
|
|
2135
|
+
* import type { SectionCategory } from "@savvy-web/changesets";
|
|
2136
|
+
*
|
|
2137
|
+
* const category: SectionCategory = Schema.decodeUnknownSync(SectionCategorySchema)({
|
|
2138
|
+
* heading: "Features",
|
|
2139
|
+
* priority: 2,
|
|
2140
|
+
* commitTypes: ["feat"],
|
|
2141
|
+
* description: "New functionality",
|
|
2142
|
+
* });
|
|
2143
|
+
* ```
|
|
2144
|
+
*
|
|
2145
|
+
* @see {@link SectionCategory} for the inferred TypeScript type
|
|
2146
|
+
* @see {@link CATEGORIES} for all predefined categories
|
|
762
2147
|
*
|
|
763
2148
|
* @public
|
|
764
2149
|
*/
|
|
@@ -776,7 +2161,33 @@ export declare const SectionCategorySchema: Schema.Struct<{
|
|
|
776
2161
|
/**
|
|
777
2162
|
* Schema accepting either a plain URL or a markdown link `[text](url)`.
|
|
778
2163
|
*
|
|
779
|
-
*
|
|
2164
|
+
* @remarks
|
|
2165
|
+
* The `\@changesets/get-github-info` vendor module returns links in two
|
|
2166
|
+
* possible formats depending on context: a bare URL string or a markdown
|
|
2167
|
+
* link like `[#42](https://github.com/owner/repo/pull/42)`. This schema
|
|
2168
|
+
* accepts both, validating that the URL portion is parseable by the
|
|
2169
|
+
* `URL` constructor.
|
|
2170
|
+
*
|
|
2171
|
+
* @example
|
|
2172
|
+
* ```typescript
|
|
2173
|
+
* import { Schema } from "effect";
|
|
2174
|
+
* import { UrlOrMarkdownLinkSchema } from "@savvy-web/changesets";
|
|
2175
|
+
*
|
|
2176
|
+
* // Succeeds — plain URL
|
|
2177
|
+
* Schema.decodeUnknownSync(UrlOrMarkdownLinkSchema)(
|
|
2178
|
+
* "https://github.com/owner/repo/pull/42"
|
|
2179
|
+
* );
|
|
2180
|
+
*
|
|
2181
|
+
* // Succeeds — markdown link
|
|
2182
|
+
* Schema.decodeUnknownSync(UrlOrMarkdownLinkSchema)(
|
|
2183
|
+
* "[#42](https://github.com/owner/repo/pull/42)"
|
|
2184
|
+
* );
|
|
2185
|
+
*
|
|
2186
|
+
* // Throws ParseError — not a URL or markdown link
|
|
2187
|
+
* Schema.decodeUnknownSync(UrlOrMarkdownLinkSchema)("not-a-url");
|
|
2188
|
+
* ```
|
|
2189
|
+
*
|
|
2190
|
+
* @see {@link GitHubInfoSchema} which uses this for commit, pull, and user links
|
|
780
2191
|
*
|
|
781
2192
|
* @public
|
|
782
2193
|
*/
|
|
@@ -785,7 +2196,25 @@ export declare const UrlOrMarkdownLinkSchema: Schema.filter<typeof Schema.String
|
|
|
785
2196
|
/**
|
|
786
2197
|
* Schema for a GitHub username.
|
|
787
2198
|
*
|
|
788
|
-
*
|
|
2199
|
+
* @remarks
|
|
2200
|
+
* Validates against GitHub's username rules: alphanumeric characters and
|
|
2201
|
+
* hyphens only, cannot start or end with a hyphen. Does not enforce the
|
|
2202
|
+
* 39-character maximum length since GitHub may change that limit.
|
|
2203
|
+
*
|
|
2204
|
+
* @example
|
|
2205
|
+
* ```typescript
|
|
2206
|
+
* import { Schema } from "effect";
|
|
2207
|
+
* import { UsernameSchema } from "@savvy-web/changesets";
|
|
2208
|
+
*
|
|
2209
|
+
* // Succeeds
|
|
2210
|
+
* Schema.decodeUnknownSync(UsernameSchema)("octocat");
|
|
2211
|
+
* Schema.decodeUnknownSync(UsernameSchema)("my-user-123");
|
|
2212
|
+
*
|
|
2213
|
+
* // Throws ParseError — starts with hyphen
|
|
2214
|
+
* Schema.decodeUnknownSync(UsernameSchema)("-invalid");
|
|
2215
|
+
* ```
|
|
2216
|
+
*
|
|
2217
|
+
* @see {@link GitHubInfoSchema} which uses this for the `user` field
|
|
789
2218
|
*
|
|
790
2219
|
* @public
|
|
791
2220
|
*/
|
|
@@ -793,12 +2222,43 @@ export declare const UsernameSchema: Schema.filter<typeof Schema.String>;
|
|
|
793
2222
|
|
|
794
2223
|
/**
|
|
795
2224
|
* Inferred type for {@link VersionFileConfigSchema}.
|
|
2225
|
+
*
|
|
2226
|
+
* @public
|
|
796
2227
|
*/
|
|
797
2228
|
export declare interface VersionFileConfig extends Schema.Schema.Type<typeof VersionFileConfigSchema> {
|
|
798
2229
|
}
|
|
799
2230
|
|
|
800
2231
|
/**
|
|
801
2232
|
* Schema for a single version file configuration entry.
|
|
2233
|
+
*
|
|
2234
|
+
* @remarks
|
|
2235
|
+
* Each entry specifies a glob pattern that matches one or more JSON files
|
|
2236
|
+
* and an optional array of JSONPath expressions indicating which fields
|
|
2237
|
+
* within those files contain version numbers. When `paths` is omitted,
|
|
2238
|
+
* it defaults to `["$.version"]` at runtime.
|
|
2239
|
+
*
|
|
2240
|
+
* @example
|
|
2241
|
+
* ```typescript
|
|
2242
|
+
* import { Schema } from "effect";
|
|
2243
|
+
* import { VersionFileConfigSchema } from "@savvy-web/changesets";
|
|
2244
|
+
* import type { VersionFileConfig } from "@savvy-web/changesets";
|
|
2245
|
+
*
|
|
2246
|
+
* const config: VersionFileConfig = Schema.decodeUnknownSync(VersionFileConfigSchema)({
|
|
2247
|
+
* glob: "manifest.json",
|
|
2248
|
+
* paths: ["$.version", "$.metadata.version"],
|
|
2249
|
+
* });
|
|
2250
|
+
*
|
|
2251
|
+
* // Paths are optional — defaults to ["$.version"] at runtime
|
|
2252
|
+
* const simpleConfig: VersionFileConfig = Schema.decodeUnknownSync(VersionFileConfigSchema)({
|
|
2253
|
+
* glob: "**\/deno.json",
|
|
2254
|
+
* });
|
|
2255
|
+
* ```
|
|
2256
|
+
*
|
|
2257
|
+
* @see {@link VersionFileConfig} for the inferred TypeScript type
|
|
2258
|
+
* @see {@link VersionFilesSchema} for the array of entries
|
|
2259
|
+
* @see {@link JsonPathSchema} for JSONPath validation rules
|
|
2260
|
+
*
|
|
2261
|
+
* @public
|
|
802
2262
|
*/
|
|
803
2263
|
export declare const VersionFileConfigSchema: Schema.Struct<{
|
|
804
2264
|
/** Glob pattern to match JSON files. */
|
|
@@ -810,8 +2270,32 @@ export declare const VersionFileConfigSchema: Schema.Struct<{
|
|
|
810
2270
|
/**
|
|
811
2271
|
* Version file update failure.
|
|
812
2272
|
*
|
|
813
|
-
*
|
|
814
|
-
*
|
|
2273
|
+
* @remarks
|
|
2274
|
+
* Raised when a JSON file targeted by the `versionFiles` configuration option
|
|
2275
|
+
* cannot be read, parsed, or updated at the specified JSONPath. Common causes
|
|
2276
|
+
* include missing files, invalid JSON, or JSONPath expressions that do not
|
|
2277
|
+
* match any field in the target file.
|
|
2278
|
+
*
|
|
2279
|
+
* @example
|
|
2280
|
+
* ```typescript
|
|
2281
|
+
* import { Effect } from "effect";
|
|
2282
|
+
* import { VersionFileError } from "@savvy-web/changesets";
|
|
2283
|
+
*
|
|
2284
|
+
* declare const program: Effect.Effect<void, VersionFileError>;
|
|
2285
|
+
*
|
|
2286
|
+
* const handled = program.pipe(
|
|
2287
|
+
* Effect.catchTag("VersionFileError", (err) => {
|
|
2288
|
+
* console.error(`Failed to update ${err.filePath}: ${err.reason}`);
|
|
2289
|
+
* if (err.jsonPath) {
|
|
2290
|
+
* console.error(` at JSONPath: ${err.jsonPath}`);
|
|
2291
|
+
* }
|
|
2292
|
+
* return Effect.void;
|
|
2293
|
+
* }),
|
|
2294
|
+
* );
|
|
2295
|
+
* ```
|
|
2296
|
+
*
|
|
2297
|
+
* @see {@link VersionFilesSchema} for the configuration that drives version file updates
|
|
2298
|
+
* @see {@link JsonPathSchema} for JSONPath expression validation
|
|
815
2299
|
*
|
|
816
2300
|
* @public
|
|
817
2301
|
*/
|
|
@@ -827,7 +2311,7 @@ export declare class VersionFileError extends VersionFileErrorBase<{
|
|
|
827
2311
|
}
|
|
828
2312
|
|
|
829
2313
|
/**
|
|
830
|
-
* Base class for VersionFileError.
|
|
2314
|
+
* Base class for {@link VersionFileError}.
|
|
831
2315
|
*
|
|
832
2316
|
* @privateRemarks
|
|
833
2317
|
* This export is required for api-extractor documentation generation.
|
|
@@ -842,6 +2326,26 @@ export declare const VersionFileErrorBase: new <A extends Record<string, any> =
|
|
|
842
2326
|
|
|
843
2327
|
/**
|
|
844
2328
|
* Schema for the `versionFiles` array.
|
|
2329
|
+
*
|
|
2330
|
+
* @remarks
|
|
2331
|
+
* An array of {@link VersionFileConfigSchema} entries. Each entry targets
|
|
2332
|
+
* a set of JSON files via glob and specifies which JSONPath expressions
|
|
2333
|
+
* point to version fields that should be updated.
|
|
2334
|
+
*
|
|
2335
|
+
* @example
|
|
2336
|
+
* ```typescript
|
|
2337
|
+
* import { Schema } from "effect";
|
|
2338
|
+
* import { VersionFilesSchema } from "@savvy-web/changesets";
|
|
2339
|
+
*
|
|
2340
|
+
* const versionFiles = Schema.decodeUnknownSync(VersionFilesSchema)([
|
|
2341
|
+
* { glob: "manifest.json", paths: ["$.version"] },
|
|
2342
|
+
* { glob: "deno.json" },
|
|
2343
|
+
* ]);
|
|
2344
|
+
* ```
|
|
2345
|
+
*
|
|
2346
|
+
* @see {@link ChangesetOptionsSchema} where this is used as an optional field
|
|
2347
|
+
*
|
|
2348
|
+
* @public
|
|
845
2349
|
*/
|
|
846
2350
|
export declare const VersionFilesSchema: Schema.Array$<Schema.Struct<{
|
|
847
2351
|
/** Glob pattern to match JSON files. */
|
|
@@ -850,9 +2354,40 @@ export declare const VersionFilesSchema: Schema.Array$<Schema.Struct<{
|
|
|
850
2354
|
paths: Schema.optional<Schema.Array$<Schema.filter<typeof Schema.String>>>;
|
|
851
2355
|
}>>;
|
|
852
2356
|
|
|
2357
|
+
/**
|
|
2358
|
+
* Version string or em dash (U+2014) sentinel for added/removed entries.
|
|
2359
|
+
*
|
|
2360
|
+
* @remarks
|
|
2361
|
+
* Accepts either a semver-like version string (with optional `~` or `^`
|
|
2362
|
+
* prefix and pre-release/build suffixes) or the em dash character `\u2014`
|
|
2363
|
+
* which serves as a sentinel: the "From" column uses `\u2014` for newly
|
|
2364
|
+
* added dependencies, and the "To" column uses it for removed ones.
|
|
2365
|
+
*
|
|
2366
|
+
* @example
|
|
2367
|
+
* ```typescript
|
|
2368
|
+
* import { Schema } from "effect";
|
|
2369
|
+
* import { VersionOrEmptySchema } from "@savvy-web/changesets";
|
|
2370
|
+
*
|
|
2371
|
+
* // Succeeds — semver version
|
|
2372
|
+
* Schema.decodeUnknownSync(VersionOrEmptySchema)("^3.19.1");
|
|
2373
|
+
*
|
|
2374
|
+
* // Succeeds — em dash sentinel for "no version"
|
|
2375
|
+
* Schema.decodeUnknownSync(VersionOrEmptySchema)("\u2014");
|
|
2376
|
+
*
|
|
2377
|
+
* // Throws ParseError — arbitrary text
|
|
2378
|
+
* Schema.decodeUnknownSync(VersionOrEmptySchema)("latest");
|
|
2379
|
+
* ```
|
|
2380
|
+
*
|
|
2381
|
+
* @public
|
|
2382
|
+
*/
|
|
2383
|
+
export declare const VersionOrEmptySchema: Schema.filter<typeof Schema.String>;
|
|
2384
|
+
|
|
853
2385
|
/**
|
|
854
2386
|
* Inferred type for {@link VersionTypeSchema}.
|
|
855
2387
|
*
|
|
2388
|
+
* @remarks
|
|
2389
|
+
* One of `"major"`, `"minor"`, `"patch"`, or `"none"`.
|
|
2390
|
+
*
|
|
856
2391
|
* @public
|
|
857
2392
|
*/
|
|
858
2393
|
export declare type VersionType = typeof VersionTypeSchema.Type;
|
|
@@ -860,6 +2395,22 @@ export declare type VersionType = typeof VersionTypeSchema.Type;
|
|
|
860
2395
|
/**
|
|
861
2396
|
* Semantic version bump type.
|
|
862
2397
|
*
|
|
2398
|
+
* @remarks
|
|
2399
|
+
* Represents the four possible version bump levels used by Changesets:
|
|
2400
|
+
* - `"major"` -- breaking changes (e.g., 1.x.x to 2.0.0)
|
|
2401
|
+
* - `"minor"` -- new features (e.g., 1.1.x to 1.2.0)
|
|
2402
|
+
* - `"patch"` -- bug fixes (e.g., 1.1.1 to 1.1.2)
|
|
2403
|
+
* - `"none"` -- no version bump (internal changes only)
|
|
2404
|
+
*
|
|
2405
|
+
* @example
|
|
2406
|
+
* ```typescript
|
|
2407
|
+
* import { Schema } from "effect";
|
|
2408
|
+
* import { VersionTypeSchema } from "@savvy-web/changesets";
|
|
2409
|
+
* import type { VersionType } from "@savvy-web/changesets";
|
|
2410
|
+
*
|
|
2411
|
+
* const bump: VersionType = Schema.decodeUnknownSync(VersionTypeSchema)("minor");
|
|
2412
|
+
* ```
|
|
2413
|
+
*
|
|
863
2414
|
* @public
|
|
864
2415
|
*/
|
|
865
2416
|
export declare const VersionTypeSchema: Schema.Literal<["major", "minor", "patch", "none"]>;
|