feat(editor): support user provided role and role schema (#10939)
Let me analyze the key changes in this diff: 1. **Role System Changes**: - Changed from a fixed enum of roles (`root`, `hub`, `content`) to a more flexible string-based system - Removed strict role hierarchy validation rules (hub/content/root relationships) - Added support for role-based matching using `@` prefix (e.g., `@root`, `@content`) 2. **Schema Validation Updates**: - Added new `_matchFlavourOrRole` method to handle both flavour and role-based matching - Updated `_validateParent` to consider both roles and flavours when validating parent-child relationships - Simplified `_validateRole` by removing specific role hierarchy constraints 3. **Block Schema Changes**: - Updated parent/children references in various block schemas to use the new `@` prefix notation - Changed parent definitions from `['affine:page']` to `['@root']` in several blocks - Updated children definitions to use role-based references (e.g., `['@content']`) 4. **Test Updates**: - Added new test cases for role-based schema validation - Introduced new test block schemas (`TestRoleBlockSchema`, `TestParagraphBlockSchema`) to verify role-based functionality This appears to be a significant architectural change that makes the block schema system more flexible by: 1. Moving away from hardcoded role hierarchies 2. Introducing a more dynamic role-based relationship system 3. Supporting both flavour-based and role-based parent-child relationships 4. Using the `@` prefix convention to distinguish role references from flavour references The changes make the system more extensible while maintaining backward compatibility with existing flavour-based relationships.
This commit is contained in:
@@ -54,6 +54,34 @@ const TestInvalidNoteBlockSchemaExtension = BlockSchemaExtension(
|
||||
TestInvalidNoteBlockSchema
|
||||
);
|
||||
|
||||
const TestRoleBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:note-block-role-test',
|
||||
metadata: {
|
||||
version: 1,
|
||||
role: 'content',
|
||||
parent: ['affine:note'],
|
||||
children: ['@test'],
|
||||
},
|
||||
props: internal => ({
|
||||
text: internal.Text(),
|
||||
}),
|
||||
});
|
||||
|
||||
const TestRoleBlockSchemaExtension = BlockSchemaExtension(TestRoleBlockSchema);
|
||||
|
||||
const TestParagraphBlockSchema = defineBlockSchema({
|
||||
flavour: 'affine:test-paragraph',
|
||||
metadata: {
|
||||
version: 1,
|
||||
role: 'test',
|
||||
parent: ['@content'],
|
||||
},
|
||||
});
|
||||
|
||||
const TestParagraphBlockSchemaExtension = BlockSchemaExtension(
|
||||
TestParagraphBlockSchema
|
||||
);
|
||||
|
||||
const extensions = [
|
||||
RootBlockSchemaExtension,
|
||||
ParagraphBlockSchemaExtension,
|
||||
@@ -62,6 +90,8 @@ const extensions = [
|
||||
DividerBlockSchemaExtension,
|
||||
TestCustomNoteBlockSchemaExtension,
|
||||
TestInvalidNoteBlockSchemaExtension,
|
||||
TestRoleBlockSchemaExtension,
|
||||
TestParagraphBlockSchemaExtension,
|
||||
];
|
||||
|
||||
const defaultDocId = 'doc0';
|
||||
@@ -128,4 +158,28 @@ describe('schema', () => {
|
||||
return call[0] instanceof SchemaValidateError;
|
||||
});
|
||||
});
|
||||
|
||||
it('should be able to validate schema by role', () => {
|
||||
const consoleMock = vi
|
||||
.spyOn(console, 'error')
|
||||
.mockImplementation(() => undefined);
|
||||
const doc = createTestDoc();
|
||||
const rootId = doc.addBlock('affine:page', {});
|
||||
const noteId = doc.addBlock('affine:note', {}, rootId);
|
||||
const roleId = doc.addBlock('affine:note-block-role-test', {}, noteId);
|
||||
|
||||
doc.addBlock('affine:paragraph', {}, roleId);
|
||||
doc.addBlock('affine:paragraph', {}, roleId);
|
||||
|
||||
expect(consoleMock.mock.calls[1]).toSatisfy((call: unknown[]) => {
|
||||
return call[0] instanceof SchemaValidateError;
|
||||
});
|
||||
|
||||
consoleMock.mockClear();
|
||||
doc.addBlock('affine:test-paragraph', {}, roleId);
|
||||
doc.addBlock('affine:test-paragraph', {}, roleId);
|
||||
expect(consoleMock).not.toBeCalled();
|
||||
|
||||
expect(doc.getBlocksByFlavour('affine:test-paragraph')).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user