mirror of
https://github.com/firstsun-dev/git-files-sync.git
synced 2026-07-22 06:54:27 +00:00
build(compat): derive the compat typecheck's target version dynamically
The 1.11 compatibility gate previously hardcoded the target Obsidian version in two places (an obsidian-1_11 alias devDependency and a static tsconfig.compat.json), so bumping minAppVersion would silently leave the check pinned to the old version. Replace both with scripts/typecheck-compat.mjs, which reads the target from versions.json (the entry for the current manifest version, falling back to manifest.minAppVersion), installs the matching Obsidian typings into a git-ignored cache on demand, and type-checks src against them. The gate now follows minAppVersion automatically with no code changes. Also fold `typecheck:compat` into `npm run build` so it runs wherever the build runs (the husky pre-commit hook and any CI step that builds). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SSikT9ZAfQF8K4SE3DatD3
This commit is contained in:
parent
d896015765
commit
692fc0f293
5 changed files with 67 additions and 37 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -21,6 +21,9 @@ data.json
|
|||
# test coverage
|
||||
coverage/
|
||||
|
||||
# generated by scripts/typecheck-compat.mjs
|
||||
tsconfig.compat.generated.json
|
||||
|
||||
# Claude worktrees
|
||||
.claude/
|
||||
|
||||
|
|
|
|||
17
package-lock.json
generated
17
package-lock.json
generated
|
|
@ -31,7 +31,6 @@
|
|||
"husky": "^9.1.7",
|
||||
"jiti": "2.6.1",
|
||||
"jsdom": "^29.1.1",
|
||||
"obsidian-1_11": "npm:obsidian@^1.11.0",
|
||||
"semantic-release": "^25.0.5",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "^5.8.3",
|
||||
|
|
@ -9858,22 +9857,6 @@
|
|||
"@codemirror/view": "6.38.6"
|
||||
}
|
||||
},
|
||||
"node_modules/obsidian-1_11": {
|
||||
"name": "obsidian",
|
||||
"version": "1.11.0",
|
||||
"resolved": "https://registry.npmjs.org/obsidian/-/obsidian-1.11.0.tgz",
|
||||
"integrity": "sha512-lVqN9AmDWHzhNATi2tDnjqVgI6WUYKeT+lIsAycAyLt4XCC6zRsWzb+tFCiB7Rn3PpttefjoovilhYwvS4Iqxw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/codemirror": "5.60.8",
|
||||
"moment": "2.29.4"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/state": "6.5.0",
|
||||
"@codemirror/view": "6.38.6"
|
||||
}
|
||||
},
|
||||
"node_modules/obug": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz",
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@
|
|||
},
|
||||
"scripts": {
|
||||
"dev": "node esbuild.config.mjs",
|
||||
"build": "tsc -noEmit -skipLibCheck && node esbuild.config.mjs production",
|
||||
"typecheck:compat": "tsc -p tsconfig.compat.json",
|
||||
"build": "tsc -noEmit -skipLibCheck && npm run typecheck:compat && node esbuild.config.mjs production",
|
||||
"typecheck:compat": "node scripts/typecheck-compat.mjs",
|
||||
"version": "node version-bump.mjs && git add manifest.json versions.json",
|
||||
"lint": "eslint .",
|
||||
"test": "vitest run",
|
||||
|
|
@ -41,7 +41,6 @@
|
|||
"husky": "^9.1.7",
|
||||
"jiti": "2.6.1",
|
||||
"jsdom": "^29.1.1",
|
||||
"obsidian-1_11": "npm:obsidian@^1.11.0",
|
||||
"semantic-release": "^25.0.5",
|
||||
"tslib": "2.4.0",
|
||||
"typescript": "^5.8.3",
|
||||
|
|
|
|||
62
scripts/typecheck-compat.mjs
Normal file
62
scripts/typecheck-compat.mjs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env node
|
||||
/*
|
||||
* Type-checks src/ against the exact Obsidian API version this release targets.
|
||||
* Any use of an API newer than our declared minAppVersion that is NOT
|
||||
* runtime-guarded becomes a compile error here.
|
||||
*
|
||||
* The target version is derived dynamically — never hardcoded. versions.json
|
||||
* maps each plugin version to its minAppVersion; we use the entry for the
|
||||
* current manifest version, falling back to manifest.minAppVersion (which is the
|
||||
* canonical floor, and the reliable source when version-bump.mjs omits a
|
||||
* versions.json entry because the minAppVersion was unchanged).
|
||||
*
|
||||
* The matching Obsidian typings are installed on demand into node_modules/.cache
|
||||
* (git-ignored) and reused across runs, so bumping minAppVersion automatically
|
||||
* re-points this check with no code changes.
|
||||
*/
|
||||
import { execSync } from 'node:child_process';
|
||||
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { dirname, join, relative } from 'node:path';
|
||||
import process from 'node:process';
|
||||
|
||||
const root = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const readJson = (p) => JSON.parse(readFileSync(join(root, p), 'utf8'));
|
||||
|
||||
const manifest = readJson('manifest.json');
|
||||
const versions = readJson('versions.json');
|
||||
const target = versions[manifest.version] ?? manifest.minAppVersion;
|
||||
|
||||
if (!target) {
|
||||
console.error('compat: could not resolve target Obsidian version from versions.json / manifest.json');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Install the target typings into a per-version cache (reused on later runs).
|
||||
const cacheDir = join(root, 'node_modules', '.cache', 'obsidian-compat', target);
|
||||
const dtsBase = join(cacheDir, 'node_modules', 'obsidian', 'obsidian'); // no extension
|
||||
if (!existsSync(`${dtsBase}.d.ts`)) {
|
||||
mkdirSync(cacheDir, { recursive: true });
|
||||
console.log(`compat: installing obsidian@${target} typings...`);
|
||||
execSync(
|
||||
`npm install --prefix "${cacheDir}" --no-save --no-audit --no-fund --loglevel=error obsidian@${target}`,
|
||||
{ stdio: 'inherit' },
|
||||
);
|
||||
}
|
||||
|
||||
// Generate a tsconfig that points the "obsidian" import at the target typings.
|
||||
const generated = join(root, 'tsconfig.compat.generated.json');
|
||||
writeFileSync(generated, `${JSON.stringify({
|
||||
extends: './tsconfig.json',
|
||||
compilerOptions: {
|
||||
noEmit: true,
|
||||
skipLibCheck: true,
|
||||
baseUrl: '.',
|
||||
paths: { obsidian: [relative(root, dtsBase).split('\\').join('/')] },
|
||||
},
|
||||
include: ['src/**/*.ts'],
|
||||
}, null, '\t')}\n`);
|
||||
|
||||
console.log(`compat: type-checking src against Obsidian ${target} API...`);
|
||||
execSync(`node "${join(root, 'node_modules', 'typescript', 'bin', 'tsc')}" -p "${generated}"`, { stdio: 'inherit' });
|
||||
console.log(`compat: ✓ src is compatible with Obsidian ${target}`);
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
{
|
||||
// Type-checks src against the Obsidian 1.11 API typings (installed as the
|
||||
// "obsidian-1_11" alias) instead of the latest ones. Because the plugin
|
||||
// declares minAppVersion 1.11.0, any use of an API newer than 1.11 that is
|
||||
// not runtime-guarded becomes a compile error here. Run via `npm run
|
||||
// typecheck:compat`. Keep this passing whenever minAppVersion stays at 1.11.
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"noEmit": true,
|
||||
"skipLibCheck": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"obsidian": ["node_modules/obsidian-1_11/obsidian"]
|
||||
}
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Loading…
Reference in a new issue