',
16 | to: invitedByEmail,
17 | subject: 'You have been invited to Onlook',
18 | react: InviteUserEmail({ invitedByEmail, inviteLink }),
19 | });
20 | };
21 |
--------------------------------------------------------------------------------
/packages/email/src/templates/index.ts:
--------------------------------------------------------------------------------
1 | export * from './invite-user';
2 |
--------------------------------------------------------------------------------
/packages/email/src/types/send-email.ts:
--------------------------------------------------------------------------------
1 | import type { Resend } from 'resend';
2 |
3 | export interface SendEmailOptions {
4 | dryRun?: boolean;
5 | }
6 |
7 | export type SendEmailParams = [client: Resend, props: P, options?: Partial];
8 |
--------------------------------------------------------------------------------
/packages/email/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/fonts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/fonts",
3 | "description": "Onlook supported fonts",
4 | "version": "0.0.0",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/onlook-dev/onlook.git"
8 | },
9 | "type": "module",
10 | "main": "src/index.ts",
11 | "scripts": {
12 | "clean": "rm -rf node_modules",
13 | "lint": "eslint --fix",
14 | "format": "prettier --write .",
15 | "typecheck": "tsc --noEmit"
16 | },
17 | "keywords": [
18 | "onlook",
19 | "fonts"
20 | ],
21 | "author": {
22 | "name": "Onlook",
23 | "email": "contact@onlook.com"
24 | },
25 | "license": "Apache-2.0",
26 | "homepage": "https://onlook.com",
27 | "exports": {
28 | ".": "./src/index.ts",
29 | "./*": "./src/*/index.ts"
30 | },
31 | "devDependencies": {
32 | "@onlook/typescript": "*",
33 | "typescript": "^5.5.4"
34 | },
35 | "dependencies": {}
36 | }
37 |
--------------------------------------------------------------------------------
/packages/fonts/src/default.ts:
--------------------------------------------------------------------------------
1 | export const DEFAULT = {
2 | WEIGHT: '400',
3 | STYLE: 'normal',
4 | };
5 |
--------------------------------------------------------------------------------
/packages/fonts/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './default';
2 | export * from './family';
3 | export * from './variants';
4 | export * from './helper';
5 | export * from './utils';
6 |
--------------------------------------------------------------------------------
/packages/fonts/src/variants.ts:
--------------------------------------------------------------------------------
1 | export enum WEIGHT {
2 | THIN = 'Thin',
3 | EXTRA_LIGHT = 'Extra Light',
4 | LIGHT = 'Light',
5 | REGULAR = 'Regular',
6 | MEDIUM = 'Medium',
7 | SEMI_BOLD = 'Semi Bold',
8 | BOLD = 'Bold',
9 | EXTRA_BOLD = 'Extra Bold',
10 | BLACK = 'Black',
11 | }
12 |
13 | export const VARIANTS: { name: WEIGHT; value: string }[] = [
14 | {
15 | name: WEIGHT.THIN,
16 | value: '100',
17 | },
18 | {
19 | name: WEIGHT.EXTRA_LIGHT,
20 | value: '200',
21 | },
22 | {
23 | name: WEIGHT.LIGHT,
24 | value: '300',
25 | },
26 | {
27 | name: WEIGHT.REGULAR,
28 | value: '400',
29 | },
30 | {
31 | name: WEIGHT.MEDIUM,
32 | value: '500',
33 | },
34 | {
35 | name: WEIGHT.SEMI_BOLD,
36 | value: '600',
37 | },
38 | {
39 | name: WEIGHT.BOLD,
40 | value: '700',
41 | },
42 | {
43 | name: WEIGHT.EXTRA_BOLD,
44 | value: '800',
45 | },
46 | {
47 | name: WEIGHT.BLACK,
48 | value: '900',
49 | },
50 | ];
51 |
--------------------------------------------------------------------------------
/packages/fonts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/git/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/git",
3 | "description": "A git library for Onlook",
4 | "main": "./src/index.ts",
5 | "type": "module",
6 | "module": "src/index.ts",
7 | "types": "src/index.ts",
8 | "version": "0.0.0",
9 | "private": true,
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/onlook-dev/onlook.git"
13 | },
14 | "scripts": {
15 | "clean": "rm -rf node_modules",
16 | "lint": "eslint --fix .",
17 | "format": "prettier --write .",
18 | "typecheck": "tsc --noEmit"
19 | },
20 | "keywords": [
21 | "onlook",
22 | "git"
23 | ],
24 | "author": {
25 | "name": "Onlook",
26 | "email": "contact@onlook.com"
27 | },
28 | "license": "Apache-2.0",
29 | "homepage": "https://onlook.com",
30 | "devDependencies": {
31 | "@onlook/typescript": "*"
32 | },
33 | "dependencies": {
34 | "globby": "^14.1.0",
35 | "isomorphic-git": "^1.29.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/git/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './git';
2 |
--------------------------------------------------------------------------------
/packages/git/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/growth/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/growth",
3 | "description": "Growth helpers",
4 | "main": "./src/index.ts",
5 | "type": "module",
6 | "module": "src/index.ts",
7 | "types": "src/index.ts",
8 | "version": "0.0.0",
9 | "private": true,
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/onlook-dev/onlook.git"
13 | },
14 | "scripts": {
15 | "clean": "rm -rf node_modules",
16 | "lint": "eslint --fix .",
17 | "format": "prettier --write .",
18 | "typecheck": "tsc --noEmit"
19 | },
20 | "keywords": [
21 | "onlook",
22 | "growth"
23 | ],
24 | "author": {
25 | "name": "Onlook",
26 | "email": "contact@onlook.com"
27 | },
28 | "license": "Apache-2.0",
29 | "homepage": "https://onlook.com",
30 | "devDependencies": {
31 | "@onlook/typescript": "*"
32 | },
33 | "dependencies": {
34 | "@babel/types": "^7.27.0",
35 | "@onlook/parser": "*"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/packages/growth/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './inject';
2 | export * from './remove';
3 |
--------------------------------------------------------------------------------
/packages/growth/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/mastra/src/agents/index.ts:
--------------------------------------------------------------------------------
1 | import { anthropic } from '@ai-sdk/anthropic';
2 | import { Agent } from '@mastra/core/agent';
3 | import { weatherTool } from '../tools';
4 |
5 | export const weatherAgent = new Agent({
6 | name: 'Weather Agent',
7 | instructions: `
8 | You are a helpful weather assistant that provides accurate weather information.
9 |
10 | Your primary function is to help users get weather details for specific locations. When responding:
11 | - Always ask for a location if none is provided
12 | - If the location name isn’t in English, please translate it
13 | - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
14 | - Include relevant details like humidity, wind conditions, and precipitation
15 | - Keep responses concise but informative
16 |
17 | Use the weatherTool to fetch current weather data.
18 | `,
19 | model: anthropic('claude-3-5-sonnet-20241022'),
20 | tools: { weatherTool },
21 | });
22 |
--------------------------------------------------------------------------------
/packages/mastra/src/index.ts:
--------------------------------------------------------------------------------
1 | import { Mastra } from '@mastra/core/mastra';
2 | import { createLogger } from '@mastra/core/logger';
3 | import { weatherWorkflow } from './workflows';
4 | import { weatherAgent } from './agents';
5 |
6 | export const mastra = new Mastra({
7 | workflows: { weatherWorkflow },
8 | agents: { weatherAgent },
9 | logger: createLogger({
10 | name: 'Mastra',
11 | level: 'info',
12 | }),
13 | });
14 |
--------------------------------------------------------------------------------
/packages/mastra/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/models/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/models",
3 | "description": "Common models shared between onlook packages",
4 | "version": "0.0.0",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/onlook-dev/onlook.git"
8 | },
9 | "type": "module",
10 | "main": "src/index.ts",
11 | "scripts": {
12 | "clean": "rm -rf node_modules",
13 | "lint": "eslint --fix",
14 | "format": "prettier --write .",
15 | "typecheck": "tsc --noEmit"
16 | },
17 | "keywords": [
18 | "onlook",
19 | "models"
20 | ],
21 | "author": {
22 | "name": "Onlook",
23 | "email": "contact@onlook.com"
24 | },
25 | "license": "Apache-2.0",
26 | "homepage": "https://onlook.com",
27 | "exports": {
28 | ".": "./src/index.ts",
29 | "./*": "./src/*/index.ts"
30 | },
31 | "devDependencies": {
32 | "@onlook/typescript": "*",
33 | "typescript": "^5.5.4",
34 | "ai": "^4.2.6"
35 | },
36 | "dependencies": {
37 | "zod": "^3.23.8"
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/packages/models/src/actions/index.ts:
--------------------------------------------------------------------------------
1 | export * from './action.ts';
2 | export * from './code.ts';
3 | export * from './location.ts';
4 | export * from './target.ts';
5 |
--------------------------------------------------------------------------------
/packages/models/src/actions/location.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | const BaseActionLocationSchema = z.object({
4 | type: z.enum(['prepend', 'append']),
5 | targetDomId: z.string(),
6 | targetOid: z.string().nullable(),
7 | });
8 |
9 | export const IndexActionLocationSchema = BaseActionLocationSchema.extend({
10 | type: z.literal('index'),
11 | index: z.number(),
12 | originalIndex: z.number(),
13 | });
14 |
15 | export const ActionLocationSchema = z.discriminatedUnion('type', [
16 | IndexActionLocationSchema,
17 | BaseActionLocationSchema,
18 | ]);
19 |
20 | export type ActionLocation = z.infer;
21 | export type IndexActionLocation = z.infer;
22 |
--------------------------------------------------------------------------------
/packages/models/src/actions/target.ts:
--------------------------------------------------------------------------------
1 | import type { StyleChange } from '../style';
2 |
3 | export type Change = {
4 | updated: T;
5 | original: T;
6 | };
7 |
8 | export interface ActionTarget {
9 | domId: string;
10 | oid: string | null;
11 | frameId: string;
12 | }
13 |
14 | export interface StyleActionTarget extends ActionTarget {
15 | change: Change>;
16 | }
17 |
--------------------------------------------------------------------------------
/packages/models/src/auth/index.ts:
--------------------------------------------------------------------------------
1 | export enum SignInMethod {
2 | GITHUB = 'github',
3 | GOOGLE = 'google',
4 | }
5 |
--------------------------------------------------------------------------------
/packages/models/src/chat/conversation/index.ts:
--------------------------------------------------------------------------------
1 | export type ChatConversation = {
2 | id: string;
3 | projectId: string;
4 | displayName: string | null;
5 | createdAt: string;
6 | updatedAt: string;
7 | };
8 |
--------------------------------------------------------------------------------
/packages/models/src/chat/index.ts:
--------------------------------------------------------------------------------
1 | export * from './conversation/';
2 | export * from './message/';
3 | export * from './request.ts';
4 | export * from './response.ts';
5 | export * from './stream.ts';
6 | export * from './suggestion.ts';
7 | export * from './summary.ts';
8 |
--------------------------------------------------------------------------------
/packages/models/src/chat/message/code.ts:
--------------------------------------------------------------------------------
1 | export interface CodeBlock {
2 | fileName?: string;
3 | language?: string;
4 | content: string;
5 | }
6 |
7 | export interface CodeSearchReplace {
8 | search: string;
9 | replace: string;
10 | }
11 |
--------------------------------------------------------------------------------
/packages/models/src/chat/message/index.ts:
--------------------------------------------------------------------------------
1 | export * from '../response.ts';
2 | export * from './code.ts';
3 | export * from './context.ts';
4 | export * from './message.ts';
5 |
--------------------------------------------------------------------------------
/packages/models/src/chat/message/message.ts:
--------------------------------------------------------------------------------
1 | import type { Message } from '@ai-sdk/react';
2 | import type { TextPart } from 'ai';
3 | import type { CodeDiff } from '../../code/index.ts';
4 | import { type ChatMessageContext } from './context.ts';
5 |
6 | export enum ChatMessageRole {
7 | USER = 'user',
8 | ASSISTANT = 'assistant',
9 | SYSTEM = 'system',
10 | }
11 |
12 | export interface UserChatMessage extends Message {
13 | role: ChatMessageRole.USER;
14 | context: ChatMessageContext[];
15 | parts: TextPart[];
16 | content: string;
17 | }
18 |
19 | export interface AssistantChatMessage extends Message {
20 | role: ChatMessageRole.ASSISTANT;
21 | applied: boolean;
22 | snapshots: ChatSnapshot;
23 | parts: Message['parts'];
24 | content: string;
25 | }
26 |
27 | export type ChatSnapshot = Record;
28 |
29 | export interface SystemChatMessage extends Message {
30 | role: ChatMessageRole.SYSTEM;
31 | }
32 |
33 | export type ChatMessage = UserChatMessage | AssistantChatMessage | SystemChatMessage;
34 |
--------------------------------------------------------------------------------
/packages/models/src/chat/request.ts:
--------------------------------------------------------------------------------
1 | import type { CoreMessage } from 'ai';
2 |
3 | export enum StreamRequestType {
4 | CHAT = 'chat',
5 | CREATE = 'create',
6 | ERROR_FIX = 'error-fix',
7 | SUGGESTIONS = 'suggestions',
8 | SUMMARY = 'summary',
9 | }
10 |
11 | export type StreamRequest = {
12 | messages: CoreMessage[];
13 | systemPrompt: string;
14 | requestType: StreamRequestType;
15 | useAnalytics: boolean;
16 | };
17 |
18 | export type StreamRequestV2 = {
19 | messages: CoreMessage[];
20 | requestType: StreamRequestType;
21 | useAnalytics: boolean;
22 | };
23 |
--------------------------------------------------------------------------------
/packages/models/src/chat/response.ts:
--------------------------------------------------------------------------------
1 | export interface UsageCheckResult {
2 | exceeded: boolean;
3 | reason: 'none' | 'daily' | 'monthly';
4 | daily_requests_count: number;
5 | monthly_requests_count: number;
6 | daily_requests_limit: number;
7 | monthly_requests_limit: number;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/models/src/chat/stream.ts:
--------------------------------------------------------------------------------
1 | import type { CoreMessage, LanguageModelUsage, TextStreamPart, ToolSet } from 'ai';
2 | import type { UsageCheckResult } from './response';
3 |
4 | export interface StreamResponse {
5 | type: 'partial' | 'full' | 'error' | 'rate-limited';
6 | }
7 |
8 | export interface PartialStreamResponse extends StreamResponse {
9 | payload: TextStreamPart;
10 | type: 'partial';
11 | }
12 |
13 | export interface FullStreamResponse extends StreamResponse {
14 | payload: CoreMessage[];
15 | type: 'full';
16 | usage?: LanguageModelUsage;
17 | text: string;
18 | }
19 |
20 | export interface ErrorStreamResponse extends StreamResponse {
21 | type: 'error';
22 | message: string;
23 | }
24 |
25 | export interface RateLimitedStreamResponse extends StreamResponse {
26 | type: 'rate-limited';
27 | rateLimitResult: UsageCheckResult;
28 | }
29 |
30 | export type CompletedStreamResponse =
31 | | FullStreamResponse
32 | | RateLimitedStreamResponse
33 | | ErrorStreamResponse;
34 |
--------------------------------------------------------------------------------
/packages/models/src/chat/suggestion.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | export interface ProjectSuggestions {
4 | id: string;
5 | projectId: string;
6 | suggestions: ChatSuggestion[];
7 | }
8 |
9 | export interface ChatSuggestion {
10 | title: string;
11 | prompt: string;
12 | }
13 |
14 | export const ChatSuggestionSchema = z.object({
15 | title: z
16 | .string()
17 | .describe(
18 | 'The display title of the suggestion. This will be shown to the user. Keep it concise but descriptive.',
19 | ),
20 | prompt: z
21 | .string()
22 | .describe(
23 | 'The prompt for the suggestion. This will be used to generate the suggestion. Make this as detailed and specific as possible.',
24 | ),
25 | });
26 |
--------------------------------------------------------------------------------
/packages/models/src/chat/summary.ts:
--------------------------------------------------------------------------------
1 | import { z } from 'zod';
2 |
3 | export const ChatSummarySchema = z.object({
4 | filesDiscussed: z
5 | .array(z.string())
6 | .describe('List of file paths mentioned in the conversation'),
7 | projectContext: z
8 | .string()
9 | .describe('Summary of what the user is building and their overall goals'),
10 | implementationDetails: z
11 | .string()
12 | .describe('Summary of key code decisions, patterns, and important implementation details'),
13 | userPreferences: z
14 | .string()
15 | .describe('Specific preferences the user has expressed about implementation, design, etc.'),
16 | currentStatus: z.string().describe('Current state of the project and any pending work'),
17 | });
18 |
--------------------------------------------------------------------------------
/packages/models/src/code/index.ts:
--------------------------------------------------------------------------------
1 | import { type CodeAction } from '../actions/code';
2 |
3 | export interface CodeDiffRequest {
4 | oid: string;
5 | attributes: Record;
6 | textContent: string | null;
7 | overrideClasses: boolean | null;
8 | structureChanges: CodeAction[];
9 | }
10 |
11 | export interface CodeDiff {
12 | original: string;
13 | generated: string;
14 | path: string;
15 | }
16 |
17 | export type FileToRequests = Map<
18 | string,
19 | {
20 | oidToRequest: Map;
21 | content: string;
22 | }
23 | >;
24 |
25 | export interface FileNode {
26 | id: string;
27 | name: string;
28 | path: string;
29 | isDirectory: boolean;
30 | children?: FileNode[];
31 | extension?: string;
32 | }
33 |
--------------------------------------------------------------------------------
/packages/models/src/create/index.ts:
--------------------------------------------------------------------------------
1 | export enum CreateStage {
2 | CLONING = 'cloning',
3 | GIT_INIT = 'git_init',
4 | INSTALLING = 'installing',
5 | COMPLETE = 'complete',
6 | ERROR = 'error',
7 | }
8 |
9 | export enum VerifyStage {
10 | CHECKING = 'checking',
11 | NOT_INSTALLED = 'not_installed',
12 | INSTALLED = 'installed',
13 | ERROR = 'error',
14 | }
15 |
16 | export enum SetupStage {
17 | INSTALLING = 'installing',
18 | CONFIGURING = 'configuring',
19 | COMPLETE = 'complete',
20 | ERROR = 'error',
21 | }
22 |
23 | export interface CreateProjectResponse {
24 | success: boolean;
25 | error?: string;
26 | response?: {
27 | projectPath: string;
28 | content: string;
29 | };
30 | cancelled?: boolean;
31 | }
32 |
33 | export type CreateCallback = (stage: CreateStage, message: string) => void;
34 | export type VerifyCallback = (stage: VerifyStage, message: string) => void;
35 | export type SetupCallback = (stage: SetupStage, message: string) => void;
36 |
--------------------------------------------------------------------------------
/packages/models/src/editor/index.ts:
--------------------------------------------------------------------------------
1 | export interface WebviewMetadata {
2 | id: string;
3 | title: string;
4 | src: string;
5 | }
6 |
7 | export enum EditorMode {
8 | DESIGN = 'design',
9 | PREVIEW = 'preview',
10 | PAN = 'pan',
11 | INSERT_TEXT = 'insert-text',
12 | INSERT_DIV = 'insert-div',
13 | INSERT_IMAGE = 'insert-image',
14 | }
15 |
16 | export enum EditorTabValue {
17 | CHAT = 'chat',
18 | DEV = 'dev',
19 | }
20 |
21 | export enum SettingsTabValue {
22 | SITE = 'site',
23 | DOMAIN = 'domain',
24 | PROJECT = 'project',
25 | PREFERENCES = 'preferences',
26 | VERSIONS = 'versions',
27 | ADVANCED = 'advanced',
28 | }
29 |
30 | export enum LeftPanelTabValue {
31 | PAGES = 'pages',
32 | LAYERS = 'layers',
33 | COMPONENTS = 'components',
34 | IMAGES = 'images',
35 | WINDOWS = 'windows',
36 | BRAND = 'brand',
37 | APPS = 'apps',
38 | }
39 |
40 | export enum BrandTabValue {
41 | COLORS = 'colors',
42 | FONTS = 'fonts',
43 | }
44 |
45 | export enum MouseAction {
46 | MOVE = 'move',
47 | MOUSE_DOWN = 'click',
48 | DOUBLE_CLICK = 'double-click',
49 | }
50 |
--------------------------------------------------------------------------------
/packages/models/src/element/classes.ts:
--------------------------------------------------------------------------------
1 | interface ParsedClasses {
2 | type: 'classes';
3 | value: string[];
4 | }
5 |
6 | interface ClassParsingError {
7 | type: 'error';
8 | reason: string;
9 | }
10 |
11 | export type ClassParsingResult = ParsedClasses | ClassParsingError;
12 |
--------------------------------------------------------------------------------
/packages/models/src/element/element.ts:
--------------------------------------------------------------------------------
1 | interface BaseDomElement {
2 | domId: string;
3 | frameId: string;
4 | oid: string | null;
5 | instanceId: string | null;
6 | rect: DOMRect;
7 | }
8 |
9 | export interface ParentDomElement extends BaseDomElement {}
10 |
11 | export interface DomElement extends BaseDomElement {
12 | tagName: string;
13 | styles: DomElementStyles | null;
14 | parent: ParentDomElement | null;
15 | }
16 |
17 | export interface DomElementStyles {
18 | defined: Record; // Styles from stylesheets or inline
19 | computed: Record; // Browser computed styles
20 | }
21 |
22 | export interface ElementPosition {
23 | x: number;
24 | y: number;
25 | }
26 |
27 | export interface DropElementProperties {
28 | tagName: string;
29 | styles: Record;
30 | textContent: string | null;
31 | }
32 |
33 | export interface RectDimensions {
34 | width: number;
35 | height: number;
36 | top: number;
37 | left: number;
38 | }
39 |
--------------------------------------------------------------------------------
/packages/models/src/element/index.ts:
--------------------------------------------------------------------------------
1 | export * from './classes';
2 | export * from './element';
3 | export * from './layers';
4 | export * from './templateNode';
5 | export * from './props';
6 |
--------------------------------------------------------------------------------
/packages/models/src/element/layers.ts:
--------------------------------------------------------------------------------
1 | export enum DynamicType {
2 | ARRAY = 'array',
3 | CONDITIONAL = 'conditional',
4 | UNKNOWN = 'unknown',
5 | }
6 |
7 | export enum CoreElementType {
8 | COMPONENT_ROOT = 'component-root',
9 | BODY_TAG = 'body-tag',
10 | }
11 |
12 | export interface LayerNode {
13 | domId: string;
14 | frameId: string;
15 | instanceId: string | null;
16 | oid: string | null;
17 | textContent: string;
18 | tagName: string;
19 | isVisible: boolean;
20 | dynamicType: DynamicType | null;
21 | coreElementType: CoreElementType | null;
22 | component: string | null;
23 | children: string[] | null;
24 | parent: string | null;
25 | }
26 |
--------------------------------------------------------------------------------
/packages/models/src/element/props.ts:
--------------------------------------------------------------------------------
1 | interface ParsedProps {
2 | type: 'props';
3 | props: NodeProps[];
4 | }
5 |
6 | export enum PropsType {
7 | String = 'string',
8 | Number = 'number',
9 | Boolean = 'boolean',
10 | Object = 'object',
11 | Array = 'array',
12 | Code = 'code',
13 | }
14 |
15 | export interface NodeProps {
16 | key: any;
17 | value: any;
18 | type: PropsType;
19 | }
20 |
21 | interface PropsParsingError {
22 | type: 'error';
23 | reason: string;
24 | }
25 |
26 | export type PropsParsingResult = ParsedProps | PropsParsingError;
27 |
--------------------------------------------------------------------------------
/packages/models/src/element/templateNode.ts:
--------------------------------------------------------------------------------
1 | import { type CoreElementType, type DynamicType } from './layers';
2 |
3 | export interface TemplateNode {
4 | path: string;
5 | startTag: TemplateTag;
6 | endTag: TemplateTag | null;
7 | component: string | null;
8 | dynamicType: DynamicType | null;
9 | coreElementType: CoreElementType | null;
10 | }
11 |
12 | export interface TemplateTag {
13 | start: TemplateTagPosition;
14 | end: TemplateTagPosition;
15 | }
16 |
17 | export interface TemplateTagPosition {
18 | line: number;
19 | column: number;
20 | }
21 |
--------------------------------------------------------------------------------
/packages/models/src/ide/index.ts:
--------------------------------------------------------------------------------
1 | export enum IdeType {
2 | VS_CODE = 'VSCode',
3 | CURSOR = 'Cursor',
4 | ZED = 'Zed',
5 | WINDSURF = 'Windsurf',
6 | ONLOOK = 'Onlook',
7 | }
8 |
9 | export const DEFAULT_IDE = IdeType.ONLOOK;
10 |
--------------------------------------------------------------------------------
/packages/models/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './actions/';
2 | export * from './assets/';
3 | export * from './auth/';
4 | export * from './chat/';
5 | export * from './code/';
6 | export * from './create/';
7 | export * from './editor/';
8 | export * from './element/';
9 | export * from './ide/';
10 | export * from './llm/';
11 | export * from './pages/';
12 | export * from './project/';
13 | export * from './run/';
14 | export * from './style/';
15 | export * from './user/';
16 |
--------------------------------------------------------------------------------
/packages/models/src/llm/index.ts:
--------------------------------------------------------------------------------
1 | export enum LLMProvider {
2 | ANTHROPIC = 'anthropic',
3 | }
4 |
5 | export enum CLAUDE_MODELS {
6 | SONNET_4 = 'claude-sonnet-4-20250514',
7 | SONNET_3_7 = 'claude-3-7-sonnet-20250219',
8 | HAIKU = 'claude-3-5-haiku-20241022',
9 | }
10 |
--------------------------------------------------------------------------------
/packages/models/src/project/canvas.ts:
--------------------------------------------------------------------------------
1 | import type { RectPosition } from './rect';
2 |
3 | export interface Canvas {
4 | id: string;
5 | scale: number;
6 | position: RectPosition;
7 | }
8 |
--------------------------------------------------------------------------------
/packages/models/src/project/command.ts:
--------------------------------------------------------------------------------
1 | export interface Commands {
2 | build?: string;
3 | run?: string;
4 | install?: string;
5 | }
6 |
--------------------------------------------------------------------------------
/packages/models/src/project/domain.ts:
--------------------------------------------------------------------------------
1 | export enum DomainType {
2 | BASE = 'base',
3 | CUSTOM = 'custom',
4 | }
5 |
6 | export interface ProjectDomain {
7 | base: DomainSettings | null;
8 | custom: DomainSettings | null;
9 | }
10 |
11 | export interface DomainSettings {
12 | url: string;
13 | type: DomainType;
14 | publishedAt?: string;
15 | }
16 |
--------------------------------------------------------------------------------
/packages/models/src/project/frame.ts:
--------------------------------------------------------------------------------
1 | import { Orientation, Theme } from '@onlook/constants';
2 | import type { RectDimension, RectPosition } from './rect';
3 |
4 | export enum FrameType {
5 | WEB = 'web',
6 | }
7 |
8 | export interface Frame {
9 | id: string;
10 | position: RectPosition;
11 | type: FrameType;
12 | dimension: RectDimension;
13 | }
14 |
15 | export interface WebFrame extends Frame {
16 | url: string;
17 | type: FrameType.WEB;
18 | }
19 |
20 | export interface WindowMetadata {
21 | orientation: Orientation;
22 | aspectRatioLocked: boolean;
23 | device: string;
24 | theme: Theme;
25 | width: number;
26 | height: number;
27 | }
28 |
--------------------------------------------------------------------------------
/packages/models/src/project/index.ts:
--------------------------------------------------------------------------------
1 | export * from './canvas';
2 | export * from './command';
3 | export * from './domain';
4 | export * from './frame';
5 | export * from './invitation';
6 | export * from './project';
7 | export * from './rect';
8 | export * from './role';
9 |
--------------------------------------------------------------------------------
/packages/models/src/project/invitation.ts:
--------------------------------------------------------------------------------
1 | import type { ProjectRole } from './role';
2 |
3 | export interface Invitation {
4 | id: string;
5 | inviteeEmail: string;
6 | role: ProjectRole;
7 | expiresAt: Date;
8 | }
9 |
--------------------------------------------------------------------------------
/packages/models/src/project/project.ts:
--------------------------------------------------------------------------------
1 | export interface Project {
2 | id: string;
3 | name: string;
4 | metadata: {
5 | createdAt: string;
6 | updatedAt: string;
7 | previewImg: string | null;
8 | description: string | null;
9 | };
10 | sandbox: {
11 | id: string;
12 | url: string;
13 | };
14 | }
15 |
--------------------------------------------------------------------------------
/packages/models/src/project/rect.ts:
--------------------------------------------------------------------------------
1 | export interface RectPosition {
2 | x: number;
3 | y: number;
4 | }
5 |
6 | export interface RectDimension {
7 | width: number;
8 | height: number;
9 | }
10 |
--------------------------------------------------------------------------------
/packages/models/src/project/role.ts:
--------------------------------------------------------------------------------
1 | export enum ProjectRole {
2 | OWNER = 'owner',
3 | ADMIN = 'admin',
4 | }
5 |
--------------------------------------------------------------------------------
/packages/models/src/run/index.ts:
--------------------------------------------------------------------------------
1 | export enum RunState {
2 | STOPPED = 'stopped',
3 | SETTING_UP = 'setting-up',
4 | RUNNING = 'running',
5 | STOPPING = 'stopping',
6 | ERROR = 'error',
7 | }
8 |
--------------------------------------------------------------------------------
/packages/models/src/style/index.ts:
--------------------------------------------------------------------------------
1 | export interface StyleChange {
2 | value: string;
3 | type: StyleChangeType;
4 | }
5 |
6 | export enum StyleChangeType {
7 | Value = 'value',
8 | Custom = 'custom',
9 | Remove = 'remove',
10 | }
11 |
12 | export interface TailwindColor {
13 | name: string;
14 | originalKey: string;
15 | lightColor: string;
16 | darkColor?: string;
17 | line?: {
18 | config?: number;
19 | css?: {
20 | lightMode?: number;
21 | darkMode?: number;
22 | };
23 | };
24 | override?: boolean;
25 | }
26 |
--------------------------------------------------------------------------------
/packages/models/src/usage/index.ts:
--------------------------------------------------------------------------------
1 | export enum UsagePlanType {
2 | BASIC = 'basic',
3 | PRO = 'pro',
4 | }
5 |
6 | export interface UserUsage {
7 | id: number;
8 | user_id: string;
9 | stripe_customer_id?: string;
10 | stripe_subscription_id?: string;
11 | daily_requests_count: number;
12 | monthly_requests_count: number;
13 | plan_id: number;
14 | created_at: string;
15 | updated_at: string;
16 | cancelled: boolean;
17 | }
18 |
19 | export interface UsagePlan {
20 | id: number;
21 | name: UsagePlanType;
22 | daily_requests_limit: number;
23 | monthly_requests_limit: number;
24 | stripe_price_id: string;
25 | stripe_product_id: string;
26 | is_free: boolean;
27 | }
28 |
--------------------------------------------------------------------------------
/packages/models/src/user/index.ts:
--------------------------------------------------------------------------------
1 | export * from './settings';
2 | export * from './user';
3 |
--------------------------------------------------------------------------------
/packages/models/src/user/settings.ts:
--------------------------------------------------------------------------------
1 | export interface UserSettings {
2 | id: string;
3 | chat: ChatSettings;
4 | }
5 |
6 | export interface ChatSettings {
7 | showSuggestions: boolean;
8 | autoApplyCode: boolean;
9 | expandCodeBlocks: boolean;
10 | showMiniChat: boolean;
11 | }
12 |
--------------------------------------------------------------------------------
/packages/models/src/user/user.ts:
--------------------------------------------------------------------------------
1 | export interface UserMetadata {
2 | id: string;
3 | name?: string;
4 | avatarUrl?: string | null;
5 | email?: string;
6 | }
7 |
--------------------------------------------------------------------------------
/packages/models/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/parser/src/code-edit/image.ts:
--------------------------------------------------------------------------------
1 | import { DefaultSettings } from '@onlook/constants';
2 | import { type CodeInsertImage, type CodeRemoveImage } from '@onlook/models/actions';
3 | import { type NodePath, type t as T } from '../packages';
4 | import { addClassToNode } from './style';
5 |
6 | export function insertImageToNode(path: NodePath, action: CodeInsertImage): void {
7 | const imageName = writeImageToFile(action);
8 | if (!imageName) {
9 | console.error('Failed to write image to file');
10 | return;
11 | }
12 | const prefix = DefaultSettings.IMAGE_FOLDER.replace(/^public\//, '');
13 | const backgroundClass = `bg-[url(/${prefix}/${imageName})]`;
14 | addClassToNode(path.node, backgroundClass);
15 | }
16 |
17 | function writeImageToFile(action: CodeInsertImage): string | null {
18 | // TODO: Implement
19 | return null;
20 | }
21 |
22 | export function removeImageFromNode(path: NodePath, action: CodeRemoveImage): void {}
23 |
--------------------------------------------------------------------------------
/packages/parser/src/code-edit/index.ts:
--------------------------------------------------------------------------------
1 | export * from './group';
2 | export * from './image';
3 | export * from './insert';
4 | export * from './move';
5 | export * from './remove';
6 | export * from './style';
7 | export * from './text';
8 | export * from './transform';
9 |
--------------------------------------------------------------------------------
/packages/parser/src/code-edit/text.ts:
--------------------------------------------------------------------------------
1 | import { type t as T, types as t } from '../packages';
2 |
3 | export function updateNodeTextContent(node: T.JSXElement, textContent: string): void {
4 | const textNode = node.children.find((child) => t.isJSXText(child)) as T.JSXText | undefined;
5 | if (textNode) {
6 | textNode.value = textContent;
7 | } else {
8 | node.children.unshift(t.jsxText(textContent));
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/packages/parser/src/helpers.ts:
--------------------------------------------------------------------------------
1 | import { type t as T, types as t } from './packages';
2 |
3 | export function isReactFragment(openingElement: T.JSXOpeningElement): boolean {
4 | const name = openingElement.name;
5 |
6 | if (t.isJSXIdentifier(name)) {
7 | return name.name === 'Fragment';
8 | }
9 |
10 | if (t.isJSXMemberExpression(name)) {
11 | return (
12 | t.isJSXIdentifier(name.object) &&
13 | name.object.name === 'React' &&
14 | t.isJSXIdentifier(name.property) &&
15 | name.property.name === 'Fragment'
16 | );
17 | }
18 |
19 | return false;
20 | }
21 |
22 | export function isColorsObjectProperty(path: any): boolean {
23 | return (
24 | path.parent.type === 'ObjectExpression' &&
25 | path.node.key.type === 'Identifier' &&
26 | path.node.key.name === 'colors' &&
27 | path.node.value.type === 'ObjectExpression'
28 | );
29 | }
30 |
31 | export function isObjectExpression(node: any): node is T.ObjectExpression {
32 | return node.type === 'ObjectExpression';
33 | }
34 |
--------------------------------------------------------------------------------
/packages/parser/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './code-edit';
2 | export * from './helpers';
3 | export * from './ids';
4 | export * from './packages';
5 | export * from './parse';
6 | export * from './template-node';
7 |
--------------------------------------------------------------------------------
/packages/parser/src/packages.ts:
--------------------------------------------------------------------------------
1 | import { packages } from '@babel/standalone';
2 |
3 | import type * as t from '@babel/types';
4 | import type { NodePath } from '@babel/traverse';
5 | import type { GeneratorOptions } from '@babel/generator';
6 |
7 | export const { parse } = packages.parser;
8 | export const { generate } = packages.generator;
9 | export const traverse = packages.traverse.default;
10 | export const types = packages.types;
11 |
12 | export type { t, NodePath, GeneratorOptions };
13 |
--------------------------------------------------------------------------------
/packages/parser/src/template-node/index.ts:
--------------------------------------------------------------------------------
1 | export * from './helpers';
2 | export * from './map';
3 |
--------------------------------------------------------------------------------
/packages/parser/test/parse.test.ts:
--------------------------------------------------------------------------------
1 | import { describe, expect, test } from 'bun:test';
2 | import { getAstFromContent, getContentFromAst } from 'src';
3 |
4 | describe('Parse Tests', () => {
5 | test('should parse and serialize a simple component', async () => {
6 | const code = `export default function App() {\n return (\n Hello, world!
);\n\n}`;
7 | const ast = getAstFromContent(code);
8 | const serialized = await getContentFromAst(ast);
9 | expect(serialized).toEqual(code);
10 | });
11 | });
12 |
--------------------------------------------------------------------------------
/packages/parser/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/penpal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/penpal",
3 | "description": "A utility library to facilitates rpc-style calls with penpal between preload and iframe",
4 | "main": "./src/index.ts",
5 | "type": "module",
6 | "module": "src/index.ts",
7 | "types": "src/index.ts",
8 | "version": "0.0.0",
9 | "private": true,
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/onlook-dev/onlook.git"
13 | },
14 | "scripts": {
15 | "clean": "rm -rf node_modules",
16 | "lint": "eslint --fix .",
17 | "format": "prettier --write .",
18 | "typecheck": "tsc --noEmit"
19 | },
20 | "keywords": [
21 | "onlook",
22 | "penpal",
23 | "preload",
24 | "iframe"
25 | ],
26 | "author": {
27 | "name": "Onlook",
28 | "email": "contact@onlook.com"
29 | },
30 | "license": "Apache-2.0",
31 | "homepage": "https://onlook.com",
32 | "devDependencies": {
33 | "@onlook/typescript": "*"
34 | },
35 | "dependencies": {}
36 | }
37 |
--------------------------------------------------------------------------------
/packages/penpal/src/child.ts:
--------------------------------------------------------------------------------
1 | import type { PenpalChildMethods as PenpalChildMethodsType } from '@onlook/web-preload/script/api';
2 |
3 | // Preload methods should be treated as promises
4 | export type PromisifiedPendpalChildMethods = {
5 | [K in keyof PenpalChildMethods]: (
6 | ...args: Parameters
7 | ) => Promise>;
8 | };
9 |
10 | export type PenpalChildMethods = PenpalChildMethodsType;
11 |
12 | export const PENPAL_CHILD_CHANNEL = 'PENPAL_CHILD';
13 |
--------------------------------------------------------------------------------
/packages/penpal/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './child';
2 | export * from './parent';
3 | export * from './utils';
4 |
--------------------------------------------------------------------------------
/packages/penpal/src/parent.ts:
--------------------------------------------------------------------------------
1 | export type PenpalParentMethods = {
2 | getFrameId: () => string;
3 | };
4 |
5 | // Parent methods should be treated as promises
6 | export type PromisifiedPenpalParentMethods = {
7 | [K in keyof PenpalParentMethods]: (
8 | ...args: Parameters
9 | ) => Promise>;
10 | };
11 |
12 | export const PENPAL_PARENT_CHANNEL = 'PENPAL_PARENT';
13 |
--------------------------------------------------------------------------------
/packages/penpal/src/utils.ts:
--------------------------------------------------------------------------------
1 | export const promisifyMethod = any>(
2 | method: T | undefined,
3 | ): ((...args: Parameters) => Promise>) => {
4 | return async (...args: Parameters) => {
5 | if (!method) throw new Error('Method not initialized');
6 | return method(...args);
7 | };
8 | };
9 |
--------------------------------------------------------------------------------
/packages/penpal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/rpc/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/rpc",
3 | "description": "An rpc library for Onlook web",
4 | "main": "./src/index.ts",
5 | "type": "module",
6 | "module": "src/index.ts",
7 | "types": "src/index.ts",
8 | "version": "0.0.0",
9 | "private": true,
10 | "repository": {
11 | "type": "git",
12 | "url": "https://github.com/onlook-dev/onlook.git"
13 | },
14 | "scripts": {
15 | "clean": "rm -rf node_modules",
16 | "lint": "eslint --fix .",
17 | "format": "prettier --write .",
18 | "typecheck": "tsc --noEmit"
19 | },
20 | "keywords": [
21 | "onlook",
22 | "rpc"
23 | ],
24 | "author": {
25 | "name": "Onlook",
26 | "email": "contact@onlook.com"
27 | },
28 | "license": "Apache-2.0",
29 | "homepage": "https://onlook.com",
30 | "devDependencies": {
31 | "@onlook/typescript": "*"
32 | },
33 | "dependencies": {
34 | "@onlook/web-server": "*"
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/packages/rpc/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './trpc';
2 |
--------------------------------------------------------------------------------
/packages/rpc/src/trpc/config.ts:
--------------------------------------------------------------------------------
1 | export interface EditorServerOptions {
2 | dev?: boolean;
3 | port?: number;
4 | prefix?: string;
5 | }
6 |
7 | export const editorServerConfig: EditorServerOptions = {
8 | dev: true,
9 | port: 8080,
10 | prefix: '/trpc',
11 | };
12 |
--------------------------------------------------------------------------------
/packages/rpc/src/trpc/index.ts:
--------------------------------------------------------------------------------
1 | export * from './config';
2 | export * from './types';
3 |
--------------------------------------------------------------------------------
/packages/rpc/src/trpc/types.ts:
--------------------------------------------------------------------------------
1 | import type { AppRouter } from '@onlook/web-server/src/router';
2 |
3 | export type EditorRouter = AppRouter;
4 |
--------------------------------------------------------------------------------
/packages/rpc/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/scripts/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/scripts",
3 | "version": "0.0.1",
4 | "private": true,
5 | "type": "module",
6 | "scripts": {
7 | "build": "bun build src/index.ts --outdir=dist --target=node",
8 | "dev": "tsc --watch",
9 | "start": "bun run build && bun dist/index.js",
10 | "typecheck": "tsc --noEmit",
11 | "lint": "eslint . --ext .ts",
12 | "format": "prettier --write ."
13 | },
14 | "bin": {
15 | "env": "dist/index.js"
16 | },
17 | "dependencies": {
18 | "chalk": "^4.1.2",
19 | "commander": "^4.1.1",
20 | "prompts": "^2.4.2",
21 | "ora": "^5.4.1"
22 | },
23 | "devDependencies": {
24 | "@onlook/typescript": "*",
25 | "@types/node": "^20.10.5",
26 | "@types/prompts": "^2.4.9",
27 | "typescript": "^5.3.3"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/scripts/src/helpers.ts:
--------------------------------------------------------------------------------
1 | import fs from 'node:fs';
2 | import ora from 'ora';
3 |
4 | export const writeEnvFile = (filePath: string, content: string, label: string) => {
5 | const spinner = ora(`Writing ${label} .env to ${filePath}`).start();
6 | try {
7 | fs.appendFileSync(filePath, content);
8 | spinner.succeed(`${label} .env written to ${filePath}`);
9 | } catch (err) {
10 | spinner.fail(`Failed writing ${label} .env`);
11 | throw err;
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/packages/scripts/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "rootDir": "src",
6 | "module": "ESNext",
7 | "moduleResolution": "node",
8 | "target": "ES2020",
9 | "allowSyntheticDefaultImports": true,
10 | "esModuleInterop": true
11 | },
12 | "include": ["src/**/*"]
13 | }
14 |
--------------------------------------------------------------------------------
/packages/types/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/types",
3 | "description": "Common types shared between onlook packages",
4 | "version": "0.0.0",
5 | "repository": {
6 | "type": "git",
7 | "url": "https://github.com/onlook-dev/onlook.git"
8 | },
9 | "type": "module",
10 | "main": "src/index.ts",
11 | "scripts": {
12 | "clean": "rm -rf node_modules",
13 | "lint": "eslint --fix .",
14 | "format": "prettier --write .",
15 | "typecheck": "tsc --noEmit"
16 | },
17 | "keywords": [
18 | "onlook",
19 | "types"
20 | ],
21 | "author": {
22 | "name": "Onlook",
23 | "email": "contact@onlook.com"
24 | },
25 | "license": "Apache-2.0",
26 | "homepage": "https://onlook.com",
27 | "exports": {
28 | "./*": "./src/*/index.ts"
29 | },
30 | "devDependencies": {
31 | "@onlook/typescript": "*",
32 | "typescript": "^5.5.4"
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/packages/types/src/adapters/index.ts:
--------------------------------------------------------------------------------
1 | import * as PropType from './props';
2 |
3 | export { PropType };
4 |
5 | export interface Prop {
6 | name: string;
7 | type: PropType.StringType | PropType.BooleanType | PropType.EnumType;
8 | }
9 |
10 | export interface ComponentDescriptor {
11 | framework: 'react'; // TODO: support other frameworks
12 | name: string; // export name; e.g. "Button" ("default" for default export)
13 | sourceFilePath: string; // relative path to component e.g. "src/Button.tsx"
14 | props: Prop[];
15 | createRenderer: (element: HTMLElement) => ComponentRenderer;
16 | }
17 |
18 | export interface ComponentRenderer {
19 | render(props: Record): Promise;
20 | dispose(): void;
21 | }
22 |
--------------------------------------------------------------------------------
/packages/types/src/design-tokens/index.ts:
--------------------------------------------------------------------------------
1 | // W3C design tokens https://design-tokens.github.io/community-group/format
2 |
3 | export interface ColorToken {
4 | $value: string;
5 | $type: 'color';
6 | }
7 |
8 | export type DesignToken = ColorToken;
9 |
10 | export interface DesignTokens {
11 | [key: string]: DesignToken | DesignTokens;
12 | }
13 |
--------------------------------------------------------------------------------
/packages/types/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './adapters';
2 | export * from './design-tokens';
3 |
--------------------------------------------------------------------------------
/packages/types/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/packages/ui/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/onlook-dev/onlook/430860fdd6ebd403e21eb2bc340925edef3ed158/packages/ui/README.md
--------------------------------------------------------------------------------
/packages/ui/components.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://ui.shadcn.com/schema.json",
3 | "style": "new-york",
4 | "rsc": false,
5 | "tsx": true,
6 | "tailwind": {
7 | "config": "tailwind.config.ts",
8 | "css": "src/globals.css",
9 | "baseColor": "stone",
10 | "cssVariables": true,
11 | "prefix": ""
12 | },
13 | "aliases": {
14 | "components": "@/components",
15 | "hooks": "@/hooks",
16 | "lib": "@/lib",
17 | "ui": "@/components",
18 | "utils": "@/utils"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/packages/ui/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | '@tailwindcss/postcss': {},
4 | },
5 | };
6 |
--------------------------------------------------------------------------------
/packages/ui/src/components/aspect-ratio.tsx:
--------------------------------------------------------------------------------
1 | import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio';
2 |
3 | function AspectRatio({ ...props }: React.ComponentProps) {
4 | return ;
5 | }
6 |
7 | export { AspectRatio };
8 |
--------------------------------------------------------------------------------
/packages/ui/src/components/collapsible.tsx:
--------------------------------------------------------------------------------
1 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible';
2 |
3 | function Collapsible({ ...props }: React.ComponentProps) {
4 | return ;
5 | }
6 |
7 | function CollapsibleTrigger({
8 | ...props
9 | }: React.ComponentProps) {
10 | return ;
11 | }
12 |
13 | function CollapsibleContent({
14 | ...props
15 | }: React.ComponentProps) {
16 | return ;
17 | }
18 |
19 | export { Collapsible, CollapsibleTrigger, CollapsibleContent };
20 |
--------------------------------------------------------------------------------
/packages/ui/src/components/color-picker/checkPattern.ts:
--------------------------------------------------------------------------------
1 | import { css } from '@emotion/react';
2 |
3 | export function checkPattern(
4 | color0: string,
5 | color1: string,
6 | size: string,
7 | offsetX = '0px',
8 | offsetY = '0px',
9 | ) {
10 | return css`
11 | background-color: ${color0};
12 | background-image:
13 | linear-gradient(
14 | 45deg,
15 | ${color1} 25%,
16 | transparent 25%,
17 | transparent 75%,
18 | ${color1} 75%,
19 | ${color1}
20 | ),
21 | linear-gradient(
22 | 45deg,
23 | ${color1} 25%,
24 | transparent 25%,
25 | transparent 75%,
26 | ${color1} 75%,
27 | ${color1}
28 | );
29 | background-position:
30 | ${offsetX} ${offsetY},
31 | calc(${size} / 2 + ${offsetX}) calc(${size} / 2 + ${offsetY});
32 | background-size: ${size} ${size};
33 | `;
34 | }
35 |
--------------------------------------------------------------------------------
/packages/ui/src/components/color-picker/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './checkPattern';
2 | export * from './ColorPicker';
3 | export * from './ColorSlider';
4 | export * from './SVPicker';
5 |
--------------------------------------------------------------------------------
/packages/ui/src/components/hotkey-label.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '../utils';
2 | import { Kbd } from './kbd';
3 |
4 | export type Hotkey = {
5 | command: string;
6 | description: string;
7 | readableCommand: string;
8 | };
9 |
10 | export function HotkeyLabel({ hotkey, className }: { hotkey: Hotkey; className?: string }) {
11 | return (
12 |
13 | {hotkey.description}
14 |
15 |
16 |
20 |
21 |
22 | );
23 | }
24 |
--------------------------------------------------------------------------------
/packages/ui/src/components/index.tsx:
--------------------------------------------------------------------------------
1 | export * from './';
2 |
--------------------------------------------------------------------------------
/packages/ui/src/components/input.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { cn } from '../utils';
4 |
5 | function Input({ className, type, ...props }: React.ComponentProps<'input'>) {
6 | return (
7 |
18 | );
19 | }
20 |
21 | export { Input };
22 |
--------------------------------------------------------------------------------
/packages/ui/src/components/kbd.tsx:
--------------------------------------------------------------------------------
1 | import type React from 'react';
2 | import { cn } from '../utils';
3 |
4 | export function Kbd({ children, className }: { children: React.ReactNode; className?: string }) {
5 | return (
6 |
12 | {children}
13 |
14 | );
15 | }
16 |
--------------------------------------------------------------------------------
/packages/ui/src/components/label.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import * as LabelPrimitive from '@radix-ui/react-label';
4 | import * as React from 'react';
5 |
6 | import { cn } from '../utils';
7 |
8 | function Label({ className, ...props }: React.ComponentProps) {
9 | return (
10 |
18 | );
19 | }
20 |
21 | export { Label };
22 |
--------------------------------------------------------------------------------
/packages/ui/src/components/progress.tsx:
--------------------------------------------------------------------------------
1 | import * as ProgressPrimitive from '@radix-ui/react-progress';
2 | import * as React from 'react';
3 |
4 | import { cn } from '../utils';
5 |
6 | function Progress({
7 | className,
8 | value,
9 | ...props
10 | }: React.ComponentProps) {
11 | return (
12 |
20 |
25 |
26 | );
27 | }
28 |
29 | export { Progress };
30 |
--------------------------------------------------------------------------------
/packages/ui/src/components/separator.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import * as SeparatorPrimitive from '@radix-ui/react-separator';
4 | import * as React from 'react';
5 |
6 | import { cn } from '../utils';
7 |
8 | function Separator({
9 | className,
10 | orientation = 'horizontal',
11 | decorative = true,
12 | ...props
13 | }: React.ComponentProps) {
14 | return (
15 |
25 | );
26 | }
27 |
28 | export { Separator };
29 |
--------------------------------------------------------------------------------
/packages/ui/src/components/skeleton.tsx:
--------------------------------------------------------------------------------
1 | import { cn } from '../utils';
2 |
3 | function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
4 | return (
5 |
10 | );
11 | }
12 |
13 | export { Skeleton };
14 |
--------------------------------------------------------------------------------
/packages/ui/src/components/sonner.tsx:
--------------------------------------------------------------------------------
1 | 'use client';
2 |
3 | import { useTheme } from 'next-themes';
4 | import { Toaster as Sonner, type ToasterProps, toast } from 'sonner';
5 |
6 | const Toaster = ({ ...props }: ToasterProps) => {
7 | const { theme = 'system' } = useTheme();
8 |
9 | return (
10 |
22 | );
23 | };
24 |
25 | export { Toaster, toast };
26 |
--------------------------------------------------------------------------------
/packages/ui/src/components/textarea.tsx:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | import { cn } from '../utils';
4 |
5 | function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {
6 | return (
7 |
15 | );
16 | }
17 |
18 | export { Textarea };
19 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/index.ts:
--------------------------------------------------------------------------------
1 | export * from './use-media-query';
2 | export * from './use-resize-observer';
3 | export * from './use-enter-submit';
4 | export * from './use-pointer-stroke';
5 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/use-enter-submit.ts:
--------------------------------------------------------------------------------
1 | import { type RefObject, useRef } from 'react';
2 |
3 | export function useEnterSubmit(): {
4 | formRef: RefObject;
5 | onKeyDown: (event: React.KeyboardEvent) => void;
6 | } {
7 | const formRef = useRef(null);
8 |
9 | const handleKeyDown = (event: React.KeyboardEvent): void => {
10 | if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {
11 | formRef.current?.requestSubmit();
12 | event.preventDefault();
13 | }
14 | };
15 |
16 | return { formRef, onKeyDown: handleKeyDown };
17 | }
18 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/use-media-query.ts:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from 'react';
2 |
3 | export function useMediaQuery(query: string) {
4 | const [value, setValue] = useState(false);
5 |
6 | useEffect(() => {
7 | function onChange(event: MediaQueryListEvent) {
8 | setValue(event.matches);
9 | }
10 |
11 | const result = matchMedia(query);
12 | result.addEventListener('change', onChange);
13 | setValue(result.matches);
14 |
15 | return () => result.removeEventListener('change', onChange);
16 | }, [query]);
17 |
18 | return value;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/use-mobile.ts:
--------------------------------------------------------------------------------
1 | import * as React from 'react';
2 |
3 | const MOBILE_BREAKPOINT = 768;
4 |
5 | export function useIsMobile() {
6 | const [isMobile, setIsMobile] = React.useState(undefined);
7 |
8 | React.useEffect(() => {
9 | const mql = window.matchMedia(`(max-width: ${MOBILE_BREAKPOINT - 1}px)`);
10 | const onChange = () => {
11 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
12 | };
13 | mql.addEventListener('change', onChange);
14 | setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
15 | return () => mql.removeEventListener('change', onChange);
16 | }, []);
17 |
18 | return !!isMobile;
19 | }
20 |
--------------------------------------------------------------------------------
/packages/ui/src/hooks/use-resize-observer.ts:
--------------------------------------------------------------------------------
1 | import { type RefObject, useEffect, useState } from 'react';
2 |
3 | export function useResizeObserver(elementRef: RefObject): ResizeObserverEntry | undefined {
4 | const [entry, setEntry] = useState();
5 |
6 | const updateEntry = ([entry]: ResizeObserverEntry[]): void => {
7 | setEntry(entry);
8 | };
9 |
10 | useEffect(() => {
11 | const node = elementRef?.current;
12 | if (!node) return;
13 |
14 | const observer = new ResizeObserver(updateEntry);
15 |
16 | observer.observe(node);
17 |
18 | return () => observer.disconnect();
19 | }, [elementRef]);
20 |
21 | return entry;
22 | }
23 |
--------------------------------------------------------------------------------
/packages/ui/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './components';
2 | export * from './hooks';
3 | export * from './utils';
4 |
--------------------------------------------------------------------------------
/packages/ui/src/utils/cn.ts:
--------------------------------------------------------------------------------
1 | import { type ClassValue, clsx } from 'clsx';
2 | import { twMerge } from 'tailwind-merge';
3 |
4 | export function cn(...inputs: ClassValue[]) {
5 | return twMerge(clsx(inputs));
6 | }
7 |
--------------------------------------------------------------------------------
/packages/ui/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | export * from './cn';
2 | export * from './truncate';
3 |
--------------------------------------------------------------------------------
/packages/ui/src/utils/truncate.ts:
--------------------------------------------------------------------------------
1 | export const platformSlash = '/';
2 |
3 | export const truncate = (str: string | null | undefined, length: number): string | null => {
4 | if (!str || str.length <= length) return str ?? null;
5 | return `${str.slice(0, length - 3)}...`;
6 | };
7 |
8 | export function getTruncatedFileName(fileName: string): string {
9 | const parts = fileName.split(platformSlash);
10 | return parts[parts.length - 1] ?? '';
11 | }
12 |
--------------------------------------------------------------------------------
/packages/ui/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/react-library.json",
3 | "compilerOptions": {
4 | "baseUrl": ".",
5 | "paths": {
6 | "@/*": ["./src/*"]
7 | }
8 | },
9 | "include": ["src", "tokens.ts"],
10 | "exclude": ["node_modules"]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/utility/src/assert.ts:
--------------------------------------------------------------------------------
1 | export function assertNever(n: never): never {
2 | throw new Error(`Expected \`never\`, found: ${JSON.stringify(n)}`);
3 | }
4 |
--------------------------------------------------------------------------------
/packages/utility/src/clone.ts:
--------------------------------------------------------------------------------
1 | export const jsonClone = (obj: T): T => JSON.parse(JSON.stringify(obj));
2 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/canvas.ts:
--------------------------------------------------------------------------------
1 | import type { Canvas as DbCanvas } from '@onlook/db';
2 | import { v4 as uuidv4 } from 'uuid';
3 |
4 | export const createDefaultCanvas = (projectId: string): DbCanvas => {
5 | return {
6 | id: uuidv4(),
7 | projectId: projectId,
8 | };
9 | };
10 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/conversation.ts:
--------------------------------------------------------------------------------
1 | import type { Conversation as DbConversation } from '@onlook/db';
2 | import { v4 as uuidv4 } from 'uuid';
3 |
4 | export const createDefaultConversation = (projectId: string): DbConversation => {
5 | return {
6 | id: uuidv4(),
7 | projectId,
8 | createdAt: new Date(),
9 | updatedAt: new Date(),
10 | displayName: 'New Conversation',
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/frame.ts:
--------------------------------------------------------------------------------
1 | import { DefaultSettings } from '@onlook/constants';
2 | import type { Frame as DbFrame } from '@onlook/db';
3 | import { FrameType } from '@onlook/models';
4 | import { v4 as uuidv4 } from 'uuid';
5 |
6 | export const createDefaultFrame = (canvasId: string, url: string): DbFrame => {
7 | return {
8 | id: uuidv4(),
9 | canvasId: canvasId,
10 | type: FrameType.WEB,
11 | url: url,
12 | x: DefaultSettings.FRAME_POSITION.x.toString(),
13 | y: DefaultSettings.FRAME_POSITION.y.toString(),
14 | width: DefaultSettings.FRAME_DIMENSION.width.toString(),
15 | height: DefaultSettings.FRAME_DIMENSION.height.toString(),
16 | };
17 | };
18 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/index.ts:
--------------------------------------------------------------------------------
1 | export * from './canvas';
2 | export * from './conversation';
3 | export * from './frame';
4 | export * from './user-canvas';
5 | export * from './user-settings';
6 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/user-canvas.ts:
--------------------------------------------------------------------------------
1 | import { DefaultSettings } from '@onlook/constants';
2 | import type { UserCanvas as DbUserCanvas } from '@onlook/db';
3 |
4 | export const createDefaultUserCanvas = (userId: string, canvasId: string): DbUserCanvas => {
5 | return {
6 | userId,
7 | canvasId,
8 | scale: DefaultSettings.SCALE.toString(),
9 | x: DefaultSettings.PAN_POSITION.x.toString(),
10 | y: DefaultSettings.PAN_POSITION.y.toString(),
11 | };
12 | };
13 |
--------------------------------------------------------------------------------
/packages/utility/src/defaults/user-settings.ts:
--------------------------------------------------------------------------------
1 | import { DefaultSettings } from '@onlook/constants';
2 | import type { UserSettings as DbUserSettings } from '@onlook/db';
3 | import { v4 as uuid } from 'uuid';
4 |
5 | export const createDefaultUserSettings = (userId: string): DbUserSettings => {
6 | return {
7 | id: uuid(),
8 | userId,
9 | autoApplyCode: DefaultSettings.CHAT_SETTINGS.autoApplyCode,
10 | expandCodeBlocks: DefaultSettings.CHAT_SETTINGS.expandCodeBlocks,
11 | showSuggestions: DefaultSettings.CHAT_SETTINGS.showSuggestions,
12 | showMiniChat: DefaultSettings.CHAT_SETTINGS.showMiniChat,
13 | };
14 | };
15 |
--------------------------------------------------------------------------------
/packages/utility/src/email.ts:
--------------------------------------------------------------------------------
1 | import freeEmailDomains from 'free-email-domains';
2 |
3 | export const isFreeEmail = (email: string) => {
4 | const domain = email.split('@').at(-1);
5 | return freeEmailDomains.includes(domain ?? '');
6 | };
7 |
--------------------------------------------------------------------------------
/packages/utility/src/image.ts:
--------------------------------------------------------------------------------
1 | import imageCompression from 'browser-image-compression';
2 |
3 | export async function compressImage(file: File): Promise {
4 | const options = {
5 | maxSizeMB: 1,
6 | maxWidthOrHeight: 1024,
7 | };
8 |
9 | try {
10 | const compressedFile = await imageCompression(file, options);
11 | const base64URL = imageCompression.getDataUrlFromFile(compressedFile);
12 | console.log(`Image size reduced from ${file.size} to ${compressedFile.size} (bytes)`);
13 | return base64URL;
14 | } catch (error) {
15 | console.error('Error compressing image:', error);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/packages/utility/src/index.ts:
--------------------------------------------------------------------------------
1 | export * from './assert';
2 | export * from './autolayout';
3 | export * from './clone';
4 | export * from './color';
5 | export * from './defaults';
6 | export * from './defaults/canvas';
7 | export * from './errors';
8 | export * from './font';
9 | export * from './email';
10 | export * from './id';
11 | export * from './image';
12 | export * from './initials';
13 | export * from './math';
14 | export * from './null';
15 | export * from './path';
16 | export * from './string';
17 | export * from './tailwind';
18 | export * from './time';
19 | export * from './unit';
20 | export * from './urls';
21 | export * from './window-metadata';
22 |
--------------------------------------------------------------------------------
/packages/utility/src/initials.ts:
--------------------------------------------------------------------------------
1 | export const getInitials = (name: string) => {
2 | return name
3 | ?.split(' ')
4 | ?.map((word) => word[0])
5 | ?.join('')
6 | ?.toUpperCase();
7 | };
8 |
--------------------------------------------------------------------------------
/packages/utility/src/math.ts:
--------------------------------------------------------------------------------
1 | export function isNearEqual(x: number, y: number, delta: number): boolean {
2 | return Math.abs(x - y) <= delta;
3 | }
4 |
5 | export function mod(x: number, y: number): number {
6 | return x - y * Math.floor(x / y);
7 | }
8 |
--------------------------------------------------------------------------------
/packages/utility/src/null.ts:
--------------------------------------------------------------------------------
1 | export function isNullOrUndefined(value: any) {
2 | return value === null || value === undefined;
3 | }
4 |
--------------------------------------------------------------------------------
/packages/utility/src/unit.ts:
--------------------------------------------------------------------------------
1 | export function stringToParsedValue(val: string, percent = false): { num: number; unit: string } {
2 | const matches = val.match(/([-+]?[0-9]*\.?[0-9]+)([a-zA-Z%]*)/);
3 |
4 | let num = matches ? Number.parseFloat(matches[1] ?? '0') : 0;
5 | let unit = matches && matches[2] ? matches[2] : 'px';
6 |
7 | if (percent && unit === '') {
8 | unit = '%';
9 | num = num <= 1 ? num * 100 : num;
10 | }
11 | return { num, unit };
12 | }
13 |
--------------------------------------------------------------------------------
/packages/utility/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "@onlook/typescript/base.json",
3 | "compilerOptions": {
4 | "baseUrl": "."
5 | },
6 | "include": ["src", "test"],
7 | "exclude": ["node_modules"]
8 | }
9 |
--------------------------------------------------------------------------------
/scripts/increment_tag.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | # Navigate to the studio app directory
4 | cd apps/studio || exit 1
5 |
6 | # Read the current version and increment patch version using Node.js
7 | current_version=$(node -p "require('./package.json').version")
8 | new_version=$(node -p "const v = '${current_version}'.split('.'); v[2] = parseInt(v[2]) + 1; v.join('.')")
9 |
10 | # Update package.json with new version using temporary file
11 | tmp_file=$(mktemp)
12 | jq --arg version "$new_version" '.version = $version' package.json > "$tmp_file" && mv "$tmp_file" package.json
13 |
14 | echo "Version updated from $current_version to $new_version"
15 |
--------------------------------------------------------------------------------
/scripts/publish_tag.sh:
--------------------------------------------------------------------------------
1 | # Get the version from package.json
2 | VERSION=$(node -p "require('./apps/studio/package.json').version")
3 |
4 | # Add all changes to the staging area
5 | git add .
6 |
7 | # Commit changes with a message
8 | git commit -m "Publish version v$VERSION"
9 |
10 | # Create an annotated tag
11 | git tag -a v$VERSION -m "Version $VERSION"
12 |
13 | # Push the tag to the remote repository
14 | git push --follow-tags origin HEAD
15 |
--------------------------------------------------------------------------------
/scripts/remove_tag.sh:
--------------------------------------------------------------------------------
1 | # Get the version from package.json
2 | VERSION=$(node -p "require('./apps/studio/package').version")
3 |
4 | # Remove tag locally
5 | git tag -d v$VERSION
6 |
7 | # Remove tag remotely
8 | git push origin :refs/tags/v$VERSION
--------------------------------------------------------------------------------
/tooling/typescript/base.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Base",
4 | "docs": "https://bun.sh/docs/typescript",
5 | "compilerOptions": {
6 | "target": "ES2023",
7 | "lib": [
8 | "ES2023",
9 | "DOM",
10 | "DOM.Iterable"
11 | ],
12 | "module": "ESNext",
13 | "moduleDetection": "force",
14 | "allowJs": true,
15 | "moduleResolution": "bundler",
16 | "allowImportingTsExtensions": true,
17 | "verbatimModuleSyntax": true,
18 | "noEmit": true,
19 | "strict": true,
20 | "skipLibCheck": true,
21 | "noFallthroughCasesInSwitch": true,
22 | "noUnusedLocals": false,
23 | "noUnusedParameters": false,
24 | "noPropertyAccessFromIndexSignature": false,
25 | "noUncheckedIndexedAccess": true,
26 | }
27 | }
--------------------------------------------------------------------------------
/tooling/typescript/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@onlook/typescript",
3 | "description": "The Onlook TypeScript Configuration",
4 | "version": "0.0.0",
5 | "private": true
6 | }
--------------------------------------------------------------------------------
/tooling/typescript/react-library.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "React Library",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "jsx": "react-jsx"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/tooling/typescript/vite-react.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://json.schemastore.org/tsconfig",
3 | "display": "Vite React",
4 | "extends": "./base.json",
5 | "compilerOptions": {
6 | "target": "ES2023",
7 | "lib": [
8 | "ES2023",
9 | "DOM",
10 | "DOM.Iterable"
11 | ],
12 | "useDefineForClassFields": true,
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "react-jsx"
16 | }
17 | }
--------------------------------------------------------------------------------