feat(nacos): namespace production protection and sidebar visibility

This commit is contained in:
二丫讲梵 authored and GitHub committed 2026-08-08 10:55:21 +08:00
1 parent 9057be0e78
commit efd0c381ad
25 files changed
+492 -26

No files matched your search

@@ -40,6 +40,12 @@ describe("production SQL safety", () => {
expect(productionContextForDatabase(connection(), "staging").active).toBe(false);
});
it("treats Nacos public and empty namespace IDs as the same protected namespace", () => {
const nacos = connection({ db_type: "nacos", production_databases: [""] });
expect(productionContextForDatabase(nacos, "public")).toMatchObject({ active: true, reason: "database", databases: ["public"] });
expect(productionContextForDatabase(nacos, "")).toMatchObject({ active: true, reason: "database", databases: ["public"] });
});
it("detects a write after a USE production switch despite comments", () => {
const assessment = assessProductionSql("-- install\nUSE `prod_app`; /* migration */ DELETE FROM users", connection(), "staging");
expect(assessment).toMatchObject({ active: true, isMutation: true, databases: ["prod_app"] });
@@ -1,4 +1,5 @@
import type { ConnectionConfig, DatabaseType } from "@/types/database";
import { nacosNamespaceIdentity } from "@/lib/nacos/nacosNamespaceVisibility";
import { classifySqlRisk, isSqlRiskMutation } from "@/lib/sql/sqlRisk";
export type ProductionContextReason = "connection" | "database" | "sql_target";
@@ -93,6 +94,9 @@ export function normalizeProductionDatabase(value: string | undefined | null): s
export function productionDatabases(connection: ConnectionConfig | undefined): string[] {
if (!connection?.production_databases?.length) return [];
if (connection.db_type === "nacos") {
return [...new Set(connection.production_databases.map(nacosNamespaceIdentity))];
}
return [...new Set(connection.production_databases.map(normalizeProductionDatabase).filter(Boolean))];
}
@@ -100,10 +104,10 @@ export function productionContextForDatabase(connection: ConnectionConfig | unde
if (!connection) return { active: false, databases: [] };
if (connection.is_production) return { active: true, reason: "connection", databases: [] };
const normalizedDatabase = normalizeProductionDatabase(database);
const normalizedDatabase = connection.db_type === "nacos" ? nacosNamespaceIdentity(String(database ?? "")) : normalizeProductionDatabase(database);
const marked = productionDatabases(connection);
if (normalizedDatabase && marked.includes(normalizedDatabase)) {
return { active: true, reason: "database", databases: [String(database)] };
return { active: true, reason: "database", databases: [connection.db_type === "nacos" ? normalizedDatabase : String(database)] };
}
return { active: false, databases: [] };
}