feat: replace 'Is a' / 'is_a' with 'type' as the canonical frontmatter key
- Rust Frontmatter struct now parses both 'type' (new) and 'Is A'/'is_a' (legacy), with 'type' taking precedence via resolve_type() - Added migrate_is_a_to_type() vault-wide migration (runs on startup, also exposed as Tauri command) - Frontend: buildNoteContent and resolveNewType now emit 'type:' in YAML - Inspector SKIP_KEYS hides 'is_a', 'Is A', 'type', 'title' from property list (TypeRow already renders the type with its dedicated UI) - frontmatterToEntryPatch handles both 'type' and legacy 'is_a' keys - Mock data updated: all YAML content uses 'type:' instead of 'is_a:'/'Is A:' - Tests updated to expect 'type:' in generated frontmatter Product decision: internal VaultEntry field stays as `isA` (TS) / `is_a` (Rust) to minimize blast radius. The user-facing change is the YAML key and inspector. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -166,12 +166,12 @@ describe('entryMatchesTarget', () => {
|
||||
describe('buildNoteContent', () => {
|
||||
it('generates frontmatter with status for regular types', () => {
|
||||
const content = buildNoteContent('My Note', 'Note', 'Active')
|
||||
expect(content).toBe('---\ntitle: My Note\nis_a: Note\nstatus: Active\n---\n\n# My Note\n\n')
|
||||
expect(content).toBe('---\ntitle: My Note\ntype: Note\nstatus: Active\n---\n\n# My Note\n\n')
|
||||
})
|
||||
|
||||
it('omits status when null', () => {
|
||||
const content = buildNoteContent('AI', 'Topic', null)
|
||||
expect(content).toBe('---\ntitle: AI\nis_a: Topic\n---\n\n# AI\n\n')
|
||||
expect(content).toBe('---\ntitle: AI\ntype: Topic\n---\n\n# AI\n\n')
|
||||
})
|
||||
})
|
||||
|
||||
@@ -181,7 +181,7 @@ describe('resolveNewNote', () => {
|
||||
expect(entry.path).toBe('/Users/luca/Laputa/project/my-project.md')
|
||||
expect(entry.isA).toBe('Project')
|
||||
expect(entry.status).toBe('Active')
|
||||
expect(content).toContain('is_a: Project')
|
||||
expect(content).toContain('type: Project')
|
||||
expect(content).toContain('status: Active')
|
||||
})
|
||||
|
||||
@@ -208,13 +208,14 @@ describe('resolveNewType', () => {
|
||||
expect(entry.path).toBe('/Users/luca/Laputa/type/recipe.md')
|
||||
expect(entry.isA).toBe('Type')
|
||||
expect(entry.status).toBeNull()
|
||||
expect(content).toContain('Is A: Type')
|
||||
expect(content).toContain('type: Type')
|
||||
expect(content).toContain('# Recipe')
|
||||
})
|
||||
})
|
||||
|
||||
describe('frontmatterToEntryPatch', () => {
|
||||
it.each([
|
||||
['type', 'Project', { isA: 'Project' }],
|
||||
['is_a', 'Project', { isA: 'Project' }],
|
||||
['status', 'Done', { status: 'Done' }],
|
||||
['color', 'red', { color: 'red' }],
|
||||
|
||||
Reference in New Issue
Block a user