mirror of
https://github.com/QWRK-ORG/qwrk-laconic-core.git
synced 2026-09-08 05:34:07 +00:00
Add precommit hook
This commit is contained in:
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "Laconic Core Development",
|
||||
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
|
||||
|
||||
// Add environment variables
|
||||
"containerEnv": {
|
||||
"NODE_ENV": "development"
|
||||
},
|
||||
|
||||
// Mount your SSH keys for git authentication
|
||||
"mounts": [
|
||||
"source=${localEnv:HOME}/.ssh,target=/home/node/.ssh,type=bind,readonly"
|
||||
],
|
||||
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"biomejs.biome",
|
||||
"ms-vscode.vscode-typescript-next",
|
||||
"ms-azuretools.vscode-docker",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"christian-kohler.path-intellisense",
|
||||
"github.vscode-pull-request-github",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"eamodio.gitlens"
|
||||
],
|
||||
"settings": {
|
||||
"editor.defaultFormatter": "biomejs.biome",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": "explicit",
|
||||
"source.fixAll": "explicit",
|
||||
"source.addMissingImports.ts": "explicit",
|
||||
"source.fixAll.ts": "explicit",
|
||||
"source.removeUnusedImports": "explicit"
|
||||
},
|
||||
// Additional helpful settings
|
||||
"editor.bracketPairColorization.enabled": true,
|
||||
"editor.guides.bracketPairs": true,
|
||||
"terminal.integrated.defaultProfile.linux": "bash",
|
||||
"javascript.updateImportsOnFileMove.enabled": "always",
|
||||
"typescript.updateImportsOnFileMove.enabled": "always",
|
||||
"files.exclude": {
|
||||
"**/.git": true,
|
||||
"**/node_modules": true,
|
||||
"**/dist": true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Forward common development ports
|
||||
"forwardPorts": [3000, 4000, 5000, 8000],
|
||||
|
||||
// Set up git configuration
|
||||
"postCreateCommand": "pnpm install && git config --global pull.rebase true",
|
||||
|
||||
"remoteUser": "node",
|
||||
|
||||
// Features to install in the container
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {},
|
||||
"ghcr.io/devcontainers/features/git:1": {}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint'],
|
||||
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
|
||||
rules: {
|
||||
// Add rules that can be auto-fixed
|
||||
'@typescript-eslint/no-unused-vars': 'error',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'warn',
|
||||
'@typescript-eslint/no-non-null-assertion': 'warn'
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
# Setting Up Contribution Guidelines with CODEOWNERS
|
||||
|
||||
You can create a CODEOWNERS file to define which files require specific approval before changes can be merged. This helps protect critical files in your project.
|
||||
|
||||
## Steps to implement CODEOWNERS:
|
||||
|
||||
1. Create a CODEOWNERS file in either the root directory, .github directory, or docs directory
|
||||
2. Define file patterns and the users/teams who own those files
|
||||
|
||||
Here's how to implement it:
|
||||
|
||||
# CODEOWNERS file defines who needs to approve changes to specific files
|
||||
# Format: file-pattern @user-or-team
|
||||
|
||||
# Dev container configuration
|
||||
.devcontainer/* @your-username
|
||||
|
||||
# Core configuration files
|
||||
.vscode/* @your-username
|
||||
*.json @your-username
|
||||
|
||||
# Critical application files that need review
|
||||
/src/core/* @your-username @another-team-member
|
||||
/services/api/* @api-team-name
|
||||
|
||||
# Documentation changes can be reviewed by docs team
|
||||
/docs/* @docs-team-or-username
|
||||
|
||||
# Default owners for everything else
|
||||
* @default-team-or-username
|
||||
@@ -0,0 +1,46 @@
|
||||
# Contributing to Laconic Core
|
||||
|
||||
Thank you for considering contributing to our project! Here are some guidelines to help you get started.
|
||||
|
||||
## Development Environment
|
||||
|
||||
This project uses dev containers to ensure consistent development environments. To get started:
|
||||
|
||||
1. Install [Docker](https://www.docker.com/products/docker-desktop) and [VS Code](https://code.visualstudio.com/)
|
||||
2. Install the [Remote - Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension
|
||||
3. Clone the repository and open it in VS Code
|
||||
4. Click the green button in the bottom-left corner and select "Reopen in Container"
|
||||
|
||||
## Protected Files
|
||||
|
||||
Some files in this repository are protected and require specific approval before changes can be merged:
|
||||
|
||||
- `.devcontainer/*` - Dev container configuration
|
||||
- `.vscode/*` - VS Code workspace settings
|
||||
- `core configuration files` - Project configuration files
|
||||
- `critical application files` - Core functionality
|
||||
|
||||
Please discuss any changes to these files with the maintainers before submitting pull requests.
|
||||
|
||||
## Code Style
|
||||
|
||||
This project uses Biome for formatting and linting. The dev container will automatically configure your editor to use the correct settings.
|
||||
|
||||
## Submitting Changes
|
||||
|
||||
1. Fork the repository
|
||||
2. Create a new branch for your changes
|
||||
3. Make your changes following the code style guidelines
|
||||
4. Write tests for your changes
|
||||
5. Submit a pull request
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
1. Update the README.md with details of changes if applicable
|
||||
2. The version numbers will be updated by maintainers following semantic versioning
|
||||
3. Pull requests require approval from at least one maintainer
|
||||
4. Once approved, maintainers will merge the PR
|
||||
|
||||
## Questions?
|
||||
|
||||
If you have questions, please open an issue or contact the maintainers.
|
||||
+3
-1
@@ -69,4 +69,6 @@ logs
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
Thumbs.db
|
||||
|
||||
.pnpm-store
|
||||
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"recommendations": [
|
||||
"biomejs.biome",
|
||||
"ms-vscode-remote.remote-containers",
|
||||
"ms-typescript.vscode-typescript-next"
|
||||
]
|
||||
}
|
||||
Vendored
+29
-2
@@ -1,3 +1,30 @@
|
||||
{
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
}
|
||||
// This file can be empty since all settings are in devcontainer.json
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll": true,
|
||||
"source.organizeImports": true
|
||||
},
|
||||
"editor.defaultFormatter": "biomejs.biome",
|
||||
"[typescript]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"[typescriptreact]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"[javascript]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"[javascriptreact]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "biomejs.biome"
|
||||
},
|
||||
"typescript.validate.enable": true,
|
||||
"javascript.validate.enable": true,
|
||||
"typescript.reportStyleChecksAsWarnings": true,
|
||||
"typescript.surveys.enabled": false
|
||||
}
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
import { Geist, Geist_Mono } from "next/font/google"
|
||||
import '@workspace/ui/globals.css'
|
||||
|
||||
import "@workspace/ui/globals.css"
|
||||
import { Providers } from "@/components/providers"
|
||||
import { Providers } from '@/components/providers'
|
||||
import { Geist, Geist_Mono } from 'next/font/google'
|
||||
|
||||
const fontSans = Geist({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-sans",
|
||||
subsets: ['latin'],
|
||||
variable: '--font-sans'
|
||||
})
|
||||
|
||||
const fontMono = Geist_Mono({
|
||||
subsets: ["latin"],
|
||||
variable: "--font-mono",
|
||||
subsets: ['latin'],
|
||||
variable: '--font-mono'
|
||||
})
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
children
|
||||
}: Readonly<{
|
||||
children: React.ReactNode
|
||||
}>) {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Button } from "@workspace/ui/components/button"
|
||||
import { Button } from '@workspace/ui/components/button'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"use client"
|
||||
'use client'
|
||||
|
||||
import * as React from "react"
|
||||
import { ThemeProvider as NextThemesProvider } from "next-themes"
|
||||
import { ThemeProvider as NextThemesProvider } from 'next-themes'
|
||||
import type * as React from 'react'
|
||||
|
||||
export function Providers({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import * as React from "react"
|
||||
import * as React from 'react'
|
||||
|
||||
const MOBILE_BREAKPOINT = 768
|
||||
|
||||
@@ -10,9 +10,9 @@ export function useIsMobile() {
|
||||
const onChange = () => {
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
||||
}
|
||||
mql.addEventListener("change", onChange)
|
||||
mql.addEventListener('change', onChange)
|
||||
setIsMobile(window.innerWidth < MOBILE_BREAKPOINT)
|
||||
return () => mql.removeEventListener("change", onChange)
|
||||
return () => mql.removeEventListener('change', onChange)
|
||||
}, [])
|
||||
|
||||
return !!isMobile
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** @type {import('next').NextConfig} */
|
||||
const nextConfig = {
|
||||
transpilePackages: ["@workspace/ui"],
|
||||
transpilePackages: ['@workspace/ui']
|
||||
}
|
||||
|
||||
export default nextConfig
|
||||
|
||||
@@ -7,9 +7,16 @@
|
||||
"dev": "next dev --turbopack",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"lint": "next lint"
|
||||
"lint": "biome check .",
|
||||
"lint:fix": "biome check --apply .",
|
||||
"format": "biome format .",
|
||||
"format:fix": "biome format --write .",
|
||||
"check-types": "tsc --noEmit",
|
||||
"fix-types": "tsc --noEmit --pretty --incremental"
|
||||
},
|
||||
"dependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@biomejs/monorepo": "github:biomejs/biome",
|
||||
"@hookform/resolvers": "^4.1.2",
|
||||
"@radix-ui/react-accordion": "^1.2.3",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.6",
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { default } from "@workspace/ui/postcss.config";
|
||||
export { default } from '@workspace/ui/postcss.config'
|
||||
|
||||
@@ -1 +1 @@
|
||||
export * from "@workspace/ui/tailwind.config";
|
||||
export * from '@workspace/ui/tailwind.config'
|
||||
|
||||
+39
-31
@@ -1,33 +1,41 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": {
|
||||
"enabled": false,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": false
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": false,
|
||||
"ignore": []
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 80
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"quoteStyle": "single",
|
||||
"trailingCommas": "none"
|
||||
}
|
||||
}
|
||||
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
||||
"vcs": {
|
||||
"enabled": false,
|
||||
"clientKind": "git",
|
||||
"useIgnoreFile": false
|
||||
},
|
||||
"files": {
|
||||
"ignoreUnknown": false,
|
||||
"ignore": ["node_modules", "dist", "build"]
|
||||
},
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"indentStyle": "space",
|
||||
"indentWidth": 2,
|
||||
"lineWidth": 80
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
"recommended": true
|
||||
}
|
||||
},
|
||||
"javascript": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"quoteStyle": "single",
|
||||
"trailingCommas": "none",
|
||||
"semicolons": "asNeeded"
|
||||
}
|
||||
},
|
||||
"json": {
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"trailingCommas": "none"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
lint:
|
||||
glob: "*.{js,ts,jsx,tsx}"
|
||||
run: pnpm lint:fix {staged_files}
|
||||
stage_fixed: true
|
||||
format:
|
||||
glob: "*.{js,ts,jsx,tsx}"
|
||||
run: pnpm format:fix {staged_files}
|
||||
stage_fixed: true
|
||||
typecheck:
|
||||
glob: "*.{ts,tsx}"
|
||||
run: pnpm check-types
|
||||
# TypeScript requires checking the whole project context
|
||||
# We can't easily check only staged files while maintaining type relationships
|
||||
|
||||
# Add a manual hook that can be run with `npx lefthook run fix-all`
|
||||
fix-all:
|
||||
commands:
|
||||
fix-code:
|
||||
glob: "*.{js,ts,jsx,tsx}"
|
||||
run: pnpm fix-all
|
||||
@@ -0,0 +1,14 @@
|
||||
pre-commit:
|
||||
commands:
|
||||
check:
|
||||
glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
|
||||
# run: npx @biomejs/biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files}
|
||||
run: pnpm biome format --write {staged_files}
|
||||
stage_fixed: true
|
||||
|
||||
pre-push:
|
||||
parallel: true
|
||||
commands:
|
||||
check:
|
||||
glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
|
||||
run: npx @biomejs/biome check --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {push_files}
|
||||
+19
-9
@@ -1,25 +1,35 @@
|
||||
{
|
||||
"name": "qwrk-laconic-core",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"description": "Monorepo for Laconic frontend codebases",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"build": "turbo build",
|
||||
"dev": "turbo dev",
|
||||
"lint": "turbo lint",
|
||||
"lint:fix": "biome lint --write",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
"lint:fix": "turbo lint:fix",
|
||||
"format": "turbo format",
|
||||
"format:fix": "turbo format:fix",
|
||||
"check-types": "turbo check-types",
|
||||
"fix-types": "turbo fix-types",
|
||||
"validate": "turbo lint check-types format",
|
||||
"fix-all": "turbo lint:fix fix-types format:fix",
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"test:hooks": "lefthook run pre-commit"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"author": "QWRK",
|
||||
"license": "ISC",
|
||||
"packageManager": "pnpm@10.5.1",
|
||||
"devDependencies": {
|
||||
"turbo": "^2.4.4",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@workspace/typescript-config": "workspace:*",
|
||||
"chalk": "5",
|
||||
"lefthook": "^1.11.2",
|
||||
"turbo": "^2.4.4",
|
||||
"typescript": "^5.7.3"
|
||||
},
|
||||
"packageManager": "pnpm@10.5.1",
|
||||
"engines": {
|
||||
"node": ">=22.14.0"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Generated
+131
-4
@@ -14,6 +14,12 @@ importers:
|
||||
'@workspace/typescript-config':
|
||||
specifier: workspace:*
|
||||
version: link:services/typescript-config
|
||||
chalk:
|
||||
specifier: '5'
|
||||
version: 5.4.1
|
||||
lefthook:
|
||||
specifier: ^1.11.2
|
||||
version: 1.11.2
|
||||
turbo:
|
||||
specifier: ^2.4.4
|
||||
version: 2.4.4
|
||||
@@ -23,6 +29,12 @@ importers:
|
||||
|
||||
apps/web:
|
||||
dependencies:
|
||||
'@biomejs/biome':
|
||||
specifier: ^1.9.4
|
||||
version: 1.9.4
|
||||
'@biomejs/monorepo':
|
||||
specifier: github:biomejs/biome
|
||||
version: https://codeload.github.com/biomejs/biome/tar.gz/d95df40a86c8debb369fdc9070c91642325bfe1f
|
||||
'@hookform/resolvers':
|
||||
specifier: ^4.1.2
|
||||
version: 4.1.2(react-hook-form@7.54.2(react@19.0.0))
|
||||
@@ -185,6 +197,12 @@ importers:
|
||||
|
||||
services/ui:
|
||||
dependencies:
|
||||
'@biomejs/biome':
|
||||
specifier: ^1.9.4
|
||||
version: 1.9.4
|
||||
'@biomejs/monorepo':
|
||||
specifier: github:biomejs/biome
|
||||
version: https://codeload.github.com/biomejs/biome/tar.gz/d95df40a86c8debb369fdc9070c91642325bfe1f
|
||||
'@radix-ui/react-slot':
|
||||
specifier: ^1.1.1
|
||||
version: 1.1.2(@types/react@18.3.0)(react@19.0.0)
|
||||
@@ -307,6 +325,10 @@ packages:
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
'@biomejs/monorepo@https://codeload.github.com/biomejs/biome/tar.gz/d95df40a86c8debb369fdc9070c91642325bfe1f':
|
||||
resolution: {tarball: https://codeload.github.com/biomejs/biome/tar.gz/d95df40a86c8debb369fdc9070c91642325bfe1f}
|
||||
version: 0.0.0
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1468,6 +1490,10 @@ packages:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
chalk@5.4.1:
|
||||
resolution: {integrity: sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==}
|
||||
engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
|
||||
|
||||
change-case@3.1.0:
|
||||
resolution: {integrity: sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==}
|
||||
|
||||
@@ -1652,8 +1678,8 @@ packages:
|
||||
dot-case@2.1.1:
|
||||
resolution: {integrity: sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==}
|
||||
|
||||
electron-to-chromium@1.5.106:
|
||||
resolution: {integrity: sha512-12keJGdXQWPnfVOu6/6ZzZgPPNodiDOSe3LjA8qk2yXTjnCnw2LeGUsAmtlNAmH4UW0K7tOLcz0j9lI2eJCJRA==}
|
||||
electron-to-chromium@1.5.107:
|
||||
resolution: {integrity: sha512-dJr1o6yCntRkXElnhsHh1bAV19bo/hKyFf7tCcWgpXbuFIF0Lakjgqv5LRfSDaNzAII8Fnxg2tqgHkgCvxdbxw==}
|
||||
|
||||
embla-carousel-react@8.5.2:
|
||||
resolution: {integrity: sha512-Tmx+uY3MqseIGdwp0ScyUuxpBgx5jX1f7od4Cm5mDwg/dptEiTKf9xp6tw0lZN2VA9JbnVMl/aikmbc53c6QFA==}
|
||||
@@ -1919,6 +1945,60 @@ packages:
|
||||
jsonfile@6.1.0:
|
||||
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
|
||||
|
||||
lefthook-darwin-arm64@1.11.2:
|
||||
resolution: {integrity: sha512-8DpvrybtWdt6UmfZk+hA8daYXr6zkpJVogZ8M49BQx6ISSKUaC03xzO1m4MrAsoKok77ka4JAidYhOa2gCu15A==}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
|
||||
lefthook-darwin-x64@1.11.2:
|
||||
resolution: {integrity: sha512-DrL1SOT8lJksjudRu6fTZTp3M0EbpCP2RQ22MDT71clS8BMrFL8x3h9Ziw+uNH76j9zA241tW5zMxWMSv+foAA==}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
|
||||
lefthook-freebsd-arm64@1.11.2:
|
||||
resolution: {integrity: sha512-AliG4Wi8BNC27hCSnuFBeUXh/eA3fppnUbQQPISy/G94yfwRkzyml9MZzvb7HKmUpw1LT0sq9RQ6FQPxBZ2DYA==}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
|
||||
lefthook-freebsd-x64@1.11.2:
|
||||
resolution: {integrity: sha512-V6cgRCoi5+jcq6XBIdRYraeEOK1UhBrtL/XZlNypAIkhPoBtfTP9u2wSprGMDzZvJCRriLXZxV/d0v94laKXzA==}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
|
||||
lefthook-linux-arm64@1.11.2:
|
||||
resolution: {integrity: sha512-VKcK7sjIK8UpXX/qK6Fxa0Lnwr4gzRtlXDS17jzxThcyFk8iGBpQ+9ZnPLv2yAaEIzmGhJUG9sDgOb9IQ5kpBQ==}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
|
||||
lefthook-linux-x64@1.11.2:
|
||||
resolution: {integrity: sha512-aGa2Krph14YwSW7KF0PrlCBK9P7V/Z4oFklonmz3r2Fjm8EdhA750y7OQvA9KerXRleIb5SaUH/cz1azG/izeQ==}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
|
||||
lefthook-openbsd-arm64@1.11.2:
|
||||
resolution: {integrity: sha512-f7owNQ9Ki6Y07KBgdXdH28EYO0eBdZuGTpIggMeHNhYFVDavxuINP2BjmbXtzpUu8K5BX6exGx0umtWhRhXbvQ==}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
|
||||
lefthook-openbsd-x64@1.11.2:
|
||||
resolution: {integrity: sha512-HKv6PV64vOjqPrlxAqo07N9+Z34jdPDBfeExqi0ldR7vACFaBJFIdhWCLLP+3uQUrNKc8GXlikqplZn8MgRSQw==}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
|
||||
lefthook-windows-arm64@1.11.2:
|
||||
resolution: {integrity: sha512-042jCKZ/H+lS6XYoMIf2FWMP2hxXqfAT52UW6lYObIOvQ5xu/epUXFjtmXRyYxCv57No3JYYMg1Yr06xdzTKkQ==}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
|
||||
lefthook-windows-x64@1.11.2:
|
||||
resolution: {integrity: sha512-1Map6Ck2AyfY6ptN9T19N41HFKFqRTzmILtGaRGJABEzHiE4+gSWcq5YT1R6cCtkVlewD3Lx+J/80D/Kb/cVtw==}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
|
||||
lefthook@1.11.2:
|
||||
resolution: {integrity: sha512-/5royc/WbL2KTfFJ54wEdvxUZOBXwc54v/fW2Bz4LMOkAA3LWIxnoUiybSiauu+nhdTG98qERxH1YHwF2wZlAA==}
|
||||
hasBin: true
|
||||
|
||||
lodash.get@4.4.2:
|
||||
resolution: {integrity: sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==}
|
||||
deprecated: This package is deprecated. Use the optional chaining (?.) operator instead.
|
||||
@@ -2650,6 +2730,8 @@ snapshots:
|
||||
'@biomejs/cli-win32-x64@1.9.4':
|
||||
optional: true
|
||||
|
||||
'@biomejs/monorepo@https://codeload.github.com/biomejs/biome/tar.gz/d95df40a86c8debb369fdc9070c91642325bfe1f': {}
|
||||
|
||||
'@cspotcode/source-map-support@0.8.1':
|
||||
dependencies:
|
||||
'@jridgewell/trace-mapping': 0.3.9
|
||||
@@ -3783,7 +3865,7 @@ snapshots:
|
||||
browserslist@4.24.4:
|
||||
dependencies:
|
||||
caniuse-lite: 1.0.30001701
|
||||
electron-to-chromium: 1.5.106
|
||||
electron-to-chromium: 1.5.107
|
||||
node-releases: 2.0.19
|
||||
update-browserslist-db: 1.1.3(browserslist@4.24.4)
|
||||
|
||||
@@ -3819,6 +3901,8 @@ snapshots:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
chalk@5.4.1: {}
|
||||
|
||||
change-case@3.1.0:
|
||||
dependencies:
|
||||
camel-case: 3.0.0
|
||||
@@ -4008,7 +4092,7 @@ snapshots:
|
||||
dependencies:
|
||||
no-case: 2.3.2
|
||||
|
||||
electron-to-chromium@1.5.106: {}
|
||||
electron-to-chromium@1.5.107: {}
|
||||
|
||||
embla-carousel-react@8.5.2(react@19.0.0):
|
||||
dependencies:
|
||||
@@ -4295,6 +4379,49 @@ snapshots:
|
||||
optionalDependencies:
|
||||
graceful-fs: 4.2.11
|
||||
|
||||
lefthook-darwin-arm64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-darwin-x64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-freebsd-arm64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-freebsd-x64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-linux-arm64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-linux-x64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-openbsd-arm64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-openbsd-x64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-windows-arm64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook-windows-x64@1.11.2:
|
||||
optional: true
|
||||
|
||||
lefthook@1.11.2:
|
||||
optionalDependencies:
|
||||
lefthook-darwin-arm64: 1.11.2
|
||||
lefthook-darwin-x64: 1.11.2
|
||||
lefthook-freebsd-arm64: 1.11.2
|
||||
lefthook-freebsd-x64: 1.11.2
|
||||
lefthook-linux-arm64: 1.11.2
|
||||
lefthook-linux-x64: 1.11.2
|
||||
lefthook-openbsd-arm64: 1.11.2
|
||||
lefthook-openbsd-x64: 1.11.2
|
||||
lefthook-windows-arm64: 1.11.2
|
||||
lefthook-windows-x64: 1.11.2
|
||||
|
||||
lodash.get@4.4.2: {}
|
||||
|
||||
lodash@4.17.21: {}
|
||||
|
||||
@@ -1,5 +1,42 @@
|
||||
# QWRK-Laconic Turborepo Migration Technical Specification
|
||||
|
||||
## Implementation Starting Points
|
||||
|
||||
This migration specification supports multiple entry points depending on the current state of your repository:
|
||||
|
||||
### Scenario 1: New Repository Implementation
|
||||
- Follow all steps sequentially starting from "Repository Initialization"
|
||||
- Execute all setup commands to build the complete architecture from scratch
|
||||
|
||||
### Scenario 2: Existing Repository Conversion
|
||||
If the repository already exists but requires Turborepo integration:
|
||||
1. Preserve existing package structure and Git history
|
||||
2. Add Turborepo configuration (`turbo.json`, `pnpm-workspace.yaml`)
|
||||
3. Adapt existing packages to the recommended structure
|
||||
4. Integrate shared package dependencies
|
||||
5. Skip initialization steps that would conflict with existing setup
|
||||
|
||||
### Scenario 3: Partial Turborepo Implementation
|
||||
For repositories with partial Turborepo architecture:
|
||||
1. Audit existing configuration against this specification
|
||||
2. Upgrade task definitions to latest syntax (`tasks` vs legacy `pipeline`)
|
||||
3. Apply missing architectural components
|
||||
4. Align package structure with recommended patterns
|
||||
5. Integrate modular services approach
|
||||
|
||||
### Prerequisite Validation
|
||||
Run the following diagnostic commands to determine your starting point:
|
||||
```bash
|
||||
# Check for existing Turborepo configuration
|
||||
[ -f turbo.json ] && echo "Existing turbo.json found, requires update" || echo "New turbo.json needed"
|
||||
|
||||
# Verify package manager
|
||||
command -v pnpm >/dev/null 2>&1 && echo "pnpm installed" || echo "pnpm installation required"
|
||||
|
||||
# Check Next.js applications
|
||||
find . -path "*/package.json" -exec grep -l "next" {} \; | xargs -I{} dirname {}
|
||||
```
|
||||
|
||||
## Architecture Overview
|
||||
|
||||
```mermaid
|
||||
@@ -84,6 +121,7 @@ qwrk-laconic-mono/
|
||||
|
||||
### 1. Repository Initialization
|
||||
|
||||
#### New Repository Approach
|
||||
```bash
|
||||
# Initialize Turborepo with pnpm
|
||||
pnpm dlx create-turbo@latest qwrk-laconic-mono --package-manager=pnpm
|
||||
@@ -93,6 +131,23 @@ cd qwrk-laconic-mono
|
||||
rm -rf apps/docs apps/web
|
||||
```
|
||||
|
||||
#### Existing Repository Approach
|
||||
```bash
|
||||
# If repository already exists and initialized:
|
||||
git clone <existing-repo-url> qwrk-laconic-mono
|
||||
cd qwrk-laconic-mono
|
||||
|
||||
# Create workspace structure if not exists
|
||||
mkdir -p apps packages
|
||||
|
||||
# Save existing structure (optional)
|
||||
find . -maxdepth 2 -type d -not -path "*/\.*" -not -path "./node_modules" \
|
||||
-not -path "./apps" -not -path "./packages" > existing_directories.txt
|
||||
|
||||
# Create migration branch
|
||||
git checkout -b feature/turborepo-migration
|
||||
```
|
||||
|
||||
### 2. Configure Package Manager
|
||||
|
||||
```bash
|
||||
@@ -940,6 +995,76 @@ flowchart TD
|
||||
- Create project management features
|
||||
- Implement deployment functionality
|
||||
|
||||
## Repository Structural Migration
|
||||
|
||||
For existing repositories that require Turborepo conversion, follow this structural migration approach:
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph "Initial State"
|
||||
A[Existing Repository]
|
||||
B[Frontend Application]
|
||||
C[Backend Services]
|
||||
D[Shared Libraries]
|
||||
end
|
||||
|
||||
subgraph "Migration Process"
|
||||
E[Create Migration Branch]
|
||||
F[Add Turborepo Config]
|
||||
G[Restructure Packages]
|
||||
H[Refactor Dependencies]
|
||||
I[Implement Build System]
|
||||
end
|
||||
|
||||
subgraph "Final State"
|
||||
J[apps/laconic-web]
|
||||
K[apps/laconic-deploy]
|
||||
L[apps/docs]
|
||||
M[packages/ui]
|
||||
N[packages/utils]
|
||||
O[packages/services]
|
||||
end
|
||||
|
||||
A --> E
|
||||
E --> F
|
||||
F --> G
|
||||
G --> H
|
||||
H --> I
|
||||
I --> J & K & L & M & N & O
|
||||
```
|
||||
|
||||
### Repository Structure Analysis
|
||||
|
||||
Before migration, analyze the existing code structure:
|
||||
|
||||
```bash
|
||||
# Identify package dependencies
|
||||
find . -name "package.json" -not -path "*/node_modules/*" -exec jq -r '.dependencies | keys[]' {} \; | sort | uniq -c | sort -nr
|
||||
|
||||
# Identify file distribution
|
||||
find . -type f -name "*.ts*" | grep -v "node_modules" | grep -v ".turbo" | grep -v "dist" | wc -l
|
||||
|
||||
# Analyze potential shared components
|
||||
find . -type f -name "*.tsx" -not -path "*/node_modules/*" | xargs grep -l "export" | sort
|
||||
```
|
||||
|
||||
### Incremental Migration Strategy
|
||||
|
||||
1. **Coexistence Phase**
|
||||
- Implement Turborepo alongside existing structure
|
||||
- Gradually move components to new architecture
|
||||
- Maintain backward compatibility during transition
|
||||
|
||||
2. **Dual Build System**
|
||||
- Configure builds for both legacy and new structure
|
||||
- Implement feature flags for incremental adoption
|
||||
- Monitor performance metrics across both systems
|
||||
|
||||
3. **Final Migration**
|
||||
- Complete transition to Turborepo architecture
|
||||
- Remove legacy configuration
|
||||
- Optimize build pipeline for new structure
|
||||
|
||||
## Best Practices and Guidelines
|
||||
|
||||
### TypeScript Configuration
|
||||
@@ -1045,4 +1170,4 @@ jobs:
|
||||
|
||||
This technical specification provides a comprehensive guide for migrating the qwrk-laconic repository to a modern Turborepo structure with Next.js 15. By following this guide, you can create a modular, maintainable monorepo that leverages the latest technologies and best practices for web development.
|
||||
|
||||
The migration approach prioritizes incremental adoption, allowing for gradual transition while maintaining backward compatibility with existing systems.
|
||||
The migration approach prioritizes incremental adoption, allowing for gradual transition while maintaining backward compatibility with existing systems.
|
||||
@@ -0,0 +1,36 @@
|
||||
# Scripts and Hooks
|
||||
|
||||
This directory contains utility scripts for the project.
|
||||
|
||||
## Lefthook Configuration
|
||||
|
||||
The project uses [Lefthook](https://github.com/evilmartians/lefthook) for git hooks to ensure code quality before commits.
|
||||
|
||||
### Pre-commit Hooks
|
||||
|
||||
The pre-commit hooks run:
|
||||
|
||||
1. **Linting** - Checks and fixes code style issues
|
||||
2. **Formatting** - Ensures consistent code formatting
|
||||
3. **Type Checking** - Verifies TypeScript types
|
||||
|
||||
These hooks are configured in `lefthook.yaml` in the root directory.
|
||||
|
||||
### Usage
|
||||
|
||||
The hooks run automatically when you commit code. You can also run them manually:
|
||||
|
||||
```bash
|
||||
# Run all pre-commit hooks
|
||||
pnpm test:hooks
|
||||
|
||||
# Run individual commands
|
||||
pnpm lint:fix
|
||||
pnpm format:fix
|
||||
pnpm check-types
|
||||
pnpm fix-all
|
||||
```
|
||||
|
||||
## VS Code Integration
|
||||
|
||||
TypeScript errors will show up directly in VS Code thanks to the configuration in `.vscode/settings.json`.
|
||||
Executable
+81
@@ -0,0 +1,81 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import chalk from 'chalk'
|
||||
|
||||
const command = process.argv[2]
|
||||
const files = process.argv.slice(3)
|
||||
|
||||
// Format the command name for display
|
||||
const formatCommand = (cmd) => {
|
||||
switch (cmd) {
|
||||
case 'lint:fix':
|
||||
return chalk.blue.bold('LINTING')
|
||||
case 'format:fix':
|
||||
return chalk.magenta.bold('FORMATTING')
|
||||
case 'check-types':
|
||||
return chalk.yellow.bold('TYPE CHECKING')
|
||||
case 'fix-all':
|
||||
return chalk.green.bold('FIXING ALL ISSUES')
|
||||
default:
|
||||
return chalk.white.bold(cmd.toUpperCase())
|
||||
}
|
||||
}
|
||||
|
||||
// Display a header for the command
|
||||
console.log(
|
||||
'\n' +
|
||||
chalk.gray(
|
||||
'╔═════════════════════════════════════════════════════════════════════════════╗'
|
||||
)
|
||||
)
|
||||
console.log(
|
||||
chalk.gray('║ ') +
|
||||
chalk.white.bold(`LEFTHOOK: ${formatCommand(command)}`) +
|
||||
chalk.gray(' ║')
|
||||
)
|
||||
console.log(
|
||||
chalk.gray(
|
||||
'╚═════════════════════════════════════════════════════════════════════════════╝\n'
|
||||
)
|
||||
)
|
||||
|
||||
// If we have files, display them
|
||||
if (files.length > 0) {
|
||||
console.log(chalk.gray('Files being processed:'))
|
||||
for (const file of files) {
|
||||
console.log(chalk.cyan(` → ${file}`))
|
||||
}
|
||||
console.log('')
|
||||
}
|
||||
|
||||
// Execute the original command
|
||||
const { execSync } = await import('node:child_process')
|
||||
try {
|
||||
// Construct the command based on what was passed
|
||||
let fullCommand
|
||||
if (files.length > 0 && command !== 'check-types') {
|
||||
// For commands that support specific files
|
||||
fullCommand = `pnpm ${command} ${files.join(' ')}`
|
||||
} else {
|
||||
// For commands that run on the whole project
|
||||
fullCommand = `pnpm ${command}`
|
||||
}
|
||||
|
||||
// Execute the command
|
||||
execSync(fullCommand, { stdio: 'inherit' })
|
||||
|
||||
// Show success message
|
||||
console.log(
|
||||
'\n' +
|
||||
chalk.green.bold('✓ SUCCESS') +
|
||||
chalk.green(` ${formatCommand(command)} completed successfully`)
|
||||
)
|
||||
} catch (error) {
|
||||
// Show error message
|
||||
console.log(
|
||||
'\n' +
|
||||
chalk.red.bold('✗ ERROR') +
|
||||
chalk.red(` ${formatCommand(command)} failed`)
|
||||
)
|
||||
process.exit(1)
|
||||
}
|
||||
@@ -3,6 +3,6 @@
|
||||
"display": "React Library",
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"jsx": "react-jsx",
|
||||
"jsx": "react-jsx"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,8 +3,12 @@
|
||||
"version": "0.0.0",
|
||||
"type": "module",
|
||||
"private": true,
|
||||
"scripts": {},
|
||||
"scripts": {
|
||||
"lint": "biome format --write"
|
||||
},
|
||||
"dependencies": {
|
||||
"@biomejs/biome": "^1.9.4",
|
||||
"@biomejs/monorepo": "github:biomejs/biome",
|
||||
"@radix-ui/react-slot": "^1.1.1",
|
||||
"class-variance-authority": "^0.7.0",
|
||||
"clsx": "^2.1.1",
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
const config = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
};
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
||||
@@ -1,35 +1,35 @@
|
||||
import * as React from "react"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva, type VariantProps } from "class-variance-authority"
|
||||
import { Slot } from '@radix-ui/react-slot'
|
||||
import { type VariantProps, cva } from 'class-variance-authority'
|
||||
import * as React from 'react'
|
||||
|
||||
import { cn } from "@workspace/ui/lib/utils"
|
||||
import { cn } from '@workspace/ui/lib/utils'
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0',
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
||||
default: 'bg-primary text-primary-foreground hover:bg-primary/90',
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90',
|
||||
outline:
|
||||
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
||||
'border border-input bg-background hover:bg-accent hover:text-accent-foreground',
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
'bg-secondary text-secondary-foreground hover:bg-secondary/80',
|
||||
ghost: 'hover:bg-accent hover:text-accent-foreground',
|
||||
link: 'text-primary underline-offset-4 hover:underline'
|
||||
},
|
||||
size: {
|
||||
default: "h-10 px-4 py-2",
|
||||
sm: "h-9 rounded-md px-3",
|
||||
lg: "h-11 rounded-md px-8",
|
||||
icon: "h-10 w-10",
|
||||
},
|
||||
default: 'h-10 px-4 py-2',
|
||||
sm: 'h-9 rounded-md px-3',
|
||||
lg: 'h-11 rounded-md px-8',
|
||||
icon: 'h-10 w-10'
|
||||
}
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
variant: 'default',
|
||||
size: 'default'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
@@ -41,7 +41,7 @@ export interface ButtonProps
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button"
|
||||
const Comp = asChild ? Slot : 'button'
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
@@ -51,6 +51,6 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
)
|
||||
}
|
||||
)
|
||||
Button.displayName = "Button"
|
||||
Button.displayName = 'Button'
|
||||
|
||||
export { Button, buttonVariants }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { clsx, type ClassValue } from "clsx"
|
||||
import { twMerge } from "tailwind-merge"
|
||||
import { type ClassValue, clsx } from 'clsx'
|
||||
import { twMerge } from 'tailwind-merge'
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs))
|
||||
|
||||
@@ -83,8 +83,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border outline-ring/50;
|
||||
|
||||
@@ -1,100 +1,94 @@
|
||||
import type { Config } from "tailwindcss"
|
||||
import defaultTheme from "tailwindcss"
|
||||
import tailwindcssAnimate from "tailwindcss-animate"
|
||||
import type { Config } from 'tailwindcss'
|
||||
import defaultTheme from 'tailwindcss'
|
||||
import tailwindcssAnimate from 'tailwindcss-animate'
|
||||
const config = {
|
||||
// darkMode: ["class"],
|
||||
content: [
|
||||
"app/**/*.{ts,tsx}",
|
||||
"components/**/*.{ts,tsx}",
|
||||
"../../services/ui/src/components/**/*.{ts,tsx}",
|
||||
'app/**/*.{ts,tsx}',
|
||||
'components/**/*.{ts,tsx}',
|
||||
'../../services/ui/src/components/**/*.{ts,tsx}'
|
||||
],
|
||||
theme: {
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: [
|
||||
'var(--font-sans)',
|
||||
...defaultTheme.fontFamily.sans
|
||||
],
|
||||
mono: [
|
||||
'var(--font-mono)',
|
||||
...defaultTheme.fontFamily.mono
|
||||
]
|
||||
},
|
||||
colors: {
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
ring: 'hsl(var(--ring))',
|
||||
background: 'hsl(var(--background))',
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
foreground: 'hsl(var(--primary-foreground))'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
foreground: 'hsl(var(--destructive-foreground))'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted))',
|
||||
foreground: 'hsl(var(--muted-foreground))'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
foreground: 'hsl(var(--accent-foreground))'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover))',
|
||||
foreground: 'hsl(var(--popover-foreground))'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))'
|
||||
},
|
||||
sidebar: {
|
||||
DEFAULT: 'hsl(var(--sidebar-background))',
|
||||
foreground: 'hsl(var(--sidebar-foreground))',
|
||||
primary: 'hsl(var(--sidebar-primary))',
|
||||
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
|
||||
accent: 'hsl(var(--sidebar-accent))',
|
||||
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
|
||||
border: 'hsl(var(--sidebar-border))',
|
||||
ring: 'hsl(var(--sidebar-ring))'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: {
|
||||
height: '0'
|
||||
},
|
||||
to: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
}
|
||||
},
|
||||
'accordion-up': {
|
||||
from: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
},
|
||||
to: {
|
||||
height: '0'
|
||||
}
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out'
|
||||
}
|
||||
}
|
||||
extend: {
|
||||
fontFamily: {
|
||||
sans: ['var(--font-sans)', ...defaultTheme.fontFamily.sans],
|
||||
mono: ['var(--font-mono)', ...defaultTheme.fontFamily.mono]
|
||||
},
|
||||
colors: {
|
||||
border: 'hsl(var(--border))',
|
||||
input: 'hsl(var(--input))',
|
||||
ring: 'hsl(var(--ring))',
|
||||
background: 'hsl(var(--background))',
|
||||
foreground: 'hsl(var(--foreground))',
|
||||
primary: {
|
||||
DEFAULT: 'hsl(var(--primary))',
|
||||
foreground: 'hsl(var(--primary-foreground))'
|
||||
},
|
||||
secondary: {
|
||||
DEFAULT: 'hsl(var(--secondary))',
|
||||
foreground: 'hsl(var(--secondary-foreground))'
|
||||
},
|
||||
destructive: {
|
||||
DEFAULT: 'hsl(var(--destructive))',
|
||||
foreground: 'hsl(var(--destructive-foreground))'
|
||||
},
|
||||
muted: {
|
||||
DEFAULT: 'hsl(var(--muted))',
|
||||
foreground: 'hsl(var(--muted-foreground))'
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: 'hsl(var(--accent))',
|
||||
foreground: 'hsl(var(--accent-foreground))'
|
||||
},
|
||||
popover: {
|
||||
DEFAULT: 'hsl(var(--popover))',
|
||||
foreground: 'hsl(var(--popover-foreground))'
|
||||
},
|
||||
card: {
|
||||
DEFAULT: 'hsl(var(--card))',
|
||||
foreground: 'hsl(var(--card-foreground))'
|
||||
},
|
||||
sidebar: {
|
||||
DEFAULT: 'hsl(var(--sidebar-background))',
|
||||
foreground: 'hsl(var(--sidebar-foreground))',
|
||||
primary: 'hsl(var(--sidebar-primary))',
|
||||
'primary-foreground': 'hsl(var(--sidebar-primary-foreground))',
|
||||
accent: 'hsl(var(--sidebar-accent))',
|
||||
'accent-foreground': 'hsl(var(--sidebar-accent-foreground))',
|
||||
border: 'hsl(var(--sidebar-border))',
|
||||
ring: 'hsl(var(--sidebar-ring))'
|
||||
}
|
||||
},
|
||||
borderRadius: {
|
||||
lg: 'var(--radius)',
|
||||
md: 'calc(var(--radius) - 2px)',
|
||||
sm: 'calc(var(--radius) - 4px)'
|
||||
},
|
||||
keyframes: {
|
||||
'accordion-down': {
|
||||
from: {
|
||||
height: '0'
|
||||
},
|
||||
to: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
}
|
||||
},
|
||||
'accordion-up': {
|
||||
from: {
|
||||
height: 'var(--radix-accordion-content-height)'
|
||||
},
|
||||
to: {
|
||||
height: '0'
|
||||
}
|
||||
}
|
||||
},
|
||||
animation: {
|
||||
'accordion-down': 'accordion-down 0.2s ease-out',
|
||||
'accordion-up': 'accordion-up 0.2s ease-out'
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [tailwindcssAnimate],
|
||||
plugins: [tailwindcssAnimate]
|
||||
} satisfies Config
|
||||
|
||||
export default config
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
{
|
||||
"extends": "@workspace/typescript-config/base.json"
|
||||
}
|
||||
|
||||
|
||||
+27
-2
@@ -2,15 +2,40 @@
|
||||
"$schema": "https://turbo.build/schema.json",
|
||||
"tasks": {
|
||||
"build": {
|
||||
"inputs": ["$TURBO_DEFAULT$", ".env*"],
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**", "!.next/cache/**"]
|
||||
},
|
||||
"check-types": {
|
||||
"dependsOn": ["^check-types"]
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": []
|
||||
},
|
||||
"fix-types": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": []
|
||||
},
|
||||
"format": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": []
|
||||
},
|
||||
"format:fix": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": []
|
||||
},
|
||||
"test": {
|
||||
"outputs": ["coverage/**"],
|
||||
"dependsOn": []
|
||||
},
|
||||
"lint": {
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"lint:fix": {
|
||||
"dependsOn": ["^build"]
|
||||
},
|
||||
"dev": {
|
||||
"dependsOn": ["^build"],
|
||||
"persistent": true,
|
||||
"cache": false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user