Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 35 additions & 28 deletions apps/web/client/src/app/projects/import/local/_context/index.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
'use client';

import { ProcessedFileType, type NextJsProjectValidation, type ProcessedFile } from '@/app/projects/types';
import { api } from '@/trpc/react';
import { Routes } from '@/utils/constants';
import { CodeProvider, createCodeProviderClient, Provider } from '@onlook/code-provider';
import type { ReactNode } from 'react';
import { createContext, useContext, useState } from 'react';
import { useRouter } from 'next/navigation';

import type { Provider } from '@onlook/code-provider';
import { CodeProvider, createCodeProviderClient } from '@onlook/code-provider';
import { NEXT_JS_FILE_EXTENSIONS, SandboxTemplates, Templates } from '@onlook/constants';
import { RouterType } from '@onlook/models';
import { generate, getAstFromContent, injectPreloadScript } from '@onlook/parser';
import { isRootLayoutFile, isTargetFile } from '@onlook/utility';
import { useRouter } from 'next/navigation';
import type { ReactNode } from 'react';
import { createContext, useContext, useState } from 'react';

import type { NextJsProjectValidation, ProcessedFile } from '@/app/projects/types';
import { ProcessedFileType } from '@/app/projects/types';
import { api } from '@/trpc/react';
import { Routes } from '@/utils/constants';

