Skip to content

Commit 2d372f3

Browse files
erikhoferclaude
andcommitted
fix(data): restore RELATION_TYPE_PATTERNS, only remove issue ref from comment
Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
1 parent 03dda9b commit 2d372f3

4 files changed

Lines changed: 89 additions & 6 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { RELATION_TYPE_PATTERNS } from './relation-patterns'
2+
3+
const md = RELATION_TYPE_PATTERNS['markdown-link']
4+
const adoc = RELATION_TYPE_PATTERNS['asciidoc-link']
5+
const obs = RELATION_TYPE_PATTERNS['obsidian-link']
6+
7+
describe('markdown-link pattern', () => {
8+
test.each([
9+
['[x](foo.md)', 'foo.md'],
10+
['[](foo.md)', 'foo.md'],
11+
['[x](../a/b.md)', '../a/b.md'],
12+
['[A title](001 Foo.md)', '001 Foo.md']
13+
])('%s captures %s', (input, target) => {
14+
const m = input.match(md)
15+
expect(m).not.toBeNull()
16+
expect(m![1]).toBe(target)
17+
})
18+
19+
test.each(['[x]', '[x](foo)tail', 'head[x](foo)', 'plain text', '(foo.md)'])(
20+
'rejects %s',
21+
input => {
22+
expect(md.test(input)).toBe(false)
23+
}
24+
)
25+
})
26+
27+
describe('asciidoc-link pattern', () => {
28+
test.each([
29+
['<<foo>>', 'foo'],
30+
['<<foo,Text>>', 'foo'],
31+
['<<foo bar>>', 'foo bar']
32+
])('%s captures %s', (input, target) => {
33+
const m = input.match(adoc)
34+
expect(m).not.toBeNull()
35+
expect(m![1]).toBe(target)
36+
})
37+
38+
test.each(['<<foo>>tail', '<< >>', '<<foo', 'head<<foo>>'])(
39+
'rejects %s',
40+
input => {
41+
expect(adoc.test(input)).toBe(false)
42+
}
43+
)
44+
})
45+
46+
describe('obsidian-link pattern', () => {
47+
test.each([
48+
['[[issue-1]]', 'issue-1'],
49+
['[[issue-1|Alias]]', 'issue-1'],
50+
['[[a/b/c]]', 'a/b/c']
51+
])('%s captures %s', (input, target) => {
52+
const m = input.match(obs)
53+
expect(m).not.toBeNull()
54+
expect(m![1]).toBe(target)
55+
})
56+
57+
test.each(['[[]]', '[[a|b|c]]', '[[a]]tail', '[a]', 'foo'])(
58+
'rejects %s',
59+
input => {
60+
expect(obs.test(input)).toBe(false)
61+
}
62+
)
63+
})
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
1+
/**
2+
* Built-in anchored regex patterns, one per supported relation-link syntax.
3+
* A relation value must match the pattern in full; capture group 1 contains
4+
* the relation target. These are consumed by the linter; this library does
5+
* not apply them.
6+
*/
17
export const RELATION_TYPES = [
28
'markdown-link',
39
'asciidoc-link',
410
'obsidian-link'
511
] as const
612
export type RelationType = (typeof RELATION_TYPES)[number]
13+
14+
export const RELATION_TYPE_PATTERNS: Record<RelationType, RegExp> = {
15+
'markdown-link': /^\[[^\]]*\]\(([^)]+)\)$/,
16+
'asciidoc-link': /^<<(\S[^,>]*)(?:,[^>]*)?>>$/,
17+
'obsidian-link': /^\[\[([^|\]]+)(?:\|[^|\]]+)?\]\]$/
18+
}

packages/scope42-data/src/model/workspace-config.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ describe('WorkspaceConfigSchema', () => {
1313
expect(parsed.exclude).toEqual([])
1414
expect(parsed.validation).toEqual({
1515
fileNamePattern: undefined,
16-
relationPattern: undefined,
17-
relationType: undefined
16+
relationPattern: undefined
1817
})
1918
})
2019

@@ -77,12 +76,13 @@ describe('WorkspaceConfigSchema', () => {
7776
expect(parsed.validation.relationPattern!.test('x')).toBe(true)
7877
})
7978

80-
test('relationType is preserved as-is', () => {
79+
test('relationType produces the matching built-in pattern', () => {
8180
const parsed = WorkspaceConfigSchema.parse({
8281
...minimal,
8382
validation: { relationType: 'markdown-link' }
8483
})
85-
expect(parsed.validation.relationType).toBe('markdown-link')
84+
expect(parsed.validation.relationPattern).toBeInstanceOf(RegExp)
85+
expect(parsed.validation.relationPattern!.test('[x](foo.md)')).toBe(true)
8686
})
8787

8888
test('rejects relationPattern and relationType together', () => {

packages/scope42-data/src/model/workspace-config.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/* eslint-disable @typescript-eslint/no-redeclare */
22
import { z } from 'zod'
3-
import { RELATION_TYPES } from './relation-patterns'
3+
import { RELATION_TYPES, RELATION_TYPE_PATTERNS } from './relation-patterns'
44

55
// Parses a regex string and exposes a compiled RegExp. Invalid syntax is
66
// reported as a Zod issue at parse time.
@@ -51,7 +51,15 @@ const ValidationConfig = ValidationConfigBase.refine(
5151
message: 'relationPattern and relationType are mutually exclusive',
5252
path: ['relationType']
5353
}
54-
)
54+
).transform((v: ValidationConfigInput) => ({
55+
fileNamePattern: v.fileNamePattern,
56+
// After transform, only relationPattern is exposed as a compiled RegExp.
57+
// The user's original intent (pattern or type) is collapsed into a single
58+
// effective RegExp.
59+
relationPattern:
60+
v.relationPattern ??
61+
(v.relationType ? RELATION_TYPE_PATTERNS[v.relationType] : undefined)
62+
}))
5563

5664
export const WorkspaceConfigSchema = z
5765
.object({

0 commit comments

Comments
 (0)