mirror of
https://github.com/nejimakibird/model-weave.git
synced 2026-07-22 06:51:24 +00:00
chore: add obsidian compatibility lint baseline
This commit is contained in:
parent
6f28126222
commit
17b37c91e2
6 changed files with 4780 additions and 3 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -24,3 +24,6 @@ pnpm-debug.log*
|
|||
# working directory
|
||||
_archives/
|
||||
scripts/
|
||||
!scripts/
|
||||
scripts/*
|
||||
!scripts/check-css-compat.mjs
|
||||
|
|
|
|||
15
docs/release/obsidian-lint-baseline-0.1.12.md
Normal file
15
docs/release/obsidian-lint-baseline-0.1.12.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# Obsidian lint baseline 0.1.12
|
||||
|
||||
This baseline introduces local lint visibility for Obsidian community plugin compatibility review concerns. The goal for 0.1.12 is to surface warning groups before release, not to fix every existing warning in this task.
|
||||
|
||||
## Warning groups
|
||||
|
||||
- Popout compatibility: replace direct `document` access with Obsidian active document/window APIs where appropriate, prefer window-scoped timers for `requestAnimationFrame`, and avoid `instanceof HTMLElement` checks that can fail across popout windows.
|
||||
- Unsafe TypeScript values: review `any` usage and type-aware unsafe assignment, calls, member access, arguments, and returns reported by `@typescript-eslint`.
|
||||
- `require()` style import: replace CommonJS-style imports with ES module imports where practical.
|
||||
- Filesystem, vault enumeration, and clipboard behavior: review warnings around broad vault iteration, filesystem-style access patterns, and clipboard or DOM interactions against Obsidian plugin review expectations.
|
||||
- CSS compatibility: `scripts/check-css-compat.mjs` guards active CSS against `display: contents`; the current codebase passes this check.
|
||||
|
||||
## Follow-up
|
||||
|
||||
Treat these warning groups as cleanup candidates for focused implementation tickets. Do not change model syntax, renderer behavior, or release version files as part of the lint baseline itself.
|
||||
50
eslint.config.mjs
Normal file
50
eslint.config.mjs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { defineConfig } from "eslint/config";
|
||||
import obsidianmd from "eslint-plugin-obsidianmd";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
const obsidianWarningRules = Object.fromEntries(
|
||||
Object.keys(obsidianmd.rules).map((ruleName) => [`obsidianmd/${ruleName}`, "warn"]),
|
||||
);
|
||||
|
||||
function withWarningSeverity(ruleConfig) {
|
||||
if (Array.isArray(ruleConfig)) {
|
||||
return ["warn", ...ruleConfig.slice(1)];
|
||||
}
|
||||
|
||||
return "warn";
|
||||
}
|
||||
|
||||
const typescriptWarningRules = Object.fromEntries(
|
||||
tseslint.configs.recommendedTypeChecked
|
||||
.flatMap((config) => Object.entries(config.rules ?? {}))
|
||||
.filter(([ruleName]) => ruleName.startsWith("@typescript-eslint/"))
|
||||
.map(([ruleName, ruleConfig]) => [ruleName, withWarningSeverity(ruleConfig)]),
|
||||
);
|
||||
|
||||
export default defineConfig([
|
||||
{
|
||||
ignores: ["dist/**", "build/**", "node_modules/**", "main.js"],
|
||||
},
|
||||
...obsidianmd.configs.recommended,
|
||||
...tseslint.configs.recommendedTypeChecked,
|
||||
{
|
||||
files: ["src/**/*.ts"],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
project: "./tsconfig.json",
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
...obsidianWarningRules,
|
||||
...typescriptWarningRules,
|
||||
"@typescript-eslint/no-explicit-any": "warn",
|
||||
"@typescript-eslint/no-unsafe-argument": "warn",
|
||||
"@typescript-eslint/no-unsafe-assignment": "warn",
|
||||
"@typescript-eslint/no-unsafe-call": "warn",
|
||||
"@typescript-eslint/no-unsafe-member-access": "warn",
|
||||
"@typescript-eslint/no-unsafe-return": "warn",
|
||||
"@typescript-eslint/no-require-imports": "warn",
|
||||
},
|
||||
},
|
||||
]);
|
||||
4654
package-lock.json
generated
4654
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
|
@ -5,7 +5,10 @@
|
|||
"main": "main.js",
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production"
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"lint": "npm run lint:obsidian && npm run lint:css-compat",
|
||||
"lint:obsidian": "eslint \"src/**/*.ts\"",
|
||||
"lint:css-compat": "node scripts/check-css-compat.mjs"
|
||||
},
|
||||
"keywords": [
|
||||
"obsidian",
|
||||
|
|
@ -16,10 +19,14 @@
|
|||
"author": "",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@eslint/js": "^10.0.1",
|
||||
"@types/node": "^20.17.24",
|
||||
"esbuild": "^0.25.2",
|
||||
"eslint": "^10.4.1",
|
||||
"eslint-plugin-obsidianmd": "^0.3.0",
|
||||
"obsidian": "^1.8.10",
|
||||
"tslib": "^2.8.1",
|
||||
"typescript": "^5.8.3"
|
||||
"typescript": "^5.8.3",
|
||||
"typescript-eslint": "^8.60.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
50
scripts/check-css-compat.mjs
Normal file
50
scripts/check-css-compat.mjs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { readdir, readFile } from "node:fs/promises";
|
||||
import path from "node:path";
|
||||
|
||||
const root = process.cwd();
|
||||
const ignoredDirectories = new Set(["node_modules", "dist", "build"]);
|
||||
const displayContentsPattern = /\bdisplay\s*:\s*contents\b/i;
|
||||
const findings = [];
|
||||
|
||||
async function scanDirectory(directory) {
|
||||
const entries = await readdir(directory, { withFileTypes: true });
|
||||
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
if (!ignoredDirectories.has(entry.name)) {
|
||||
await scanDirectory(path.join(directory, entry.name));
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!entry.isFile() || !entry.name.endsWith(".css")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const filePath = path.join(directory, entry.name);
|
||||
const source = await readFile(filePath, "utf8");
|
||||
const lines = source.split(/\r?\n/);
|
||||
|
||||
lines.forEach((line, index) => {
|
||||
if (displayContentsPattern.test(line)) {
|
||||
findings.push({
|
||||
filePath: path.relative(root, filePath),
|
||||
line: index + 1,
|
||||
text: line.trim(),
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
await scanDirectory(root);
|
||||
|
||||
if (findings.length > 0) {
|
||||
console.error("CSS compatibility check failed: avoid `display: contents` in active CSS.");
|
||||
for (const finding of findings) {
|
||||
console.error(`${finding.filePath}:${finding.line}: ${finding.text}`);
|
||||
}
|
||||
process.exitCode = 1;
|
||||
} else {
|
||||
console.log("CSS compatibility check passed: no active `display: contents` usage found.");
|
||||
}
|
||||
Loading…
Reference in a new issue