export interface Project {
name: string;
Expand Down Expand Up @@ -44,7 +48,11 @@ const ProjectCreationContext = createContext<ProjectCreationContextValue | undef
export function detectPortFromPackageJson(packageJsonFile: ProcessedFile | undefined): number {
const defaultPort = 3000;

if (!packageJsonFile || typeof packageJsonFile.content !== 'string' || packageJsonFile.type !== ProcessedFileType.TEXT) {
if (
!packageJsonFile ||
typeof packageJsonFile.content !== 'string' ||
packageJsonFile.type !== ProcessedFileType.TEXT
) {
return defaultPort;
}

Expand Down Expand Up @@ -80,10 +88,7 @@ interface ProjectCreationProviderProps {
totalSteps: number;
}

export const ProjectCreationProvider = ({
children,
totalSteps,
}: ProjectCreationProviderProps) => {
export const ProjectCreationProvider = ({ children, totalSteps }: ProjectCreationProviderProps) => {
const router = useRouter();
const [currentStep, setCurrentStep] = useState(0);
const [projectData, setProjectDataState] = useState<Partial<Project>>({
Expand Down Expand Up @@ -116,7 +121,7 @@ export const ProjectCreationProvider = ({
}

const packageJsonFile = projectData.files.find(
(f) => f.path.endsWith('package.json') && f.type === ProcessedFileType.TEXT
(f) => f.path.endsWith('package.json') && f.type === ProcessedFileType.TEXT,
);

const template = SandboxTemplates[Templates.BLANK];
Expand Down Expand Up @@ -176,32 +181,38 @@ export const ProjectCreationProvider = ({
const validateNextJsProject = async (
files: ProcessedFile[],
): Promise<NextJsProjectValidation> => {
const packageJsonFile = files.find((f) => f.path.endsWith('package.json') && f.type === ProcessedFileType.TEXT);
const packageJsonFile = files.find(
(f) => f.path.endsWith('package.json') && f.type === ProcessedFileType.TEXT,
);

if (!packageJsonFile) {
if (!packageJsonFile?.content || typeof packageJsonFile.content !== 'string') {
return { isValid: false, error: 'No package.json found' };
}

try {
const packageJson = JSON.parse(packageJsonFile.content as string);
const hasNext = packageJson.dependencies?.next || packageJson.devDependencies?.next;
const packageJson = JSON.parse(packageJsonFile.content) as Record<string, unknown>;
const dependencies = packageJson.dependencies as Record<string, string> | undefined;
const devDependencies = packageJson.devDependencies as
| Record<string, string>
| undefined;
const hasNext = dependencies?.next ?? devDependencies?.next;
if (!hasNext) {
return { isValid: false, error: 'Next.js not found in dependencies' };
}

const hasReact = packageJson.dependencies?.react || packageJson.devDependencies?.react;
const hasReact = dependencies?.react ?? devDependencies?.react;
if (!hasReact) {
return { isValid: false, error: 'React not found in dependencies' };
}

let routerType: RouterType = RouterType.PAGES;

const hasAppLayout = files.some(
(f) => isTargetFile(f.path, {
const hasAppLayout = files.some((f) =>
isTargetFile(f.path, {
fileName: 'layout',
targetExtensions: NEXT_JS_FILE_EXTENSIONS,
potentialPaths: ['app', 'src/app'],
})
}),
);

if (hasAppLayout) {
Expand All @@ -226,7 +237,6 @@ export const ProjectCreationProvider = ({
}
};


const nextStep = () => {
if (currentStep < totalSteps - 2) {
// -2 because we have 2 final steps
Expand All @@ -235,7 +245,7 @@ export const ProjectCreationProvider = ({
} else {
// This is the final step, so we should finalize the project
setCurrentStep((prev) => prev + 1);
finalizeProject();
void finalizeProject();
}
};

Expand All @@ -260,7 +270,7 @@ export const ProjectCreationProvider = ({

const retry = () => {
setError(null);
finalizeProject();
void finalizeProject();
};

const cancel = () => {
Expand Down Expand Up @@ -323,10 +333,7 @@ export const uploadToSandbox = async (files: ProcessedFile[], provider: Provider
const modifiedAst = injectPreloadScript(ast);
content = generate(modifiedAst, {}, content).code;
} catch (parseError) {
console.warn(
'Failed to add script config to layout.tsx:',
parseError,
);
console.warn('Failed to add script config to layout.tsx:', parseError);
}
}
await provider.writeFile({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { camelCase } from 'lodash';
import { makeAutoObservable, reaction } from 'mobx';

import type { CodeDiff, Font } from '@onlook/models';
import type { T } from '@onlook/parser';
import {
addGoogleFontSpecifier,
generateFontVariableExport,
Expand All @@ -6,10 +11,9 @@ import {
removeFontDeclaration,
validateGoogleFontSetup,
} from '@onlook/fonts';
import { RouterType, type CodeDiff, type Font } from '@onlook/models';
import { generate, getAstFromContent, types as t, type t as T } from '@onlook/parser';
import { camelCase } from 'lodash';
import { makeAutoObservable, reaction } from 'mobx';
import { RouterType } from '@onlook/models';
import { generate, getAstFromContent, t } from '@onlook/parser';

import type { EditorEngine } from '../engine';
import { normalizePath } from '../sandbox/helpers';

Expand Down Expand Up @@ -143,7 +147,10 @@ export class FontConfigManager {
return false;
}

const success = await this.editorEngine.activeSandbox.writeFile(this.fontConfigPath, code);
const success = await this.editorEngine.activeSandbox.writeFile(
this.fontConfigPath,
code,
);

if (!success) {
throw new Error('Failed to write font configuration');
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
import * as pathModule from 'path';
import { camelCase } from 'lodash';
import { makeAutoObservable } from 'mobx';

import type { FontConfig, FontUploadFile } from '@onlook/models';
import type { T } from '@onlook/parser';
import { DefaultSettings } from '@onlook/constants';
import {
createFontSrcObjects,
Expand All @@ -6,12 +12,9 @@ import {
hasLocalFontImport,
mergeLocalFontSources,
} from '@onlook/fonts';
import type { FontConfig, FontUploadFile } from '@onlook/models';
import { types as t, type t as T } from '@onlook/parser';
import { t } from '@onlook/parser';
import { getFontFileName } from '@onlook/utility';
import { camelCase } from 'lodash';
import { makeAutoObservable } from 'mobx';
import * as pathModule from 'path';

import type { EditorEngine } from '../engine';

export class FontUploadManager {
Expand Down Expand Up @@ -45,15 +48,18 @@ export class FontUploadManager {

const fontName = camelCase(`custom-${baseFontName}`);

const { fontNameExists, existingFontNode } = findFontExportDeclaration(fontConfigAst, fontName);
const { fontNameExists, existingFontNode } = findFontExportDeclaration(
fontConfigAst,
fontName,
);

const fontConfigs = await this.processFontFiles(fontFiles, baseFontName, basePath);
const fontsSrc = createFontSrcObjects(fontConfigs);

await this.updateAstWithFontConfig(
fontConfigAst,
fontName,
fontsSrc,
fontsSrc as T.ObjectExpression[],
fontNameExists,
existingFontNode,
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
import { camelCase } from 'lodash';
import { makeAutoObservable } from 'mobx';

import type { CodeDiff, Font } from '@onlook/models';
import type { T } from '@onlook/parser';
import {
addFontImportToFile,
createStringLiteralWithFont,
Expand All @@ -8,10 +13,8 @@ import {
updateClassNameWithFontVar,
updateTemplateLiteralWithFontClass,
} from '@onlook/fonts';
import type { CodeDiff, Font } from '@onlook/models';
import { generate, getAstFromContent, types as t, traverse, type t as T } from '@onlook/parser';
import { camelCase } from 'lodash';
import { makeAutoObservable } from 'mobx';
import { generate, getAstFromContent, t, traverse } from '@onlook/parser';

import type { EditorEngine } from '../engine';
import { normalizePath } from '../sandbox/helpers';

Expand Down
7 changes: 5 additions & 2 deletions apps/web/client/src/components/store/editor/pages/helper.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { nanoid } from 'nanoid';

import type { ListFilesOutputFile } from '@onlook/code-provider';
import type { PageMetadata, PageNode, SandboxFile } from '@onlook/models';
import type { T } from '@onlook/parser';
import { RouterType } from '@onlook/models';
import { generate, getAstFromContent, types as t, traverse, type t as T } from '@onlook/parser';
import { nanoid } from 'nanoid';
import { generate, getAstFromContent, t, traverse } from '@onlook/parser';

import type { SandboxManager } from '../sandbox';
import { formatContent } from '../sandbox/helpers';

Expand Down
8 changes: 5 additions & 3 deletions apps/web/client/src/components/store/editor/theme/util.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import type { Root, Rule } from 'postcss';
import postcss from 'postcss';

import type { T } from '@onlook/parser';
import { DEFAULT_COLOR_NAME } from '@onlook/constants';
import { SystemTheme } from '@onlook/models/assets';
import { generate, getAstFromContent, parse, traverse, type t as T } from '@onlook/parser';
import { generate, getAstFromContent, parse, traverse } from '@onlook/parser';
import { parseHslValue } from '@onlook/utility';
import type { Root, Rule } from 'postcss';
import postcss from 'postcss';

export function addTailwindNestedColor(
colorObj: T.ObjectExpression,
Expand Down
6 changes: 4 additions & 2 deletions packages/fonts/src/helpers/ast-generators.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import type { Font, FontConfig } from '@onlook/models';
import { types as t, type t as T } from '@onlook/parser';
import { camelCase } from 'lodash';

import type { Font, FontConfig } from '@onlook/models';
import type { T } from '@onlook/parser';
import { t } from '@onlook/parser';

/**
* Creates an AST object expression containing font configuration properties for Google Fonts.
* Generates the configuration object with subsets, weights, styles, CSS variable name, and display strategy.
Expand Down
13 changes: 4 additions & 9 deletions packages/fonts/src/helpers/ast-manipulators.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { createAndInsertImport } from '@onlook/fonts';
import type { Font } from '@onlook/models';
import {
generate,
getAstFromContent,
types as t,
traverse,
type NodePath,
type t as T,
} from '@onlook/parser';
import type { NodePath, T } from '@onlook/parser';
import { createAndInsertImport } from '@onlook/fonts';
import { generate, getAstFromContent, t, traverse } from '@onlook/parser';

import { createFontFamilyProperty } from './ast-generators';
import {
hasPropertyName,
Expand Down
7 changes: 4 additions & 3 deletions packages/fonts/src/helpers/class-utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { types as t, type t as T } from '@onlook/parser';
import type { T } from '@onlook/parser';
import { t } from '@onlook/parser';

const FONT_WEIGHT_REGEX =
/font-(thin|extralight|light|normal|medium|semibold|bold|extrabold|black)/;
Expand All @@ -21,7 +22,7 @@ export function findFontClass(classString: string): string | null {
* Filters out font-related classes from a className string, keeping only font weight classes
*/
export function filterFontClasses(className: string): string[] {
return className.split(' ').filter((c) => !c.startsWith('font-') || c.match(FONT_WEIGHT_REGEX));
return className.split(' ').filter((c) => !c.startsWith('font-') || FONT_WEIGHT_REGEX.exec(c));
}

/**
Expand Down Expand Up @@ -86,7 +87,7 @@ export function removeFontsFromClassName(
removeAll?: boolean;
},
): boolean {
if (!classNameAttr || !classNameAttr.value) {
if (!classNameAttr?.value) {
return false;
}

Expand Down
4 changes: 3 additions & 1 deletion packages/fonts/src/helpers/font-extractors.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { Font } from '@onlook/models';
import { generate, getAstFromContent, type t as T, types as t, traverse } from '@onlook/parser';
import type { T } from '@onlook/parser';
import { generate, getAstFromContent, t, traverse } from '@onlook/parser';

import { removeFontsFromClassName } from './class-utils';

/**
Expand Down
3 changes: 2 additions & 1 deletion packages/fonts/src/helpers/import-export-manager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { generate, traverse, types as t, type t as T, type NodePath } from '@onlook/parser';
import type { NodePath, T } from '@onlook/parser';
import { createAndInsertImport } from '@onlook/fonts';
import { generate, t, traverse } from '@onlook/parser';

/**
* Removes a font import from a file using AST traversal
Expand Down
4 changes: 2 additions & 2 deletions packages/fonts/src/helpers/validators.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import {
getAstFromContent,
types as t,
t,
traverse,
type NodePath,
type t as T,
type T,
} from '@onlook/parser';

/**
Expand Down
6 changes: 4 additions & 2 deletions packages/fonts/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { type Font, type RawFont, RouterType } from '@onlook/models';
import { types as t, type t as T } from '@onlook/parser';
import type { Font, RawFont } from '@onlook/models';
import type { T } from '@onlook/parser';
import { RouterType } from '@onlook/models';
import { t } from '@onlook/parser';

/**
* Converts a RawFont to a Font
Expand Down
2 changes: 1 addition & 1 deletion packages/fonts/test/ast-generators.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import { runDataDrivenTests } from './test-utils';
import { describe } from 'bun:test';
import path from 'path';
import { types as t } from '@onlook/parser';
import { t } from '@onlook/parser';

const __dirname = import.meta.dir;

Expand Down
2 changes: 1 addition & 1 deletion packages/fonts/test/class-utils.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { describe, expect, test } from 'bun:test';
import fs from 'fs';
import path from 'path';
import { generate, parse, types as t, type t as T } from '@onlook/parser';
import { generate, parse, t, T } from '@onlook/parser';
import {
updateJSXExpressionClassNameWithFont,
updateStringLiteralClassNameWithFont,
Expand Down
2 changes: 1 addition & 1 deletion packages/fonts/test/font-extractors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
migrateFontsFromLayout,
} from '../src/helpers/font-extractors';
import { runDataDrivenTests } from './test-utils';
import { parse, traverse, type t as T } from '@onlook/parser';
import { parse, traverse, T } from '@onlook/parser';
import path from 'path';

const __dirname = import.meta.dir;
Expand Down
Loading