forked from onlook-dev/onlook
-
Notifications
You must be signed in to change notification settings - Fork 22
Expand file tree
/
Copy pathcleanup.ts
More file actions
124 lines (110 loc) · 4.11 KB
/
cleanup.ts
File metadata and controls
124 lines (110 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import traverse, { NodePath } from '@babel/traverse';
import * as t from '@babel/types';
import { EditorAttributes } from '@onlook/models/constants';
import { generateCode } from '../code/diff/helpers';
import { createHash, formatContent, readFile, writeFile } from '../code/files';
import { parseJsxFile } from '../code/helpers';
import { GENERATE_CODE_OPTIONS, getValidFiles, isReactFragment } from './helpers';
import path from 'path';
import type { HashesJson } from '@onlook/models';
export async function removeIdsFromDirectory(dirPath: string) {
const filePaths = await getValidFiles(dirPath);
for (const filePath of filePaths) {
const isFileChanged = await checkIfFileChanged(dirPath, filePath);
if (isFileChanged) {
await removeIdsFromFile(filePath);
}
}
}
export async function removeIdsFromFile(filePath: string) {
const content = await getFileContentWithoutIds(filePath);
if (!content || content.trim() === '') {
console.error(`Failed to remove ids from file: ${filePath}`);
return;
}
await writeFile(filePath, content);
}
export async function getFileContentWithoutIds(filePath: string): Promise<string | null> {
const content = await readFile(filePath);
if (content == null) {
console.error(`Failed to read file: ${filePath}`);
return null;
}
const ast = parseJsxFile(content);
if (!ast) {
console.error(`Failed to parse file: ${filePath}`);
return content;
}
removeIdsFromAst(ast);
const generated = generateCode(ast, GENERATE_CODE_OPTIONS, content);
const formatted = await formatContent(filePath, generated);
return formatted;
}
export function removeIdsFromAst(ast: t.File) {
traverse(ast, {
JSXOpeningElement(path: NodePath<t.JSXOpeningElement>) {
if (isReactFragment(path.node)) {
return;
}
const attributes = path.node.attributes;
const existingAttrIndex = attributes.findIndex(
(attr: any) => attr.name?.name === EditorAttributes.DATA_ONLOOK_ID,
);
if (existingAttrIndex !== -1) {
attributes.splice(existingAttrIndex, 1);
}
},
JSXAttribute(path: NodePath<t.JSXAttribute>) {
if (path.node.name.name === 'key') {
const value = path.node.value;
if (
t.isStringLiteral(value) &&
value.value.startsWith(EditorAttributes.ONLOOK_MOVE_KEY_PREFIX)
) {
return path.remove();
}
}
},
});
}
export async function checkIfFileChanged(projectDir: string, filePath: string): Promise<boolean> {
if (!filePath) {
console.error('No file path provided.');
return false;
}
const cacheDir = path.join(projectDir, '.onlook', 'cache');
const hashesFilePath = path.join(cacheDir, 'hashes.json');
let hashesJson: HashesJson = {};
try {
const existing = await readFile(hashesFilePath);
if (existing?.trim()) {
hashesJson = JSON.parse(existing);
}
} catch (error) {
console.error('Failed to read hashes.json. Proceeding without cache.');
return true;
}
const storedEntry = hashesJson[filePath];
if (!storedEntry) {
console.warn(`No stored hash for file: ${filePath}`);
return true;
}
const fileContentWithIds = await readFile(filePath);
if (!fileContentWithIds || fileContentWithIds.trim() === '') {
console.error(`Failed to get content for file: ${filePath}`);
return false;
}
const calculatedHash = createHash(fileContentWithIds);
if (calculatedHash === storedEntry.hash) {
try {
const cacheFileContent = await readFile(storedEntry.cache_path);
if (cacheFileContent?.trim()) {
await writeFile(filePath, cacheFileContent);
return false;
}
} catch (err) {
console.error(`Failed to read cached file at ${storedEntry.cache_path}:`, err);
}
}
return true;
}