@savvy-web/silk-effects 0.6.1 → 1.0.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 +48 -17
- package/_virtual/_rolldown/runtime.js +18 -0
- package/changesets/api/categories.js +247 -0
- package/changesets/api/changelog.js +134 -0
- package/changesets/api/dependency-table.js +163 -0
- package/changesets/api/linter.js +168 -0
- package/changesets/api/transformer.js +140 -0
- package/changesets/categories/index.js +299 -0
- package/changesets/categories/types.js +66 -0
- package/changesets/changelog/formatting.js +119 -0
- package/changesets/changelog/getDependencyReleaseLine.js +114 -0
- package/changesets/changelog/getReleaseLine.js +122 -0
- package/changesets/changelog/index.js +99 -0
- package/changesets/constants.js +43 -0
- package/changesets/errors.js +305 -0
- package/changesets/index.js +146 -0
- package/changesets/markdownlint/index.js +29 -0
- package/changesets/markdownlint/rules/content-structure.js +98 -0
- package/changesets/markdownlint/rules/dependency-table-format.js +170 -0
- package/changesets/markdownlint/rules/heading-hierarchy.js +61 -0
- package/changesets/markdownlint/rules/required-sections.js +54 -0
- package/changesets/markdownlint/rules/uncategorized-content.js +54 -0
- package/changesets/markdownlint/rules/utils.js +30 -0
- package/changesets/remark/plugins/aggregate-dependency-tables.js +47 -0
- package/changesets/remark/plugins/contributor-footnotes.js +123 -0
- package/changesets/remark/plugins/deduplicate-items.js +30 -0
- package/changesets/remark/plugins/issue-link-refs.js +58 -0
- package/changesets/remark/plugins/merge-sections.js +43 -0
- package/changesets/remark/plugins/normalize-format.js +47 -0
- package/changesets/remark/plugins/reorder-sections.js +34 -0
- package/changesets/remark/presets.js +119 -0
- package/changesets/remark/rules/content-structure.js +22 -0
- package/changesets/remark/rules/dependency-table-format.js +40 -0
- package/changesets/remark/rules/heading-hierarchy.js +19 -0
- package/changesets/remark/rules/required-sections.js +17 -0
- package/changesets/remark/rules/uncategorized-content.js +31 -0
- package/changesets/schemas/changeset.js +146 -0
- package/changesets/schemas/dependency-table.js +189 -0
- package/changesets/schemas/git.js +69 -0
- package/changesets/schemas/github.js +175 -0
- package/changesets/schemas/options.js +182 -0
- package/changesets/schemas/package-scope.js +128 -0
- package/changesets/schemas/primitives.js +72 -0
- package/changesets/schemas/version-files.js +151 -0
- package/changesets/services/branch-analyzer.js +278 -0
- package/changesets/services/changelog.js +50 -0
- package/changesets/services/config-inspector.js +390 -0
- package/changesets/services/github.js +178 -0
- package/changesets/services/markdown.js +106 -0
- package/changesets/services/workspace-snapshot.js +182 -0
- package/changesets/utils/commit-parser.js +80 -0
- package/changesets/utils/dep-diff.js +77 -0
- package/changesets/utils/dependency-table.js +347 -0
- package/changesets/utils/issue-refs.js +101 -0
- package/changesets/utils/jsonpath.js +175 -0
- package/changesets/utils/logger.js +50 -0
- package/changesets/utils/markdown-link.js +57 -0
- package/changesets/utils/publishability.js +39 -0
- package/changesets/utils/remark-pipeline.js +79 -0
- package/changesets/utils/section-parser.js +94 -0
- package/changesets/utils/strip-frontmatter.js +46 -0
- package/changesets/utils/version-blocks.js +108 -0
- package/changesets/utils/version-files.js +336 -0
- package/changesets/utils/worktree-snapshot.js +142 -0
- package/changesets/vendor/github-info.js +55 -0
- package/commitlint/config/factory.js +69 -0
- package/commitlint/config/plugins.js +227 -0
- package/commitlint/config/rules.js +155 -0
- package/commitlint/config/schema.js +46 -0
- package/commitlint/detection/dco.js +53 -0
- package/commitlint/detection/scopes.js +45 -0
- package/commitlint/formatter/format.js +85 -0
- package/commitlint/formatter/messages.js +79 -0
- package/commitlint/hook/diagnostics/branch.js +36 -0
- package/commitlint/hook/diagnostics/cache.js +37 -0
- package/commitlint/hook/diagnostics/commitlint-config.js +36 -0
- package/commitlint/hook/diagnostics/open-issues.js +56 -0
- package/commitlint/hook/diagnostics/package-manager.js +51 -0
- package/commitlint/hook/diagnostics/signing.js +107 -0
- package/commitlint/hook/envelope.js +46 -0
- package/commitlint/hook/output.js +45 -0
- package/commitlint/hook/parse-bash-command.js +105 -0
- package/commitlint/hook/rules/closes-trailer.js +31 -0
- package/commitlint/hook/rules/forbidden-content.js +32 -0
- package/commitlint/hook/rules/plan-leakage.js +36 -0
- package/commitlint/hook/rules/signing-flag-conflict.js +25 -0
- package/commitlint/hook/rules/soft-wrap.js +37 -0
- package/commitlint/hook/rules/types.js +14 -0
- package/commitlint/hook/rules/verbosity.js +31 -0
- package/commitlint/hook/silence-logger.js +39 -0
- package/commitlint/index.js +146 -0
- package/commitlint/prompt/config.js +91 -0
- package/commitlint/prompt/emojis.js +74 -0
- package/commitlint/prompt/prompter.js +135 -0
- package/commitlint/static.js +73 -0
- package/errors/BiomeSyncError.js +21 -0
- package/errors/ChangesetConfigError.js +20 -0
- package/errors/ConfigNotFoundError.js +21 -0
- package/errors/SectionParseError.js +16 -0
- package/errors/SectionValidationError.js +16 -0
- package/errors/SectionWriteError.js +16 -0
- package/errors/TagFormatError.js +20 -0
- package/errors/ToolNotFoundError.js +11 -0
- package/errors/ToolResolutionError.js +11 -0
- package/errors/ToolVersionMismatchError.js +11 -0
- package/errors/VersioningDetectionError.js +20 -0
- package/errors/WorkspaceAnalysisError.js +21 -0
- package/index.d.ts +9743 -8380
- package/index.js +36 -6657
- package/lint/Handler.js +39 -0
- package/lint/cli/sections.js +65 -0
- package/lint/cli/templates/markdownlint.gen.js +183 -0
- package/lint/config/Preset.js +152 -0
- package/lint/config/createConfig.js +89 -0
- package/lint/handlers/Biome.js +179 -0
- package/lint/handlers/Markdown.js +139 -0
- package/lint/handlers/PackageJson.js +130 -0
- package/lint/handlers/PnpmWorkspace.js +141 -0
- package/lint/handlers/ShellScripts.js +58 -0
- package/lint/handlers/TypeScript.js +134 -0
- package/lint/handlers/Yaml.js +167 -0
- package/lint/index.js +52 -0
- package/lint/utils/Command.js +285 -0
- package/lint/utils/Filter.js +100 -0
- package/lint/utils/Workspace.js +86 -0
- package/package.json +52 -63
- package/schemas/CommentStyle.js +16 -0
- package/schemas/ResolvedTool.js +63 -0
- package/schemas/SavvySections.js +113 -0
- package/schemas/SectionBlock.js +70 -0
- package/schemas/SectionDefinition.js +121 -0
- package/schemas/SectionResults.js +12 -0
- package/schemas/TagStrategySchemas.js +18 -0
- package/schemas/ToolDefinition.js +39 -0
- package/schemas/ToolResults.js +14 -0
- package/schemas/VersioningSchemas.js +95 -0
- package/schemas/WorkspaceAnalysisSchemas.js +190 -0
- package/services/BiomeSchemaSync.js +133 -0
- package/services/ChangesetConfig.js +78 -0
- package/services/ChangesetConfigReader.js +106 -0
- package/services/ConfigDiscovery.js +71 -0
- package/services/ManagedSection.js +288 -0
- package/services/SilkPublishability.js +193 -0
- package/services/SilkWorkspaceAnalyzer.js +213 -0
- package/services/TagStrategy.js +54 -0
- package/services/ToolDiscovery.js +229 -0
- package/services/VersioningStrategy.js +67 -0
- package/tsdoc-metadata.json +11 -11
- package/turbo/digest.js +127 -0
- package/turbo/errors.js +48 -0
- package/turbo/index.js +32 -0
- package/turbo/schemas/DryRun.js +57 -0
- package/turbo/schemas/results.js +61 -0
- package/turbo/services/TurboInspector.js +100 -0
- package/utils/ToolCommand.js +40 -0
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ Shared [Effect](https://effect.website/) library providing Silk Suite convention
|
|
|
13
13
|
- Discover and resolve CLI tools globally or locally with version enforcement and caching
|
|
14
14
|
- Detect versioning strategy and format git tags from changeset configuration
|
|
15
15
|
- Locate config files and keep Biome schema URLs in sync across workspaces
|
|
16
|
+
- Inspect a Turborepo read-only — diagnose per-package cache hits, derive the task graph and compute affected packages, all over `turbo --dry`
|
|
16
17
|
|
|
17
18
|
## Install
|
|
18
19
|
|
|
@@ -36,17 +37,21 @@ import {
|
|
|
36
37
|
} from "@savvy-web/silk-effects";
|
|
37
38
|
```
|
|
38
39
|
|
|
39
|
-
`SilkPublishability.detect` is a pure static — no layers, no Effect runtime. Pass a package name
|
|
40
|
+
`SilkPublishability.detect` is a pure static — no layers, no Effect runtime. Pass a package name, the raw `package.json` and the bundler's resolved target binding (or `null` before the prod build has run) and get back the publish targets the silk rules resolve:
|
|
40
41
|
|
|
41
42
|
```typescript
|
|
42
43
|
import { SilkPublishability } from "@savvy-web/silk-effects";
|
|
43
44
|
|
|
44
|
-
const targets = SilkPublishability.detect(
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
45
|
+
const targets = SilkPublishability.detect(
|
|
46
|
+
"@my-org/my-package",
|
|
47
|
+
{
|
|
48
|
+
private: true,
|
|
49
|
+
publishConfig: { access: "public", targets: { npm: true, github: true } },
|
|
50
|
+
},
|
|
51
|
+
null, // pre-build: one count-accurate placeholder per declared target key
|
|
52
|
+
);
|
|
53
|
+
// => [PublishTarget { name: "@my-org/my-package", registry: "https://registry.npmjs.org", ... },
|
|
54
|
+
// PublishTarget { name: "@my-org/my-package", registry: "https://npm.pkg.github.com", ... }]
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
## Services
|
|
@@ -61,23 +66,27 @@ These services are pure logic — no filesystem or shell access needed.
|
|
|
61
66
|
|
|
62
67
|
#### SilkPublishability
|
|
63
68
|
|
|
64
|
-
Apply silk publishability rules to a raw `package.json` and resolve
|
|
69
|
+
Apply silk publishability rules to a raw `package.json` and the bundler's resolved target binding, and resolve the publish targets. Targets are `PublishTarget` records from `workspaces-effect` with `name`, `registry`, `directory`, `access` and `provenance` fields. The static `detect` helper is pure; `resolveTargets` and `listPublishable` are Effects that read from disk (see below), and `readTargetsBinding` reads the binding `detect` consumes.
|
|
65
70
|
|
|
66
|
-
In silk mode `private: true` is the norm on workspace `package.json` files. Publishability is derived from `publishConfig`, with the `private` flag consulted only as a last-resort default.
|
|
71
|
+
In silk mode `private: true` is the norm on workspace `package.json` files. Publishability is derived from `publishConfig`, with the `private` flag consulted only as a last-resort default. Publish targets are declared as the bundler's keyed `publishConfig.targets` map; the legacy array form is no longer supported.
|
|
67
72
|
|
|
68
73
|
```typescript
|
|
69
74
|
import { SilkPublishability } from "@savvy-web/silk-effects";
|
|
70
75
|
|
|
71
|
-
// Targets-first: one PublishTarget per
|
|
72
|
-
const targets = SilkPublishability.detect(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
// Targets-first: one PublishTarget per declared publishConfig.targets key
|
|
77
|
+
const targets = SilkPublishability.detect(
|
|
78
|
+
"@my-org/pkg",
|
|
79
|
+
{
|
|
80
|
+
private: true,
|
|
81
|
+
publishConfig: { access: "public", targets: { npm: true, github: true } },
|
|
82
|
+
},
|
|
83
|
+
null, // pre-build placeholder; pass the dist/prod/targets.json binding post-build
|
|
84
|
+
);
|
|
85
|
+
// => [PublishTarget { registry: "https://registry.npmjs.org", access: "public", ... },
|
|
86
|
+
// PublishTarget { registry: "https://npm.pkg.github.com", access: "public", ... }]
|
|
78
87
|
|
|
79
88
|
// Not publishable -> empty array
|
|
80
|
-
const none = SilkPublishability.detect("@my-org/internal", { private: true });
|
|
89
|
+
const none = SilkPublishability.detect("@my-org/internal", { private: true }, null);
|
|
81
90
|
// => []
|
|
82
91
|
```
|
|
83
92
|
|
|
@@ -379,6 +388,28 @@ const biome = yield* td.require(
|
|
|
379
388
|
);
|
|
380
389
|
```
|
|
381
390
|
|
|
391
|
+
#### TurboInspector
|
|
392
|
+
|
|
393
|
+
Read-only Turborepo inspection. Every method shells out to `turbo` with `--dry=json`, so no task ever runs. `diagnoseCache(task, cwd)` reports a per-package cache HIT/MISS breakdown for a task, `taskGraph(cwd, task?)` derives the task graph and its critical path and `affected(cwd, base?)` lists the packages affected relative to `base` (default `main`). It resolves the `turbo` binary through `ToolDiscovery` and fails with a tagged error when `turbo` is missing or the directory is not a Turborepo. The service tag and its layer are exported under the `Turbo` namespace.
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
import { Effect } from "effect";
|
|
397
|
+
import { NodeContext } from "@effect/platform-node";
|
|
398
|
+
import { Turbo, ToolDiscoveryLive } from "@savvy-web/silk-effects";
|
|
399
|
+
|
|
400
|
+
const diagnosis = await Effect.runPromise(
|
|
401
|
+
Effect.gen(function* () {
|
|
402
|
+
const turbo = yield* Turbo.TurboInspector;
|
|
403
|
+
return yield* turbo.diagnoseCache("build:dev", process.cwd());
|
|
404
|
+
}).pipe(
|
|
405
|
+
Effect.provide(Turbo.TurboInspectorLive),
|
|
406
|
+
Effect.provide(ToolDiscoveryLive),
|
|
407
|
+
Effect.provide(NodeContext.layer),
|
|
408
|
+
),
|
|
409
|
+
);
|
|
410
|
+
// => CacheDiagnosis: per-package HIT/MISS breakdown for the task
|
|
411
|
+
```
|
|
412
|
+
|
|
382
413
|
## Documentation
|
|
383
414
|
|
|
384
415
|
- [Overview](./docs/overview.md) — what the library is, its design philosophy and platform-layer model
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) {
|
|
6
|
+
__defProp(target, name, {
|
|
7
|
+
get: all[name],
|
|
8
|
+
enumerable: true
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
if (!no_symbols) {
|
|
12
|
+
__defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
13
|
+
}
|
|
14
|
+
return target;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { __exportAll };
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
import { BREAKING_CHANGES, BUG_FIXES, BUILD_SYSTEM, CATEGORIES, CI, DEPENDENCIES, DOCUMENTATION, FEATURES, MAINTENANCE, OTHER, PERFORMANCE, REFACTORING, REVERTS, TESTS, allHeadings, fromHeading, isValidHeading, resolveCommitType } from "../categories/index.js";
|
|
2
|
+
|
|
3
|
+
//#region src/changesets/api/categories.ts
|
|
4
|
+
/**
|
|
5
|
+
* Class-based API wrapper for section categories.
|
|
6
|
+
*
|
|
7
|
+
* Provides a static class interface that bridges to the underlying
|
|
8
|
+
* Effect-native category functions for higher-level consumers.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Static class wrapper for section category operations.
|
|
14
|
+
*
|
|
15
|
+
* Provides methods for resolving conventional commit types to changelog
|
|
16
|
+
* section categories, validating section headings, and accessing the
|
|
17
|
+
* canonical set of 13 section categories used throughout the pipeline.
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* This class wraps the pure functions and constants from the internal
|
|
21
|
+
* `categories/` module. Each {@link SectionCategory} is defined by the
|
|
22
|
+
* {@link SectionCategorySchema} Effect Schema, which provides runtime
|
|
23
|
+
* validation at system boundaries. The class itself is stateless; all
|
|
24
|
+
* methods and properties are `static`.
|
|
25
|
+
*
|
|
26
|
+
* Categories control how changelog entries are grouped and ordered.
|
|
27
|
+
* Lower priority numbers appear first in the output. The 13 built-in
|
|
28
|
+
* categories cover all conventional commit types plus special cases
|
|
29
|
+
* like dependency updates and breaking changes.
|
|
30
|
+
*
|
|
31
|
+
* @example Looking up categories from commit metadata
|
|
32
|
+
* ```typescript
|
|
33
|
+
* import { Categories } from "\@savvy-web/changesets";
|
|
34
|
+
* import type { SectionCategory } from "\@savvy-web/changesets";
|
|
35
|
+
*
|
|
36
|
+
* // Resolve a conventional commit type to its category
|
|
37
|
+
* const feature: SectionCategory = Categories.fromCommitType("feat");
|
|
38
|
+
* // feature.heading === "Features"
|
|
39
|
+
* // feature.priority === 2
|
|
40
|
+
*
|
|
41
|
+
* // Breaking changes always win regardless of commit type
|
|
42
|
+
* const breaking: SectionCategory = Categories.fromCommitType("fix", undefined, true);
|
|
43
|
+
* // breaking.heading === "Breaking Changes"
|
|
44
|
+
* // breaking.priority === 1
|
|
45
|
+
*
|
|
46
|
+
* // The special scope "deps" on "chore" maps to Dependencies
|
|
47
|
+
* const deps: SectionCategory = Categories.fromCommitType("chore", "deps");
|
|
48
|
+
* // deps.heading === "Dependencies"
|
|
49
|
+
* ```
|
|
50
|
+
*
|
|
51
|
+
* @example Validating section headings
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { Categories } from "\@savvy-web/changesets";
|
|
54
|
+
*
|
|
55
|
+
* const headings: readonly string[] = Categories.allHeadings();
|
|
56
|
+
* // ["Breaking Changes", "Features", "Bug Fixes", ...]
|
|
57
|
+
*
|
|
58
|
+
* const valid: boolean = Categories.isValidHeading("Bug Fixes");
|
|
59
|
+
* // true
|
|
60
|
+
*
|
|
61
|
+
* const unknown: boolean = Categories.isValidHeading("Miscellaneous");
|
|
62
|
+
* // false
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @example Reverse-lookup from heading text
|
|
66
|
+
* ```typescript
|
|
67
|
+
* import { Categories } from "\@savvy-web/changesets";
|
|
68
|
+
* import type { SectionCategory } from "\@savvy-web/changesets";
|
|
69
|
+
*
|
|
70
|
+
* const category: SectionCategory | undefined = Categories.fromHeading("Features");
|
|
71
|
+
* if (category) {
|
|
72
|
+
* const commitTypes: readonly string[] = category.commitTypes;
|
|
73
|
+
* // ["feat"]
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*
|
|
77
|
+
* @see {@link SectionCategory} for the category shape (heading, priority, commitTypes, description)
|
|
78
|
+
* @see {@link SectionCategorySchema} for the Effect Schema that validates category data
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
var Categories = class {
|
|
83
|
+
constructor() {}
|
|
84
|
+
/**
|
|
85
|
+
* Breaking changes -- backward-incompatible changes (priority 1).
|
|
86
|
+
*
|
|
87
|
+
* @remarks
|
|
88
|
+
* Mapped from any commit type when the `breaking` flag is `true`.
|
|
89
|
+
* Always appears first in changelog output.
|
|
90
|
+
*/
|
|
91
|
+
static BREAKING_CHANGES = BREAKING_CHANGES;
|
|
92
|
+
/**
|
|
93
|
+
* Features -- new functionality (priority 2).
|
|
94
|
+
*
|
|
95
|
+
* @remarks
|
|
96
|
+
* Mapped from the `feat` commit type.
|
|
97
|
+
*/
|
|
98
|
+
static FEATURES = FEATURES;
|
|
99
|
+
/**
|
|
100
|
+
* Bug Fixes -- bug corrections (priority 3).
|
|
101
|
+
*
|
|
102
|
+
* @remarks
|
|
103
|
+
* Mapped from the `fix` commit type.
|
|
104
|
+
*/
|
|
105
|
+
static BUG_FIXES = BUG_FIXES;
|
|
106
|
+
/**
|
|
107
|
+
* Performance -- performance improvements (priority 4).
|
|
108
|
+
*
|
|
109
|
+
* @remarks
|
|
110
|
+
* Mapped from the `perf` commit type.
|
|
111
|
+
*/
|
|
112
|
+
static PERFORMANCE = PERFORMANCE;
|
|
113
|
+
/**
|
|
114
|
+
* Documentation -- documentation changes (priority 5).
|
|
115
|
+
*
|
|
116
|
+
* @remarks
|
|
117
|
+
* Mapped from the `docs` commit type.
|
|
118
|
+
*/
|
|
119
|
+
static DOCUMENTATION = DOCUMENTATION;
|
|
120
|
+
/**
|
|
121
|
+
* Refactoring -- code restructuring (priority 6).
|
|
122
|
+
*
|
|
123
|
+
* @remarks
|
|
124
|
+
* Mapped from the `refactor` commit type.
|
|
125
|
+
*/
|
|
126
|
+
static REFACTORING = REFACTORING;
|
|
127
|
+
/**
|
|
128
|
+
* Tests -- test additions or modifications (priority 7).
|
|
129
|
+
*
|
|
130
|
+
* @remarks
|
|
131
|
+
* Mapped from the `test` commit type.
|
|
132
|
+
*/
|
|
133
|
+
static TESTS = TESTS;
|
|
134
|
+
/**
|
|
135
|
+
* Build System -- build configuration changes (priority 8).
|
|
136
|
+
*
|
|
137
|
+
* @remarks
|
|
138
|
+
* Mapped from the `build` commit type.
|
|
139
|
+
*/
|
|
140
|
+
static BUILD_SYSTEM = BUILD_SYSTEM;
|
|
141
|
+
/**
|
|
142
|
+
* CI -- continuous integration changes (priority 9).
|
|
143
|
+
*
|
|
144
|
+
* @remarks
|
|
145
|
+
* Mapped from the `ci` commit type.
|
|
146
|
+
*/
|
|
147
|
+
static CI = CI;
|
|
148
|
+
/**
|
|
149
|
+
* Dependencies -- dependency updates (priority 10).
|
|
150
|
+
*
|
|
151
|
+
* @remarks
|
|
152
|
+
* Mapped from `chore(deps)` and similar dependency-scoped commits.
|
|
153
|
+
*/
|
|
154
|
+
static DEPENDENCIES = DEPENDENCIES;
|
|
155
|
+
/**
|
|
156
|
+
* Maintenance -- general maintenance (priority 11).
|
|
157
|
+
*
|
|
158
|
+
* @remarks
|
|
159
|
+
* Mapped from the `chore` commit type (without the `deps` scope).
|
|
160
|
+
*/
|
|
161
|
+
static MAINTENANCE = MAINTENANCE;
|
|
162
|
+
/**
|
|
163
|
+
* Reverts -- reverted changes (priority 12).
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Mapped from the `revert` commit type.
|
|
167
|
+
*/
|
|
168
|
+
static REVERTS = REVERTS;
|
|
169
|
+
/**
|
|
170
|
+
* Other -- uncategorized changes (priority 13).
|
|
171
|
+
*
|
|
172
|
+
* @remarks
|
|
173
|
+
* Fallback category for unrecognized commit types. Always appears
|
|
174
|
+
* last in changelog output.
|
|
175
|
+
*/
|
|
176
|
+
static OTHER = OTHER;
|
|
177
|
+
/**
|
|
178
|
+
* All 13 categories ordered by priority (ascending, 1-13).
|
|
179
|
+
*
|
|
180
|
+
* @remarks
|
|
181
|
+
* This array is frozen and sorted from highest priority (Breaking Changes)
|
|
182
|
+
* to lowest (Other). Useful for iterating over categories in display order.
|
|
183
|
+
*/
|
|
184
|
+
static ALL = CATEGORIES;
|
|
185
|
+
/**
|
|
186
|
+
* Resolve a conventional commit type to its section category.
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* Resolution follows a precedence chain:
|
|
190
|
+
*
|
|
191
|
+
* 1. If `breaking` is `true`, always returns {@link Categories.BREAKING_CHANGES}
|
|
192
|
+
* 2. If `type` is `"chore"` and `scope` is `"deps"`, returns {@link Categories.DEPENDENCIES}
|
|
193
|
+
* 3. Otherwise, looks up `type` in the `commitTypes` arrays of all categories
|
|
194
|
+
* 4. Falls back to {@link Categories.OTHER} for unrecognized types
|
|
195
|
+
*
|
|
196
|
+
* @param type - The conventional commit type (e.g., `"feat"`, `"fix"`, `"chore"`)
|
|
197
|
+
* @param scope - Optional commit scope (e.g., `"deps"` from `chore(deps):`)
|
|
198
|
+
* @param breaking - Whether the commit includes a breaking change indicator (`!`)
|
|
199
|
+
* @returns The resolved {@link SectionCategory}
|
|
200
|
+
*/
|
|
201
|
+
static fromCommitType(type, scope, breaking) {
|
|
202
|
+
return resolveCommitType(type, scope, breaking);
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Look up a category by its section heading text.
|
|
206
|
+
*
|
|
207
|
+
* @remarks
|
|
208
|
+
* Comparison is case-insensitive. For example, both `"Bug Fixes"` and
|
|
209
|
+
* `"bug fixes"` will match {@link Categories.BUG_FIXES}.
|
|
210
|
+
*
|
|
211
|
+
* @param heading - The heading text (e.g., `"Features"`, `"Bug Fixes"`)
|
|
212
|
+
* @returns The matching {@link SectionCategory}, or `undefined` if the heading
|
|
213
|
+
* does not correspond to any known category
|
|
214
|
+
*/
|
|
215
|
+
static fromHeading(heading) {
|
|
216
|
+
return fromHeading(heading);
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Get all valid section heading strings in priority order.
|
|
220
|
+
*
|
|
221
|
+
* @remarks
|
|
222
|
+
* Returns the `heading` field from each category in {@link Categories.ALL},
|
|
223
|
+
* preserving priority order. Useful for building validation sets or
|
|
224
|
+
* rendering category pickers.
|
|
225
|
+
*
|
|
226
|
+
* @returns Readonly array of heading strings (e.g., `["Breaking Changes", "Features", ...]`)
|
|
227
|
+
*/
|
|
228
|
+
static allHeadings() {
|
|
229
|
+
return allHeadings();
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* Check whether a heading string matches a known category.
|
|
233
|
+
*
|
|
234
|
+
* @remarks
|
|
235
|
+
* Comparison is case-insensitive. Equivalent to
|
|
236
|
+
* `Categories.fromHeading(heading) !== undefined`.
|
|
237
|
+
*
|
|
238
|
+
* @param heading - The heading text to validate
|
|
239
|
+
* @returns `true` if the heading matches a known category, `false` otherwise
|
|
240
|
+
*/
|
|
241
|
+
static isValidHeading(heading) {
|
|
242
|
+
return isValidHeading(heading);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
//#endregion
|
|
247
|
+
export { Categories };
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import changelogFunctions from "../changelog/index.js";
|
|
2
|
+
|
|
3
|
+
//#region src/changesets/api/changelog.ts
|
|
4
|
+
/**
|
|
5
|
+
* Class-based API wrapper for changelog formatting.
|
|
6
|
+
*
|
|
7
|
+
* Provides a static class interface that delegates to the underlying
|
|
8
|
+
* Changesets API-compatible default export.
|
|
9
|
+
*
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Static class wrapper for changelog formatting operations.
|
|
14
|
+
*
|
|
15
|
+
* Delegates to the Changesets-compatible `getReleaseLine` and
|
|
16
|
+
* `getDependencyReleaseLine` functions. Internally, these use the
|
|
17
|
+
* {@link ChangelogService} Effect service layer, which coordinates
|
|
18
|
+
* the {@link GitHubService} (for commit/PR metadata) and
|
|
19
|
+
* {@link MarkdownService} (for AST manipulation) to produce
|
|
20
|
+
* structured changelog entries.
|
|
21
|
+
*
|
|
22
|
+
* @remarks
|
|
23
|
+
* This class provides the same formatting capabilities as the
|
|
24
|
+
* `\@savvy-web/changesets/changelog` subpath export, but through a
|
|
25
|
+
* class-based API rather than the Changesets default-export convention.
|
|
26
|
+
* The underlying formatter parses conventional commit prefixes from the
|
|
27
|
+
* changeset summary to determine the section category (via
|
|
28
|
+
* {@link Categories}), resolves GitHub metadata (authors, PR links,
|
|
29
|
+
* commit hashes), and produces markdown output grouped by category.
|
|
30
|
+
*
|
|
31
|
+
* The `options` parameter must include a `repo` field in `"owner/repo"`
|
|
32
|
+
* format (e.g., `"savvy-web/changesets"`) so that GitHub links can be
|
|
33
|
+
* constructed. Additional options are defined by {@link ChangesetOptionsSchema}.
|
|
34
|
+
*
|
|
35
|
+
* @example Formatting a single changeset release line
|
|
36
|
+
* ```typescript
|
|
37
|
+
* import { Changelog } from "\@savvy-web/changesets";
|
|
38
|
+
*
|
|
39
|
+
* const changeset = {
|
|
40
|
+
* id: "brave-pandas-learn",
|
|
41
|
+
* summary: "feat: add token refresh endpoint",
|
|
42
|
+
* releases: [{ name: "\@savvy-web/auth", type: "minor" as const }],
|
|
43
|
+
* commit: "abc1234567890abcdef1234567890abcdef123456",
|
|
44
|
+
* };
|
|
45
|
+
*
|
|
46
|
+
* const line: string = await Changelog.formatReleaseLine(changeset, "minor", {
|
|
47
|
+
* repo: "savvy-web/auth",
|
|
48
|
+
* });
|
|
49
|
+
* // line contains a markdown bullet under the "Features" section heading
|
|
50
|
+
* ```
|
|
51
|
+
*
|
|
52
|
+
* @example Formatting dependency update lines
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { Changelog } from "\@savvy-web/changesets";
|
|
55
|
+
*
|
|
56
|
+
* const changesets = [
|
|
57
|
+
* {
|
|
58
|
+
* id: "cool-dogs-fly",
|
|
59
|
+
* summary: "chore(deps): update effect to 3.20.0",
|
|
60
|
+
* releases: [{ name: "\@savvy-web/core", type: "patch" as const }],
|
|
61
|
+
* commit: "def4567890abcdef1234567890abcdef456789ab",
|
|
62
|
+
* },
|
|
63
|
+
* ];
|
|
64
|
+
*
|
|
65
|
+
* const dependenciesUpdated = [
|
|
66
|
+
* {
|
|
67
|
+
* name: "\@savvy-web/utils",
|
|
68
|
+
* type: "patch" as const,
|
|
69
|
+
* oldVersion: "1.2.0",
|
|
70
|
+
* newVersion: "1.2.1",
|
|
71
|
+
* changesets: ["cool-dogs-fly"],
|
|
72
|
+
* packageJson: { name: "\@savvy-web/utils", version: "1.2.1" },
|
|
73
|
+
* },
|
|
74
|
+
* ];
|
|
75
|
+
*
|
|
76
|
+
* const depLines: string = await Changelog.formatDependencyReleaseLine(
|
|
77
|
+
* changesets,
|
|
78
|
+
* dependenciesUpdated,
|
|
79
|
+
* { repo: "savvy-web/core" },
|
|
80
|
+
* );
|
|
81
|
+
* // depLines contains a markdown table of dependency changes
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @see {@link ChangelogService} for the underlying Effect service
|
|
85
|
+
* @see {@link Categories} for how commit types map to section headings
|
|
86
|
+
* @see {@link ChangesetOptionsSchema} for the full options schema
|
|
87
|
+
*
|
|
88
|
+
* @public
|
|
89
|
+
*/
|
|
90
|
+
var Changelog = class {
|
|
91
|
+
/* v8 ignore next -- private constructor prevents direct instantiation */
|
|
92
|
+
constructor() {}
|
|
93
|
+
/**
|
|
94
|
+
* Format a single changeset into a changelog release line.
|
|
95
|
+
*
|
|
96
|
+
* @remarks
|
|
97
|
+
* Parses the changeset summary for a conventional commit prefix
|
|
98
|
+
* (e.g., `"feat: ..."`, `"fix!: ..."`), resolves the corresponding
|
|
99
|
+
* {@link SectionCategory}, and produces a markdown bullet item with
|
|
100
|
+
* optional GitHub metadata (author, PR link, commit hash).
|
|
101
|
+
*
|
|
102
|
+
* @param changeset - The changeset to format, including its `id`, `summary`,
|
|
103
|
+
* `releases` array, and optional `commit` hash
|
|
104
|
+
* @param versionType - The semantic version bump type (`"major"`, `"minor"`, or `"patch"`)
|
|
105
|
+
* @param options - Configuration object; must include `repo` in `"owner/repo"` format.
|
|
106
|
+
* Pass `null` to use defaults (no GitHub link resolution).
|
|
107
|
+
* @returns A promise resolving to the formatted markdown string
|
|
108
|
+
*/
|
|
109
|
+
static formatReleaseLine(changeset, versionType, options) {
|
|
110
|
+
return changelogFunctions.getReleaseLine(changeset, versionType, options);
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Format dependency update release lines into a markdown table.
|
|
114
|
+
*
|
|
115
|
+
* @remarks
|
|
116
|
+
* Generates a structured dependency table showing package names,
|
|
117
|
+
* version transitions, and dependency types. The table is placed
|
|
118
|
+
* under the "Dependencies" section heading in the changelog.
|
|
119
|
+
*
|
|
120
|
+
* @param changesets - The changesets that triggered the dependency updates
|
|
121
|
+
* @param dependenciesUpdated - Array of updated dependencies with their
|
|
122
|
+
* old/new versions and package metadata
|
|
123
|
+
* @param options - Configuration object; must include `repo` in `"owner/repo"` format.
|
|
124
|
+
* Pass `null` to use defaults.
|
|
125
|
+
* @returns A promise resolving to the formatted markdown string containing
|
|
126
|
+
* the dependency update table
|
|
127
|
+
*/
|
|
128
|
+
static formatDependencyReleaseLine(changesets, dependenciesUpdated, options) {
|
|
129
|
+
return changelogFunctions.getDependencyReleaseLine(changesets, dependenciesUpdated, options);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
//#endregion
|
|
134
|
+
export { Changelog };
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { collapseDependencyRows, parseDependencyTable, serializeDependencyTable, serializeDependencyTableToMarkdown, sortDependencyRows } from "../utils/dependency-table.js";
|
|
2
|
+
|
|
3
|
+
//#region src/changesets/api/dependency-table.ts
|
|
4
|
+
/**
|
|
5
|
+
* Static class for dependency table manipulation.
|
|
6
|
+
*
|
|
7
|
+
* Wraps the internal utility functions that operate on dependency tables --
|
|
8
|
+
* the structured markdown tables that appear in the "Dependencies" section
|
|
9
|
+
* of changelogs. Each row in a dependency table represents a single package
|
|
10
|
+
* change with its name, type, action, and version transition.
|
|
11
|
+
*
|
|
12
|
+
* @remarks
|
|
13
|
+
* The typical workflow for processing dependency tables is:
|
|
14
|
+
*
|
|
15
|
+
* 1. **Parse** an mdast `Table` node into typed {@link DependencyTableRow} objects
|
|
16
|
+
* 2. **Collapse** duplicate rows (same package updated multiple times) into single entries
|
|
17
|
+
* 3. **Sort** rows by dependency type, then alphabetically by package name
|
|
18
|
+
* 4. **Serialize** back to an mdast `Table` node or directly to a markdown string
|
|
19
|
+
*
|
|
20
|
+
* The {@link DependencyTable.aggregate} method combines the collapse and sort
|
|
21
|
+
* steps into a single call, which is the most common usage pattern.
|
|
22
|
+
*
|
|
23
|
+
* Each {@link DependencyTableRow} is validated by the {@link DependencyTableRowSchema}
|
|
24
|
+
* Effect Schema at system boundaries, ensuring that dependency names, types,
|
|
25
|
+
* actions, and version strings conform to expected formats.
|
|
26
|
+
*
|
|
27
|
+
* @example Parse, aggregate, and serialize a dependency table
|
|
28
|
+
* ```typescript
|
|
29
|
+
* import { DependencyTable } from "\@savvy-web/changesets";
|
|
30
|
+
* import type { DependencyTableRow } from "\@savvy-web/changesets";
|
|
31
|
+
* import type { Table } from "mdast";
|
|
32
|
+
*
|
|
33
|
+
* // Given an mdast Table node from a parsed CHANGELOG
|
|
34
|
+
* declare const tableNode: Table;
|
|
35
|
+
*
|
|
36
|
+
* // Parse into typed rows
|
|
37
|
+
* const rows: DependencyTableRow[] = DependencyTable.parse(tableNode);
|
|
38
|
+
*
|
|
39
|
+
* // Collapse duplicates and sort by type, then name
|
|
40
|
+
* const aggregated: DependencyTableRow[] = DependencyTable.aggregate(rows);
|
|
41
|
+
*
|
|
42
|
+
* // Serialize back to an mdast Table node for further AST manipulation
|
|
43
|
+
* const outputNode: Table = DependencyTable.serialize(aggregated);
|
|
44
|
+
*
|
|
45
|
+
* // Or serialize directly to a markdown string
|
|
46
|
+
* const markdown: string = DependencyTable.toMarkdown(aggregated);
|
|
47
|
+
* ```
|
|
48
|
+
*
|
|
49
|
+
* @example Step-by-step collapse and sort
|
|
50
|
+
* ```typescript
|
|
51
|
+
* import { DependencyTable } from "\@savvy-web/changesets";
|
|
52
|
+
* import type { DependencyTableRow } from "\@savvy-web/changesets";
|
|
53
|
+
*
|
|
54
|
+
* declare const rows: DependencyTableRow[];
|
|
55
|
+
*
|
|
56
|
+
* // Collapse duplicate entries (same package appears multiple times)
|
|
57
|
+
* const collapsed: DependencyTableRow[] = DependencyTable.collapse(rows);
|
|
58
|
+
*
|
|
59
|
+
* // Sort by dependency type, then alphabetically by name
|
|
60
|
+
* const sorted: DependencyTableRow[] = DependencyTable.sort(collapsed);
|
|
61
|
+
* ```
|
|
62
|
+
*
|
|
63
|
+
* @see {@link DependencyTableRow} for the row shape (dependency, type, action, from, to)
|
|
64
|
+
* @see {@link DependencyTableRowSchema} for the Effect Schema that validates row data
|
|
65
|
+
* @see {@link DependencyTableSchema} for the non-empty array schema
|
|
66
|
+
*
|
|
67
|
+
* @public
|
|
68
|
+
*/
|
|
69
|
+
var DependencyTable = class {
|
|
70
|
+
/* v8 ignore next -- private constructor prevents direct instantiation */
|
|
71
|
+
constructor() {}
|
|
72
|
+
/**
|
|
73
|
+
* Parse an mdast `Table` node into typed dependency table rows.
|
|
74
|
+
*
|
|
75
|
+
* @remarks
|
|
76
|
+
* Extracts the text content from each table cell and maps it to the
|
|
77
|
+
* corresponding {@link DependencyTableRow} fields. The first row is
|
|
78
|
+
* treated as the header and skipped. Rows that do not have the expected
|
|
79
|
+
* number of columns are ignored.
|
|
80
|
+
*
|
|
81
|
+
* @param tableNode - An mdast `Table` node from a parsed markdown AST
|
|
82
|
+
* @returns Array of {@link DependencyTableRow} objects, one per data row
|
|
83
|
+
*/
|
|
84
|
+
static parse(tableNode) {
|
|
85
|
+
return parseDependencyTable(tableNode);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Serialize typed dependency table rows into an mdast `Table` node.
|
|
89
|
+
*
|
|
90
|
+
* @remarks
|
|
91
|
+
* Produces a well-formed mdast `Table` with a header row
|
|
92
|
+
* (`Dependency | Type | Action | From | To`) followed by one data row
|
|
93
|
+
* per input entry. The resulting node can be inserted into a remark AST
|
|
94
|
+
* for further processing or stringification.
|
|
95
|
+
*
|
|
96
|
+
* @param rows - Array of {@link DependencyTableRow} objects to serialize
|
|
97
|
+
* @returns An mdast `Table` node ready for AST insertion
|
|
98
|
+
*/
|
|
99
|
+
static serialize(rows) {
|
|
100
|
+
return serializeDependencyTable(rows);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Serialize typed dependency table rows directly to a markdown string.
|
|
104
|
+
*
|
|
105
|
+
* @remarks
|
|
106
|
+
* Convenience method that combines {@link DependencyTable.serialize} with
|
|
107
|
+
* remark stringification. Produces a GFM-compatible markdown table string.
|
|
108
|
+
*
|
|
109
|
+
* @param rows - Array of {@link DependencyTableRow} objects to render
|
|
110
|
+
* @returns A markdown string containing the formatted table
|
|
111
|
+
*/
|
|
112
|
+
static toMarkdown(rows) {
|
|
113
|
+
return serializeDependencyTableToMarkdown(rows);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Collapse duplicate dependency rows into single entries.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* When a package appears in multiple rows (e.g., updated in separate
|
|
120
|
+
* changesets), this method merges them by keeping the earliest `from`
|
|
121
|
+
* version and the latest `to` version, producing a single row that
|
|
122
|
+
* represents the net change.
|
|
123
|
+
*
|
|
124
|
+
* @param rows - Array of {@link DependencyTableRow} objects, possibly with duplicates
|
|
125
|
+
* @returns A new array with duplicate packages collapsed into single rows
|
|
126
|
+
*/
|
|
127
|
+
static collapse(rows) {
|
|
128
|
+
return collapseDependencyRows(rows);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Sort dependency rows by action, type, and package name.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* Applies a three-level stable sort:
|
|
135
|
+
* 1. **Action** — `removed` first, then `updated`, then `added`
|
|
136
|
+
* 2. **Type** — alphabetically (e.g., `config` before `dependency`)
|
|
137
|
+
* 3. **Dependency name** — alphabetically within each action+type group
|
|
138
|
+
*
|
|
139
|
+
* @param rows - Array of {@link DependencyTableRow} objects to sort
|
|
140
|
+
* @returns A new array sorted by action, type, then name
|
|
141
|
+
*/
|
|
142
|
+
static sort(rows) {
|
|
143
|
+
return sortDependencyRows(rows);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Collapse duplicate rows and then sort the result.
|
|
147
|
+
*
|
|
148
|
+
* @remarks
|
|
149
|
+
* Equivalent to calling {@link DependencyTable.collapse} followed by
|
|
150
|
+
* {@link DependencyTable.sort}. This is the recommended method for
|
|
151
|
+
* preparing dependency table data for final output, as it produces
|
|
152
|
+
* a clean, deduplicated, and consistently ordered table.
|
|
153
|
+
*
|
|
154
|
+
* @param rows - Array of {@link DependencyTableRow} objects to aggregate
|
|
155
|
+
* @returns A new array with duplicates collapsed and rows sorted
|
|
156
|
+
*/
|
|
157
|
+
static aggregate(rows) {
|
|
158
|
+
return sortDependencyRows(collapseDependencyRows(rows));
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
//#endregion
|
|
163
|
+
export { DependencyTable };
|