@savvy-web/silk-effects 9.5.5 → 10.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/_virtual/_rolldown/runtime.js +1 -2
- package/changesets/api/categories.js +1 -2
- package/changesets/api/changelog.js +1 -2
- package/changesets/api/dependency-table.js +13 -14
- package/changesets/api/linter.js +24 -21
- package/changesets/api/transformer.js +39 -35
- package/changesets/categories/index.js +2 -3
- package/changesets/categories/types.js +3 -4
- package/changesets/changelog/formatting.js +1 -2
- package/changesets/changelog/getDependencyReleaseLine.js +2 -3
- package/changesets/changelog/getReleaseLine.js +1 -2
- package/changesets/changelog/index.js +3 -4
- package/changesets/changelog/vanilla.js +1 -2
- package/changesets/constants.js +2 -3
- package/changesets/errors.js +2 -3
- package/changesets/index.js +12 -42
- package/changesets/markdownlint/index.js +1 -2
- package/changesets/markdownlint/rules/content-structure.js +3 -4
- package/changesets/markdownlint/rules/dependency-table-format.js +1 -2
- package/changesets/markdownlint/rules/heading-hierarchy.js +3 -4
- package/changesets/markdownlint/rules/required-sections.js +3 -4
- package/changesets/markdownlint/rules/uncategorized-content.js +3 -4
- package/changesets/markdownlint/rules/utils.js +7 -8
- package/changesets/rules/content-structure.js +44 -0
- package/changesets/rules/dependency-table-format.js +54 -0
- package/changesets/rules/heading-hierarchy.js +37 -0
- package/changesets/rules/required-sections.js +34 -0
- package/changesets/rules/types.js +20 -0
- package/changesets/rules/uncategorized-content.js +30 -0
- package/changesets/schemas/changeset.js +2 -3
- package/changesets/schemas/dependency-table.js +1 -2
- package/changesets/schemas/deps-regen.js +1 -2
- package/changesets/schemas/git.js +1 -2
- package/changesets/schemas/github.js +1 -2
- package/changesets/schemas/options.js +1 -2
- package/changesets/schemas/package-scope.js +1 -2
- package/changesets/schemas/primitives.js +1 -2
- package/changesets/schemas/release-plan.js +1 -2
- package/changesets/schemas/version-files.js +1 -2
- package/changesets/services/branch-analyzer.js +1 -2
- package/changesets/services/changelog.js +1 -2
- package/changesets/services/config-inspector.js +1 -2
- package/changesets/services/deps-regen.js +1 -2
- package/changesets/services/github.js +1 -2
- package/changesets/services/maintenance-reason.js +1 -2
- package/changesets/services/release-planner.js +1 -2
- package/changesets/transforms/aggregate-dependency-tables.js +96 -0
- package/changesets/transforms/contributor-footnotes.js +290 -0
- package/changesets/transforms/deduplicate-items.js +47 -0
- package/changesets/transforms/issue-link-refs.js +47 -0
- package/changesets/transforms/maintenance-note.js +65 -0
- package/changesets/transforms/merge-sections.js +56 -0
- package/changesets/transforms/normalize-format.js +53 -0
- package/changesets/transforms/reorder-sections.js +53 -0
- package/changesets/utils/blocks.js +67 -0
- package/changesets/utils/commit-parser.js +1 -2
- package/changesets/utils/dep-diff.js +1 -2
- package/changesets/utils/dependency-section.js +1 -2
- package/changesets/utils/dependency-table.js +30 -38
- package/changesets/utils/git.js +1 -2
- package/changesets/utils/issue-refs.js +1 -2
- package/changesets/utils/jsonpath.js +1 -2
- package/changesets/utils/logger.js +1 -2
- package/changesets/utils/markdown-emit.js +12 -38
- package/changesets/utils/markdown-link.js +1 -2
- package/changesets/utils/publishability.js +1 -2
- package/changesets/utils/section-parser.js +1 -2
- package/changesets/utils/strip-frontmatter.js +1 -2
- package/changesets/utils/version-files.js +1 -2
- package/changesets/vendor/github-info.js +1 -2
- package/commitlint/config/factory.js +1 -2
- package/commitlint/config/plugins.js +1 -2
- package/commitlint/config/rules.js +1 -2
- package/commitlint/config/schema.js +1 -2
- package/commitlint/detection/dco.js +1 -2
- package/commitlint/detection/scopes.js +1 -2
- package/commitlint/formatter/format.js +1 -2
- package/commitlint/formatter/messages.js +1 -2
- package/commitlint/hook/diagnostics/branch.js +1 -2
- package/commitlint/hook/diagnostics/cache.js +1 -2
- package/commitlint/hook/diagnostics/commitlint-config.js +1 -2
- package/commitlint/hook/diagnostics/open-issues.js +1 -2
- package/commitlint/hook/diagnostics/package-manager.js +1 -2
- package/commitlint/hook/diagnostics/signing.js +1 -2
- package/commitlint/hook/envelope.js +1 -2
- package/commitlint/hook/output.js +1 -2
- package/commitlint/hook/parse-bash-command.js +1 -2
- package/commitlint/hook/rules/closes-trailer.js +1 -2
- package/commitlint/hook/rules/forbidden-content.js +1 -2
- package/commitlint/hook/rules/plan-leakage.js +1 -2
- package/commitlint/hook/rules/signing-flag-conflict.js +1 -2
- package/commitlint/hook/rules/soft-wrap.js +1 -2
- package/commitlint/hook/rules/types.js +1 -2
- package/commitlint/hook/rules/verbosity.js +1 -2
- package/commitlint/hook/silence-logger.js +1 -2
- package/commitlint/index.js +1 -2
- package/commitlint/prompt/config.js +1 -2
- package/commitlint/prompt/emojis.js +1 -2
- package/commitlint/prompt/prompter.js +1 -2
- package/commitlint/static.js +1 -2
- package/index.d.ts +141 -1450
- package/index.js +2 -2
- package/lint/Handler.js +1 -2
- package/lint/cli/sections.js +1 -2
- package/lint/cli/templates/markdownlint.gen.js +1 -2
- package/lint/config/Preset.js +1 -2
- package/lint/config/createConfig.js +1 -2
- package/lint/handlers/Biome.js +1 -2
- package/lint/handlers/Markdown.js +1 -2
- package/lint/handlers/PackageJson.js +1 -2
- package/lint/handlers/PnpmWorkspace.js +1 -2
- package/lint/handlers/ShellScripts.js +1 -2
- package/lint/handlers/TextFiles.js +1 -2
- package/lint/handlers/TypeScript.js +1 -2
- package/lint/handlers/Yaml.js +1 -2
- package/lint/index.js +1 -2
- package/lint/utils/Command.js +1 -2
- package/lint/utils/Filter.js +1 -2
- package/lint/utils/Workspace.js +1 -2
- package/package.json +15 -22
- package/repos/constants.js +1 -2
- package/repos/errors.js +1 -2
- package/repos/index.js +1 -2
- package/repos/schemas/drift.js +1 -2
- package/repos/schemas/manifest.js +1 -2
- package/repos/schemas/reports.js +1 -2
- package/repos/services/config-store.js +1 -2
- package/repos/services/drift.js +1 -2
- package/repos/services/lockdown.js +1 -2
- package/repos/services/manager.js +1 -2
- package/services/BiomeSchemaSync.js +1 -2
- package/services/ChangesetConfig.js +1 -2
- package/services/ChangesetConfigReader.js +1 -2
- package/services/ConfigDiscovery.js +1 -2
- package/services/SilkPublishability.js +147 -6
- package/services/SilkWorkspaceAnalyzer.js +1 -2
- package/turbo/digest.js +1 -2
- package/turbo/errors.js +1 -2
- package/turbo/index.js +1 -2
- package/turbo/schemas/DryRun.js +1 -2
- package/turbo/schemas/results.js +1 -2
- package/turbo/services/TurboInspector.js +1 -2
- package/changesets/remark/plugins/aggregate-dependency-tables.js +0 -99
- package/changesets/remark/plugins/contributor-footnotes.js +0 -335
- package/changesets/remark/plugins/deduplicate-items.js +0 -32
- package/changesets/remark/plugins/issue-link-refs.js +0 -58
- package/changesets/remark/plugins/maintenance-note.js +0 -75
- package/changesets/remark/plugins/merge-sections.js +0 -43
- package/changesets/remark/plugins/normalize-format.js +0 -47
- package/changesets/remark/plugins/reorder-sections.js +0 -49
- package/changesets/remark/presets.js +0 -119
- package/changesets/remark/rules/content-structure.js +0 -22
- package/changesets/remark/rules/dependency-table-format.js +0 -38
- package/changesets/remark/rules/heading-hierarchy.js +0 -19
- package/changesets/remark/rules/required-sections.js +0 -17
- package/changesets/remark/rules/uncategorized-content.js +0 -31
- package/changesets/utils/remark-pipeline.js +0 -36
- package/changesets/utils/version-blocks.js +0 -108
|
@@ -1,335 +0,0 @@
|
|
|
1
|
-
import { getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
-
import { visit } from "unist-util-visit";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/contributor-footnotes.ts
|
|
5
|
-
/**
|
|
6
|
-
* Pattern matching `Thanks @user!` at end of text.
|
|
7
|
-
*
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
const ATTRIBUTION_PLAIN_RE = /\s*Thanks @(\w[\w-]*)!$/;
|
|
11
|
-
/**
|
|
12
|
-
* Pattern matching `@user` mentions inside an existing Thanks section.
|
|
13
|
-
*
|
|
14
|
-
* @internal
|
|
15
|
-
*/
|
|
16
|
-
const MENTION_RE = /@(\w[\w-]*)/g;
|
|
17
|
-
/**
|
|
18
|
-
* Try to extract a linked attribution from the end of a paragraph's children.
|
|
19
|
-
* Pattern: text "...Thanks " + link "\@user" + text "!"
|
|
20
|
-
*
|
|
21
|
-
* @param children - The phrasing content children of a paragraph node
|
|
22
|
-
* @returns The contributor and the index to start removal from, or `undefined`
|
|
23
|
-
*
|
|
24
|
-
* @internal
|
|
25
|
-
*/
|
|
26
|
-
function extractLinkedAttribution(children) {
|
|
27
|
-
if (children.length < 3) return void 0;
|
|
28
|
-
const last = children[children.length - 1];
|
|
29
|
-
const secondLast = children[children.length - 2];
|
|
30
|
-
const thirdLast = children[children.length - 3];
|
|
31
|
-
if (last.type !== "text" || last.value !== "!") return void 0;
|
|
32
|
-
if (secondLast.type !== "link") return void 0;
|
|
33
|
-
const linkNode = secondLast;
|
|
34
|
-
if (linkNode.children.length !== 1 || linkNode.children[0].type !== "text") return void 0;
|
|
35
|
-
const linkText = linkNode.children[0].value;
|
|
36
|
-
if (!linkText.startsWith("@")) return void 0;
|
|
37
|
-
const username = linkText.slice(1);
|
|
38
|
-
if (thirdLast.type !== "text") return void 0;
|
|
39
|
-
const textNode = thirdLast;
|
|
40
|
-
if (!/\s*Thanks $/.test(textNode.value)) return void 0;
|
|
41
|
-
return {
|
|
42
|
-
contributor: {
|
|
43
|
-
username,
|
|
44
|
-
url: linkNode.url
|
|
45
|
-
},
|
|
46
|
-
removeFrom: children.length - 3
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Strip a trailing attribution (linked or plain) from a paragraph, adding
|
|
51
|
-
* the contributor to the map.
|
|
52
|
-
*
|
|
53
|
-
* @param para - The paragraph to inspect and mutate
|
|
54
|
-
* @param contributors - The per-block contributor accumulator
|
|
55
|
-
* @returns `true` when an attribution was found and removed
|
|
56
|
-
*
|
|
57
|
-
* @internal
|
|
58
|
-
*/
|
|
59
|
-
function stripAttribution(para, contributors) {
|
|
60
|
-
const linked = extractLinkedAttribution(para.children);
|
|
61
|
-
if (linked) {
|
|
62
|
-
const key = linked.contributor.username.toLowerCase();
|
|
63
|
-
if (!contributors.has(key)) contributors.set(key, linked.contributor);
|
|
64
|
-
const textNode = para.children[linked.removeFrom];
|
|
65
|
-
textNode.value = textNode.value.replace(/\s*Thanks $/, "");
|
|
66
|
-
para.children.splice(linked.removeFrom + 1, 2);
|
|
67
|
-
if (textNode.value === "") para.children.splice(linked.removeFrom, 1);
|
|
68
|
-
return true;
|
|
69
|
-
}
|
|
70
|
-
const last = para.children[para.children.length - 1];
|
|
71
|
-
if (last?.type === "text") {
|
|
72
|
-
const textNode = last;
|
|
73
|
-
const match = textNode.value.match(ATTRIBUTION_PLAIN_RE);
|
|
74
|
-
if (match) {
|
|
75
|
-
const username = match[1];
|
|
76
|
-
const key = username.toLowerCase();
|
|
77
|
-
if (!contributors.has(key)) contributors.set(key, {
|
|
78
|
-
username,
|
|
79
|
-
url: void 0
|
|
80
|
-
});
|
|
81
|
-
textNode.value = textNode.value.replace(ATTRIBUTION_PLAIN_RE, "");
|
|
82
|
-
if (textNode.value === "") para.children.pop();
|
|
83
|
-
return true;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Harvest every `@user` mention (linked or plain) from a node subtree.
|
|
90
|
-
* Used to absorb an existing `### Thanks` section so re-running the plugin
|
|
91
|
-
* is idempotent.
|
|
92
|
-
*
|
|
93
|
-
* @internal
|
|
94
|
-
*/
|
|
95
|
-
function harvestMentions(node, contributors) {
|
|
96
|
-
visit(node, (child) => {
|
|
97
|
-
if (child.type === "link") {
|
|
98
|
-
const link = child;
|
|
99
|
-
const only = link.children.length === 1 ? link.children[0] : void 0;
|
|
100
|
-
if (only?.type === "text" && only.value.startsWith("@")) {
|
|
101
|
-
const username = only.value.slice(1);
|
|
102
|
-
const key = username.toLowerCase();
|
|
103
|
-
if (!contributors.has(key)) contributors.set(key, {
|
|
104
|
-
username,
|
|
105
|
-
url: link.url
|
|
106
|
-
});
|
|
107
|
-
return "skip";
|
|
108
|
-
}
|
|
109
|
-
} else if (child.type === "text") for (const match of child.value.matchAll(MENTION_RE)) {
|
|
110
|
-
const key = match[1].toLowerCase();
|
|
111
|
-
if (!contributors.has(key)) contributors.set(key, {
|
|
112
|
-
username: match[1],
|
|
113
|
-
url: void 0
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
/**
|
|
119
|
-
* Build the `Thanks to ... for their contributions!` summary paragraph.
|
|
120
|
-
*
|
|
121
|
-
* @internal
|
|
122
|
-
*/
|
|
123
|
-
function buildSummaryParagraph(contributors) {
|
|
124
|
-
const sorted = [...contributors.values()].sort((a, b) => a.username.toLowerCase().localeCompare(b.username.toLowerCase()));
|
|
125
|
-
const phrasingChildren = [];
|
|
126
|
-
phrasingChildren.push({
|
|
127
|
-
type: "text",
|
|
128
|
-
value: "Thanks to "
|
|
129
|
-
});
|
|
130
|
-
for (let i = 0; i < sorted.length; i++) {
|
|
131
|
-
const contrib = sorted[i];
|
|
132
|
-
if (i > 0 && sorted.length > 2) phrasingChildren.push({
|
|
133
|
-
type: "text",
|
|
134
|
-
value: ", "
|
|
135
|
-
});
|
|
136
|
-
if (i > 0 && i === sorted.length - 1) phrasingChildren.push({
|
|
137
|
-
type: "text",
|
|
138
|
-
value: sorted.length === 2 ? " and " : "and "
|
|
139
|
-
});
|
|
140
|
-
if (contrib.url) phrasingChildren.push({
|
|
141
|
-
type: "link",
|
|
142
|
-
url: contrib.url,
|
|
143
|
-
children: [{
|
|
144
|
-
type: "text",
|
|
145
|
-
value: `@${contrib.username}`
|
|
146
|
-
}]
|
|
147
|
-
});
|
|
148
|
-
else phrasingChildren.push({
|
|
149
|
-
type: "text",
|
|
150
|
-
value: `@${contrib.username}`
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
phrasingChildren.push({
|
|
154
|
-
type: "text",
|
|
155
|
-
value: " for their contributions!"
|
|
156
|
-
});
|
|
157
|
-
return {
|
|
158
|
-
type: "paragraph",
|
|
159
|
-
children: phrasingChildren
|
|
160
|
-
};
|
|
161
|
-
}
|
|
162
|
-
/**
|
|
163
|
-
* Remove list items (recursively) whose content was emptied by attribution
|
|
164
|
-
* stripping — a bullet that held ONLY `Thanks @user!` must not survive as a
|
|
165
|
-
* bare `- ` husk. Runs in both the `thanks: true` and `thanks: false` paths,
|
|
166
|
-
* since stripping is unconditional.
|
|
167
|
-
*
|
|
168
|
-
* @internal
|
|
169
|
-
*/
|
|
170
|
-
function pruneEmptiedListItems(list) {
|
|
171
|
-
list.children = list.children.filter((item) => {
|
|
172
|
-
item.children = item.children.filter((child) => {
|
|
173
|
-
if (child.type === "paragraph") return child.children.length > 0;
|
|
174
|
-
if (child.type === "list") {
|
|
175
|
-
const nested = child;
|
|
176
|
-
pruneEmptiedListItems(nested);
|
|
177
|
-
return nested.children.length > 0;
|
|
178
|
-
}
|
|
179
|
-
return true;
|
|
180
|
-
});
|
|
181
|
-
return item.children.length > 0;
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Text form of a paragraph: concatenated text values, with single-text link
|
|
186
|
-
* children flattened to their label. Returns `undefined` when the paragraph
|
|
187
|
-
* holds anything other than text and simple text-labelled links.
|
|
188
|
-
*
|
|
189
|
-
* @internal
|
|
190
|
-
*/
|
|
191
|
-
function flattenToText(para) {
|
|
192
|
-
let out = "";
|
|
193
|
-
for (const child of para.children) {
|
|
194
|
-
if (child.type === "text") {
|
|
195
|
-
out += child.value;
|
|
196
|
-
continue;
|
|
197
|
-
}
|
|
198
|
-
if (child.type === "link") {
|
|
199
|
-
const link = child;
|
|
200
|
-
const only = link.children.length === 1 ? link.children[0] : void 0;
|
|
201
|
-
if (only?.type === "text") {
|
|
202
|
-
out += only.value;
|
|
203
|
-
continue;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
return out;
|
|
209
|
-
}
|
|
210
|
-
/**
|
|
211
|
-
* Pattern matching the plugin's own merged summary paragraph, e.g.
|
|
212
|
-
* `Thanks to @alice, @bob, and @carol for their contributions!`.
|
|
213
|
-
*
|
|
214
|
-
* @internal
|
|
215
|
-
*/
|
|
216
|
-
const MERGED_SUMMARY_RE = /^Thanks to @\w[\w-]*(?:(?:, | and |, and |,and )@\w[\w-]*)* for their contributions!$/;
|
|
217
|
-
/**
|
|
218
|
-
* Whether a paragraph consists ENTIRELY of attribution content the plugin
|
|
219
|
-
* owns: either its own merged `Thanks to ... for their contributions!`
|
|
220
|
-
* summary, or one or more trailing `Thanks @user!` / `Thanks [@user](url)!`
|
|
221
|
-
* attributions with nothing else. Checked against a clone so the real node
|
|
222
|
-
* is never mutated — a paragraph carrying anything beyond pure attribution
|
|
223
|
-
* is not the plugin's to touch.
|
|
224
|
-
*
|
|
225
|
-
* @internal
|
|
226
|
-
*/
|
|
227
|
-
function isPureAttributionParagraph(para) {
|
|
228
|
-
const text = flattenToText(para);
|
|
229
|
-
if (text !== void 0 && MERGED_SUMMARY_RE.test(text)) return true;
|
|
230
|
-
const clone = structuredClone(para);
|
|
231
|
-
const scratch = /* @__PURE__ */ new Map();
|
|
232
|
-
while (clone.children.length > 0 && stripAttribution(clone, scratch));
|
|
233
|
-
return clone.children.length === 0;
|
|
234
|
-
}
|
|
235
|
-
/**
|
|
236
|
-
* Whether a Thanks-section body node is a pure attribution shape the plugin
|
|
237
|
-
* may harvest and remove: an attribution-only paragraph, or a list whose
|
|
238
|
-
* every item holds only attribution-only paragraphs. Anything else
|
|
239
|
-
* (mixed prose+mention, plain-name lists, code blocks, arbitrary prose) is
|
|
240
|
-
* preserved untouched and never mined for mentions.
|
|
241
|
-
*
|
|
242
|
-
* @internal
|
|
243
|
-
*/
|
|
244
|
-
function isPureAttributionNode(node) {
|
|
245
|
-
if (node.type === "paragraph") return isPureAttributionParagraph(node);
|
|
246
|
-
if (node.type === "list") {
|
|
247
|
-
const list = node;
|
|
248
|
-
return list.children.length > 0 && list.children.every((item) => item.children.length > 0 && item.children.every((child) => child.type === "paragraph" && isPureAttributionParagraph(child)));
|
|
249
|
-
}
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
/**
|
|
253
|
-
* Whether a node is a depth-3 heading whose text is `Thanks`.
|
|
254
|
-
*
|
|
255
|
-
* @internal
|
|
256
|
-
*/
|
|
257
|
-
function isThanksHeading(node) {
|
|
258
|
-
if (node.type !== "heading" || node.depth !== 3) return false;
|
|
259
|
-
const heading = node;
|
|
260
|
-
const only = heading.children.length === 1 ? heading.children[0] : void 0;
|
|
261
|
-
return only?.type === "text" && only.value.trim().toLowerCase() === "thanks";
|
|
262
|
-
}
|
|
263
|
-
const ContributorFootnotesPlugin = (options) => {
|
|
264
|
-
const emitThanks = options?.thanks !== false;
|
|
265
|
-
return (tree) => {
|
|
266
|
-
const blocks = getVersionBlocks(tree);
|
|
267
|
-
for (let b = blocks.length - 1; b >= 0; b--) {
|
|
268
|
-
const block = blocks[b];
|
|
269
|
-
const contributors = /* @__PURE__ */ new Map();
|
|
270
|
-
const indicesToRemove = [];
|
|
271
|
-
let preservedThanksAnchor;
|
|
272
|
-
for (let i = block.startIndex; i < block.endIndex; i++) {
|
|
273
|
-
const node = tree.children[i];
|
|
274
|
-
if (node.type === "list") {
|
|
275
|
-
const listNode = node;
|
|
276
|
-
visit(listNode, "paragraph", (para) => {
|
|
277
|
-
stripAttribution(para, contributors);
|
|
278
|
-
});
|
|
279
|
-
pruneEmptiedListItems(listNode);
|
|
280
|
-
if (listNode.children.length === 0) indicesToRemove.push(i);
|
|
281
|
-
continue;
|
|
282
|
-
}
|
|
283
|
-
if (node.type === "paragraph") {
|
|
284
|
-
const para = node;
|
|
285
|
-
if (stripAttribution(para, contributors) && para.children.length === 0) indicesToRemove.push(i);
|
|
286
|
-
continue;
|
|
287
|
-
}
|
|
288
|
-
if (isThanksHeading(node)) {
|
|
289
|
-
const headingIndex = i;
|
|
290
|
-
const harvested = [];
|
|
291
|
-
let lastPreserved;
|
|
292
|
-
let j = i + 1;
|
|
293
|
-
for (; j < block.endIndex; j++) {
|
|
294
|
-
const contentNode = tree.children[j];
|
|
295
|
-
if (contentNode.type === "heading" && [2, 3].includes(contentNode.depth)) break;
|
|
296
|
-
if (contentNode.type === "definition") continue;
|
|
297
|
-
if (isPureAttributionNode(contentNode)) {
|
|
298
|
-
harvestMentions(contentNode, contributors);
|
|
299
|
-
harvested.push(j);
|
|
300
|
-
} else lastPreserved = contentNode;
|
|
301
|
-
}
|
|
302
|
-
if (lastPreserved === void 0) indicesToRemove.push(headingIndex, ...harvested);
|
|
303
|
-
else {
|
|
304
|
-
indicesToRemove.push(...harvested);
|
|
305
|
-
preservedThanksAnchor ??= lastPreserved;
|
|
306
|
-
}
|
|
307
|
-
i = j - 1;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
const uniqueIndices = [...new Set(indicesToRemove)].sort((a, b) => b - a);
|
|
311
|
-
for (const idx of uniqueIndices) tree.children.splice(idx, 1);
|
|
312
|
-
if (!emitThanks || contributors.size === 0) continue;
|
|
313
|
-
if (preservedThanksAnchor !== void 0) {
|
|
314
|
-
const anchorIndex = tree.children.indexOf(preservedThanksAnchor);
|
|
315
|
-
if (anchorIndex !== -1) {
|
|
316
|
-
tree.children.splice(anchorIndex + 1, 0, buildSummaryParagraph(contributors));
|
|
317
|
-
continue;
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
let insertAt = block.endIndex - uniqueIndices.length;
|
|
321
|
-
while (insertAt > block.startIndex && tree.children[insertAt - 1]?.type === "definition") insertAt--;
|
|
322
|
-
tree.children.splice(insertAt, 0, {
|
|
323
|
-
type: "heading",
|
|
324
|
-
depth: 3,
|
|
325
|
-
children: [{
|
|
326
|
-
type: "text",
|
|
327
|
-
value: "Thanks"
|
|
328
|
-
}]
|
|
329
|
-
}, buildSummaryParagraph(contributors));
|
|
330
|
-
}
|
|
331
|
-
};
|
|
332
|
-
};
|
|
333
|
-
|
|
334
|
-
//#endregion
|
|
335
|
-
export { ContributorFootnotesPlugin };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { getBlockSections, getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
-
import { toString } from "mdast-util-to-string";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/deduplicate-items.ts
|
|
5
|
-
const DeduplicateItemsPlugin = () => {
|
|
6
|
-
return (tree) => {
|
|
7
|
-
const blocks = getVersionBlocks(tree);
|
|
8
|
-
for (const block of blocks) {
|
|
9
|
-
const sections = getBlockSections(tree, block);
|
|
10
|
-
for (const section of sections) {
|
|
11
|
-
const seen = /* @__PURE__ */ new Set();
|
|
12
|
-
for (const node of section.contentNodes) {
|
|
13
|
-
if (node.type !== "list") continue;
|
|
14
|
-
const list = node;
|
|
15
|
-
list.children = list.children.filter((item) => {
|
|
16
|
-
const text = toString(item);
|
|
17
|
-
if (seen.has(text)) return false;
|
|
18
|
-
seen.add(text);
|
|
19
|
-
return true;
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
tree.children = tree.children.filter((node) => {
|
|
25
|
-
if (node.type === "list") return node.children.length > 0;
|
|
26
|
-
return true;
|
|
27
|
-
});
|
|
28
|
-
};
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
export { DeduplicateItemsPlugin };
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
-
import { SKIP, visit } from "unist-util-visit";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/issue-link-refs.ts
|
|
5
|
-
/**
|
|
6
|
-
* Pattern matching issue numbers like `#123`.
|
|
7
|
-
*
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
const ISSUE_RE = /^#\d+$/;
|
|
11
|
-
const IssueLinkRefsPlugin = () => {
|
|
12
|
-
return (tree) => {
|
|
13
|
-
const blocks = getVersionBlocks(tree);
|
|
14
|
-
for (let b = blocks.length - 1; b >= 0; b--) {
|
|
15
|
-
const block = blocks[b];
|
|
16
|
-
const definitions = /* @__PURE__ */ new Map();
|
|
17
|
-
for (let i = block.startIndex; i < block.endIndex; i++) {
|
|
18
|
-
const node = tree.children[i];
|
|
19
|
-
visit(node, "link", (linkNode, index, parent) => {
|
|
20
|
-
if (!parent || index === void 0) return;
|
|
21
|
-
if (linkNode.children.length !== 1 || linkNode.children[0].type !== "text") return;
|
|
22
|
-
const text = linkNode.children[0].value;
|
|
23
|
-
if (!ISSUE_RE.test(text)) return;
|
|
24
|
-
const label = text;
|
|
25
|
-
if (!definitions.has(label)) definitions.set(label, {
|
|
26
|
-
label,
|
|
27
|
-
url: linkNode.url
|
|
28
|
-
});
|
|
29
|
-
const ref = {
|
|
30
|
-
type: "linkReference",
|
|
31
|
-
identifier: label,
|
|
32
|
-
label,
|
|
33
|
-
referenceType: "full",
|
|
34
|
-
children: [{
|
|
35
|
-
type: "text",
|
|
36
|
-
value: label
|
|
37
|
-
}]
|
|
38
|
-
};
|
|
39
|
-
parent.children[index] = ref;
|
|
40
|
-
return SKIP;
|
|
41
|
-
});
|
|
42
|
-
}
|
|
43
|
-
if (definitions.size === 0) continue;
|
|
44
|
-
const defNodes = [...definitions.values()].sort((a, b) => {
|
|
45
|
-
return Number.parseInt(a.label.slice(1), 10) - Number.parseInt(b.label.slice(1), 10);
|
|
46
|
-
}).map((def) => ({
|
|
47
|
-
type: "definition",
|
|
48
|
-
identifier: def.label,
|
|
49
|
-
label: def.label,
|
|
50
|
-
url: def.url
|
|
51
|
-
}));
|
|
52
|
-
tree.children.splice(block.endIndex, 0, ...defNodes);
|
|
53
|
-
}
|
|
54
|
-
};
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
//#endregion
|
|
58
|
-
export { IssueLinkRefsPlugin };
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { getHeadingText, getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
-
import { toString } from "mdast-util-to-string";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/maintenance-note.ts
|
|
5
|
-
/**
|
|
6
|
-
* Placeholder sentence `@changesets/apply-release-plan` (>= 8.1.0) emits as the
|
|
7
|
-
* body of a version block that would otherwise render as a bare heading. Older
|
|
8
|
-
* engine versions left such a block structurally empty.
|
|
9
|
-
*/
|
|
10
|
-
const ENGINE_PLACEHOLDER = "No changes in this release.";
|
|
11
|
-
/** True when the block's only content is the engine's empty-release placeholder. */
|
|
12
|
-
function isPlaceholderOnly(tree, block) {
|
|
13
|
-
if (block.endIndex - block.startIndex !== 1) return false;
|
|
14
|
-
const node = tree.children[block.startIndex];
|
|
15
|
-
return node.type === "paragraph" && toString(node).trim() === ENGINE_PLACEHOLDER;
|
|
16
|
-
}
|
|
17
|
-
function buildNoteChildren(reason) {
|
|
18
|
-
if (reason.kind === "unspecified" || reason.triggers.length === 0) return [{
|
|
19
|
-
type: "text",
|
|
20
|
-
value: "Version-only release to keep workspace versions consistent; no changes to this package."
|
|
21
|
-
}];
|
|
22
|
-
const label = reason.kind === "fixed" ? "fixed version group" : "linked version group";
|
|
23
|
-
const children = [{
|
|
24
|
-
type: "text",
|
|
25
|
-
value: "Released in lockstep with "
|
|
26
|
-
}];
|
|
27
|
-
reason.triggers.forEach((trigger, index) => {
|
|
28
|
-
if (index > 0) children.push({
|
|
29
|
-
type: "text",
|
|
30
|
-
value: ", "
|
|
31
|
-
});
|
|
32
|
-
children.push({
|
|
33
|
-
type: "inlineCode",
|
|
34
|
-
value: `${trigger.name}@${trigger.version}`
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
children.push({
|
|
38
|
-
type: "text",
|
|
39
|
-
value: ` (${label}).`
|
|
40
|
-
});
|
|
41
|
-
return children;
|
|
42
|
-
}
|
|
43
|
-
const MaintenanceNotePlugin = (options) => {
|
|
44
|
-
return (tree) => {
|
|
45
|
-
const block = getVersionBlocks(tree).find((b) => getHeadingText(tree.children[b.headingIndex]) === options.version);
|
|
46
|
-
if (!block) return;
|
|
47
|
-
const placeholderOnly = isPlaceholderOnly(tree, block);
|
|
48
|
-
if (block.endIndex > block.startIndex && !placeholderOnly) return;
|
|
49
|
-
const heading = {
|
|
50
|
-
type: "heading",
|
|
51
|
-
depth: 3,
|
|
52
|
-
children: [{
|
|
53
|
-
type: "text",
|
|
54
|
-
value: "Maintenance"
|
|
55
|
-
}]
|
|
56
|
-
};
|
|
57
|
-
const list = {
|
|
58
|
-
type: "list",
|
|
59
|
-
ordered: false,
|
|
60
|
-
spread: false,
|
|
61
|
-
children: [{
|
|
62
|
-
type: "listItem",
|
|
63
|
-
spread: false,
|
|
64
|
-
children: [{
|
|
65
|
-
type: "paragraph",
|
|
66
|
-
children: buildNoteChildren(options.reason)
|
|
67
|
-
}]
|
|
68
|
-
}]
|
|
69
|
-
};
|
|
70
|
-
tree.children.splice(block.startIndex, placeholderOnly ? 1 : 0, heading, list);
|
|
71
|
-
};
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
//#endregion
|
|
75
|
-
export { MaintenanceNotePlugin };
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { fromHeading } from "../../categories/index.js";
|
|
2
|
-
import { getBlockSections, getHeadingText, getVersionBlocks } from "../../utils/version-blocks.js";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/merge-sections.ts
|
|
5
|
-
const MergeSectionsPlugin = () => {
|
|
6
|
-
return (tree) => {
|
|
7
|
-
const blocks = getVersionBlocks(tree);
|
|
8
|
-
for (let b = blocks.length - 1; b >= 0; b--) {
|
|
9
|
-
const sections = getBlockSections(tree, blocks[b]);
|
|
10
|
-
if (sections.length <= 1) continue;
|
|
11
|
-
const groups = /* @__PURE__ */ new Map();
|
|
12
|
-
for (let s = 0; s < sections.length; s++) {
|
|
13
|
-
const text = getHeadingText(sections[s].heading);
|
|
14
|
-
const category = fromHeading(text);
|
|
15
|
-
const key = category ? category.heading.toLowerCase() : text.toLowerCase();
|
|
16
|
-
const existing = groups.get(key);
|
|
17
|
-
if (existing) existing.push(s);
|
|
18
|
-
else groups.set(key, [s]);
|
|
19
|
-
}
|
|
20
|
-
const indicesToRemove = [];
|
|
21
|
-
for (const indices of groups.values()) {
|
|
22
|
-
if (indices.length <= 1) continue;
|
|
23
|
-
const target = sections[indices[0]];
|
|
24
|
-
const targetEndIndex = target.headingIndex + 1 + target.contentNodes.length;
|
|
25
|
-
const mergedContent = [];
|
|
26
|
-
for (let d = 1; d < indices.length; d++) {
|
|
27
|
-
const dup = sections[indices[d]];
|
|
28
|
-
mergedContent.push(...dup.contentNodes);
|
|
29
|
-
indicesToRemove.push(dup.headingIndex);
|
|
30
|
-
for (let c = 0; c < dup.contentNodes.length; c++) indicesToRemove.push(dup.headingIndex + 1 + c);
|
|
31
|
-
}
|
|
32
|
-
tree.children.splice(targetEndIndex, 0, ...mergedContent);
|
|
33
|
-
const shift = mergedContent.length;
|
|
34
|
-
for (let r = 0; r < indicesToRemove.length; r++) if (indicesToRemove[r] >= targetEndIndex) indicesToRemove[r] += shift;
|
|
35
|
-
}
|
|
36
|
-
indicesToRemove.sort((a, b) => b - a);
|
|
37
|
-
for (const idx of indicesToRemove) tree.children.splice(idx, 1);
|
|
38
|
-
}
|
|
39
|
-
};
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
//#endregion
|
|
43
|
-
export { MergeSectionsPlugin };
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { getVersionBlocks } from "../../utils/version-blocks.js";
|
|
2
|
-
import { toString } from "mdast-util-to-string";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/normalize-format.ts
|
|
5
|
-
/**
|
|
6
|
-
* Check if a node is a heading at one of the given depths.
|
|
7
|
-
*
|
|
8
|
-
* @param node - The AST node to check
|
|
9
|
-
* @param depths - Allowed heading depths
|
|
10
|
-
* @returns `true` if the node is a heading at one of the specified depths
|
|
11
|
-
*
|
|
12
|
-
* @internal
|
|
13
|
-
*/
|
|
14
|
-
function isHeadingAtDepth(node, depths) {
|
|
15
|
-
return node.type === "heading" && depths.includes(node.depth);
|
|
16
|
-
}
|
|
17
|
-
const NormalizeFormatPlugin = () => {
|
|
18
|
-
return (tree) => {
|
|
19
|
-
const blocks = getVersionBlocks(tree);
|
|
20
|
-
const indicesToRemove = /* @__PURE__ */ new Set();
|
|
21
|
-
for (const block of blocks) for (let i = block.startIndex; i < block.endIndex; i++) {
|
|
22
|
-
const node = tree.children[i];
|
|
23
|
-
if (node.type === "list" && node.children.length === 0) {
|
|
24
|
-
indicesToRemove.add(i);
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
if (!isHeadingAtDepth(node, [3])) continue;
|
|
28
|
-
let hasContent = false;
|
|
29
|
-
for (let j = i + 1; j < block.endIndex; j++) {
|
|
30
|
-
const next = tree.children[j];
|
|
31
|
-
if (next.type === "paragraph" && toString(next).trim() === "") {
|
|
32
|
-
indicesToRemove.add(j);
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
if (isHeadingAtDepth(next, [2, 3])) break;
|
|
36
|
-
hasContent = true;
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
39
|
-
if (!hasContent) indicesToRemove.add(i);
|
|
40
|
-
}
|
|
41
|
-
const sorted = [...indicesToRemove].sort((a, b) => b - a);
|
|
42
|
-
for (const idx of sorted) tree.children.splice(idx, 1);
|
|
43
|
-
};
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
//#endregion
|
|
47
|
-
export { NormalizeFormatPlugin };
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { fromHeading } from "../../categories/index.js";
|
|
2
|
-
import { getBlockSections, getHeadingText, getVersionBlocks } from "../../utils/version-blocks.js";
|
|
3
|
-
|
|
4
|
-
//#region src/changesets/remark/plugins/reorder-sections.ts
|
|
5
|
-
/**
|
|
6
|
-
* Default priority for unrecognized headings (sorts after all known categories).
|
|
7
|
-
*
|
|
8
|
-
* @internal
|
|
9
|
-
*/
|
|
10
|
-
const UNKNOWN_PRIORITY = 999;
|
|
11
|
-
/**
|
|
12
|
-
* Priority for the `Thanks` section emitted by {@link ContributorFootnotesPlugin}.
|
|
13
|
-
* Sorts after everything — including unknown headings — so the contributor
|
|
14
|
-
* credits always close the version block.
|
|
15
|
-
*
|
|
16
|
-
* @internal
|
|
17
|
-
*/
|
|
18
|
-
const THANKS_PRIORITY = 1e3;
|
|
19
|
-
/**
|
|
20
|
-
* Resolve the sort priority for a section heading.
|
|
21
|
-
*
|
|
22
|
-
* @internal
|
|
23
|
-
*/
|
|
24
|
-
function headingPriority(text) {
|
|
25
|
-
if (text.trim().toLowerCase() === "thanks") return THANKS_PRIORITY;
|
|
26
|
-
return fromHeading(text)?.priority ?? UNKNOWN_PRIORITY;
|
|
27
|
-
}
|
|
28
|
-
const ReorderSectionsPlugin = () => {
|
|
29
|
-
return (tree) => {
|
|
30
|
-
const blocks = getVersionBlocks(tree);
|
|
31
|
-
for (let b = blocks.length - 1; b >= 0; b--) {
|
|
32
|
-
const block = blocks[b];
|
|
33
|
-
const sections = getBlockSections(tree, block);
|
|
34
|
-
if (sections.length <= 1) continue;
|
|
35
|
-
const preamble = [];
|
|
36
|
-
for (let i = block.startIndex; i < block.endIndex; i++) if (i < sections[0].headingIndex) preamble.push(tree.children[i]);
|
|
37
|
-
else break;
|
|
38
|
-
const sorted = [...sections].sort((a, b) => headingPriority(getHeadingText(a.heading)) - headingPriority(getHeadingText(b.heading)));
|
|
39
|
-
if (sorted.every((s, i) => s.headingIndex === sections[i].headingIndex)) continue;
|
|
40
|
-
const newChildren = [...preamble];
|
|
41
|
-
for (const section of sorted) newChildren.push(section.heading, ...section.contentNodes);
|
|
42
|
-
const blockLength = block.endIndex - block.startIndex;
|
|
43
|
-
tree.children.splice(block.startIndex, blockLength, ...newChildren);
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
//#endregion
|
|
49
|
-
export { ReorderSectionsPlugin };
|