chore: move code-pattern checks to oxlint

This commit is contained in:
Danila Poyarkov 2026-05-14 22:22:07 +03:00
parent 686ca5326f
commit 3eedd0740e
4 changed files with 60 additions and 25 deletions

View file

@ -175,6 +175,62 @@ const noStructuredCloneSceneArrays = {
}
}
const noVueStyleBlocks = {
meta: {
docs: {
description: 'Disallow Vue component <style> blocks — use Tailwind utilities or global tokens'
}
},
create(context) {
const file = normalizedFilename(context)
if (!file.endsWith('.vue')) return {}
if (!file.includes('/src/') && !file.includes('/packages/vue/src/')) return {}
return {
Program(node) {
const source = context.sourceCode.getText()
if (/<style\b/i.test(source)) {
context.report({
node,
message:
'Vue components must not use <style> blocks. Use Tailwind utilities or global app.css tokens.'
})
}
}
}
}
}
const noDirectSelectionToolStateMutation = {
meta: {
docs: {
description: 'Disallow direct editor selection/tool state assignment outside core editor internals'
}
},
create(context) {
const file = normalizedFilename(context)
if (file.includes('/packages/core/src/editor/')) return {}
return {
AssignmentExpression(node) {
if (node.operator !== '=') return
const left = node.left
if (left?.type !== 'MemberExpression') return
if (left.property?.type !== 'Identifier') return
if (left.property.name !== 'selectedIds' && left.property.name !== 'activeTool') return
const stateExpr = left.object
if (stateExpr?.type !== 'MemberExpression') return
if (stateExpr.property?.type !== 'Identifier' || stateExpr.property.name !== 'state') return
context.report({
node,
message:
'Do not assign editor.state.selectedIds or editor.state.activeTool directly. Use editor selection/tool actions.'
})
}
}
}
}
const noMathRandom = {
meta: {
docs: {
@ -1200,6 +1256,8 @@ const plugin = {
rules: {
'no-inline-named-types': noInlineNamedTypes,
'no-structuredclone-scene-arrays': noStructuredCloneSceneArrays,
'no-vue-style-blocks': noVueStyleBlocks,
'no-direct-selection-tool-state-mutation': noDirectSelectionToolStateMutation,
'no-math-random': noMathRandom,
'no-hand-rolled-color': noHandRolledColor,
'no-raw-console-format': noRawConsoleFormat,

View file

@ -108,6 +108,8 @@
}
],
"open-pencil/no-structuredclone-scene-arrays": "error",
"open-pencil/no-vue-style-blocks": "error",
"open-pencil/no-direct-selection-tool-state-mutation": "error",
"open-pencil/no-math-random": "error",
"open-pencil/no-hand-rolled-color": "error",
"open-pencil/no-raw-console-format": "off",

View file

@ -230,27 +230,6 @@ const noE2EImportsInEngineTests = createImportRule(
}
)
const noVueStyleBlocks = createFileRule('open-pencil/no-vue-style-blocks', (sourceRel) => {
if (!sourceRel.endsWith('.vue')) return null
if (!sourceRel.startsWith('src/') && !sourceRel.startsWith('packages/vue/src/')) return null
const content = readFileSync(path.resolve(sourceRel), 'utf8')
return /<style\b/i.test(content)
? 'Vue components must not use <style> blocks. Use Tailwind utilities or global app.css tokens.'
: null
})
const noDirectSelectionOrToolStateMutation = createFileRule(
'open-pencil/no-direct-selection-tool-state-mutation',
(sourceRel) => {
if (!sourceRel.endsWith('.ts') && !sourceRel.endsWith('.vue')) return null
if (sourceRel.startsWith('packages/core/src/editor/')) return null
const content = readFileSync(path.resolve(sourceRel), 'utf8')
return /\.state\.(selectedIds|activeTool)\s*=(?!=)/.test(content)
? 'Do not assign editor.state.selectedIds or editor.state.activeTool directly. Use editor selection/tool actions.'
: null
}
)
const noRootMarkdownClutter = createFileRule('open-pencil/no-root-markdown-clutter', (sourceRel) => {
if (sourceRel.includes('/')) return null
if (!sourceRel.endsWith('.md')) return null
@ -418,8 +397,6 @@ export const openPencilArchitecturePlugin = {
meta: { name: 'open-pencil-architecture', version: '0.0.0' },
ruleDefinitions: [
preferDomainFoldersOverFilenamePrefixes,
noVueStyleBlocks,
noDirectSelectionOrToolStateMutation,
strictTestFilePlacement,
noEngineOnlyAssertionsInE2E,
noE2EImportsInEngineTests,

View file

@ -22,8 +22,6 @@ export default defineConfig([
{
rules: {
'open-pencil/prefer-domain-folders-over-filename-prefixes': 'error',
'open-pencil/no-vue-style-blocks': 'error',
'open-pencil/no-direct-selection-tool-state-mutation': 'error',
'open-pencil/strict-test-file-placement': 'error',
'open-pencil/no-engine-only-assertions-in-e2e': 'error',
'open-pencil/no-e2e-imports-in-engine-tests': 'error',