artifact-graph 0.9.1 → 0.9.3
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 +33 -0
- package/dist/cli.js +44 -9
- package/dist/index.cjs +46 -8
- package/dist/index.js +46 -8
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.9.3
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- Scenario titles and explicit relation fields inside Markdown fenced code blocks
|
|
8
|
+
(```` ``` ```` or `~~~`) are no longer scanned: examples such as
|
|
9
|
+
`**关联决策**: ADR-0001` shown inside a fence produce neither scenario nodes nor graph
|
|
10
|
+
edges. A fence closes only on the same marker with a length at least as long as the
|
|
11
|
+
opening fence.
|
|
12
|
+
- Explicit relation fields indented by four or more spaces or a tab are now treated as
|
|
13
|
+
indented code and no longer produce edges. Outside code blocks, a real relation field
|
|
14
|
+
may be indented by at most 0—3 plain spaces. Behavior tightening: adopters who relied
|
|
15
|
+
on deeply indented relation fields must move them to line start (0—3 spaces).
|
|
16
|
+
- The public `validateScenarioPrdLinks` function once again returns the complete
|
|
17
|
+
diagnostics (including `FORMAT_ERROR` for invalid feature references) when called
|
|
18
|
+
directly on scan results, restoring the public API behavior regressed in 0.9.2.
|
|
19
|
+
- `validateGraph` still uses scan diagnostics as the single source for scanned invalid
|
|
20
|
+
relations, so the same invalid feature reference is reported exactly once.
|
|
21
|
+
|
|
22
|
+
## 0.9.2
|
|
23
|
+
|
|
24
|
+
### Fixed
|
|
25
|
+
|
|
26
|
+
- Scenario explicit relation field recognition is tightened to whole-line field syntax matching:
|
|
27
|
+
plain prose mentions of `关联功能` / `关联决策` / `关联实体` no longer produce edges or
|
|
28
|
+
spurious `FORMAT_ERROR` diagnostics.
|
|
29
|
+
- An invalid explicit relation reference is no longer reported twice across the scan and
|
|
30
|
+
validation stages: `validateGraph` now returns exactly one `FORMAT_ERROR` carrying the file,
|
|
31
|
+
line number, node, invalid value, and the expected rule.
|
|
32
|
+
- Behavior tightening: Markdown list-item forms such as `- **关联决策**: ADR-0001` are no longer
|
|
33
|
+
recognized as explicit relation fields (0.9.1 misidentified them via substring matching);
|
|
34
|
+
standard line-start field syntax is unaffected.
|
|
35
|
+
|
|
3
36
|
## 0.9.1
|
|
4
37
|
|
|
5
38
|
### Fixed
|
package/dist/cli.js
CHANGED
|
@@ -4936,7 +4936,7 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
4936
4936
|
}
|
|
4937
4937
|
issues.push(...validateE2eTests(graph));
|
|
4938
4938
|
issues.push(...validateE2eRegistry(graph));
|
|
4939
|
-
issues.push(...
|
|
4939
|
+
issues.push(...validateScenarioPrdLinksInternal(graph, schema, false));
|
|
4940
4940
|
issues.push(...validateCodeCommentTraceabilityFormat(graph));
|
|
4941
4941
|
issues.push(...validateCodeCommentScenarioFeatureConsistency(graph));
|
|
4942
4942
|
for (const edge2 of graph.edges) {
|
|
@@ -5038,7 +5038,7 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
5038
5038
|
issues.sort((left, right) => left.code.localeCompare(right.code) || left.path.localeCompare(right.path) || left.line - right.line);
|
|
5039
5039
|
return issues;
|
|
5040
5040
|
}
|
|
5041
|
-
function
|
|
5041
|
+
function validateScenarioPrdLinksInternal(graph, schema, includeScanDiagnosedInvalid) {
|
|
5042
5042
|
if (!schema.relationFields.scenario?.includes("\u5173\u8054\u529F\u80FD") || !schema.relationFields.feature?.includes("scenarios")) {
|
|
5043
5043
|
return [];
|
|
5044
5044
|
}
|
|
@@ -5072,6 +5072,7 @@ function validateScenarioPrdLinks(graph, schema = DEFAULT_SCHEMA) {
|
|
|
5072
5072
|
}
|
|
5073
5073
|
pushDuplicateIssues(issues, scenarioUid, validRefs, "feature");
|
|
5074
5074
|
for (const ref of refs) {
|
|
5075
|
+
if (ref.valid === false && !includeScanDiagnosedInvalid) continue;
|
|
5075
5076
|
if (!featurePattern.test(ref.target)) {
|
|
5076
5077
|
issues.push(issue("FORMAT_ERROR", `scenario ${scenarioUid} has invalid feature reference ${ref.target}`, ref.path, ref.line, { node: scenarioUid }));
|
|
5077
5078
|
}
|
|
@@ -5575,8 +5576,12 @@ function parseFeature(path, raw) {
|
|
|
5575
5576
|
}
|
|
5576
5577
|
function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
5577
5578
|
const lines = raw.split(/\r?\n/);
|
|
5579
|
+
const codeLines = markdownCodeLineMask(lines);
|
|
5578
5580
|
const starts = [];
|
|
5579
5581
|
lines.forEach((line, index) => {
|
|
5582
|
+
if (codeLines[index]) {
|
|
5583
|
+
return;
|
|
5584
|
+
}
|
|
5580
5585
|
const match = /^#{2,3}\s+(S-\d+[a-z]?)\s*[::]\s*(.+?)\s*$/.exec(line);
|
|
5581
5586
|
if (match) {
|
|
5582
5587
|
starts.push({ code: match[1], title: match[2], line: index + 1, index });
|
|
@@ -5589,9 +5594,9 @@ function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
|
5589
5594
|
const start = starts[i];
|
|
5590
5595
|
const end = starts[i + 1]?.index ?? lines.length;
|
|
5591
5596
|
const block = lines.slice(start.index, end);
|
|
5592
|
-
const featureRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5593
|
-
const decisionRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5594
|
-
const entityRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5597
|
+
const featureRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5598
|
+
const decisionRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5599
|
+
const entityRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5595
5600
|
nodes.push({
|
|
5596
5601
|
type: "scenario",
|
|
5597
5602
|
code: start.code,
|
|
@@ -6826,13 +6831,42 @@ function decisionFrontmatterEdges(path, decisionCode, value, targetType, kind) {
|
|
|
6826
6831
|
return [edge(toUid("decision", decisionCode), toUid(targetType, code), kind, "frontmatter", path, 1)];
|
|
6827
6832
|
});
|
|
6828
6833
|
}
|
|
6829
|
-
function
|
|
6834
|
+
function matchExplicitRelationFieldLine(line, label) {
|
|
6835
|
+
const escaped = escapeRegExp(label);
|
|
6836
|
+
const match = new RegExp(`^ {0,3}(?:\\*\\*${escaped}\\*\\*|${escaped})[:\uFF1A]\\s*(.*?)\\s*$`).exec(line);
|
|
6837
|
+
return match?.[1] ?? null;
|
|
6838
|
+
}
|
|
6839
|
+
function markdownCodeLineMask(lines) {
|
|
6840
|
+
const result = new Array(lines.length).fill(false);
|
|
6841
|
+
let fence;
|
|
6842
|
+
lines.forEach((line, index) => {
|
|
6843
|
+
if (fence) {
|
|
6844
|
+
result[index] = true;
|
|
6845
|
+
const closing = /^ {0,3}(`+|~+)[ \t]*$/.exec(line);
|
|
6846
|
+
if (closing && closing[1][0] === fence.marker && closing[1].length >= fence.length) {
|
|
6847
|
+
fence = void 0;
|
|
6848
|
+
}
|
|
6849
|
+
return;
|
|
6850
|
+
}
|
|
6851
|
+
const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
|
|
6852
|
+
if (opening) {
|
|
6853
|
+
result[index] = true;
|
|
6854
|
+
fence = { marker: opening[1][0], length: opening[1].length };
|
|
6855
|
+
return;
|
|
6856
|
+
}
|
|
6857
|
+
if (/^(?: {4,}| {0,3}\t)/.test(line)) {
|
|
6858
|
+
result[index] = true;
|
|
6859
|
+
}
|
|
6860
|
+
});
|
|
6861
|
+
return result;
|
|
6862
|
+
}
|
|
6863
|
+
function markdownRelationOccurrences(path, scenario, block, codeLines, label, targetType, schema = DEFAULT_SCHEMA) {
|
|
6830
6864
|
const result = [];
|
|
6831
6865
|
block.forEach((line, index) => {
|
|
6832
|
-
if (
|
|
6866
|
+
if (codeLines[scenario.index + index]) {
|
|
6833
6867
|
return;
|
|
6834
6868
|
}
|
|
6835
|
-
const relationText = line
|
|
6869
|
+
const relationText = matchExplicitRelationFieldLine(line, label);
|
|
6836
6870
|
if (!relationText) {
|
|
6837
6871
|
return;
|
|
6838
6872
|
}
|
|
@@ -6865,7 +6899,8 @@ function relationOccurrences(node, field, targetType) {
|
|
|
6865
6899
|
target,
|
|
6866
6900
|
path: typeof record.path === "string" ? record.path : node.path,
|
|
6867
6901
|
line: typeof record.line === "number" ? record.line : node.line,
|
|
6868
|
-
raw: typeof record.raw === "string" ? record.raw : void 0
|
|
6902
|
+
raw: typeof record.raw === "string" ? record.raw : void 0,
|
|
6903
|
+
valid: typeof record.valid === "boolean" ? record.valid : void 0
|
|
6869
6904
|
}];
|
|
6870
6905
|
});
|
|
6871
6906
|
}
|
package/dist/index.cjs
CHANGED
|
@@ -4914,7 +4914,7 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
4914
4914
|
}
|
|
4915
4915
|
issues.push(...validateE2eTests(graph));
|
|
4916
4916
|
issues.push(...validateE2eRegistry(graph));
|
|
4917
|
-
issues.push(...
|
|
4917
|
+
issues.push(...validateScenarioPrdLinksInternal(graph, schema, false));
|
|
4918
4918
|
issues.push(...validateCodeCommentTraceabilityFormat(graph));
|
|
4919
4919
|
issues.push(...validateCodeCommentScenarioFeatureConsistency(graph));
|
|
4920
4920
|
for (const edge2 of graph.edges) {
|
|
@@ -5017,6 +5017,9 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
5017
5017
|
return issues;
|
|
5018
5018
|
}
|
|
5019
5019
|
function validateScenarioPrdLinks(graph, schema = DEFAULT_SCHEMA) {
|
|
5020
|
+
return validateScenarioPrdLinksInternal(graph, schema, true);
|
|
5021
|
+
}
|
|
5022
|
+
function validateScenarioPrdLinksInternal(graph, schema, includeScanDiagnosedInvalid) {
|
|
5020
5023
|
if (!schema.relationFields.scenario?.includes("\u5173\u8054\u529F\u80FD") || !schema.relationFields.feature?.includes("scenarios")) {
|
|
5021
5024
|
return [];
|
|
5022
5025
|
}
|
|
@@ -5050,6 +5053,7 @@ function validateScenarioPrdLinks(graph, schema = DEFAULT_SCHEMA) {
|
|
|
5050
5053
|
}
|
|
5051
5054
|
pushDuplicateIssues(issues, scenarioUid, validRefs, "feature");
|
|
5052
5055
|
for (const ref of refs) {
|
|
5056
|
+
if (ref.valid === false && !includeScanDiagnosedInvalid) continue;
|
|
5053
5057
|
if (!featurePattern.test(ref.target)) {
|
|
5054
5058
|
issues.push(issue("FORMAT_ERROR", `scenario ${scenarioUid} has invalid feature reference ${ref.target}`, ref.path, ref.line, { node: scenarioUid }));
|
|
5055
5059
|
}
|
|
@@ -5553,8 +5557,12 @@ function parseFeature(path, raw) {
|
|
|
5553
5557
|
}
|
|
5554
5558
|
function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
5555
5559
|
const lines = raw.split(/\r?\n/);
|
|
5560
|
+
const codeLines = markdownCodeLineMask(lines);
|
|
5556
5561
|
const starts = [];
|
|
5557
5562
|
lines.forEach((line, index) => {
|
|
5563
|
+
if (codeLines[index]) {
|
|
5564
|
+
return;
|
|
5565
|
+
}
|
|
5558
5566
|
const match = /^#{2,3}\s+(S-\d+[a-z]?)\s*[::]\s*(.+?)\s*$/.exec(line);
|
|
5559
5567
|
if (match) {
|
|
5560
5568
|
starts.push({ code: match[1], title: match[2], line: index + 1, index });
|
|
@@ -5567,9 +5575,9 @@ function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
|
5567
5575
|
const start = starts[i];
|
|
5568
5576
|
const end = starts[i + 1]?.index ?? lines.length;
|
|
5569
5577
|
const block = lines.slice(start.index, end);
|
|
5570
|
-
const featureRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5571
|
-
const decisionRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5572
|
-
const entityRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5578
|
+
const featureRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5579
|
+
const decisionRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5580
|
+
const entityRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5573
5581
|
nodes.push({
|
|
5574
5582
|
type: "scenario",
|
|
5575
5583
|
code: start.code,
|
|
@@ -6804,13 +6812,42 @@ function decisionFrontmatterEdges(path, decisionCode, value, targetType, kind) {
|
|
|
6804
6812
|
return [edge(toUid("decision", decisionCode), toUid(targetType, code), kind, "frontmatter", path, 1)];
|
|
6805
6813
|
});
|
|
6806
6814
|
}
|
|
6807
|
-
function
|
|
6815
|
+
function matchExplicitRelationFieldLine(line, label) {
|
|
6816
|
+
const escaped = escapeRegExp(label);
|
|
6817
|
+
const match = new RegExp(`^ {0,3}(?:\\*\\*${escaped}\\*\\*|${escaped})[:\uFF1A]\\s*(.*?)\\s*$`).exec(line);
|
|
6818
|
+
return match?.[1] ?? null;
|
|
6819
|
+
}
|
|
6820
|
+
function markdownCodeLineMask(lines) {
|
|
6821
|
+
const result = new Array(lines.length).fill(false);
|
|
6822
|
+
let fence;
|
|
6823
|
+
lines.forEach((line, index) => {
|
|
6824
|
+
if (fence) {
|
|
6825
|
+
result[index] = true;
|
|
6826
|
+
const closing = /^ {0,3}(`+|~+)[ \t]*$/.exec(line);
|
|
6827
|
+
if (closing && closing[1][0] === fence.marker && closing[1].length >= fence.length) {
|
|
6828
|
+
fence = void 0;
|
|
6829
|
+
}
|
|
6830
|
+
return;
|
|
6831
|
+
}
|
|
6832
|
+
const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
|
|
6833
|
+
if (opening) {
|
|
6834
|
+
result[index] = true;
|
|
6835
|
+
fence = { marker: opening[1][0], length: opening[1].length };
|
|
6836
|
+
return;
|
|
6837
|
+
}
|
|
6838
|
+
if (/^(?: {4,}| {0,3}\t)/.test(line)) {
|
|
6839
|
+
result[index] = true;
|
|
6840
|
+
}
|
|
6841
|
+
});
|
|
6842
|
+
return result;
|
|
6843
|
+
}
|
|
6844
|
+
function markdownRelationOccurrences(path, scenario, block, codeLines, label, targetType, schema = DEFAULT_SCHEMA) {
|
|
6808
6845
|
const result = [];
|
|
6809
6846
|
block.forEach((line, index) => {
|
|
6810
|
-
if (
|
|
6847
|
+
if (codeLines[scenario.index + index]) {
|
|
6811
6848
|
return;
|
|
6812
6849
|
}
|
|
6813
|
-
const relationText = line
|
|
6850
|
+
const relationText = matchExplicitRelationFieldLine(line, label);
|
|
6814
6851
|
if (!relationText) {
|
|
6815
6852
|
return;
|
|
6816
6853
|
}
|
|
@@ -6843,7 +6880,8 @@ function relationOccurrences(node, field, targetType) {
|
|
|
6843
6880
|
target,
|
|
6844
6881
|
path: typeof record.path === "string" ? record.path : node.path,
|
|
6845
6882
|
line: typeof record.line === "number" ? record.line : node.line,
|
|
6846
|
-
raw: typeof record.raw === "string" ? record.raw : void 0
|
|
6883
|
+
raw: typeof record.raw === "string" ? record.raw : void 0,
|
|
6884
|
+
valid: typeof record.valid === "boolean" ? record.valid : void 0
|
|
6847
6885
|
}];
|
|
6848
6886
|
});
|
|
6849
6887
|
}
|
package/dist/index.js
CHANGED
|
@@ -4804,7 +4804,7 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
4804
4804
|
}
|
|
4805
4805
|
issues.push(...validateE2eTests(graph));
|
|
4806
4806
|
issues.push(...validateE2eRegistry(graph));
|
|
4807
|
-
issues.push(...
|
|
4807
|
+
issues.push(...validateScenarioPrdLinksInternal(graph, schema, false));
|
|
4808
4808
|
issues.push(...validateCodeCommentTraceabilityFormat(graph));
|
|
4809
4809
|
issues.push(...validateCodeCommentScenarioFeatureConsistency(graph));
|
|
4810
4810
|
for (const edge2 of graph.edges) {
|
|
@@ -4907,6 +4907,9 @@ function validateGraph(graph, schema = DEFAULT_SCHEMA) {
|
|
|
4907
4907
|
return issues;
|
|
4908
4908
|
}
|
|
4909
4909
|
function validateScenarioPrdLinks(graph, schema = DEFAULT_SCHEMA) {
|
|
4910
|
+
return validateScenarioPrdLinksInternal(graph, schema, true);
|
|
4911
|
+
}
|
|
4912
|
+
function validateScenarioPrdLinksInternal(graph, schema, includeScanDiagnosedInvalid) {
|
|
4910
4913
|
if (!schema.relationFields.scenario?.includes("\u5173\u8054\u529F\u80FD") || !schema.relationFields.feature?.includes("scenarios")) {
|
|
4911
4914
|
return [];
|
|
4912
4915
|
}
|
|
@@ -4940,6 +4943,7 @@ function validateScenarioPrdLinks(graph, schema = DEFAULT_SCHEMA) {
|
|
|
4940
4943
|
}
|
|
4941
4944
|
pushDuplicateIssues(issues, scenarioUid, validRefs, "feature");
|
|
4942
4945
|
for (const ref of refs) {
|
|
4946
|
+
if (ref.valid === false && !includeScanDiagnosedInvalid) continue;
|
|
4943
4947
|
if (!featurePattern.test(ref.target)) {
|
|
4944
4948
|
issues.push(issue("FORMAT_ERROR", `scenario ${scenarioUid} has invalid feature reference ${ref.target}`, ref.path, ref.line, { node: scenarioUid }));
|
|
4945
4949
|
}
|
|
@@ -5443,8 +5447,12 @@ function parseFeature(path, raw) {
|
|
|
5443
5447
|
}
|
|
5444
5448
|
function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
5445
5449
|
const lines = raw.split(/\r?\n/);
|
|
5450
|
+
const codeLines = markdownCodeLineMask(lines);
|
|
5446
5451
|
const starts = [];
|
|
5447
5452
|
lines.forEach((line, index) => {
|
|
5453
|
+
if (codeLines[index]) {
|
|
5454
|
+
return;
|
|
5455
|
+
}
|
|
5448
5456
|
const match = /^#{2,3}\s+(S-\d+[a-z]?)\s*[::]\s*(.+?)\s*$/.exec(line);
|
|
5449
5457
|
if (match) {
|
|
5450
5458
|
starts.push({ code: match[1], title: match[2], line: index + 1, index });
|
|
@@ -5457,9 +5465,9 @@ function parseScenarios(path, raw, schema = DEFAULT_SCHEMA) {
|
|
|
5457
5465
|
const start = starts[i];
|
|
5458
5466
|
const end = starts[i + 1]?.index ?? lines.length;
|
|
5459
5467
|
const block = lines.slice(start.index, end);
|
|
5460
|
-
const featureRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5461
|
-
const decisionRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5462
|
-
const entityRefs = markdownRelationOccurrences(path, start, block, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5468
|
+
const featureRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u529F\u80FD", "feature", schema);
|
|
5469
|
+
const decisionRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u51B3\u7B56", "decision", schema);
|
|
5470
|
+
const entityRefs = markdownRelationOccurrences(path, start, block, codeLines, "\u5173\u8054\u5B9E\u4F53", "entity", schema);
|
|
5463
5471
|
nodes.push({
|
|
5464
5472
|
type: "scenario",
|
|
5465
5473
|
code: start.code,
|
|
@@ -6694,13 +6702,42 @@ function decisionFrontmatterEdges(path, decisionCode, value, targetType, kind) {
|
|
|
6694
6702
|
return [edge(toUid("decision", decisionCode), toUid(targetType, code), kind, "frontmatter", path, 1)];
|
|
6695
6703
|
});
|
|
6696
6704
|
}
|
|
6697
|
-
function
|
|
6705
|
+
function matchExplicitRelationFieldLine(line, label) {
|
|
6706
|
+
const escaped = escapeRegExp(label);
|
|
6707
|
+
const match = new RegExp(`^ {0,3}(?:\\*\\*${escaped}\\*\\*|${escaped})[:\uFF1A]\\s*(.*?)\\s*$`).exec(line);
|
|
6708
|
+
return match?.[1] ?? null;
|
|
6709
|
+
}
|
|
6710
|
+
function markdownCodeLineMask(lines) {
|
|
6711
|
+
const result = new Array(lines.length).fill(false);
|
|
6712
|
+
let fence;
|
|
6713
|
+
lines.forEach((line, index) => {
|
|
6714
|
+
if (fence) {
|
|
6715
|
+
result[index] = true;
|
|
6716
|
+
const closing = /^ {0,3}(`+|~+)[ \t]*$/.exec(line);
|
|
6717
|
+
if (closing && closing[1][0] === fence.marker && closing[1].length >= fence.length) {
|
|
6718
|
+
fence = void 0;
|
|
6719
|
+
}
|
|
6720
|
+
return;
|
|
6721
|
+
}
|
|
6722
|
+
const opening = /^ {0,3}(`{3,}|~{3,})(.*)$/.exec(line);
|
|
6723
|
+
if (opening) {
|
|
6724
|
+
result[index] = true;
|
|
6725
|
+
fence = { marker: opening[1][0], length: opening[1].length };
|
|
6726
|
+
return;
|
|
6727
|
+
}
|
|
6728
|
+
if (/^(?: {4,}| {0,3}\t)/.test(line)) {
|
|
6729
|
+
result[index] = true;
|
|
6730
|
+
}
|
|
6731
|
+
});
|
|
6732
|
+
return result;
|
|
6733
|
+
}
|
|
6734
|
+
function markdownRelationOccurrences(path, scenario, block, codeLines, label, targetType, schema = DEFAULT_SCHEMA) {
|
|
6698
6735
|
const result = [];
|
|
6699
6736
|
block.forEach((line, index) => {
|
|
6700
|
-
if (
|
|
6737
|
+
if (codeLines[scenario.index + index]) {
|
|
6701
6738
|
return;
|
|
6702
6739
|
}
|
|
6703
|
-
const relationText = line
|
|
6740
|
+
const relationText = matchExplicitRelationFieldLine(line, label);
|
|
6704
6741
|
if (!relationText) {
|
|
6705
6742
|
return;
|
|
6706
6743
|
}
|
|
@@ -6733,7 +6770,8 @@ function relationOccurrences(node, field, targetType) {
|
|
|
6733
6770
|
target,
|
|
6734
6771
|
path: typeof record.path === "string" ? record.path : node.path,
|
|
6735
6772
|
line: typeof record.line === "number" ? record.line : node.line,
|
|
6736
|
-
raw: typeof record.raw === "string" ? record.raw : void 0
|
|
6773
|
+
raw: typeof record.raw === "string" ? record.raw : void 0,
|
|
6774
|
+
valid: typeof record.valid === "boolean" ? record.valid : void 0
|
|
6737
6775
|
}];
|
|
6738
6776
|
});
|
|
6739
6777
|
}
|