@savvy-web/changesets 0.4.2 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -14,6 +14,7 @@ Custom changelog formatter and markdown processing pipeline for the Silk Suite.
14
14
  - **GitHub integration** -- Automatic PR links, commit references, and contributor attribution
15
15
  - **Version file syncing** -- Bump version fields in additional JSON files using glob patterns and JSONPath expressions
16
16
  - **Editor support** -- markdownlint rules for real-time validation in VS Code and CI
17
+ - **Dependency table format** -- Structured GFM tables for tracking dependency changes with automatic collapse, sort, and aggregation
17
18
  - **AI-agent-friendly errors** -- All lint and validation errors include inline fix instructions and documentation links, so AI agents can resolve issues without examining source code
18
19
 
19
20
  ## Installation
@@ -58,6 +59,21 @@ Added a new authentication system with OAuth2 support.
58
59
  - Updated integration test fixtures
59
60
  ```
60
61
 
62
+ Dependency updates use a structured table format:
63
+
64
+ ```markdown
65
+ ---
66
+ "@my/package": patch
67
+ ---
68
+
69
+ ## Dependencies
70
+
71
+ | Dependency | Type | Action | From | To |
72
+ | :--- | :--- | :--- | :--- | :--- |
73
+ | lodash | dependency | updated | ^4.17.20 | ^4.17.21 |
74
+ | prettier | devDependency | added | — | ^3.0.0 |
75
+ ```
76
+
61
77
  ## Documentation
62
78
 
63
79
  - [Section-Aware Pipeline](./docs/section-aware-pipeline.md) -- End-to-end walkthrough of how section-aware changesets flow through the pipeline
package/cjs/changelog.cjs CHANGED
@@ -165,6 +165,24 @@ var __webpack_modules__ = {
165
165
  }
166
166
  effect__rspack_import_0.Data.TaggedError("VersionFileError");
167
167
  },
168
+ "./src/schemas/dependency-table.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
169
+ __webpack_require__.d(__webpack_exports__, {
170
+ n8: ()=>DependencyTableRowSchema
171
+ });
172
+ var effect__rspack_import_0 = __webpack_require__("effect");
173
+ var _primitives_js__rspack_import_1 = __webpack_require__("./src/schemas/primitives.ts");
174
+ const DependencyActionSchema = effect__rspack_import_0.Schema.Literal("added", "updated", "removed");
175
+ const DependencyTableTypeSchema = effect__rspack_import_0.Schema.Literal("dependency", "devDependency", "peerDependency", "optionalDependency", "workspace", "config");
176
+ const VersionOrEmptySchema = effect__rspack_import_0.Schema.String.pipe(effect__rspack_import_0.Schema.pattern(/^(\u2014|[~^]?\d+\.\d+\.\d+(?:[-+.][\w.+-]*)?)$/));
177
+ const DependencyTableRowSchema = effect__rspack_import_0.Schema.Struct({
178
+ dependency: _primitives_js__rspack_import_1.u,
179
+ type: DependencyTableTypeSchema,
180
+ action: DependencyActionSchema,
181
+ from: VersionOrEmptySchema,
182
+ to: VersionOrEmptySchema
183
+ });
184
+ effect__rspack_import_0.Schema.Array(DependencyTableRowSchema).pipe(effect__rspack_import_0.Schema.minItems(1));
185
+ },
168
186
  "./src/schemas/github.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
169
187
  __webpack_require__.d(__webpack_exports__, {
170
188
  lo: ()=>GitHubInfoSchema
@@ -249,10 +267,11 @@ var __webpack_modules__ = {
249
267
  },
250
268
  "./src/schemas/primitives.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
251
269
  __webpack_require__.d(__webpack_exports__, {
252
- e: ()=>PositiveInteger
270
+ e: ()=>PositiveInteger,
271
+ u: ()=>NonEmptyString
253
272
  });
254
273
  var effect__rspack_import_0 = __webpack_require__("effect");
255
- effect__rspack_import_0.Schema.String.pipe(effect__rspack_import_0.Schema.minLength(1));
274
+ const NonEmptyString = effect__rspack_import_0.Schema.String.pipe(effect__rspack_import_0.Schema.minLength(1));
256
275
  const PositiveInteger = effect__rspack_import_0.Schema.Number.pipe(effect__rspack_import_0.Schema.int(), effect__rspack_import_0.Schema.positive());
257
276
  },
258
277
  "./src/schemas/version-files.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
@@ -312,6 +331,74 @@ var __webpack_modules__ = {
312
331
  stringify: (tree)=>effect__rspack_import_0.Effect.sync(()=>(0, _utils_remark_pipeline_js__rspack_import_1.FH)(tree))
313
332
  });
314
333
  },
334
+ "./src/utils/dependency-table.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
335
+ __webpack_require__.d(__webpack_exports__, {
336
+ S8: ()=>serializeDependencyTableToMarkdown
337
+ });
338
+ var effect__rspack_import_0 = __webpack_require__("effect");
339
+ __webpack_require__("mdast-util-to-string");
340
+ var remark_gfm__rspack_import_2 = __webpack_require__("remark-gfm");
341
+ var remark_gfm__rspack_import_2_default = /*#__PURE__*/ __webpack_require__.n(remark_gfm__rspack_import_2);
342
+ var remark_stringify__rspack_import_3 = __webpack_require__("remark-stringify");
343
+ var remark_stringify__rspack_import_3_default = /*#__PURE__*/ __webpack_require__.n(remark_stringify__rspack_import_3);
344
+ var unified__rspack_import_4 = __webpack_require__("unified");
345
+ var _schemas_dependency_table_js__rspack_import_5 = __webpack_require__("./src/schemas/dependency-table.ts");
346
+ const COLUMN_HEADERS = [
347
+ "Dependency",
348
+ "Type",
349
+ "Action",
350
+ "From",
351
+ "To"
352
+ ];
353
+ const COLUMN_KEYS = [
354
+ "dependency",
355
+ "type",
356
+ "action",
357
+ "from",
358
+ "to"
359
+ ];
360
+ effect__rspack_import_0.Schema.decodeUnknownSync(_schemas_dependency_table_js__rspack_import_5.n8);
361
+ function makeCell(text) {
362
+ return {
363
+ type: "tableCell",
364
+ children: [
365
+ {
366
+ type: "text",
367
+ value: text
368
+ }
369
+ ]
370
+ };
371
+ }
372
+ function makeRow(texts) {
373
+ return {
374
+ type: "tableRow",
375
+ children: texts.map(makeCell)
376
+ };
377
+ }
378
+ function serializeDependencyTable(rows) {
379
+ const headerRow = makeRow([
380
+ ...COLUMN_HEADERS
381
+ ]);
382
+ const dataRows = rows.map((row)=>makeRow(COLUMN_KEYS.map((key)=>row[key])));
383
+ return {
384
+ type: "table",
385
+ children: [
386
+ headerRow,
387
+ ...dataRows
388
+ ]
389
+ };
390
+ }
391
+ function serializeDependencyTableToMarkdown(rows) {
392
+ const table = serializeDependencyTable(rows);
393
+ const tree = {
394
+ type: "root",
395
+ children: [
396
+ table
397
+ ]
398
+ };
399
+ return (0, unified__rspack_import_4.unified)().use(remark_gfm__rspack_import_2_default()).use(remark_stringify__rspack_import_3_default()).stringify(tree).trim();
400
+ }
401
+ },
315
402
  "./src/utils/markdown-link.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
316
403
  __webpack_require__.d(__webpack_exports__, {
317
404
  W: ()=>extractUrlFromMarkdown,
@@ -416,44 +503,45 @@ var __webpack_exports__ = {};
416
503
  var schemas_options = __webpack_require__("./src/schemas/options.ts");
417
504
  var services_github = __webpack_require__("./src/services/github.ts");
418
505
  var markdown = __webpack_require__("./src/services/markdown.ts");
419
- function logWarning(message, ...args) {
420
- if ("u" > typeof process && process.env.VITEST) return;
421
- if ("u" > typeof process && "true" === process.env.GITHUB_ACTIONS) {
422
- const text = args.length > 0 ? `${message} ${args.join(" ")}` : message;
423
- console.warn(`::warning::${text}`);
424
- } else console.warn(message, ...args);
506
+ var dependency_table = __webpack_require__("./src/utils/dependency-table.ts");
507
+ const FIELD_MAP = [
508
+ [
509
+ "dependencies",
510
+ "dependency"
511
+ ],
512
+ [
513
+ "devDependencies",
514
+ "devDependency"
515
+ ],
516
+ [
517
+ "peerDependencies",
518
+ "peerDependency"
519
+ ],
520
+ [
521
+ "optionalDependencies",
522
+ "optionalDependency"
523
+ ]
524
+ ];
525
+ function inferDependencyType(dep) {
526
+ const pkg = dep.packageJson;
527
+ for (const [field, type] of FIELD_MAP){
528
+ const section = pkg[field];
529
+ if ("object" == typeof section && null !== section && dep.name in section) return type;
530
+ }
531
+ return "dependency";
425
532
  }
426
- function getDependencyReleaseLine(changesets, dependenciesUpdated, options) {
533
+ function getDependencyReleaseLine(_changesets, dependenciesUpdated, _options) {
427
534
  return external_effect_.Effect.gen(function*() {
428
535
  if (0 === dependenciesUpdated.length) return "";
429
- const github = yield* services_github.Xx;
430
- let apiFailures = 0;
431
- const totalWithCommit = changesets.filter((cs)=>cs.commit).length;
432
- const commitLinks = yield* external_effect_.Effect.forEach(changesets, (cs)=>{
433
- const commit = cs.commit;
434
- if (!commit) return external_effect_.Effect.succeed(null);
435
- return github.getInfo({
436
- commit,
437
- repo: options.repo
438
- }).pipe(external_effect_.Effect.map((info)=>info.links.commit), external_effect_.Effect.catchAll((error)=>{
439
- apiFailures++;
440
- logWarning(`Failed to fetch GitHub info for commit ${commit}:`, String(error));
441
- return external_effect_.Effect.succeed(`[\`${commit.substring(0, 7)}\`](https://github.com/${options.repo}/commit/${commit})`);
536
+ yield* services_github.Xx;
537
+ const rows = dependenciesUpdated.map((dep)=>({
538
+ dependency: dep.name,
539
+ type: inferDependencyType(dep),
540
+ action: "updated",
541
+ from: dep.oldVersion,
542
+ to: dep.newVersion
442
543
  }));
