├── .npmrc ├── apps ├── spa │ ├── README.md │ ├── sst-env.d.ts │ ├── turbo.json │ ├── postcss.config.js │ ├── .gitignore │ ├── tsconfig.dev.json │ ├── src │ │ ├── sst-env.d.ts │ │ ├── routes │ │ │ ├── _layout │ │ │ │ ├── _layout-2 │ │ │ │ │ ├── layout-a.tsx │ │ │ │ │ └── layout-b.tsx │ │ │ │ └── _layout-2.tsx │ │ │ ├── posts.index.tsx │ │ │ ├── _layout.tsx │ │ │ ├── index.tsx │ │ │ ├── posts.$postId.tsx │ │ │ ├── posts.tsx │ │ │ └── __root.tsx │ │ ├── main.tsx │ │ ├── posts.tsx │ │ └── routeTree.gen.ts │ ├── tailwind.config.ts │ ├── tsconfig.json │ ├── index.html │ ├── vite.config.js │ ├── playwright.config.ts │ ├── package.json │ └── tests │ │ └── app.spec.ts ├── astro │ ├── src │ │ ├── env.d.ts │ │ ├── layouts │ │ │ └── Layout.astro │ │ ├── components │ │ │ └── Card.astro │ │ └── pages │ │ │ └── index.astro │ ├── tsconfig.json │ ├── turbo.json │ ├── astro.config.mjs │ ├── package.json │ ├── public │ │ └── favicon.svg │ └── README.md └── api │ ├── src │ ├── types.ts │ ├── middleware │ │ ├── errorMiddleware.ts │ │ └── responseLoggerMiddleware.ts │ ├── __tests__ │ │ └── server.test.ts │ ├── utils │ │ ├── logger.ts │ │ └── errorHandler.ts │ ├── index.ts │ └── index.test.ts │ ├── sst-env.d.ts │ ├── turbo.json │ ├── wrangler.toml │ ├── tsconfig.json │ ├── tsup.config.ts │ └── package.json ├── .env.example ├── .markdownlint.jsonc ├── infra ├── src │ ├── index.ts │ └── pages.ts ├── bun.lockb ├── tsconfig.json ├── tsup.config.ts └── package.json ├── packages ├── ui │ ├── bunfig.toml │ ├── postcss.config.js │ ├── src │ │ ├── index.tsx │ │ ├── lib │ │ │ └── utils.ts │ │ ├── components │ │ │ ├── ui │ │ │ │ ├── aspect-ratio.tsx │ │ │ │ ├── skeleton.tsx │ │ │ │ ├── collapsible.tsx │ │ │ │ ├── toaster.tsx │ │ │ │ ├── label.tsx │ │ │ │ ├── textarea.tsx │ │ │ │ ├── separator.tsx │ │ │ │ ├── input.tsx │ │ │ │ ├── progress.tsx │ │ │ │ ├── sonner.tsx │ │ │ │ ├── checkbox.tsx │ │ │ │ ├── slider.tsx │ │ │ │ ├── badge.tsx │ │ │ │ ├── switch.tsx │ │ │ │ ├── tooltip.tsx │ │ │ │ ├── hover-card.tsx │ │ │ │ ├── popover.tsx │ │ │ │ ├── toggle.tsx │ │ │ │ ├── avatar.tsx │ │ │ │ ├── radio-group.tsx │ │ │ │ ├── alert.tsx │ │ │ │ ├── scroll-area.tsx │ │ │ │ ├── resizable.tsx │ │ │ │ ├── toggle-group.tsx │ │ │ │ ├── button.tsx │ │ │ │ ├── tabs.tsx │ │ │ │ ├── card.tsx │ │ │ │ ├── accordion.tsx │ │ │ │ ├── input-otp.tsx │ │ │ │ ├── calendar.tsx │ │ │ │ ├── breadcrumb.tsx │ │ │ │ ├── pagination.tsx │ │ │ │ ├── table.tsx │ │ │ │ ├── drawer.tsx │ │ │ │ ├── dialog.tsx │ │ │ │ ├── use-toast.ts │ │ │ │ ├── sheet.tsx │ │ │ │ ├── form.tsx │ │ │ │ ├── alert-dialog.tsx │ │ │ │ ├── toast.tsx │ │ │ │ ├── command.tsx │ │ │ │ ├── navigation-menu.tsx │ │ │ │ ├── select.tsx │ │ │ │ ├── carousel.tsx │ │ │ │ ├── context-menu.tsx │ │ │ │ └── dropdown-menu.tsx │ │ │ ├── counter-button │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ │ └── link │ │ │ │ ├── index.test.tsx │ │ │ │ └── index.tsx │ │ ├── hooks │ │ │ ├── use-media-query.ts │ │ │ ├── use-enter-submit.ts │ │ │ └── use-resize-observer.ts │ │ └── styles │ │ │ └── globals.css │ ├── turbo.json │ ├── happydom.ts │ ├── tsconfig.json │ ├── tsup.config.ts │ ├── components.json │ ├── tailwind.config.ts │ └── package.json ├── _packages-template │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ ├── turbo.json │ ├── tsup.config.ts │ └── package.json ├── core │ ├── tsconfig.json │ ├── turbo.json │ ├── src │ │ └── index.ts │ ├── tsup.config.ts │ └── package.json ├── db │ ├── tsconfig.json │ ├── README.md │ ├── turbo.json │ ├── tsup.config.ts │ ├── drizzle.config.ts │ ├── src │ │ ├── index.ts │ │ ├── client.ts │ │ └── schema │ │ │ └── index.ts │ └── package.json └── config-typescript │ ├── astro.json │ ├── package.json │ ├── nextjs.json │ ├── vite.json │ ├── react.json │ ├── node.json │ └── base.json ├── tsconfig.json ├── bun.lockb ├── env.d.ts ├── sst-env.d.ts ├── .vscode ├── settings.json └── extensions.json ├── .gitignore ├── .github └── workflows │ ├── lint.yml │ └── template-sync.yml ├── turbo.json ├── biome.jsonc ├── TODO.md ├── sst.config.ts ├── package.json ├── prompts └── explainer ├── .cursorrules └── README.md /.npmrc: -------------------------------------------------------------------------------- 1 | auto-install-peers = true 2 | -------------------------------------------------------------------------------- /apps/spa/README.md: -------------------------------------------------------------------------------- 1 | # Tanstack Router 2 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | CLOUDFLARE_API_TOKEN= 2 | DATABASE_URL= -------------------------------------------------------------------------------- /.markdownlint.jsonc: -------------------------------------------------------------------------------- 1 | { 2 | "MD033": false 3 | } 4 | -------------------------------------------------------------------------------- /infra/src/index.ts: -------------------------------------------------------------------------------- 1 | export { pagesProject } from './pages' 2 | -------------------------------------------------------------------------------- /packages/ui/bunfig.toml: -------------------------------------------------------------------------------- 1 | [test] 2 | preload = "./happydom.ts" -------------------------------------------------------------------------------- /packages/_packages-template/src/index.ts: -------------------------------------------------------------------------------- 1 | const index = 'index' 2 | -------------------------------------------------------------------------------- /apps/astro/src/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json" 3 | } 4 | -------------------------------------------------------------------------------- /apps/api/src/types.ts: -------------------------------------------------------------------------------- 1 | export type Bindings = { 2 | DATABASE_URL: string 3 | } 4 | -------------------------------------------------------------------------------- /bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/austinm911/tanstack-monorepo/HEAD/bun.lockb -------------------------------------------------------------------------------- /infra/bun.lockb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/austinm911/tanstack-monorepo/HEAD/infra/bun.lockb -------------------------------------------------------------------------------- /infra/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json", 3 | "include": [".", "../env.d.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /apps/api/sst-env.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /// 4 | export {} 5 | -------------------------------------------------------------------------------- /apps/api/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/astro/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/astro.json", 3 | "include": [".", "../../env.d.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/spa/sst-env.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | /// 4 | export {} 5 | -------------------------------------------------------------------------------- /apps/spa/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /env.d.ts: -------------------------------------------------------------------------------- 1 | declare module 'bun' { 2 | interface Env { 3 | CLOUDFLARE_ACCOUNT_ID: string 4 | DATABASE_URL: string 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json", 3 | "include": [".", "../../env.d.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /packages/db/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json", 3 | "include": [".", "../../env.d.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/api/wrangler.toml: -------------------------------------------------------------------------------- 1 | name = "api" 2 | main = "src/index.ts" 3 | compatibility_date = "2024-03-07" 4 | 5 | [dev] 6 | port = 5001 7 | -------------------------------------------------------------------------------- /apps/astro/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/core/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/db/README.md: -------------------------------------------------------------------------------- 1 | # Database Package 2 | 3 | [Drizzle Postgres](https://orm.drizzle.team/docs/get-started-postgresql#postgresjs) 4 | -------------------------------------------------------------------------------- /packages/db/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/ui/src/index.tsx: -------------------------------------------------------------------------------- 1 | export { Link } from './components/link' 2 | export { CounterButton } from './components/counter-button' 3 | -------------------------------------------------------------------------------- /packages/ui/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/_packages-template/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json", 3 | "include": [".", "../../env.d.ts"] 4 | } 5 | -------------------------------------------------------------------------------- /apps/astro/astro.config.mjs: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'astro/config' 2 | 3 | // https://astro.build/config 4 | export default defineConfig({}) 5 | -------------------------------------------------------------------------------- /packages/_packages-template/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": ["//"], 3 | "tasks": { 4 | "build": { 5 | "outputs": ["dist/**"] 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | import { db } from '@repo/db' 2 | 3 | if (!db) { 4 | throw new Error('db is not defined') 5 | } 6 | 7 | console.log(db) 8 | -------------------------------------------------------------------------------- /apps/spa/postcss.config.js: -------------------------------------------------------------------------------- 1 | // @ts-expect-error - No types for postcss 2 | import postcss from '@repo/ui/postcss.config' 3 | 4 | export default postcss 5 | -------------------------------------------------------------------------------- /sst-env.d.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable */ 2 | /* eslint-disable */ 3 | import "sst" 4 | declare module "sst" { 5 | export interface Resource { 6 | } 7 | } 8 | export {} 9 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "biomejs.biome", 3 | "editor.formatOnSave": true, 4 | "typescript.preferences.importModuleSpecifierEnding": "minimal" 5 | } 6 | -------------------------------------------------------------------------------- /apps/spa/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | dist 4 | dist-ssr 5 | *.local 6 | 7 | /test-results/ 8 | /playwright-report/ 9 | /blob-report/ 10 | /playwright/.cache/ 11 | -------------------------------------------------------------------------------- /apps/spa/tsconfig.dev.json: -------------------------------------------------------------------------------- 1 | { 2 | "composite": true, 3 | "extends": "../../../tsconfig.base.json", 4 | 5 | "files": ["src/main.tsx"], 6 | "include": ["src", "__tests__/**/*.test.*"] 7 | } 8 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "yzhang.markdown-all-in-one", 4 | "biomejs.biome", 5 | "astro-build.astro-vscode", 6 | "DavidAnson.vscode-markdownlint" 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /apps/spa/src/sst-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | interface ImportMetaEnv { 3 | readonly VITE_API_URL: string 4 | } 5 | interface ImportMeta { 6 | readonly env: ImportMetaEnv 7 | } -------------------------------------------------------------------------------- /packages/ui/src/lib/utils.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 | -------------------------------------------------------------------------------- /apps/api/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/base.json", 3 | "compilerOptions": { 4 | "types": ["@cloudflare/workers-types", "@types/bun"] 5 | }, 6 | "include": [".", "../../env.d.ts"] 7 | } 8 | -------------------------------------------------------------------------------- /packages/config-typescript/astro.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Astro", 4 | "extends": "./react.json", 5 | "compilerOptions": { 6 | "jsx": "preserve" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /packages/config-typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/config-typescript", 3 | "version": "0.0.0", 4 | "private": true, 5 | "license": "MIT", 6 | "publishConfig": { 7 | "access": "public" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/aspect-ratio.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as AspectRatioPrimitive from '@radix-ui/react-aspect-ratio' 4 | 5 | const AspectRatio = AspectRatioPrimitive.Root 6 | 7 | export { AspectRatio } 8 | -------------------------------------------------------------------------------- /packages/config-typescript/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./react.json", 5 | "compilerOptions": { 6 | "plugins": [{ "name": "next" }] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /infra/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | target: 'es2022', 6 | format: ['esm'], 7 | ...options, 8 | })) 9 | -------------------------------------------------------------------------------- /packages/config-typescript/vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Vite", 4 | "extends": "./react.json", 5 | "compilerOptions": { 6 | "types": ["vite/client", "@types/bun"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /apps/spa/tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import baseConfig from '@repo/ui/tailwind.config' 2 | import type { Config } from 'tailwindcss' 3 | 4 | export default { 5 | content: ['./src/**/*.{ts,tsx}', '../../packages/ui/src/**/*.{ts,tsx}'], 6 | presets: [baseConfig], 7 | } satisfies Config 8 | -------------------------------------------------------------------------------- /apps/spa/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/vite.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | } 8 | }, 9 | "include": [".", "../../env.d.ts"], 10 | "exclude": ["node_modules", "dist"] 11 | } 12 | -------------------------------------------------------------------------------- /packages/config-typescript/react.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "React Application", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx", 7 | "lib": ["es2022", "dom", "dom.iterable"] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/ui/happydom.ts: -------------------------------------------------------------------------------- 1 | // https://bun.sh/guides/test/happy-dom 2 | //! only able to get this to work when the bunfig.toml and this file are in the subpackages, not in the root 3 | 4 | import { GlobalRegistrator } from '@happy-dom/global-registrator' 5 | 6 | GlobalRegistrator.register() 7 | -------------------------------------------------------------------------------- /packages/config-typescript/node.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Node", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "module": "NodeNext", 7 | "moduleResolution": "NodeNext", 8 | "lib": ["es2022"] 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /packages/ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@repo/config-typescript/react.json", 3 | "compilerOptions": { 4 | "baseUrl": ".", 5 | "paths": { 6 | "@/*": ["src/*"] 7 | } 8 | }, 9 | "include": [".", "../../env.d.ts"], 10 | "exclude": ["node_modules", "dist", "build"] 11 | } 12 | -------------------------------------------------------------------------------- /apps/spa/src/routes/_layout/_layout-2/layout-a.tsx: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from '@tanstack/react-router' 2 | 3 | export const Route = createFileRoute('/_layout/_layout-2/layout-a')({ 4 | component: LayoutAComponent, 5 | }) 6 | 7 | function LayoutAComponent() { 8 | return
I'm layout A!
9 | } 10 | -------------------------------------------------------------------------------- /apps/spa/src/routes/_layout/_layout-2/layout-b.tsx: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from '@tanstack/react-router' 2 | 3 | export const Route = createFileRoute('/_layout/_layout-2/layout-b')({ 4 | component: LayoutBComponent, 5 | }) 6 | 7 | function LayoutBComponent() { 8 | return
I'm layout B!
9 | } 10 | -------------------------------------------------------------------------------- /apps/spa/src/routes/posts.index.tsx: -------------------------------------------------------------------------------- 1 | import { createFileRoute } from '@tanstack/react-router' 2 | import * as React from 'react' 3 | 4 | export const Route = createFileRoute('/posts/')({ 5 | component: PostsIndexComponent, 6 | }) 7 | 8 | function PostsIndexComponent() { 9 | return
Select a post.
10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | .turbo 4 | *.log 5 | .next 6 | dist 7 | dist-ssr 8 | *.local 9 | .env 10 | .cache 11 | server/dist 12 | public/dist 13 | tsconfig.tsbuildinfo 14 | # generated types 15 | .astro/ 16 | 17 | # sst 18 | .sst 19 | 20 | # Cloudflare 21 | .wrangler 22 | 23 | vite.config.js.timestamp-* 24 | -------------------------------------------------------------------------------- /apps/api/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | dts: { 6 | compilerOptions: { 7 | composite: false, 8 | }, 9 | }, 10 | target: 'es2022', 11 | format: ['esm'], 12 | ...options, 13 | })) 14 | -------------------------------------------------------------------------------- /packages/core/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | dts: { 6 | compilerOptions: { 7 | composite: false, 8 | }, 9 | }, 10 | target: 'es2022', 11 | format: ['esm'], 12 | ...options, 13 | })) 14 | -------------------------------------------------------------------------------- /packages/db/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | dts: { 6 | compilerOptions: { 7 | composite: false, 8 | }, 9 | }, 10 | target: 'es2022', 11 | format: ['esm'], 12 | ...options, 13 | })) 14 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/skeleton.tsx: -------------------------------------------------------------------------------- 1 | import { cn } from '@/lib/utils' 2 | 3 | function Skeleton({ 4 | className, 5 | ...props 6 | }: React.HTMLAttributes) { 7 | return ( 8 |
12 | ) 13 | } 14 | 15 | export { Skeleton } 16 | -------------------------------------------------------------------------------- /apps/spa/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Vite App 7 | 8 | 9 |
10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/spa/vite.config.js: -------------------------------------------------------------------------------- 1 | import { TanStackRouterVite } from '@tanstack/router-plugin/vite' 2 | import react from '@vitejs/plugin-react' 3 | import { defineConfig } from 'vite' 4 | import tsconfigPaths from 'vite-tsconfig-paths' 5 | 6 | // https://vitejs.dev/config/ 7 | export default defineConfig({ 8 | plugins: [TanStackRouterVite(), react(), tsconfigPaths()], 9 | }) 10 | -------------------------------------------------------------------------------- /packages/ui/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entry: ['./src/index.tsx'], 5 | format: ['esm'], 6 | dts: { 7 | compilerOptions: { 8 | composite: false, 9 | }, 10 | }, 11 | target: 'es2022', 12 | external: ['react'], 13 | banner: { 14 | js: "'use client'", 15 | }, 16 | ...options, 17 | })) 18 | -------------------------------------------------------------------------------- /apps/spa/src/routes/_layout.tsx: -------------------------------------------------------------------------------- 1 | import { Outlet, createFileRoute } from '@tanstack/react-router' 2 | 3 | export const Route = createFileRoute('/_layout')({ 4 | component: LayoutComponent, 5 | }) 6 | 7 | function LayoutComponent() { 8 | return ( 9 |
10 |
I'm a layout
11 |
12 | 13 |
14 |
15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /packages/db/drizzle.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from 'drizzle-kit' 2 | 3 | if (!process.env.DATABASE_URL) { 4 | throw new Error('DATABASE_URL is not set') 5 | } 6 | 7 | export default defineConfig({ 8 | dialect: 'postgresql', 9 | out: 'src/migrations', 10 | dbCredentials: { 11 | url: process.env.DATABASE_URL, 12 | }, 13 | schema: 'src/schema/index.ts', 14 | verbose: true, 15 | strict: true, 16 | }) 17 | -------------------------------------------------------------------------------- /packages/ui/components.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://ui.shadcn.com/schema.json", 3 | "style": "default", 4 | "rsc": true, 5 | "tsx": true, 6 | "tailwind": { 7 | "config": "tailwind.config.js", 8 | "css": "src/globals.css", 9 | "baseColor": "slate", 10 | "cssVariables": true, 11 | "prefix": "" 12 | }, 13 | "aliases": { 14 | "components": "@/components", 15 | "utils": "@/lib/utils" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/collapsible.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as CollapsiblePrimitive from '@radix-ui/react-collapsible' 4 | 5 | const Collapsible = CollapsiblePrimitive.Root 6 | 7 | const CollapsibleTrigger = CollapsiblePrimitive.CollapsibleTrigger 8 | 9 | const CollapsibleContent = CollapsiblePrimitive.CollapsibleContent 10 | 11 | export { Collapsible, CollapsibleTrigger, CollapsibleContent } 12 | -------------------------------------------------------------------------------- /packages/ui/src/components/counter-button/index.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'bun:test' 2 | import { createRoot } from 'react-dom/client' 3 | import { CounterButton } from '.' 4 | 5 | describe('CounterButton', () => { 6 | it('renders without crashing', () => { 7 | const div = document.createElement('div') 8 | const root = createRoot(div) 9 | root.render() 10 | root.unmount() 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /apps/spa/src/routes/index.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from '@repo/ui/components/ui/button' 2 | import { createFileRoute } from '@tanstack/react-router' 3 | 4 | export const Route = createFileRoute('/')({ 5 | component: Home, 6 | }) 7 | 8 | function Home() { 9 | return ( 10 |
11 |

