Files
lobe-chat/scripts/electronWorkflow/modifiers/wrapChildrenWithClientOnly.mts
T
Innei fcdaf9d814 🔧 chore: update eslint v2 configuration and suppressions (#12133)
* v2 init

* chore: update eslint suppressions and package dependencies

- Removed several eslint suppressions related to array sorting and reversing from eslint-suppressions.json to clean up the configuration.
- Updated @lobehub/lint package version from 2.0.0-beta.6 to 2.0.0-beta.7 in package.json for improvements and bug fixes.
- Made minor formatting adjustments in vitest.config.mts and various SKILL.md files for better readability and consistency.

Signed-off-by: Innei <tukon479@gmail.com>

* fix: clean up import statements and formatting

- Removed unnecessary whitespace in replaceComponentImports.ts for improved readability.
- Standardized import statements in contextEngineering.ts and createAgentExecutors.ts by adding missing spaces for consistency.

Signed-off-by: Innei <tukon479@gmail.com>

* chore: update eslint suppressions and clean up code formatting

* 🐛 fix: use vi.hoisted for mock variable initialization

Fix TDZ error in persona service test by using vi.hoisted() to ensure
mock variables are available when vi.mock factory runs.

---------

Signed-off-by: Innei <tukon479@gmail.com>
2026-02-11 13:04:48 +08:00

83 lines
2.6 KiB
TypeScript

import { Lang, parse } from '@ast-grep/napi';
import path from 'node:path';
import { invariant, isDirectRun, runStandalone, updateFile } from './utils.mjs';
export const wrapChildrenWithClientOnly = async (TEMP_DIR: string) => {
const layoutPath = path.join(TEMP_DIR, 'src/app/[variants]/layout.tsx');
console.log(' Wrapping children with ClientOnly in layout.tsx...');
await updateFile({
assertAfter: (code) => {
const hasClientOnlyImport =
/import ClientOnly from ["']@\/components\/client\/ClientOnly["']/.test(code);
const hasLoadingImport =
/import Loading from ["']@\/components\/Loading\/BrandTextLoading["']/.test(code);
const hasClientOnlyWrapper = /<ClientOnly fallback={<Loading/.test(code);
return hasClientOnlyImport && hasLoadingImport && hasClientOnlyWrapper;
},
filePath: layoutPath,
name: 'wrapChildrenWithClientOnly',
transformer: (code) => {
const ast = parse(Lang.Tsx, code);
const root = ast.root();
let result = code;
const hasClientOnlyImport =
/import ClientOnly from ["']@\/components\/client\/ClientOnly["']/.test(code);
const hasLoadingImport =
/import Loading from ["']@\/components\/Loading\/BrandTextLoading["']/.test(code);
const lastImport = root
.findAll({
rule: {
kind: 'import_statement',
},
})
.at(-1);
invariant(
lastImport,
'[wrapChildrenWithClientOnly] No import statements found in layout.tsx',
);
const insertPos = lastImport!.range().end.index;
let importsToAdd = '';
if (!hasClientOnlyImport) {
importsToAdd += "\nimport ClientOnly from '@/components/client/ClientOnly';";
}
if (!hasLoadingImport) {
importsToAdd += "\nimport Loading from '@/components/Loading/BrandTextLoading';";
}
if (importsToAdd) {
result = result.slice(0, insertPos) + importsToAdd + result.slice(insertPos);
}
const authProviderPattern = /<AuthProvider>\s*{children}\s*<\/AuthProvider>/;
invariant(
authProviderPattern.test(result),
'[wrapChildrenWithClientOnly] Pattern <AuthProvider>{children}</AuthProvider> not found in layout.tsx',
);
result = result.replace(
authProviderPattern,
`<AuthProvider>
<ClientOnly fallback={<Loading />}>{children}</ClientOnly>
</AuthProvider>`,
);
return result;
},
});
};
if (isDirectRun(import.meta.url)) {
await runStandalone('wrapChildrenWithClientOnly', wrapChildrenWithClientOnly, [
{ lang: Lang.Tsx, path: 'src/app/[variants]/layout.tsx' },
]);
}