443
- }, {
444
- concurrency: 10
445
- });
446
- if (apiFailures > 0) {
447
- const successRate = ((totalWithCommit - apiFailures) / totalWithCommit * 100).toFixed(1);
448
- logWarning(`GitHub API calls completed with ${apiFailures}/${totalWithCommit} failures (${successRate}% success rate)`);
449
- }
450
- const validLinks = commitLinks.filter(Boolean);
451
- const changesetLink = validLinks.length > 0 ? `- Updated dependencies [${validLinks.join(", ")}]:` : "- Updated dependencies:";
452
- const updatedDependenciesList = dependenciesUpdated.map((dep)=>` - ${dep.name}@${dep.newVersion}`);
453
- return [
454
- changesetLink,
455
- ...updatedDependenciesList
456
- ].join("\n");
544
+ return (0, dependency_table.S8)(rows);
457
545
  });
458
546
  }
459
547
  var categories = __webpack_require__("./src/categories/index.ts");
@@ -495,6 +583,13 @@ var __webpack_exports__ = {};
495
583
  refs: extractIssueNumbers(REFS_ISSUE_PATTERN, commitMessage)
496
584
  };
497
585
  }
586
+ function logWarning(message, ...args) {
587
+ if ("u" > typeof process && process.env.VITEST) return;
588
+ if ("u" > typeof process && "true" === process.env.GITHUB_ACTIONS) {
589
+ const text = args.length > 0 ? `${message} ${args.join(" ")}` : message;
590
+ console.warn(`::warning::${text}`);
591
+ } else console.warn(message, ...args);
592
+ }
498
593
  var external_mdast_util_to_string_ = __webpack_require__("mdast-util-to-string");