Welcome Home!

12 | 13 |
14 | ) 15 | } 16 | -------------------------------------------------------------------------------- /packages/_packages-template/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { type Options, defineConfig } from 'tsup' 2 | 3 | export default defineConfig((options: Options) => ({ 4 | entryPoints: ['src/index.ts'], 5 | dts: { 6 | // @see https://github.com/unjs/unbuild/issues/304#issuecomment-1688027556 - composite breaks dts 7 | compilerOptions: { 8 | composite: false, 9 | }, 10 | }, 11 | target: 'esnext', 12 | format: ['esm'], 13 | ...options, 14 | })) 15 | -------------------------------------------------------------------------------- /packages/ui/src/components/link/index.test.tsx: -------------------------------------------------------------------------------- 1 | import { describe, it } from 'bun:test' 2 | 3 | import { createRoot } from 'react-dom/client' 4 | import { Link } from '.' 5 | 6 | describe('Link', () => { 7 | it('renders without crashing', () => { 8 | const div = document.createElement('div') 9 | const root = createRoot(div) 10 | root.render(Turborepo Docs) 11 | root.unmount() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /infra/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/infra", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "license": "MIT", 7 | 8 | "scripts": { 9 | "clean": "rm -rf dist node_modules .turbo", 10 | "typecheck": "tsc --noEmit", 11 | "lint": "biome check --write", 12 | "outdated": "bun outdated" 13 | }, 14 | "dependencies": { 15 | "pulumi": "latest", 16 | "@pulumi/cloudflare": "latest" 17 | }, 18 | "devDependencies": {} 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/lint.yml: -------------------------------------------------------------------------------- 1 | name: Lint 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | 7 | jobs: 8 | lint: 9 | runs-on: ubuntu-latest 10 | 11 | steps: 12 | - uses: actions/checkout@v3 13 | 14 | - name: Setup Bun 15 | uses: oven-sh/setup-bun@v2 16 | with: 17 | bun-version: latest 18 | 19 | - name: Install dependencies 20 | run: bun install 21 | 22 | - name: Run lint script 23 | run: bun run lint 24 | -------------------------------------------------------------------------------- /apps/api/src/middleware/errorMiddleware.ts: -------------------------------------------------------------------------------- 1 | import type { Context, Next } from 'hono' 2 | import { handleApiError } from '../utils/errorHandler' 3 | import { customLogger } from '../utils/logger' 4 | 5 | export async function errorMiddleware(c: Context, next: Next) { 6 | try { 7 | await next() 8 | } catch (error) { 9 | customLogger( 10 | `Error occurred: ${error instanceof Error ? error.message : 'Unknown error'}`, 11 | ) 12 | return handleApiError(c, error) 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /infra/src/pages.ts: -------------------------------------------------------------------------------- 1 | import * as cloudflare from '@pulumi/cloudflare' 2 | import * as pulumi from '@pulumi/pulumi' 3 | 4 | const projectName = 'spa-cf' 5 | const CLOUDFLARE_ACCOUNT_ID = process.env.CLOUDFLARE_ACCOUNT_ID 6 | 7 | // Cloudflare Pages Project 8 | export const pagesProject = new cloudflare.PagesProject( 9 | projectName, 10 | { 11 | accountId: CLOUDFLARE_ACCOUNT_ID, 12 | name: projectName, 13 | productionBranch: 'main', 14 | }, 15 | { 16 | protect: true, 17 | }, 18 | ) 19 | -------------------------------------------------------------------------------- /apps/api/src/__tests__/server.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'bun:test' 2 | import { testClient } from 'hono/testing' 3 | import app from '..' 4 | 5 | describe('Server', () => { 6 | const client = testClient(app) 7 | 8 | it.skip('health check returns 200 with hello world', async () => { 9 | // @ts-expect-error - testClient types not working 10 | const res = await client.status.$get() 11 | expect(res.status).toBe(200) 12 | expect(await res.json()).toEqual({ hello: 'world' }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /apps/api/src/utils/logger.ts: -------------------------------------------------------------------------------- 1 | export function customLogger(message: string, ...rest: string[]) { 2 | const date = new Date() 3 | const formattedDate = date 4 | .toLocaleString('en-US', { 5 | year: 'numeric', 6 | month: '2-digit', 7 | day: '2-digit', 8 | hour: '2-digit', 9 | minute: '2-digit', 10 | second: '2-digit', 11 | hour12: true, 12 | timeZone: 'America/Los_Angeles', 13 | }) 14 | .replace(/(\d+)\/(\d+)\/(\d+),/, '$3-$1-$2') 15 | console.log(`[${formattedDate}] ${message}`, ...rest) 16 | } 17 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /apps/api/src/index.ts: -------------------------------------------------------------------------------- 1 | import { Hono } from 'hono' 2 | import { cors } from 'hono/cors' 3 | import { errorMiddleware } from './middleware/errorMiddleware' 4 | import { responseLoggerMiddleware } from './middleware/responseLoggerMiddleware' 5 | import type { Bindings } from './types' 6 | 7 | const app = new Hono<{ Bindings: Bindings }>() 8 | 9 | const routes = app 10 | .use('*', cors()) 11 | .use(errorMiddleware) 12 | .use(responseLoggerMiddleware) 13 | .get('/', (c) => c.json({ hello: 'world' })) 14 | 15 | export default app 16 | export type AppType = typeof routes 17 | -------------------------------------------------------------------------------- /packages/ui/src/components/link/index.tsx: -------------------------------------------------------------------------------- 1 | import type { AnchorHTMLAttributes, ReactNode } from 'react' 2 | 3 | interface LinkProps extends AnchorHTMLAttributes { 4 | children: ReactNode 5 | newTab?: boolean 6 | href: string 7 | } 8 | 9 | export function Link({ 10 | children, 11 | href, 12 | newTab, 13 | ...other 14 | }: LinkProps): JSX.Element { 15 | return ( 16 | 22 | {children} 23 | 24 | ) 25 | } 26 | -------------------------------------------------------------------------------- /apps/api/src/index.test.ts: -------------------------------------------------------------------------------- 1 | import { describe, expect, it } from 'bun:test' 2 | import app from '.' 3 | 4 | describe('Hono API', () => { 5 | it('should return 200 for root path', async () => { 6 | const res = await app.request('/') 7 | expect(res.status).toBe(200) 8 | const json = await res.json() 9 | expect(json).toEqual({ hello: 'world' }) 10 | }) 11 | 12 | it('should return 200 for health check', async () => { 13 | const res = await app.request('/') 14 | expect(res.status).toBe(200) 15 | const json = await res.json() 16 | expect(json).toEqual({ hello: 'world' }) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /apps/astro/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/astro", 3 | "type": "module", 4 | "version": "0.0.0", 5 | "scripts": { 6 | "dev": "astro dev", 7 | "start": "astro dev", 8 | "build": "astro check && astro build", 9 | "clean": "rm -rf node_modules .astro .turbo dist", 10 | "preview": "astro preview", 11 | "lint": "biome check --write", 12 | "format": "biome format", 13 | "typecheck": "tsc --noEmit", 14 | "test": "bun test", 15 | "astro": "astro" 16 | }, 17 | "dependencies": { 18 | "astro": "^4.14.5" 19 | }, 20 | "devDependencies": { 21 | "@astrojs/check": "^0.9.3", 22 | "typescript": "^5.5.4" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/core", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "license": "MIT", 7 | "exports": { 8 | ".": "./src/index.ts", 9 | "./*": "./src/*.ts" 10 | }, 11 | "scripts": { 12 | "build": "tsup", 13 | "clean": "rm -rf dist node_modules .turbo", 14 | "dev": "tsup --watch", 15 | "typecheck": "tsc --noEmit", 16 | "lint": "biome check --write", 17 | "test": "bun test", 18 | "outdated": "bun outdated" 19 | }, 20 | "dependencies": { 21 | "@repo/db": "workspace:*" 22 | }, 23 | "devDependencies": { 24 | "tsup": "^8.2.4", 25 | "typescript": "^5.5.4" 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /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 = ( 10 | event: React.KeyboardEvent, 11 | ): void => { 12 | if ( 13 | event.key === 'Enter' && 14 | !event.shiftKey && 15 | !event.nativeEvent.isComposing 16 | ) { 17 | formRef.current?.requestSubmit() 18 | event.preventDefault() 19 | } 20 | } 21 | 22 | return { formRef, onKeyDown: handleKeyDown } 23 | } 24 | -------------------------------------------------------------------------------- /apps/spa/playwright.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig, devices } from '@playwright/test' 2 | 3 | /** 4 | * See https://playwright.dev/docs/test-configuration. 5 | */ 6 | export default defineConfig({ 7 | testDir: './tests', 8 | 9 | reporter: [['line']], 10 | 11 | use: { 12 | /* Base URL to use in actions like `await page.goto('/')`. */ 13 | baseURL: 'http://localhost:3001/', 14 | }, 15 | 16 | webServer: { 17 | command: 'pnpm run dev', 18 | url: 'http://localhost:3001', 19 | reuseExistingServer: !process.env.CI, 20 | stdout: 'pipe', 21 | }, 22 | 23 | projects: [ 24 | { 25 | name: 'chromium', 26 | use: { ...devices['Desktop Chrome'] }, 27 | }, 28 | ], 29 | }) 30 | -------------------------------------------------------------------------------- /packages/ui/src/hooks/use-resize-observer.ts: -------------------------------------------------------------------------------- 1 | import { type RefObject, useEffect, useState } from 'react' 2 | 3 | export function useResizeObserver( 4 | elementRef: RefObject, 5 | ): ResizeObserverEntry | undefined { 6 | const [entry, setEntry] = useState() 7 | 8 | useEffect(() => { 9 | const node = elementRef?.current 10 | if (!node) return 11 | 12 | const updateEntry = ([entry]: ResizeObserverEntry[]): void => { 13 | setEntry(entry) 14 | } 15 | 16 | const observer = new ResizeObserver((entries) => { 17 | updateEntry(entries) 18 | }) 19 | 20 | observer.observe(node) 21 | 22 | return () => observer.disconnect() 23 | }, [elementRef]) 24 | 25 | return entry 26 | } 27 | -------------------------------------------------------------------------------- /apps/api/src/utils/errorHandler.ts: -------------------------------------------------------------------------------- 1 | import type { Context } from 'hono' 2 | 3 | export function handleApiError(c: Context, error: unknown) { 4 | console.error('API Error:', error) 5 | 6 | const errorMessage = 7 | error instanceof Error ? error.message : 'Unknown error occurred' 8 | const statusCode = error instanceof ApiError ? error.statusCode : 500 9 | 10 | const responseInit: ResponseInit = { status: statusCode } 11 | 12 | return c.json( 13 | { message: 'An error occurred', error: errorMessage }, 14 | responseInit, 15 | ) 16 | } 17 | 18 | export class ApiError extends Error { 19 | constructor( 20 | public override message: string, 21 | public statusCode: number, 22 | ) { 23 | super(message) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /apps/api/src/middleware/responseLoggerMiddleware.ts: -------------------------------------------------------------------------------- 1 | import type { Context, Next } from 'hono' 2 | import { customLogger } from '../utils/logger' 3 | 4 | export async function responseLoggerMiddleware(c: Context, next: Next) { 5 | await next() 6 | 7 | const { method, url } = c.req 8 | const status = c.res.status 9 | const contentLength = c.res.headers.get('Content-Length') 10 | 11 | let responseBody = '' 12 | if (c.res.headers.get('Content-Type')?.includes('application/json')) { 13 | const clonedResponse = c.res.clone() 14 | responseBody = await clonedResponse.text() 15 | } 16 | 17 | customLogger( 18 | `${method} ${url} - Status: ${status}, Content-Length: ${contentLength}`, 19 | responseBody ? `Response: ${responseBody}` : '', 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "ui": "tui", 4 | "tasks": { 5 | "build": { 6 | "inputs": ["$TURBO_DEFAULT$", ".env*"], 7 | "dependsOn": ["^build"], 8 | "outputs": [ 9 | "build/**", 10 | ".vercel/**", 11 | "dist/**", 12 | ".next/**", 13 | "!.next/cache/**", 14 | ".sst/**" 15 | ] 16 | }, 17 | "test": { 18 | "outputs": ["coverage/**"], 19 | "dependsOn": [] 20 | }, 21 | "lint": { 22 | "dependsOn": ["^build"] 23 | }, 24 | "typecheck": { 25 | "dependsOn": ["^build"] 26 | }, 27 | "dev": { 28 | "dependsOn": ["^build"], 29 | "cache": false, 30 | "persistent": true 31 | }, 32 | "outdated": {}, 33 | "clean": { 34 | "cache": false 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /apps/spa/src/routes/_layout/_layout-2.tsx: -------------------------------------------------------------------------------- 1 | import { Link, Outlet, createFileRoute } from '@tanstack/react-router' 2 | 3 | export const Route = createFileRoute('/_layout/_layout-2')({ 4 | component: LayoutComponent, 5 | }) 6 | 7 | function LayoutComponent() { 8 | return ( 9 |
10 |
I'm a nested layout
11 |
12 | 18 | Layout A 19 | 20 | 26 | Layout B 27 | 28 |
29 |
30 | 31 |
32 |
33 | ) 34 | } 35 | -------------------------------------------------------------------------------- /packages/config-typescript/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Base Configuration", 4 | "compilerOptions": { 5 | "skipLibCheck": true, 6 | "allowJs": true, 7 | "target": "es2022", 8 | "module": "ESNext", 9 | "moduleResolution": "Bundler", 10 | "resolveJsonModule": true, 11 | "esModuleInterop": true, 12 | "moduleDetection": "force", 13 | "isolatedModules": true, 14 | "verbatimModuleSyntax": true, 15 | "forceConsistentCasingInFileNames": true, 16 | "strict": true, 17 | "noUncheckedIndexedAccess": true, 18 | "noImplicitOverride": true, 19 | "sourceMap": true, 20 | "declaration": true, 21 | "declarationMap": true, 22 | "composite": false, 23 | "types": ["@types/bun"], 24 | "noEmit": true 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/_packages-template/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/packages-template", 3 | "version": "0.0.0", 4 | "private": true, 5 | "type": "module", 6 | "license": "MIT", 7 | "sideEffects": false, 8 | "main": "./dist/index.js", 9 | "module": "./dist/index.mjs", 10 | "types": "./dist/index.d.ts", 11 | "files": ["dist/**"], 12 | "exports": { 13 | ".": "./src/index.ts", 14 | "./*": "./src/*.ts" 15 | }, 16 | "scripts": { 17 | "build": "tsup", 18 | "clean": "rm -rf dist node_modules .turbo", 19 | "dev": "tsup --watch", 20 | "typecheck": "tsc --noEmit", 21 | "lint": "biome check --write", 22 | "test": "bun test", 23 | "outdated": "bun outdated" 24 | }, 25 | "dependencies": {}, 26 | "devDependencies": { 27 | "tsup": "^8.2.4", 28 | "typescript": "^5.5.4" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /apps/astro/public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /biome.jsonc: -------------------------------------------------------------------------------- 1 | // @see https://biomejs.dev/guides/big-projects/#monorepos 2 | { 3 | "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", 4 | "linter": { 5 | "enabled": true, 6 | "rules": { "recommended": true } 7 | }, 8 | "organizeImports": { 9 | "enabled": true 10 | }, 11 | "javascript": { 12 | "formatter": { 13 | "semicolons": "asNeeded", 14 | "jsxQuoteStyle": "single", 15 | "quoteStyle": "single" 16 | } 17 | }, 18 | "json": { 19 | "formatter": { 20 | "enabled": true, 21 | "indentWidth": 4, 22 | "indentStyle": "tab" 23 | } 24 | }, 25 | "files": { 26 | "ignore": [ 27 | "build/**", 28 | "dist/**", 29 | ".sst/**", 30 | ".turbo/**", 31 | "sst-env.d.ts", 32 | ".wrangler/**", 33 | "prompts/**", 34 | "routeTree.gen.ts" 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/toaster.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import { 4 | Toast, 5 | ToastClose, 6 | ToastDescription, 7 | ToastProvider, 8 | ToastTitle, 9 | ToastViewport, 10 | } from '@/components/ui/toast' 11 | import { useToast } from '@/components/ui/use-toast' 12 | 13 | export function Toaster() { 14 | const { toasts } = useToast() 15 | 16 | return ( 17 | 18 | {toasts.map(({ id, title, description, action, ...props }) => ( 19 | 20 |
21 | {title && {title}} 22 | {description && {description}} 23 |
24 | {action} 25 | 26 |
27 | ))} 28 | 29 |
30 | ) 31 | } 32 | -------------------------------------------------------------------------------- /apps/spa/src/main.tsx: -------------------------------------------------------------------------------- 1 | import { RouterProvider, createRouter } from '@tanstack/react-router' 2 | import React from 'react' 3 | import ReactDOM from 'react-dom/client' 4 | import { routeTree } from './routeTree.gen' 5 | import '@repo/ui/globals.css' 6 | 7 | // Set up a Router instance 8 | const router = createRouter({ 9 | routeTree, 10 | defaultPreload: 'intent', 11 | defaultStaleTime: 5000, 12 | }) 13 | 14 | // Register things for typesafety 15 | declare module '@tanstack/react-router' { 16 | interface Register { 17 | router: typeof router 18 | } 19 | } 20 | 21 | // biome-ignore lint/style/noNonNullAssertion: standard 22 | const rootElement = document.getElementById('app')! 23 | 24 | if (!rootElement.innerHTML) { 25 | const root = ReactDOM.createRoot(rootElement) 26 | root.render() 27 | } 28 | -------------------------------------------------------------------------------- /apps/api/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@repo/api", 3 | "version": "0.0.0", 4 | "type": "module", 5 | "private": true, 6 | "exports": "./src/index.ts", 7 | "scripts": { 8 | "dev": "sst dev", 9 | "wrangler:dev": "wrangler dev src/index.ts", 10 | "build": "tsup", 11 | "clean": "rm -rf node_modules .turbo .wrangler", 12 | "deploy": "wrangler deploy --minify src/index.ts", 13 | "lint": "biome check --write", 14 | "format": "biome format", 15 | "typecheck": "tsc --noEmit", 16 | "test": "bun test", 17 | "outdated": "bun outdated" 18 | }, 19 | "dependencies": { 20 | "@repo/core": "workspace:*", 21 | "@repo/db": "workspace:*", 22 | "hono": "^4.5.8" 23 | }, 24 | "devDependencies": { 25 | "@cloudflare/workers-types": "^4.20240821.1", 26 | "@repo/config-typescript": "*", 27 | "wrangler": "^3.72.2" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/label.tsx: -------------------------------------------------------------------------------- 1 | 'use client' 2 | 3 | import * as LabelPrimitive from '@radix-ui/react-label' 4 | import { type VariantProps, cva } from 'class-variance-authority' 5 | import * as React from 'react' 6 | 7 | import { cn } from '@/lib/utils' 8 | 9 | const labelVariants = cva( 10 | 'text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70', 11 | ) 12 | 13 | const Label = React.forwardRef< 14 | React.ElementRef, 15 | React.ComponentPropsWithoutRef & 16 | VariantProps 17 | >(({ className, ...props }, ref) => ( 18 | 23 | )) 24 | Label.displayName = LabelPrimitive.Root.displayName 25 | 26 | export { Label } 27 | -------------------------------------------------------------------------------- /packages/ui/src/components/ui/textarea.tsx: -------------------------------------------------------------------------------- 1 | import * as React from 'react' 2 | 3 | import { cn } from '@/lib/utils' 4 | 5 | export interface TextareaProps 6 | extends React.TextareaHTMLAttributes {} 7 | 8 | const Textarea = React.forwardRef( 9 | ({ className, ...props }, ref) => { 10 | return ( 11 |