feat: add ESLint rule for schema key naming convention in cache and preference schemas

- Introduced a new ESLint rule to enforce a specific naming convention for schema keys: `namespace.sub.key_name`.
- Updated cache and preference schema files to include documentation on the naming convention and examples of valid/invalid keys.
- Modified existing keys in cache schemas to comply with the new convention.
This commit is contained in:
fullex 2025-11-26 12:50:38 +08:00
parent 9583c7c3d2
commit 0f8136705e
3 changed files with 99 additions and 4 deletions

View File

@ -157,4 +157,60 @@ export default defineConfig([
// ]
}
},
// Schema key naming convention (cache & preferences)
{
files: ['packages/shared/data/cache/cacheSchemas.ts', 'packages/shared/data/preference/preferenceSchemas.ts'],
plugins: {
'data-schema-key': {
rules: {
'valid-key': {
meta: {
type: 'problem',
docs: {
description: 'Enforce schema key naming convention: namespace.sub.key_name',
recommended: true
},
messages: {
invalidKey:
'Schema key "{{key}}" must follow format: namespace.sub.key_name (e.g., app.user.avatar).'
}
},
create(context) {
const VALID_KEY_PATTERN = /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/
return {
TSPropertySignature(node) {
if (node.key.type === 'Literal' && typeof node.key.value === 'string') {
const key = node.key.value
if (!VALID_KEY_PATTERN.test(key)) {
context.report({
node: node.key,
messageId: 'invalidKey',
data: { key }
})
}
}
},
Property(node) {
if (node.key.type === 'Literal' && typeof node.key.value === 'string') {
const key = node.key.value
if (!VALID_KEY_PATTERN.test(key)) {
context.report({
node: node.key,
messageId: 'invalidKey',
data: { key }
})
}
}
}
}
}
}
}
}
},
rules: {
'data-schema-key/valid-key': 'error'
}
}
])

View File

@ -1,5 +1,27 @@
import type * as CacheValueTypes from './cacheValueTypes'
/**
* Cache Schema Definitions
*
* ## Key Naming Convention
*
* All cache keys MUST follow the format: `namespace.sub.key_name`
*
* Rules:
* - At least 2 segments separated by dots (.)
* - Each segment uses lowercase letters, numbers, and underscores only
* - Pattern: /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/
*
* Examples:
* - 'app.user.avatar' (valid)
* - 'chat.multi_select_mode' (valid)
* - 'minapp.opened_keep_alive' (valid)
* - 'userAvatar' (invalid - missing dot separator)
* - 'App.user' (invalid - uppercase not allowed)
*
* This convention is enforced by ESLint rule: data-schema-key/valid-key
*/
/**
* Use cache schema for renderer hook
*/
@ -63,11 +85,11 @@ export const DefaultUseCache: UseCacheSchema = {
* Use shared cache schema for renderer hook
*/
export type UseSharedCacheSchema = {
'example-key': string
'example_scope.example_key': string
}
export const DefaultUseSharedCache: UseSharedCacheSchema = {
'example-key': 'example default value'
'example_scope.example_key': 'example default value'
}
/**
@ -75,11 +97,11 @@ export const DefaultUseSharedCache: UseSharedCacheSchema = {
* This ensures type safety and prevents key conflicts
*/
export type RendererPersistCacheSchema = {
'example-key': string
'example_scope.example_key': string
}
export const DefaultRendererPersistCache: RendererPersistCacheSchema = {
'example-key': 'example default value'
'example_scope.example_key': 'example default value'
}
/**

View File

@ -6,6 +6,23 @@
* To update this file, modify classification.json and run:
* node .claude/data-classify/scripts/generate-preferences.js
*
* ## Key Naming Convention
*
* All preference keys MUST follow the format: `namespace.sub.key_name`
*
* Rules:
* - At least 2 segments separated by dots (.)
* - Each segment uses lowercase letters, numbers, and underscores only
* - Pattern: /^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*)+$/
*
* Examples:
* - 'app.user.avatar' (valid)
* - 'chat.multi_select_mode' (valid)
* - 'userAvatar' (invalid - missing dot separator)
* - 'App.user' (invalid - uppercase not allowed)
*
* This convention is enforced by ESLint rule: data-schema-key/valid-key
*
* === AUTO-GENERATED CONTENT START ===
*/