Compare commits

...
Author SHA1 Message Date
Paul Bakaus 93dce3d62e Centralize framework detection probes
Reuse the shared dependency and ordered file-probe helpers in the SvelteKit and TanStack live adapters, removing duplicate package parsing and path search.

AI assistance: prepared by OpenAI Codex under maintainer pbakaus standing scheduled architecture-refactor authorization.
2026-08-20 11:38:20 -07:00
2 changed files with 19 additions and 52 deletions
+15 -27
View File
@@ -11,6 +11,8 @@ import crypto from 'node:crypto';
import fs from 'node:fs';
import path from 'node:path';
import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
export const SVELTE_LIVE_ROOT_COMPONENT = 'src/lib/impeccable/ImpeccableLiveRoot.svelte';
export const SVELTE_LAYOUT_MARKER_OPEN = '<!-- impeccable-live-svelte-start -->';
export const SVELTE_LAYOUT_MARKER_CLOSE = '<!-- impeccable-live-svelte-end -->';
@@ -45,11 +47,17 @@ export function detectSvelteKitProject(cwd = process.cwd(), config = null) {
&& fileIncludes(path.join(cwd, appHtml), '%sveltekit.head%');
if (!hasTemplateMarkers) return null;
const hasSvelteConfig = fs.existsSync(path.join(cwd, 'svelte.config.js'))
|| fs.existsSync(path.join(cwd, 'svelte.config.mjs'))
|| fs.existsSync(path.join(cwd, 'svelte.config.cjs'))
|| fs.existsSync(path.join(cwd, 'svelte.config.ts'));
const hasKitPackage = packageHasSvelteKit(cwd);
const hasSvelteConfig = Boolean(firstExistingFile(cwd, [
'svelte.config.js',
'svelte.config.mjs',
'svelte.config.cjs',
'svelte.config.ts',
]));
const hasKitPackage = hasAnyDependency(cwd, [
'@sveltejs/kit',
'@sveltejs/vite-plugin-svelte',
'svelte',
]);
if (!hasSvelteConfig && !hasKitPackage) return null;
return {
@@ -260,36 +268,16 @@ function findSvelteKitAppHtml(cwd, config) {
}
function findSvelteKitLayout(cwd) {
const candidates = [
return firstExistingFile(cwd, [
'src/routes/+layout.svelte',
'src/routes/(app)/+layout.svelte',
];
for (const rel of candidates) {
if (fs.existsSync(path.join(cwd, rel))) return rel;
}
return 'src/routes/+layout.svelte';
]) || 'src/routes/+layout.svelte';
}
function defaultSvelteLayout() {
return `<script>\n let { children } = $props();\n</script>\n\n{@render children?.()}\n`;
}
function packageHasSvelteKit(cwd) {
const file = path.join(cwd, 'package.json');
if (!fs.existsSync(file)) return false;
try {
const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
const deps = {
...(pkg.dependencies || {}),
...(pkg.devDependencies || {}),
...(pkg.peerDependencies || {}),
};
return Boolean(deps['@sveltejs/kit'] || deps['@sveltejs/vite-plugin-svelte'] || deps.svelte);
} catch {
return false;
}
}
function fileIncludes(file, text) {
try {
return fs.readFileSync(file, 'utf-8').includes(text);
+4 -25
View File
@@ -19,6 +19,8 @@
import fs from 'node:fs';
import path from 'node:path';
import { firstExistingFile, hasAnyDependency } from './frameworks/detect-utils.mjs';
import { buildLiveScriptSrc } from './frameworks/script-src.mjs';
export const TANSTACK_MARKER_OPEN = '{/* impeccable-live-tanstack-start */}';
@@ -42,8 +44,8 @@ const START_PACKAGES = [
];
export function detectTanStackStartProject(cwd = process.cwd()) {
if (!packageHasTanStackStart(cwd)) return null;
const rootRoute = findRootRouteFile(cwd);
if (!hasAnyDependency(cwd, START_PACKAGES)) return null;
const rootRoute = firstExistingFile(cwd, ROOT_ROUTE_CANDIDATES);
if (!rootRoute) return null;
const ext = path.extname(rootRoute);
@@ -218,29 +220,6 @@ function isManagedComponent(content) {
return String(content || '').includes('impeccable-live-tanstack');
}
function findRootRouteFile(cwd) {
for (const rel of ROOT_ROUTE_CANDIDATES) {
if (fs.existsSync(path.join(cwd, rel))) return rel;
}
return null;
}
function packageHasTanStackStart(cwd) {
const file = path.join(cwd, 'package.json');
if (!fs.existsSync(file)) return false;
try {
const pkg = JSON.parse(fs.readFileSync(file, 'utf-8'));
const deps = {
...(pkg.dependencies || {}),
...(pkg.devDependencies || {}),
...(pkg.peerDependencies || {}),
};
return START_PACKAGES.some((name) => Boolean(deps[name]));
} catch {
return false;
}
}
function relativeImportSpecifier(fromFile, toFile) {
const rel = path.posix.relative(
path.posix.dirname(fromFile.split(path.sep).join('/')),