chore: initial monorepo scaffold
Setup pnpm workspaces with apps/{web,api} placeholders and shared
packages: tsconfig, eslint-config, shared, ui, db. Includes Prettier,
ESLint, Husky pre-commit, lint-staged, EditorConfig, VSCode settings.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
commit
87ca5af765
40 files changed
+700
No files matched your search
@@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_style = space
|
||||
indent_size = 2
|
||||
insert_final_newline = true
|
||||
trim_trailing_whitespace = true
|
||||
|
||||
[*.md]
|
||||
trim_trailing_whitespace = false
|
||||
@@ -0,0 +1,14 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@ketopath/eslint-config'],
|
||||
ignorePatterns: [
|
||||
'node_modules/',
|
||||
'dist/',
|
||||
'build/',
|
||||
'.next/',
|
||||
'out/',
|
||||
'coverage/',
|
||||
'pnpm-lock.yaml',
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
* text=auto eol=lf
|
||||
|
||||
*.docx binary
|
||||
*.png binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.pdf binary
|
||||
|
||||
pnpm-lock.yaml linguist-generated=true -diff
|
||||
Whitespace-only changes.
+41
@@ -0,0 +1,41 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
.pnpm-store/
|
||||
|
||||
# Build output
|
||||
dist/
|
||||
build/
|
||||
.next/
|
||||
out/
|
||||
.turbo/
|
||||
|
||||
# Test / coverage
|
||||
coverage/
|
||||
.nyc_output/
|
||||
|
||||
# Env files (NEVER commit)
|
||||
.env
|
||||
.env.*
|
||||
!.env.example
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Editor
|
||||
.idea/
|
||||
*.swp
|
||||
*.swo
|
||||
|
||||
# TypeScript
|
||||
*.tsbuildinfo
|
||||
|
||||
# Misc
|
||||
.cache/
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
pnpm lint-staged
|
||||
@@ -0,0 +1,14 @@
|
||||
node_modules/
|
||||
.pnpm-store/
|
||||
dist/
|
||||
build/
|
||||
.next/
|
||||
out/
|
||||
.turbo/
|
||||
coverage/
|
||||
pnpm-lock.yaml
|
||||
*.docx
|
||||
*.pdf
|
||||
|
||||
# User-authored project doc — preserve exact formatting
|
||||
CLAUDE.md
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"singleQuote": true,
|
||||
"semi": true,
|
||||
"trailingComma": "all",
|
||||
"printWidth": 100,
|
||||
"tabWidth": 2,
|
||||
"arrowParens": "always",
|
||||
"endOfLine": "lf",
|
||||
"plugins": ["prettier-plugin-tailwindcss"]
|
||||
}
|
||||
Vendored
+11
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"editor.formatOnSave": true,
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit"
|
||||
},
|
||||
"eslint.workingDirectories": [{ "pattern": "apps/*" }, { "pattern": "packages/*" }],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true,
|
||||
"files.eol": "\n"
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
# KetoPath
|
||||
|
||||
> Web app responsive multi-utente per la gestione personalizzata di chetogenica e digiuno intermittente, con piani alimentari adattivi, tracking peso/progressi, gestione del digiuno e lista della spesa automatica.
|
||||
|
||||
Questo file viene letto automaticamente da Claude Code a ogni sessione. Tienilo aggiornato con le decisioni architetturali e di prodotto.
|
||||
|
||||
---
|
||||
|
||||
## Vision
|
||||
|
||||
Trasformare la chetogenica e il digiuno intermittente da diete temporanee a stili di vita strutturati, accompagnando ogni utente dalla prima settimana di adattamento al mantenimento per la vita.
|
||||
|
||||
Il documento di prodotto completo è in `docs/PRD_KetoPath.docx`. Quando devi prendere decisioni di prodotto non banali, leggilo prima di proporre soluzioni.
|
||||
|
||||
---
|
||||
|
||||
## Tech stack
|
||||
|
||||
**Frontend**
|
||||
- Next.js 14 (App Router) + TypeScript strict mode
|
||||
- Tailwind CSS + shadcn/ui per i componenti
|
||||
- TanStack Query per data fetching client-side
|
||||
- Zustand per stato globale leggero
|
||||
- Zod per validazione form e tipi runtime
|
||||
|
||||
**Backend**
|
||||
- Node.js + Fastify + TypeScript
|
||||
- Prisma come ORM
|
||||
- Auth gestita via Clerk (no roll-your-own)
|
||||
|
||||
**Database & infrastruttura**
|
||||
- PostgreSQL 15+ come DB principale
|
||||
- Redis per cache, sessioni e queue di job
|
||||
- Cloudflare R2 per storage foto progress
|
||||
- SendGrid per email transazionali
|
||||
- Firebase Cloud Messaging per push web
|
||||
|
||||
**Hosting & DevOps**
|
||||
- Vercel per il frontend Next.js
|
||||
- Render o Fly.io per il backend Fastify
|
||||
- GitHub Actions per CI/CD
|
||||
- PostHog (self-hosted) per analytics
|
||||
- Sentry per error tracking
|
||||
|
||||
---
|
||||
|
||||
## Repository structure
|
||||
|
||||
```
|
||||
ketopath/
|
||||
├── apps/
|
||||
│ ├── web/ # Next.js frontend (App Router)
|
||||
│ └── api/ # Fastify backend
|
||||
├── packages/
|
||||
│ ├── db/ # Prisma schema, client, migrations
|
||||
│ ├── shared/ # Tipi TS, utility e logica di dominio condivisa
|
||||
│ └── ui/ # Componenti UI riusabili (estensione shadcn/ui)
|
||||
├── docs/
|
||||
│ ├── PRD_KetoPath.docx
|
||||
│ └── decisions/ # ADR (Architecture Decision Records)
|
||||
├── .github/workflows/
|
||||
└── CLAUDE.md # questo file
|
||||
```
|
||||
|
||||
Usa un monorepo con pnpm workspaces o Turborepo. Tutto in TypeScript.
|
||||
|
||||
---
|
||||
|
||||
## Convenzioni di codice
|
||||
|
||||
- **TypeScript strict mode** sempre. Mai `any` senza commento `// eslint-disable-next-line` motivato.
|
||||
- **File**: `kebab-case.tsx` per i moduli, `PascalCase.tsx` per i componenti React esposti.
|
||||
- **Componenti React**: function components + hooks, no class components.
|
||||
- **Naming**:
|
||||
- Variabili e funzioni: `camelCase`
|
||||
- Componenti, tipi e interfacce: `PascalCase`
|
||||
- Costanti globali: `SCREAMING_SNAKE_CASE`
|
||||
- **Commit message**: Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, ecc.).
|
||||
- **Linting**: ESLint + Prettier, formattazione automatica al pre-commit con husky + lint-staged.
|
||||
- **Test**: Vitest per unit test, Playwright per E2E. Coverage minima 70% sui moduli di dominio (calcoli BMR, macros, fasi).
|
||||
|
||||
---
|
||||
|
||||
## Pattern di codice da preferire
|
||||
|
||||
- **Server Components** di default in Next.js; `"use client"` solo dove serve interattività.
|
||||
- **Server Actions** per mutazioni semplici di form, API routes per logica più complessa.
|
||||
- **Suspense + Error Boundary** per ogni feature.
|
||||
- **Form**: React Hook Form + Zod resolver. Mai validazione manuale.
|
||||
- **Date**: usa `date-fns`. Mai `Date.parse` o stringhe ad-hoc.
|
||||
- **DB queries**: Prisma client. Niente raw SQL se non strettamente necessario, e in quel caso commenta perché.
|
||||
- **Optimistic updates** per le azioni utente frequenti (segnare un pasto come consumato, spuntare un articolo della lista spesa).
|
||||
|
||||
---
|
||||
|
||||
## Conoscenza di dominio
|
||||
|
||||
Il dominio dell'app ha alcuni concetti chiave che devi conoscere prima di scrivere codice:
|
||||
|
||||
- **3 Fasi del percorso utente**:
|
||||
- `INTENSIVE` (giorni 1-30/45) — deficit calorico aggressivo, IF stretto
|
||||
- `TRANSITION` (giorni 31-90) — reverse dieting, calorie in salita
|
||||
- `MAINTENANCE` (per sempre) — 14:10, regola 80/20, soglia di allarme
|
||||
- **Calcolo calorie** con formula Mifflin-St Jeor:
|
||||
- Uomini: `BMR = 10 × peso(kg) + 6.25 × altezza(cm) − 5 × età + 5`
|
||||
- Donne: `BMR = 10 × peso(kg) + 6.25 × altezza(cm) − 5 × età − 161`
|
||||
- TDEE = BMR × fattore attività (1.2 / 1.375 / 1.55 / 1.725)
|
||||
- **Macros target per fase**:
|
||||
- Carboidrati netti: 5-10% in Phase 1, sale in Phase 2-3
|
||||
- Proteine: 1.5-1.8 g/kg di peso ideale
|
||||
- Grassi: il resto
|
||||
- **Protocolli di digiuno**: enum `FASTING_PROTOCOL = 14_10 | 16_8 | 18_6 | 20_4 | ESE_24 | FIVE_TWO`
|
||||
- **Esclusioni alimentari**: ogni `Ingredient` ha `exclusion_groups` (es. `lactose`, `fish`, `nuts`); ogni `Recipe` eredita le esclusioni dai suoi ingredienti
|
||||
|
||||
Quando implementi una nuova funzionalità, mappa sempre prima a quale fase appartiene e quali macros/vincoli rispetta.
|
||||
|
||||
---
|
||||
|
||||
## Comandi comuni
|
||||
|
||||
```bash
|
||||
# Sviluppo
|
||||
pnpm dev # Avvia frontend + backend in parallelo
|
||||
pnpm dev:web # Solo Next.js
|
||||
pnpm dev:api # Solo Fastify
|
||||
|
||||
# Build & deploy
|
||||
pnpm build # Build di tutti i package
|
||||
pnpm start # Avvia in production mode
|
||||
|
||||
# Database
|
||||
pnpm db:migrate # prisma migrate dev
|
||||
pnpm db:studio # Apre Prisma Studio
|
||||
pnpm db:seed # Popola DB con dati di test
|
||||
|
||||
# Quality
|
||||
pnpm lint # ESLint
|
||||
pnpm format # Prettier
|
||||
pnpm typecheck # tsc --noEmit
|
||||
pnpm test # Vitest
|
||||
pnpm test:e2e # Playwright
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Vincoli non negoziabili
|
||||
|
||||
- **Lingua UI di default: italiano**. Tutti i testi user-facing in italiano. Predisporre i18n con `next-intl` per l'eventuale internazionalizzazione futura.
|
||||
- **Mobile-first responsive**: ogni pagina deve essere progettata e testata prima a 375px di larghezza.
|
||||
- **GDPR by design**: i dati di salute (peso, misure, foto, sintomi) rientrano nell'art. 9 GDPR. Crittografia at-rest sul DB, niente log dei dati sanitari, consenso esplicito.
|
||||
- **Disclaimer medico** sempre visibile in onboarding, nelle pagine di calcolo calorico e nelle pagine di tracking. Testo da concordare con un medico advisor.
|
||||
- **Privacy first**: niente tracking di terze parti senza consenso, no Google Analytics di default. Se proprio servono analytics, usa PostHog self-hosted con cookie-less mode.
|
||||
- **Accessibilità WCAG 2.1 AA**: tutto il contenuto navigabile da tastiera, contrasto colori sufficiente, alt text sulle immagini, semantica HTML corretta.
|
||||
|
||||
---
|
||||
|
||||
## Cosa NON fare mai
|
||||
|
||||
- Salvare password in chiaro (Clerk gestisce auth, non implementarla a mano).
|
||||
- Loggare dati di salute fuori dal DB cifrato.
|
||||
- Usare `eval()` o `new Function()` con input utente.
|
||||
- Disabilitare feature di sicurezza (CSP, CORS, rate limiting) per "comodità di sviluppo".
|
||||
- Fare claim medici sui prodotti o suggerire farmaci/integratori specifici.
|
||||
- Esportare dati utente in chiaro senza autenticazione e log dell'export.
|
||||
- Fare commit di file `.env`, chiavi API, dump di database.
|
||||
- Usare librerie deprecate o senza manutenzione attiva (controlla l'ultimo commit prima di aggiungere una dipendenza).
|
||||
|
||||
---
|
||||
|
||||
## Workflow consigliato per Claude Code
|
||||
|
||||
Quando ti chiedo una nuova funzionalità, segui questo flusso:
|
||||
|
||||
1. **Domanda di chiarimento** se il task non è completamente specificato.
|
||||
2. **Lettura preventiva**: leggi i file pertinenti prima di proporre modifiche, non scrivere codice "alla cieca".
|
||||
3. **Plan mode** per task non banali: presentami un piano in 5-10 punti prima di toccare il codice.
|
||||
4. **Implementazione progressiva**: feature piccole, commit frequenti, ogni commit verde (lint + test passano).
|
||||
5. **Diff esplicito**: mostrami sempre i diff prima di applicare modifiche a file critici (`prisma/schema.prisma`, `package.json`, file di config).
|
||||
6. **Test**: per ogni nuova logica di dominio (calcoli macros, fasi, vincoli) scrivi anche unit test.
|
||||
7. **Documentazione**: aggiorna il README e questo CLAUDE.md quando introduci pattern nuovi o cambi decisioni architetturali.
|
||||
|
||||
---
|
||||
|
||||
## Decisioni architetturali aperte (da prendere insieme)
|
||||
|
||||
Queste decisioni non sono ancora finalizzate. Se le tocchi, aprire un ADR in `docs/decisions/`.
|
||||
|
||||
- [ ] Stripe vs Lemon Squeezy per il payment provider
|
||||
- [ ] PostHog self-hosted vs Mixpanel per analytics di prodotto
|
||||
- [ ] Render vs Fly.io vs AWS ECS per l'hosting backend
|
||||
- [ ] Strategia di seeding del database ricette (manuale vs scraping autorizzato vs LLM-assisted)
|
||||
- [ ] Localizzazione: i18n da subito o solo italiano per MVP?
|
||||
- [ ] App mobile nativa post-MVP: React Native o Expo?
|
||||
|
||||
---
|
||||
|
||||
## Riferimenti
|
||||
|
||||
- PRD completo: `docs/PRD_KetoPath.docx`
|
||||
- Documentazione Next.js: https://nextjs.org/docs
|
||||
- Documentazione Prisma: https://www.prisma.io/docs
|
||||
- Documentazione Clerk: https://clerk.com/docs
|
||||
- shadcn/ui: https://ui.shadcn.com
|
||||
- GDPR e dati sanitari: https://www.garanteprivacy.it/
|
||||
|
||||
---
|
||||
|
||||
*Ultimo aggiornamento: aprile 2026. Modifica questo file ogni volta che cambia una decisione architetturale o un pattern di codice.*
|
||||
@@ -0,0 +1,46 @@
|
||||
# KetoPath
|
||||
|
||||
Web app responsive multi-utente per la gestione personalizzata di chetogenica e digiuno intermittente.
|
||||
|
||||
> Vedi `CLAUDE.md` per le convenzioni di progetto e `docs/PRD_KetoPath.docx` per il PRD completo.
|
||||
|
||||
## Prerequisiti
|
||||
|
||||
- Node.js `>=20.11` (vedi `.nvmrc`)
|
||||
- pnpm `>=9` (`corepack enable && corepack prepare pnpm@latest --activate`)
|
||||
|
||||
## Getting started
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm typecheck
|
||||
pnpm lint
|
||||
pnpm format:check
|
||||
```
|
||||
|
||||
## Struttura del monorepo
|
||||
|
||||
```
|
||||
apps/
|
||||
web/ # Next.js 14 frontend (da scaffoldare)
|
||||
api/ # Fastify backend (da scaffoldare)
|
||||
packages/
|
||||
shared/ # Tipi e utility di dominio
|
||||
ui/ # Componenti UI riusabili
|
||||
db/ # Prisma client (da scaffoldare)
|
||||
tsconfig/ # tsconfig presets condivisi
|
||||
eslint-config/ # ESLint config condivisa
|
||||
docs/
|
||||
PRD_KetoPath.docx
|
||||
```
|
||||
|
||||
## Script disponibili
|
||||
|
||||
- `pnpm dev` — avvia tutte le app in parallelo
|
||||
- `pnpm dev:web` / `pnpm dev:api` — avvia singola app
|
||||
- `pnpm build` — build di produzione
|
||||
- `pnpm lint` / `pnpm lint:fix` — ESLint
|
||||
- `pnpm format` / `pnpm format:check` — Prettier
|
||||
- `pnpm typecheck` — `tsc -b` su tutto il monorepo
|
||||
- `pnpm test` — Vitest (unit test)
|
||||
- `pnpm test:e2e` — Playwright (E2E)
|
||||
Whitespace-only changes.
Whitespace-only changes.
Binary file not shown.
@@ -0,0 +1,48 @@
|
||||
{
|
||||
"name": "ketopath",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"description": "KetoPath monorepo — web app per la gestione di chetogenica e digiuno intermittente",
|
||||
"packageManager": "pnpm@9.12.0",
|
||||
"engines": {
|
||||
"node": ">=20.11",
|
||||
"pnpm": ">=9"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "pnpm --parallel --filter \"./apps/*\" dev",
|
||||
"dev:web": "pnpm --filter @ketopath/web dev",
|
||||
"dev:api": "pnpm --filter @ketopath/api dev",
|
||||
"build": "pnpm --filter \"./apps/*\" build",
|
||||
"start": "pnpm --filter \"./apps/*\" start",
|
||||
"lint": "eslint . --max-warnings=0",
|
||||
"lint:fix": "eslint . --fix",
|
||||
"format": "prettier --write .",
|
||||
"format:check": "prettier --check .",
|
||||
"typecheck": "tsc -b",
|
||||
"test": "pnpm --filter \"./packages/*\" --filter \"./apps/*\" -r --if-present test",
|
||||
"test:e2e": "pnpm --filter @ketopath/web test:e2e",
|
||||
"prepare": "husky"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.12.7",
|
||||
"@typescript-eslint/eslint-plugin": "^7.7.0",
|
||||
"@typescript-eslint/parser": "^7.7.0",
|
||||
"eslint": "^8.57.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-import": "^2.29.1",
|
||||
"husky": "^9.0.11",
|
||||
"lint-staged": "^15.2.2",
|
||||
"prettier": "^3.2.5",
|
||||
"prettier-plugin-tailwindcss": "^0.5.14",
|
||||
"typescript": "5.4.5"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,jsx,cjs,mjs}": [
|
||||
"eslint --fix --max-warnings=0",
|
||||
"prettier --write"
|
||||
],
|
||||
"*.{json,md,yml,yaml,css}": [
|
||||
"prettier --write"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@ketopath/eslint-config/node.cjs'],
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@ketopath/db",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint src --max-warnings=0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ketopath/eslint-config": "workspace:*",
|
||||
"@ketopath/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@ketopath/tsconfig/node.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: false,
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 2022,
|
||||
sourceType: 'module',
|
||||
},
|
||||
plugins: ['@typescript-eslint', 'import'],
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:import/recommended',
|
||||
'plugin:import/typescript',
|
||||
'prettier',
|
||||
],
|
||||
settings: {
|
||||
'import/resolver': {
|
||||
typescript: {
|
||||
alwaysTryTypes: true,
|
||||
},
|
||||
node: true,
|
||||
},
|
||||
},
|
||||
rules: {
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{ argsIgnorePattern: '^_', varsIgnorePattern: '^_' },
|
||||
],
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{ prefer: 'type-imports', fixStyle: 'inline-type-imports' },
|
||||
],
|
||||
'import/order': [
|
||||
'error',
|
||||
{
|
||||
groups: ['builtin', 'external', 'internal', 'parent', 'sibling', 'index'],
|
||||
'newlines-between': 'always',
|
||||
alphabetize: { order: 'asc', caseInsensitive: true },
|
||||
},
|
||||
],
|
||||
'import/no-default-export': 'off',
|
||||
},
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.cjs', '*.config.js', '*.config.mjs'],
|
||||
env: { node: true },
|
||||
rules: {
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
},
|
||||
},
|
||||
],
|
||||
ignorePatterns: [
|
||||
'node_modules/',
|
||||
'dist/',
|
||||
'build/',
|
||||
'.next/',
|
||||
'out/',
|
||||
'coverage/',
|
||||
'*.config.js',
|
||||
'*.config.cjs',
|
||||
'*.config.mjs',
|
||||
],
|
||||
};
|
||||
@@ -0,0 +1,8 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: [require.resolve('./index.cjs'), 'next/core-web-vitals'],
|
||||
rules: {
|
||||
'react/no-unescaped-entities': 'off',
|
||||
'@next/next/no-html-link-for-pages': 'off',
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,11 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
extends: [require.resolve('./index.cjs')],
|
||||
env: {
|
||||
node: true,
|
||||
es2022: true,
|
||||
},
|
||||
rules: {
|
||||
'no-console': ['warn', { allow: ['warn', 'error', 'info'] }],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "@ketopath/eslint-config",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"main": "index.cjs",
|
||||
"files": [
|
||||
"index.cjs",
|
||||
"nextjs.cjs",
|
||||
"node.cjs"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"eslint": "^8.57.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@ketopath/eslint-config'],
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@ketopath/shared",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint src --max-warnings=0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ketopath/eslint-config": "workspace:*",
|
||||
"@ketopath/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"extends": "@ketopath/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Base",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "Bundler",
|
||||
"esModuleInterop": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
|
||||
"strict": true,
|
||||
"noUncheckedIndexedAccess": true,
|
||||
"exactOptionalPropertyTypes": true,
|
||||
"noImplicitOverride": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
|
||||
"skipLibCheck": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
||||
"declaration": true,
|
||||
"declarationMap": true,
|
||||
"sourceMap": true,
|
||||
"incremental": true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Next.js",
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
||||
"jsx": "preserve",
|
||||
"allowJs": true,
|
||||
"noEmit": true,
|
||||
"plugins": [{ "name": "next" }]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/tsconfig",
|
||||
"display": "Node.js 20",
|
||||
"extends": "./base.json",
|
||||
"compilerOptions": {
|
||||
"target": "ES2022",
|
||||
"lib": ["ES2022"],
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"types": ["node"]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@ketopath/tsconfig",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"files": [
|
||||
"base.json",
|
||||
"nextjs.json",
|
||||
"node.json"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
/** @type {import('eslint').Linter.Config} */
|
||||
module.exports = {
|
||||
root: true,
|
||||
extends: ['@ketopath/eslint-config'],
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@ketopath/ui",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"main": "./src/index.ts",
|
||||
"types": "./src/index.ts",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
},
|
||||
"scripts": {
|
||||
"typecheck": "tsc --noEmit",
|
||||
"lint": "eslint src --max-warnings=0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@ketopath/eslint-config": "workspace:*",
|
||||
"@ketopath/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export {};
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"extends": "@ketopath/tsconfig/base.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"rootDir": "src",
|
||||
"composite": true,
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2022"],
|
||||
"jsx": "preserve"
|
||||
},
|
||||
"include": ["src/**/*"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Generated
BIN
Binary file not shown.
@@ -0,0 +1,3 @@
|
||||
packages:
|
||||
- 'apps/*'
|
||||
- 'packages/*'
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"files": [],
|
||||
"references": [
|
||||
{ "path": "./packages/shared" },
|
||||
{ "path": "./packages/ui" },
|
||||
{ "path": "./packages/db" }
|
||||
]
|
||||
}
|
||||
Reference in new issue
Block a user