docbridge 0.14.0 → 0.16.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/CHANGELOG.md +20 -1
- package/dist/bin/darwin-arm64/SHA256SUMS +3 -3
- package/dist/bin/darwin-arm64/docbridge-go-scanner +0 -0
- package/dist/bin/darwin-arm64/docbridge-swift-scanner +0 -0
- package/dist/bin/darwin-arm64/docbridge_dart_scanner +0 -0
- package/dist/bin/linux-x64/SHA256SUMS +2 -2
- package/dist/bin/linux-x64/docbridge-go-scanner +0 -0
- package/dist/bin/linux-x64/docbridge-swift-scanner +1 -1
- package/dist/index.js +86 -54
- package/dist/workers/java/docbridge-java-scanner.jar +0 -0
- package/docs/user/configuration.md +26 -4
- package/package.json +1 -1
- package/schemas/docbridge.schema.json +63 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.16.0] - 2026-10-12
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- A language entry under `include.code` accepts an optional `exclude` array.
|
|
15
|
+
Matched files that an `exclude` pattern selects are not managed, such as
|
|
16
|
+
Flutter's `*.g.dart` and `*.freezed.dart` files.
|
|
17
|
+
|
|
18
|
+
## [0.15.0] - 2026-10-12
|
|
19
|
+
|
|
20
|
+
### Added
|
|
21
|
+
|
|
22
|
+
- `doc_anchor_not_found` suggests the closest anchor in the same Markdown file
|
|
23
|
+
with `Did you mean`, for both `@doc` annotations and link manifest entries.
|
|
24
|
+
Anchors in other doc files are not suggested, and no suggestion is added when
|
|
25
|
+
no anchor is close enough.
|
|
26
|
+
|
|
10
27
|
## [0.14.0] - 2026-10-08
|
|
11
28
|
|
|
12
29
|
### Changed
|
|
@@ -568,7 +585,9 @@ Initial release of the SpecLink CLI.
|
|
|
568
585
|
- `speclink check` command with `--root`, `--json`, and `--audit` options.
|
|
569
586
|
- `speclink --version` (alias `-v`) and `speclink --help` (alias `-h`).
|
|
570
587
|
|
|
571
|
-
[Unreleased]: https://github.com/salan70/docbridge/compare/v0.
|
|
588
|
+
[Unreleased]: https://github.com/salan70/docbridge/compare/v0.16.0...HEAD
|
|
589
|
+
[0.16.0]: https://github.com/salan70/docbridge/releases/tag/v0.16.0
|
|
590
|
+
[0.15.0]: https://github.com/salan70/docbridge/releases/tag/v0.15.0
|
|
572
591
|
[0.14.0]: https://github.com/salan70/docbridge/releases/tag/v0.14.0
|
|
573
592
|
[0.13.1]: https://github.com/salan70/docbridge/releases/tag/v0.13.1
|
|
574
593
|
[0.13.0]: https://github.com/salan70/docbridge/releases/tag/v0.13.0
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
fbe811d3c84850751dca02c4b9ed6c71404d1b6e6666f4e0955054b12f4448e2 docbridge-swift-scanner
|
|
2
|
+
a49fb9474445a3d7d35ab332a1660c3ddd50dbe4ed11adb81c19d99568abb9fa docbridge_dart_scanner
|
|
3
3
|
7fc3e6842b3e1bf425b8fd63e241eee7e64875f16be7ba8d1ae4a25baa7f2338 docbridge-rust-scanner
|
|
4
|
-
|
|
4
|
+
81a1f97936f7b503131a1380dbcdbe610c5662ffa86284af754c7e6dfd792f21 docbridge-go-scanner
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
86af421dafc4dbff3498893c7600e44e6bdb230177ae63a0639267ebba78ed94 docbridge-swift-scanner
|
|
2
2
|
b75b14006ca792ed3ca8faf7ceee9e4d33c895f27dd416b640818cf8a4bdd9c8 docbridge_dart_scanner
|
|
3
3
|
e0da7b8cc6ee23704f5fe8514cc309f0bb60380c77b55e3bc5ed113abd1f3478 docbridge-rust-scanner
|
|
4
|
-
|
|
4
|
+
c89df71f1762fa25da26de1ffbd511c9ebc967e088d9653115b944c7a9b02c00 docbridge-go-scanner
|
|
Binary file
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
[diffend] Oversized file quarantined before diffing.
|
|
2
2
|
name: package/dist/bin/linux-x64/docbridge-swift-scanner
|
|
3
3
|
size: 40932352 bytes
|
|
4
|
-
sha256:
|
|
4
|
+
sha256: 86af421dafc4dbff3498893c7600e44e6bdb230177ae63a0639267ebba78ed94
|
package/dist/index.js
CHANGED
|
@@ -175581,7 +175581,7 @@ import { join as join15, resolve as resolve5 } from "node:path";
|
|
|
175581
175581
|
// package.json
|
|
175582
175582
|
var package_default = {
|
|
175583
175583
|
name: "docbridge",
|
|
175584
|
-
version: "0.
|
|
175584
|
+
version: "0.16.0",
|
|
175585
175585
|
description: "A CLI that links Markdown specifications and code declarations. Runs on Node.js and Bun.",
|
|
175586
175586
|
keywords: [
|
|
175587
175587
|
"bun",
|
|
@@ -175829,7 +175829,7 @@ function collectCodeFiles(projectRoot, codeInclude) {
|
|
|
175829
175829
|
if (entry === undefined) {
|
|
175830
175830
|
continue;
|
|
175831
175831
|
}
|
|
175832
|
-
for (const relPath of collectLanguageFiles(projectRoot, language, entry
|
|
175832
|
+
for (const relPath of collectLanguageFiles(projectRoot, language, entry)) {
|
|
175833
175833
|
if (seen.has(relPath)) {
|
|
175834
175834
|
continue;
|
|
175835
175835
|
}
|
|
@@ -175847,7 +175847,7 @@ function codeFileOwners(projectRoot, codeInclude) {
|
|
|
175847
175847
|
if (entry === undefined) {
|
|
175848
175848
|
continue;
|
|
175849
175849
|
}
|
|
175850
|
-
for (const relPath of collectLanguageFiles(projectRoot, language, entry
|
|
175850
|
+
for (const relPath of collectLanguageFiles(projectRoot, language, entry)) {
|
|
175851
175851
|
const existing = owners.get(relPath);
|
|
175852
175852
|
if (existing === undefined) {
|
|
175853
175853
|
owners.set(relPath, [language]);
|
|
@@ -175858,8 +175858,9 @@ function codeFileOwners(projectRoot, codeInclude) {
|
|
|
175858
175858
|
}
|
|
175859
175859
|
return owners;
|
|
175860
175860
|
}
|
|
175861
|
-
function collectLanguageFiles(projectRoot, language,
|
|
175862
|
-
|
|
175861
|
+
function collectLanguageFiles(projectRoot, language, entry) {
|
|
175862
|
+
const excluded = entry.exclude ?? [];
|
|
175863
|
+
return collectFiles(projectRoot, entry.patterns).filter((relPath) => !hasExcludedSuffix(language, relPath) && !excluded.some((pattern) => matchGlob(pattern, relPath)));
|
|
175863
175864
|
}
|
|
175864
175865
|
|
|
175865
175866
|
// src/config/scanner-runtimes.ts
|
|
@@ -175918,7 +175919,7 @@ var EMPTY_CONFIG = {
|
|
|
175918
175919
|
};
|
|
175919
175920
|
var KNOWN_TOP_LEVEL_KEYS = new Set(["$schema", "include", "scanners"]);
|
|
175920
175921
|
var KNOWN_INCLUDE_KEYS = new Set(["code", "docs"]);
|
|
175921
|
-
var KNOWN_CODE_ENTRY_KEYS = new Set(["patterns", "visibility"]);
|
|
175922
|
+
var KNOWN_CODE_ENTRY_KEYS = new Set(["patterns", "exclude", "visibility"]);
|
|
175922
175923
|
var LANGUAGE_VISIBILITY = {
|
|
175923
175924
|
typescript: ["public", "protected", "private"],
|
|
175924
175925
|
swift: ["public", "open", "internal"],
|
|
@@ -176047,6 +176048,9 @@ function validateCodeEntry(language, value, diagnostics) {
|
|
|
176047
176048
|
}
|
|
176048
176049
|
const before = diagnostics.length;
|
|
176049
176050
|
validatePatternArray(value.patterns, `code.${language}.patterns`, LANGUAGE_SUFFIXES[language], EXCLUDED_SUFFIXES[language], diagnostics);
|
|
176051
|
+
if ("exclude" in value) {
|
|
176052
|
+
validateExcludePatterns(language, value.exclude, diagnostics);
|
|
176053
|
+
}
|
|
176050
176054
|
if ("visibility" in value) {
|
|
176051
176055
|
if (!isStringArray(value.visibility)) {
|
|
176052
176056
|
diagnostics.push(configDiagnostic2("config_invalid_value", `${target}.visibility`, `\`${target}.visibility\` must be an array of strings.`));
|
|
@@ -176058,6 +176062,9 @@ function validateCodeEntry(language, value, diagnostics) {
|
|
|
176058
176062
|
return;
|
|
176059
176063
|
}
|
|
176060
176064
|
const entry = { patterns: value.patterns };
|
|
176065
|
+
if (isStringArray(value.exclude)) {
|
|
176066
|
+
entry.exclude = value.exclude;
|
|
176067
|
+
}
|
|
176061
176068
|
if (isStringArray(value.visibility)) {
|
|
176062
176069
|
entry.visibility = value.visibility;
|
|
176063
176070
|
}
|
|
@@ -176071,6 +176078,14 @@ function validateVisibilityOptions(language, values, target, diagnostics) {
|
|
|
176071
176078
|
}
|
|
176072
176079
|
}
|
|
176073
176080
|
}
|
|
176081
|
+
function validateExcludePatterns(language, value, diagnostics) {
|
|
176082
|
+
const target = `include.code.${language}.exclude`;
|
|
176083
|
+
if (!Array.isArray(value)) {
|
|
176084
|
+
diagnostics.push(configDiagnostic2("config_invalid_value", target, `\`${target}\` must be an array of strings.`));
|
|
176085
|
+
return;
|
|
176086
|
+
}
|
|
176087
|
+
validatePatternStrings(value, `code.${language}.exclude`, LANGUAGE_SUFFIXES[language], EXCLUDED_SUFFIXES[language], diagnostics);
|
|
176088
|
+
}
|
|
176074
176089
|
function validatePatternArray(value, field, suffixes, excludedSuffixes, diagnostics) {
|
|
176075
176090
|
const target = `include.${field}`;
|
|
176076
176091
|
if (!Array.isArray(value)) {
|
|
@@ -176081,6 +176096,10 @@ function validatePatternArray(value, field, suffixes, excludedSuffixes, diagnost
|
|
|
176081
176096
|
diagnostics.push(configDiagnostic2("config_invalid_value", target, `\`${target}\` must contain at least one pattern.`));
|
|
176082
176097
|
return;
|
|
176083
176098
|
}
|
|
176099
|
+
validatePatternStrings(value, field, suffixes, excludedSuffixes, diagnostics);
|
|
176100
|
+
}
|
|
176101
|
+
function validatePatternStrings(value, field, suffixes, excludedSuffixes, diagnostics) {
|
|
176102
|
+
const target = `include.${field}`;
|
|
176084
176103
|
for (const pattern of value) {
|
|
176085
176104
|
if (typeof pattern !== "string") {
|
|
176086
176105
|
diagnostics.push(configDiagnostic2("config_invalid_value", target, `\`${target}\` patterns must be strings.`));
|
|
@@ -177171,6 +177190,51 @@ function pluralize(word, count) {
|
|
|
177171
177190
|
return count === 1 ? word : `${word}s`;
|
|
177172
177191
|
}
|
|
177173
177192
|
|
|
177193
|
+
// src/shared/suggest.ts
|
|
177194
|
+
function nearestMatch(input, candidates) {
|
|
177195
|
+
const ranked = candidates.map((candidate, index) => ({
|
|
177196
|
+
candidate,
|
|
177197
|
+
distance: editDistance(input, candidate),
|
|
177198
|
+
index
|
|
177199
|
+
})).toSorted((left, right) => left.distance - right.distance || left.index - right.index);
|
|
177200
|
+
const abbreviation = ranked.find(({ candidate }) => isOrderedAbbreviation(input, candidate));
|
|
177201
|
+
if (abbreviation !== undefined) {
|
|
177202
|
+
return abbreviation.candidate;
|
|
177203
|
+
}
|
|
177204
|
+
const best = ranked[0];
|
|
177205
|
+
if (best === undefined) {
|
|
177206
|
+
return;
|
|
177207
|
+
}
|
|
177208
|
+
const closeEnough = best.distance <= Math.max(1, Math.floor(best.candidate.length / 2));
|
|
177209
|
+
return closeEnough ? best.candidate : undefined;
|
|
177210
|
+
}
|
|
177211
|
+
function isOrderedAbbreviation(input, candidate) {
|
|
177212
|
+
if (input.length < 3 || input.length >= candidate.length) {
|
|
177213
|
+
return false;
|
|
177214
|
+
}
|
|
177215
|
+
let candidateIndex = 0;
|
|
177216
|
+
for (const character of input) {
|
|
177217
|
+
const matchIndex = candidate.indexOf(character, candidateIndex);
|
|
177218
|
+
if (matchIndex === -1) {
|
|
177219
|
+
return false;
|
|
177220
|
+
}
|
|
177221
|
+
candidateIndex = matchIndex + 1;
|
|
177222
|
+
}
|
|
177223
|
+
return true;
|
|
177224
|
+
}
|
|
177225
|
+
function editDistance(left, right) {
|
|
177226
|
+
let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
177227
|
+
for (let leftIndex = 1;leftIndex <= left.length; leftIndex += 1) {
|
|
177228
|
+
const current = [leftIndex];
|
|
177229
|
+
for (let rightIndex = 1;rightIndex <= right.length; rightIndex += 1) {
|
|
177230
|
+
const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;
|
|
177231
|
+
current[rightIndex] = Math.min((current[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + 1, (previous[rightIndex] ?? Number.POSITIVE_INFINITY) + 1, (previous[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + substitutionCost);
|
|
177232
|
+
}
|
|
177233
|
+
previous = current;
|
|
177234
|
+
}
|
|
177235
|
+
return previous[right.length] ?? 0;
|
|
177236
|
+
}
|
|
177237
|
+
|
|
177174
177238
|
// src/link/resolver.ts
|
|
177175
177239
|
function resolveLinks(input) {
|
|
177176
177240
|
const diagnostics = [];
|
|
@@ -177178,10 +177242,12 @@ function resolveLinks(input) {
|
|
|
177178
177242
|
const docFilePaths = new Set(input.docFiles.map((file) => file.filePath));
|
|
177179
177243
|
const codeFilePaths = new Set(input.codeFiles.map((file) => file.filePath));
|
|
177180
177244
|
const docAnchorEndpoints = new Set;
|
|
177245
|
+
const docAnchorsByFile = new Map;
|
|
177181
177246
|
for (const file of input.docFiles) {
|
|
177182
177247
|
for (const anchor of file.anchors) {
|
|
177183
177248
|
docAnchorEndpoints.add(anchor.endpoint);
|
|
177184
177249
|
}
|
|
177250
|
+
docAnchorsByFile.set(file.filePath, file.anchors.map((anchor) => anchor.anchor));
|
|
177185
177251
|
}
|
|
177186
177252
|
const docToCodePairs = new Set;
|
|
177187
177253
|
for (const file of input.docFiles) {
|
|
@@ -177216,7 +177282,7 @@ function resolveLinks(input) {
|
|
|
177216
177282
|
continue;
|
|
177217
177283
|
}
|
|
177218
177284
|
if (!docAnchorEndpoints.has(docEndpoint)) {
|
|
177219
|
-
diagnostics.push(relationshipDiagnostic("doc_anchor_not_found", link.source, docEndpoint, `Doc anchor ${docEndpoint} referenced by ${link.source} does not exist.`, link));
|
|
177285
|
+
diagnostics.push(relationshipDiagnostic("doc_anchor_not_found", link.source, docEndpoint, withAnchorSuggestion(`Doc anchor ${docEndpoint} referenced by ${link.source} does not exist.`, docEndpoint, docAnchorsByFile), link));
|
|
177220
177286
|
continue;
|
|
177221
177287
|
}
|
|
177222
177288
|
if (!docToCodePairs.has(pairKey(docEndpoint, link.source))) {
|
|
@@ -177330,6 +177396,11 @@ function unlinkedDocSectionDiagnostic(node, anchor) {
|
|
|
177330
177396
|
}
|
|
177331
177397
|
return diagnostic;
|
|
177332
177398
|
}
|
|
177399
|
+
function withAnchorSuggestion(message, docEndpoint, docAnchorsByFile) {
|
|
177400
|
+
const docFilePath = filePathOf(docEndpoint);
|
|
177401
|
+
const suggestion = nearestMatch(fragmentOf(docEndpoint), docAnchorsByFile.get(docFilePath) ?? []);
|
|
177402
|
+
return suggestion === undefined ? message : `${message} Did you mean \`${docFilePath}#${suggestion}\`?`;
|
|
177403
|
+
}
|
|
177333
177404
|
function pairKey(source, target) {
|
|
177334
177405
|
return `${source}->${target}`;
|
|
177335
177406
|
}
|
|
@@ -177348,51 +177419,6 @@ function relationshipDiagnostic(code, source, target, message, link) {
|
|
|
177348
177419
|
return diagnostic;
|
|
177349
177420
|
}
|
|
177350
177421
|
|
|
177351
|
-
// src/shared/suggest.ts
|
|
177352
|
-
function nearestMatch(input, candidates) {
|
|
177353
|
-
const ranked = candidates.map((candidate, index) => ({
|
|
177354
|
-
candidate,
|
|
177355
|
-
distance: editDistance(input, candidate),
|
|
177356
|
-
index
|
|
177357
|
-
})).toSorted((left, right) => left.distance - right.distance || left.index - right.index);
|
|
177358
|
-
const abbreviation = ranked.find(({ candidate }) => isOrderedAbbreviation(input, candidate));
|
|
177359
|
-
if (abbreviation !== undefined) {
|
|
177360
|
-
return abbreviation.candidate;
|
|
177361
|
-
}
|
|
177362
|
-
const best = ranked[0];
|
|
177363
|
-
if (best === undefined) {
|
|
177364
|
-
return;
|
|
177365
|
-
}
|
|
177366
|
-
const closeEnough = best.distance <= Math.max(1, Math.floor(best.candidate.length / 2));
|
|
177367
|
-
return closeEnough ? best.candidate : undefined;
|
|
177368
|
-
}
|
|
177369
|
-
function isOrderedAbbreviation(input, candidate) {
|
|
177370
|
-
if (input.length < 3 || input.length >= candidate.length) {
|
|
177371
|
-
return false;
|
|
177372
|
-
}
|
|
177373
|
-
let candidateIndex = 0;
|
|
177374
|
-
for (const character of input) {
|
|
177375
|
-
const matchIndex = candidate.indexOf(character, candidateIndex);
|
|
177376
|
-
if (matchIndex === -1) {
|
|
177377
|
-
return false;
|
|
177378
|
-
}
|
|
177379
|
-
candidateIndex = matchIndex + 1;
|
|
177380
|
-
}
|
|
177381
|
-
return true;
|
|
177382
|
-
}
|
|
177383
|
-
function editDistance(left, right) {
|
|
177384
|
-
let previous = Array.from({ length: right.length + 1 }, (_, index) => index);
|
|
177385
|
-
for (let leftIndex = 1;leftIndex <= left.length; leftIndex += 1) {
|
|
177386
|
-
const current = [leftIndex];
|
|
177387
|
-
for (let rightIndex = 1;rightIndex <= right.length; rightIndex += 1) {
|
|
177388
|
-
const substitutionCost = left[leftIndex - 1] === right[rightIndex - 1] ? 0 : 1;
|
|
177389
|
-
current[rightIndex] = Math.min((current[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + 1, (previous[rightIndex] ?? Number.POSITIVE_INFINITY) + 1, (previous[rightIndex - 1] ?? Number.POSITIVE_INFINITY) + substitutionCost);
|
|
177390
|
-
}
|
|
177391
|
-
previous = current;
|
|
177392
|
-
}
|
|
177393
|
-
return previous[right.length] ?? 0;
|
|
177394
|
-
}
|
|
177395
|
-
|
|
177396
177422
|
// src/link/manifest-apply.ts
|
|
177397
177423
|
function applyLinkManifest(input) {
|
|
177398
177424
|
if (input.manifest.entries.length === 0) {
|
|
@@ -177476,7 +177502,7 @@ class ApplyState {
|
|
|
177476
177502
|
return false;
|
|
177477
177503
|
}
|
|
177478
177504
|
if (!state.anchors.has(entry.docEndpoint)) {
|
|
177479
|
-
this.report("doc_anchor_not_found", entry.docEndpoint,
|
|
177505
|
+
this.report("doc_anchor_not_found", entry.docEndpoint, this.docAnchorNotFoundMessage(entry, state), entry, "doc");
|
|
177480
177506
|
return false;
|
|
177481
177507
|
}
|
|
177482
177508
|
this.markAnnotated(state, entry.docEndpoint);
|
|
@@ -177546,6 +177572,12 @@ class ApplyState {
|
|
|
177546
177572
|
const suggestion = nearestMatch(entry.code.fragment, candidates);
|
|
177547
177573
|
return suggestion === undefined ? base : `${base} Did you mean \`${suggestion}\`?`;
|
|
177548
177574
|
}
|
|
177575
|
+
docAnchorNotFoundMessage(entry, state) {
|
|
177576
|
+
const base = `Doc anchor ${entry.docEndpoint} declared in the link manifest does not exist.`;
|
|
177577
|
+
const candidates = state.file.anchors.map((anchor) => anchor.anchor);
|
|
177578
|
+
const suggestion = nearestMatch(entry.doc.fragment, candidates);
|
|
177579
|
+
return suggestion === undefined ? base : `${base} Did you mean \`${entry.doc.filePath}#${suggestion}\`?`;
|
|
177580
|
+
}
|
|
177549
177581
|
report(code, target, message, entry, side, language) {
|
|
177550
177582
|
const range = side === "code" ? entry.codeRange : entry.docRange;
|
|
177551
177583
|
const diagnostic = {
|
|
@@ -179805,7 +179837,7 @@ class Project {
|
|
|
179805
179837
|
if (hasExcludedSuffix(language, relPath)) {
|
|
179806
179838
|
continue;
|
|
179807
179839
|
}
|
|
179808
|
-
if (entry.patterns.some((pattern) => matchGlob(pattern, relPath))) {
|
|
179840
|
+
if (entry.patterns.some((pattern) => matchGlob(pattern, relPath)) && !(entry.exclude ?? []).some((pattern) => matchGlob(pattern, relPath))) {
|
|
179809
179841
|
seen.add(relPath);
|
|
179810
179842
|
all.push({ language, relPath });
|
|
179811
179843
|
}
|
|
Binary file
|
|
@@ -69,7 +69,9 @@ source file may match only one language.
|
|
|
69
69
|
| `ruby` | `.rb` | `public`, `protected`, `private` | `public` | CRuby 3.3 or later |
|
|
70
70
|
| `java` | `.java` | `public`, `protected`, `package`, `private` | `public` | JDK 17 or later |
|
|
71
71
|
|
|
72
|
-
Patterns must end with one of the language's extensions.
|
|
72
|
+
Patterns must end with one of the language's extensions. Each language also
|
|
73
|
+
accepts an optional `exclude` array that removes matched files, such as generated
|
|
74
|
+
code; see [Excluded files](#excluded-files). The npm package
|
|
73
75
|
bundles the Swift, Dart, Rust, and Go scanners for `darwin-arm64` and
|
|
74
76
|
`linux-x64`; TypeScript, JavaScript, and Markdown need no scanner binary.
|
|
75
77
|
Python, Ruby, and Java are scanned by workers in the package that run on the
|
|
@@ -136,9 +138,29 @@ DocBridge there.
|
|
|
136
138
|
|
|
137
139
|
## Excluded files
|
|
138
140
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
141
|
+
Use `exclude` in a language entry to remove matched files that should not be
|
|
142
|
+
managed, such as generated code. Flutter's `build_runner` outputs `*.g.dart` and
|
|
143
|
+
`*.freezed.dart` are the usual case:
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"include": {
|
|
148
|
+
"code": {
|
|
149
|
+
"dart": {
|
|
150
|
+
"patterns": ["lib/**/*.dart"],
|
|
151
|
+
"exclude": ["lib/**/*.g.dart", "lib/**/*.freezed.dart"]
|
|
152
|
+
}
|
|
153
|
+
},
|
|
154
|
+
"docs": ["docs/**/*.md"]
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Each `exclude` pattern follows the `patterns` rules and must end with the
|
|
160
|
+
language's extension. The configuration has no glob negation, so `exclude` is the
|
|
161
|
+
only way to remove files that `patterns` matches. Narrow the positive include
|
|
162
|
+
patterns when tests, fixtures, or general documentation should stay outside the
|
|
163
|
+
graph:
|
|
142
164
|
|
|
143
165
|
```json
|
|
144
166
|
{
|
package/package.json
CHANGED
|
@@ -78,6 +78,13 @@
|
|
|
78
78
|
"pattern": "^(?!.*\\.d\\.[cm]?ts$).*\\.(ts|tsx|mts|cts)$"
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
+
"exclude": {
|
|
82
|
+
"type": "array",
|
|
83
|
+
"items": {
|
|
84
|
+
"type": "string",
|
|
85
|
+
"pattern": "^(?!.*\\.d\\.[cm]?ts$).*\\.(ts|tsx|mts|cts)$"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
81
88
|
"visibility": {
|
|
82
89
|
"type": "array",
|
|
83
90
|
"items": {
|
|
@@ -100,6 +107,13 @@
|
|
|
100
107
|
"pattern": "\\.swift$"
|
|
101
108
|
}
|
|
102
109
|
},
|
|
110
|
+
"exclude": {
|
|
111
|
+
"type": "array",
|
|
112
|
+
"items": {
|
|
113
|
+
"type": "string",
|
|
114
|
+
"pattern": "\\.swift$"
|
|
115
|
+
}
|
|
116
|
+
},
|
|
103
117
|
"visibility": {
|
|
104
118
|
"type": "array",
|
|
105
119
|
"items": {
|
|
@@ -122,6 +136,13 @@
|
|
|
122
136
|
"pattern": "\\.dart$"
|
|
123
137
|
}
|
|
124
138
|
},
|
|
139
|
+
"exclude": {
|
|
140
|
+
"type": "array",
|
|
141
|
+
"items": {
|
|
142
|
+
"type": "string",
|
|
143
|
+
"pattern": "\\.dart$"
|
|
144
|
+
}
|
|
145
|
+
},
|
|
125
146
|
"visibility": {
|
|
126
147
|
"type": "array",
|
|
127
148
|
"items": {
|
|
@@ -144,6 +165,13 @@
|
|
|
144
165
|
"pattern": "\\.rs$"
|
|
145
166
|
}
|
|
146
167
|
},
|
|
168
|
+
"exclude": {
|
|
169
|
+
"type": "array",
|
|
170
|
+
"items": {
|
|
171
|
+
"type": "string",
|
|
172
|
+
"pattern": "\\.rs$"
|
|
173
|
+
}
|
|
174
|
+
},
|
|
147
175
|
"visibility": {
|
|
148
176
|
"type": "array",
|
|
149
177
|
"items": {
|
|
@@ -166,6 +194,13 @@
|
|
|
166
194
|
"pattern": "\\.go$"
|
|
167
195
|
}
|
|
168
196
|
},
|
|
197
|
+
"exclude": {
|
|
198
|
+
"type": "array",
|
|
199
|
+
"items": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"pattern": "\\.go$"
|
|
202
|
+
}
|
|
203
|
+
},
|
|
169
204
|
"visibility": {
|
|
170
205
|
"type": "array",
|
|
171
206
|
"items": {
|
|
@@ -188,6 +223,13 @@
|
|
|
188
223
|
"pattern": "\\.(js|jsx|mjs|cjs)$"
|
|
189
224
|
}
|
|
190
225
|
},
|
|
226
|
+
"exclude": {
|
|
227
|
+
"type": "array",
|
|
228
|
+
"items": {
|
|
229
|
+
"type": "string",
|
|
230
|
+
"pattern": "\\.(js|jsx|mjs|cjs)$"
|
|
231
|
+
}
|
|
232
|
+
},
|
|
191
233
|
"visibility": {
|
|
192
234
|
"type": "array",
|
|
193
235
|
"items": {
|
|
@@ -210,6 +252,13 @@
|
|
|
210
252
|
"pattern": "\\.py$"
|
|
211
253
|
}
|
|
212
254
|
},
|
|
255
|
+
"exclude": {
|
|
256
|
+
"type": "array",
|
|
257
|
+
"items": {
|
|
258
|
+
"type": "string",
|
|
259
|
+
"pattern": "\\.py$"
|
|
260
|
+
}
|
|
261
|
+
},
|
|
213
262
|
"visibility": {
|
|
214
263
|
"type": "array",
|
|
215
264
|
"items": {
|
|
@@ -232,6 +281,13 @@
|
|
|
232
281
|
"pattern": "\\.rb$"
|
|
233
282
|
}
|
|
234
283
|
},
|
|
284
|
+
"exclude": {
|
|
285
|
+
"type": "array",
|
|
286
|
+
"items": {
|
|
287
|
+
"type": "string",
|
|
288
|
+
"pattern": "\\.rb$"
|
|
289
|
+
}
|
|
290
|
+
},
|
|
235
291
|
"visibility": {
|
|
236
292
|
"type": "array",
|
|
237
293
|
"items": {
|
|
@@ -254,6 +310,13 @@
|
|
|
254
310
|
"pattern": "\\.java$"
|
|
255
311
|
}
|
|
256
312
|
},
|
|
313
|
+
"exclude": {
|
|
314
|
+
"type": "array",
|
|
315
|
+
"items": {
|
|
316
|
+
"type": "string",
|
|
317
|
+
"pattern": "\\.java$"
|
|
318
|
+
}
|
|
319
|
+
},
|
|
257
320
|
"visibility": {
|
|
258
321
|
"type": "array",
|
|
259
322
|
"items": {
|