release(main): 同步 dev 最新候选改动
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (push) Has been cancelled
Client Quality Gates / Shared client and Web (push) Has been cancelled
Client Quality Gates / macOS Desktop (push) Has been cancelled
Client Quality Gates / Shared client and Web (pull_request) Has been cancelled
Client Quality Gates / macOS Desktop (pull_request) Has been cancelled
Storage Persistence Guard / storage-persistence-audit (pull_request) Has been cancelled
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { readdir, readFile } from "node:fs/promises";
|
||||
import { extname, relative, resolve } from "node:path";
|
||||
import { extname, isAbsolute, relative, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const frontendDir = fileURLToPath(new URL("../", import.meta.url));
|
||||
@@ -7,6 +7,15 @@ const sourceDir = resolve(frontendDir, "src");
|
||||
const runtimeDir = resolve(sourceDir, "runtime");
|
||||
const sourceExtensions = new Set([".ts", ".tsx", ".vue", ".js", ".jsx"]);
|
||||
const violations = [];
|
||||
const toPosixPath = (path) => path.split("\\").join("/");
|
||||
|
||||
const platformSource = await readFile(resolve(runtimeDir, "platform.ts"), "utf8");
|
||||
if (!platformSource.includes("runtimeGlobal.isTauri")) {
|
||||
violations.push("src/runtime/platform.ts: Tauri v2 runtime detection must use the official isTauri marker");
|
||||
}
|
||||
if (platformSource.includes("__TAURI")) {
|
||||
violations.push("src/runtime/platform.ts: Tauri runtime detection must not depend on legacy or internal markers");
|
||||
}
|
||||
|
||||
const walk = async (directory) => {
|
||||
const entries = await readdir(directory, { withFileTypes: true });
|
||||
@@ -21,16 +30,21 @@ const walk = async (directory) => {
|
||||
};
|
||||
|
||||
for (const path of await walk(sourceDir)) {
|
||||
if (!sourceExtensions.has(extname(path)) || path.startsWith(`${runtimeDir}/`)) continue;
|
||||
const runtimeRelativePath = relative(runtimeDir, path);
|
||||
const isRuntimeFile = Boolean(runtimeRelativePath) && !runtimeRelativePath.startsWith("..") && !isAbsolute(runtimeRelativePath);
|
||||
if (!sourceExtensions.has(extname(path)) || isRuntimeFile) continue;
|
||||
|
||||
const source = await readFile(path, "utf8");
|
||||
const file = relative(frontendDir, path);
|
||||
if (source.includes("@tauri-apps/") || source.includes("__TAURI")) {
|
||||
const file = toPosixPath(relative(frontendDir, path));
|
||||
if (source.includes("@tauri-apps/") || source.includes("__TAURI") || /(?:globalThis|window)\.isTauri/.test(source)) {
|
||||
violations.push(`${file}: direct Tauri access is only allowed inside src/runtime`);
|
||||
}
|
||||
if (/from\s+["'][^"']*\/runtime\/[^"']+["']/.test(source)) {
|
||||
violations.push(`${file}: import platform behavior through src/runtime/index.ts`);
|
||||
}
|
||||
if (/\bindexedDB\b|\bcaches\.open\s*\(|\bCacheStorage\b|\bsqlite\b/i.test(source)) {
|
||||
violations.push(`${file}: local data cache storage must be routed through src/runtime`);
|
||||
}
|
||||
}
|
||||
|
||||
if (violations.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user