tina4-nodejs 3.13.36 → 3.13.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1904,6 +1904,49 @@ const handleFiles: RouteHandler = async (req, res) => {
1904
1904
  res.json({ path: relative(root, target).replace(/\\/g, "/") || ".", branch, entries });
1905
1905
  };
1906
1906
 
1907
+ // Canonical extension→language map. Kept identical in coverage to the Python
1908
+ // master (tina4_python/tina4_python/dev_admin/__init__.py `lang_map`) and the
1909
+ // PHP/Ruby file-read endpoints. The dev-admin SPA maps the returned "language"
1910
+ // string to a CodeMirror grammar for syntax highlighting.
1911
+ const DEV_ADMIN_LANG_MAP: Record<string, string> = {
1912
+ ".py": "python", ".php": "php", ".rb": "ruby",
1913
+ ".ts": "typescript", ".js": "javascript", ".jsx": "javascript",
1914
+ ".tsx": "typescript", ".json": "json", ".html": "html",
1915
+ ".twig": "html", ".css": "css", ".scss": "css",
1916
+ ".md": "markdown", ".sql": "sql", ".yaml": "yaml",
1917
+ ".yml": "yaml", ".toml": "toml", ".xml": "html",
1918
+ ".env": "env", ".env.example": "env",
1919
+ ".sh": "shell", ".bash": "shell",
1920
+ ".bat": "shell", ".cmd": "shell", ".ps1": "shell",
1921
+ ".rs": "rust", ".go": "go", ".java": "java",
1922
+ ".txt": "text", ".csv": "text", ".log": "text",
1923
+ ".gemspec": "ruby", ".rake": "ruby",
1924
+ ".svg": "svg",
1925
+ };
1926
+
1927
+ /**
1928
+ * Resolve a CodeMirror-friendly language id from a file path's basename.
1929
+ *
1930
+ * - `Dockerfile` / `Dockerfile.dev` / `Dockerfile.prod` (no extension) → "dockerfile"
1931
+ * - `.env.example` (two-part) and `.env` → "env"
1932
+ * - otherwise the file extension is looked up in DEV_ADMIN_LANG_MAP
1933
+ * - anything unknown → "text"
1934
+ */
1935
+ export function devAdminLanguage(rel: string): string {
1936
+ const base = (rel.split(/[\\/]/).pop() ?? "").toLowerCase();
1937
+ if (base === "dockerfile" || base === "dockerfile.dev" || base === "dockerfile.prod") {
1938
+ return "dockerfile";
1939
+ }
1940
+ // Two-part extension first (e.g. ".env.example"), then the single extension.
1941
+ if (base.endsWith(".env.example")) return DEV_ADMIN_LANG_MAP[".env.example"];
1942
+ const dot = base.lastIndexOf(".");
1943
+ // A leading dot with no other dot is a dotfile name, not an extension
1944
+ // (e.g. ".env" → ext ".env"); only treat as "no extension" when there's no dot.
1945
+ if (dot < 0) return "text";
1946
+ const ext = base.slice(dot);
1947
+ return DEV_ADMIN_LANG_MAP[ext] ?? "text";
1948
+ }
1949
+
1907
1950
  const handleFileRead: RouteHandler = (req, res) => {
1908
1951
  const url = new URL(req.url ?? "/", "http://localhost");
1909
1952
  const rel = url.searchParams.get("path") ?? "";
@@ -1915,7 +1958,8 @@ const handleFileRead: RouteHandler = (req, res) => {
1915
1958
  }
1916
1959
  try {
1917
1960
  const content = readFileSync(target, "utf-8");
1918
- res.json({ path: relative(root, target), content, bytes: Buffer.byteLength(content, "utf-8") });
1961
+ const path = relative(root, target);
1962
+ res.json({ path, content, language: devAdminLanguage(path), bytes: Buffer.byteLength(content, "utf-8") });
1919
1963
  } catch (e) {
1920
1964
  res.json({ error: (e as Error).message }, 500);
1921
1965
  }
@@ -74,7 +74,7 @@ export type { ResponseCacheConfig, CacheBackend } from "./cache.js";
74
74
  export { Api } from "./api.js";
75
75
  export type { ApiResult } from "./api.js";
76
76
  export { Events } from "./events.js";
77
- export { DevAdmin, MessageLog, RequestInspector, ErrorTracker, DevMailboxStore, DevQueue, WsTracker, supervisorBaseUrl } from "./devAdmin.js";
77
+ export { DevAdmin, MessageLog, RequestInspector, ErrorTracker, DevMailboxStore, DevQueue, WsTracker, supervisorBaseUrl, devAdminLanguage } from "./devAdmin.js";
78
78
  export {
79
79
  feedbackEnabled,
80
80
  feedbackWhitelist,