MCPcopy Create free account
hub / github.com/heygen-com/hyperframes / lintProject

Function lintProject

packages/lint/src/project.ts:178–252  ·  view source on GitHub ↗
(projectDir: string)

Source from the content-addressed store, hash-verified

176}
177
178export async function lintProject(projectDir: string): Promise<ProjectLintResult> {
179 const indexPath = resolve(projectDir, "index.html");
180 const results: Array<{ file: string; result: HyperframeLintResult }> = [];
181 let totalErrors = 0;
182 let totalWarnings = 0;
183 let totalInfos = 0;
184
185 const rootHtml = readFileSync(indexPath, "utf-8");
186 const rootResult = await lintHyperframeHtml(rootHtml, {
187 filePath: indexPath,
188 externalStyles: collectExternalStyles(projectDir, rootHtml),
189 });
190 results.push({ file: "index.html", result: rootResult });
191 totalErrors += rootResult.errorCount;
192 totalWarnings += rootResult.warningCount;
193 totalInfos += rootResult.infoCount;
194
195 const allHtmlSources: HtmlSource[] = [{ html: rootHtml }];
196 const compositionsDir = resolve(projectDir, "compositions");
197 if (existsSync(compositionsDir)) {
198 const collectHtmlFiles = (dir: string, rel: string): string[] => {
199 const out: string[] = [];
200 for (const entry of readdirSync(dir, { withFileTypes: true })) {
201 const relPath = rel ? `${rel}/${entry.name}` : entry.name;
202 if (entry.isDirectory()) out.push(...collectHtmlFiles(join(dir, entry.name), relPath));
203 else if (entry.isFile() && entry.name.endsWith(".html")) out.push(relPath);
204 }
205 return out;
206 };
207 const files = collectHtmlFiles(compositionsDir, "").sort();
208 for (const file of files) {
209 const filePath = join(compositionsDir, file);
210 const html = readFileSync(filePath, "utf-8");
211 const compSrcPath = `compositions/${file}`;
212 allHtmlSources.push({ html, compSrcPath });
213 const result = await lintHyperframeHtml(html, {
214 filePath,
215 isSubComposition: true,
216 externalStyles: collectExternalStyles(projectDir, html, compSrcPath),
217 });
218 results.push({ file: `compositions/${file}`, result });
219 totalErrors += result.errorCount;
220 totalWarnings += result.warningCount;
221 totalInfos += result.infoCount;
222 }
223 }
224
225 const projectFindings = [
226 ...lintProjectAudioFiles(projectDir, allHtmlSources),
227 ...lintAudioSrcNotFound(projectDir, allHtmlSources),
228 ...lintMissingLocalAsset(projectDir, allHtmlSources),
229 ...lintTextureMaskAssetNotFound(projectDir, allHtmlSources),
230 ...lintMultipleRootCompositions(projectDir),
231 ...lintDuplicateAudioTracks(allHtmlSources),
232 ...lintMissingOrEmptySubComposition(projectDir, rootHtml),
233 ];
234 if (projectFindings.length > 0) {
235 for (const finding of projectFindings) {

Callers 9

lintSubCompFunction · 0.85
project.test.tsFile · 0.85
lintSubCompFunction · 0.85
runFunction · 0.85
runFunction · 0.85
validateInBrowserFunction · 0.85
runFunction · 0.85
runFunction · 0.85

Calls 11

resolveFunction · 0.85
lintHyperframeHtmlFunction · 0.85
collectExternalStylesFunction · 0.85
collectHtmlFilesFunction · 0.85
lintProjectAudioFilesFunction · 0.85
lintAudioSrcNotFoundFunction · 0.85
lintMissingLocalAssetFunction · 0.85
lintDuplicateAudioTracksFunction · 0.85

Tested by 2

lintSubCompFunction · 0.68
lintSubCompFunction · 0.68