499
594
  var remark_pipeline = __webpack_require__("./src/utils/remark-pipeline.ts");
500
595
  function parseChangesetSections(summary) {
@@ -1,8 +1,22 @@
1
1
  /**
2
- * Changesets API changelog formatter.
2
+ * Changesets API changelog formatter — `\@savvy-web/changesets/changelog`
3
3
  *
4
- * This module exports the `ChangelogFunctions` required by the Changesets API.
5
- * Configure in `.changeset/config.json`:
4
+ * This module is the default export consumed by the Changesets CLI via the
5
+ * `changelog` field in `.changeset/config.json`. It implements the
6
+ * `ChangelogFunctions` interface from `\@changesets/types`, wiring the
7
+ * Effect-based formatting pipeline into the async API that Changesets expects.
8
+ *
9
+ * @remarks
10
+ * The module composes two Effect programs — {@link getReleaseLine} and
11
+ * {@link getDependencyReleaseLine} — and runs each through
12
+ * `Effect.runPromise` with a merged layer of {@link GitHubLive} (for commit
13
+ * metadata) and {@link MarkdownLive} (for mdast parsing). Options are
14
+ * validated at the boundary via `validateChangesetOptions` before being
15
+ * passed to the formatters.
16
+ *
17
+ * ### Configuration
18
+ *
19
+ * Add the following to your `.changeset/config.json`:
6
20
  *
7
21
  * ```json
8
22
  * {
@@ -10,11 +24,46 @@
10
24
  * }
11
25
  * ```
12
26
  *
27
+ * The `repo` option is **required** and must be in `owner/repo` format.
28
+ *
29
+ * ### Pipeline
30
+ *
31
+ * 1. **Options validation** — the raw `options` object from the Changesets
32
+ * config is decoded through `ChangesetOptionsSchema`.
33
+ * 2. **Release line formatting** — each changeset is formatted by
34
+ * `getReleaseLine`, which resolves GitHub metadata, parses sections,
35
+ * and produces structured markdown with commit links and attribution.
36
+ * 3. **Dependency table formatting** — bulk dependency updates are
37
+ * formatted by `getDependencyReleaseLine` into a markdown table.
38
+ *
39
+ * @example Configuring in `.changeset/config.json`
40
+ * ```json
41
+ * {
42
+ * "$schema": "https://unpkg.com/\@changesets/config\@3.1.1/schema.json",
43
+ * "changelog": ["\@savvy-web/changesets/changelog", { "repo": "savvy-web/my-package" }],
44
+ * "commit": false,
45
+ * "access": "public"
46
+ * }
47
+ * ```
48
+ *
49
+ * @see {@link getReleaseLine} in `./getReleaseLine.ts` for individual changeset formatting
50
+ * @see {@link getDependencyReleaseLine} in `./getDependencyReleaseLine.ts` for dependency table formatting
51
+ *
13
52
  * @packageDocumentation
14
53
  */
15
54
 
16
55
  import { ChangelogFunctions } from '@changesets/types';
17
56
 
57
+ /**
58
+ * Changesets API `ChangelogFunctions` implementation.
59
+ *
60
+ * This object satisfies the `ChangelogFunctions` contract from
61
+ * `\@changesets/types`. Each method validates options, runs the
62
+ * corresponding Effect program with the merged service layer, and
63
+ * returns a `Promise<string>`.
64
+ *
65
+ * @internal
66
+ */
18
67
  declare const changelogFunctions: ChangelogFunctions;
19
68
  export default changelogFunctions;
20
69