feat: 添加 API 客户端以处理 basePath 并更新所有 fetch 调用

移除 next.config.js 中的 standalone 输出配置,添加 lib/api-client.ts 封装 fetch 请求,
自动为所有 API 调用添加配置的 basePath。更新所有页面和组件中的 fetch 调用以使用新的 fetchApi 函数,
确保在部署到子路径时 API 请求能正确工作。同时调整 tsconfig.json 的格式并修复项目创建时的字段名。
This commit is contained in:
2026-01-28 15:54:19 +08:00
parent 7948b1afc7
commit fc9cfda29e
21 changed files with 118 additions and 65 deletions

View File

@@ -28,6 +28,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { fetchApi } from '@/lib/api-client';
const metricSchema = z.object({
name: z.string().min(1, '名称不能为空'),
@@ -61,7 +62,7 @@ export default function AdminMetricsPage() {
const fetchMetrics = async () => {
try {
const res = await fetch('/api/metrics');
const res = await fetchApi('/api/metrics');
if (res.ok) {
const data = await res.json();
setMetrics(data);
@@ -83,7 +84,7 @@ export default function AdminMetricsPage() {
const url = editingMetric ? `/api/metrics/${editingMetric.id}` : '/api/metrics';
const method = editingMetric ? 'PATCH' : 'POST';
const res = await fetch(url, {
const res = await fetchApi(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
@@ -119,7 +120,7 @@ export default function AdminMetricsPage() {
const handleToggleActive = async (metric: Metric) => {
try {
const res = await fetch(`/api/metrics/${metric.id}`, {
const res = await fetchApi(`/api/metrics/${metric.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ is_active: !metric.is_active }),
@@ -143,7 +144,7 @@ export default function AdminMetricsPage() {
if (!deleteMetricId) return;
setIsDeleting(true);
try {
const res = await fetch(`/api/metrics/${deleteMetricId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/metrics/${deleteMetricId}`, { method: 'DELETE' });
if (!res.ok) throw new Error('删除失败');
toast.success('指标已删除');

View File

@@ -28,6 +28,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { fetchApi } from '@/lib/api-client';
const templateItemSchema = z.object({
title: z.string().min(1, '标题不能为空'),
@@ -75,7 +76,7 @@ export default function AdminTemplatesPage() {
const fetchTemplates = async () => {
try {
const res = await fetch('/api/templates');
const res = await fetchApi('/api/templates');
if (res.ok) {
const data = await res.json();
setTemplates(data);
@@ -97,7 +98,7 @@ export default function AdminTemplatesPage() {
const url = editingTemplate ? `/api/templates/${editingTemplate.id}` : '/api/templates';
const method = editingTemplate ? 'PATCH' : 'POST';
const res = await fetch(url, {
const res = await fetchApi(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(values),
@@ -133,7 +134,7 @@ export default function AdminTemplatesPage() {
const handleToggleActive = async (template: Template) => {
try {
const res = await fetch(`/api/templates/${template.id}`, {
const res = await fetchApi(`/api/templates/${template.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ is_active: !template.is_active }),
@@ -157,7 +158,7 @@ export default function AdminTemplatesPage() {
if (!deleteTemplateId) return;
setIsDeleting(true);
try {
const res = await fetch(`/api/templates/${deleteTemplateId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/templates/${deleteTemplateId}`, { method: 'DELETE' });
if (!res.ok) throw new Error('删除失败');
toast.success('模板已删除');

View File

@@ -28,6 +28,7 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from '@/components/ui/alert-dialog';
import { fetchApi } from '@/lib/api-client';
const userSchema = z.object({
name: z.string().min(1, '名称不能为空'),
@@ -81,7 +82,7 @@ export default function AdminUsersPage() {
password: values.password ? values.password : undefined,
};
const res = await fetch(url, {
const res = await fetchApi(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload),
@@ -124,7 +125,7 @@ export default function AdminUsersPage() {
if (!deleteUserId) return;
setIsDeleting(true);
try {
const res = await fetch(`/api/users/${deleteUserId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/users/${deleteUserId}`, { method: 'DELETE' });
const data = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(data?.error || '删除失败');

View File

@@ -23,6 +23,7 @@ import {
Legend,
} from 'recharts';
import { BarChart3, PieChart as PieChartIcon, TrendingUp, Users, Target } from 'lucide-react';
import { fetchApi } from '@/lib/api-client';
interface KRWithRelations extends KR {
owner: User | null;
@@ -48,10 +49,10 @@ export default function AnalysisPage() {
async function fetchData() {
try {
const [projectsRes, krsRes, checkinsRes, usersRes] = await Promise.all([
fetch('/api/projects'),
fetch('/api/krs'),
fetch('/api/checkins?limit=100'),
fetch('/api/users'),
fetchApi('/api/projects'),
fetchApi('/api/krs'),
fetchApi('/api/checkins?limit=100'),
fetchApi('/api/users'),
]);
if (projectsRes.ok) setProjects(await projectsRes.json());

View File

@@ -48,6 +48,7 @@ import {
} from 'lucide-react';
import { getErrorMessage } from '@/lib/error-utils';
import { fetchApi } from '@/lib/api-client';
interface KRWithRelations extends KR {
owner: User | null;
@@ -90,9 +91,9 @@ export default function KRDetailPage({ krId }: { krId: string }) {
const fetchData = useCallback(async () => {
try {
const [krRes, checkinsRes, tasksRes] = await Promise.all([
fetch(`/api/krs/${krId}`),
fetch(`/api/checkins?kr_id=${krId}`),
fetch(`/api/tasks?kr_id=${krId}`),
fetchApi(`/api/krs/${krId}`),
fetchApi(`/api/checkins?kr_id=${krId}`),
fetchApi(`/api/tasks?kr_id=${krId}`),
]);
if (krRes.status === 403) {
@@ -159,7 +160,7 @@ export default function KRDetailPage({ krId }: { krId: string }) {
setIsSubmitting(true);
try {
const res = await fetch('/api/checkins', {
const res = await fetchApi('/api/checkins', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -192,7 +193,7 @@ export default function KRDetailPage({ krId }: { krId: string }) {
if (!kr) return;
try {
const res = await fetch(`/api/krs/${kr.id}`, {
const res = await fetchApi(`/api/krs/${kr.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -214,7 +215,7 @@ export default function KRDetailPage({ krId }: { krId: string }) {
if (!kr) return;
setIsDeleting(true);
try {
const res = await fetch(`/api/krs/${kr.id}`, { method: 'DELETE' });
const res = await fetchApi(`/api/krs/${kr.id}`, { method: 'DELETE' });
if (!res.ok) throw new Error('删除失败');
toast.success('KR 已删除');
router.push(`/projects/${kr.project_id}`);
@@ -233,7 +234,7 @@ export default function KRDetailPage({ krId }: { krId: string }) {
const formData = new FormData(e.currentTarget);
try {
const res = await fetch(`/api/krs/${kr.id}`, {
const res = await fetchApi(`/api/krs/${kr.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -293,7 +294,7 @@ export default function KRDetailPage({ krId }: { krId: string }) {
const handleTaskStatusChange = async (taskId: string, newStatus: string) => {
try {
const res = await fetch(`/api/tasks/${taskId}`, {
const res = await fetchApi(`/api/tasks/${taskId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: newStatus }),

View File

@@ -8,6 +8,7 @@ import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { toast } from 'sonner';
import { useUser } from '@/components/user-context';
import { fetchApi } from '@/lib/api-client';
const DEFAULT_USERNAME = 'baicaimiao';
const DEFAULT_PASSWORD = 'baicaimiao123';
@@ -29,7 +30,7 @@ export default function LoginPage() {
e.preventDefault();
setIsSubmitting(true);
try {
const res = await fetch('/api/auth/login', {
const res = await fetchApi('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),

View File

@@ -30,6 +30,7 @@ import {
Presentation,
} from 'lucide-react';
import { getErrorMessage } from '@/lib/error-utils';
import { fetchApi } from '@/lib/api-client';
interface ProjectWithRelations extends Project {
owner: User | null;
@@ -78,9 +79,9 @@ export default function MeetingPage() {
async function fetchData() {
try {
const [projectsRes, krsRes, meetingsRes] = await Promise.all([
fetch('/api/projects'),
fetch('/api/krs'),
fetch('/api/meetings'),
fetchApi('/api/projects'),
fetchApi('/api/krs'),
fetchApi('/api/meetings'),
]);
if (projectsRes.ok) {
@@ -182,7 +183,7 @@ export default function MeetingPage() {
setIsSubmitting(true);
try {
const res = await fetch('/api/meetings', {
const res = await fetchApi('/api/meetings', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({

View File

@@ -12,6 +12,7 @@ import { calculateProgress, getDaysRemaining, formatDateRange, isKRActive, getTo
import { PERIOD_TYPES, REASON_CODES } from '@/lib/constants';
import type { KR, User } from '@/types/database';
import { Target, Clock, AlertTriangle, CheckCircle, History } from 'lucide-react';
import { fetchApi } from '@/lib/api-client';
interface KRWithRelations extends KR {
owner: User | null;
@@ -38,7 +39,7 @@ export default function MyKRsPage() {
useEffect(() => {
async function fetchKRs() {
try {
const res = await fetch('/api/krs');
const res = await fetchApi('/api/krs');
if (res.ok) {
const data = await res.json();
setKRs(data);

View File

@@ -12,6 +12,7 @@ import type { Task, TaskStep, User } from '@/types/database';
import { CheckSquare, Clock, Calendar, AlertTriangle, User as UserIcon, Plus } from 'lucide-react';
import { TaskEditDialog } from '@/components/task-edit-dialog';
import { toast } from 'sonner';
import { fetchApi } from '@/lib/api-client';
interface TaskWithRelations extends Task {
steps: TaskStep[];
@@ -41,7 +42,7 @@ export default function MyTasksPage() {
? '/api/tasks'
: `/api/tasks?user_id=${currentUser?.id}&include_help=true`;
const res = await fetch(url);
const res = await fetchApi(url);
if (res.ok) {
const data = await res.json();
// Enrich with owner info locally since API doesn't join
@@ -61,7 +62,7 @@ export default function MyTasksPage() {
const fetchHelpSteps = async () => {
if (!currentUser?.id || currentUser.role === 'owner') return;
try {
const res = await fetch(`/api/task-steps?help_requested_to_user_id=${currentUser.id}`);
const res = await fetchApi(`/api/task-steps?help_requested_to_user_id=${currentUser.id}`);
if (res.ok) {
const data = await res.json();
setHelpSteps(data);
@@ -80,7 +81,7 @@ export default function MyTasksPage() {
const handleTaskStatusChange = async (taskId: string, newStatus: string) => {
try {
const res = await fetch(`/api/tasks/${taskId}`, {
const res = await fetchApi(`/api/tasks/${taskId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: newStatus }),

View File

@@ -19,6 +19,7 @@ import {
AlertCircle,
HandHelping,
} from 'lucide-react';
import { fetchApi } from '@/lib/api-client';
interface ProjectWithRelations extends Project {
owner: User | null;
@@ -40,8 +41,8 @@ export default function DashboardPage() {
async function fetchData() {
try {
const [projectsRes, krsRes] = await Promise.all([
fetch('/api/projects'),
fetch('/api/krs'),
fetchApi('/api/projects'),
fetchApi('/api/krs'),
]);
if (projectsRes.ok) {

View File

@@ -35,6 +35,7 @@ import {
User as UserIcon,
} from 'lucide-react';
import { TaskEditDialog } from '@/components/task-edit-dialog';
import { fetchApi } from '@/lib/api-client';
interface ProjectWithRelations extends Project {
owner: User | null;
@@ -100,10 +101,10 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
const fetchData = useCallback(async () => {
try {
const [projectRes, objectivesRes, krsRes, tasksRes] = await Promise.all([
fetch(`/api/projects/${projectId}`),
fetch(`/api/objectives?project_id=${projectId}`),
fetch(`/api/krs?project_id=${projectId}`),
fetch(`/api/tasks?project_id=${projectId}`),
fetchApi(`/api/projects/${projectId}`),
fetchApi(`/api/objectives?project_id=${projectId}`),
fetchApi(`/api/krs?project_id=${projectId}`),
fetchApi(`/api/tasks?project_id=${projectId}`),
]);
if (projectRes.status === 403) {
@@ -156,7 +157,7 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
const handleDeleteProject = async () => {
setIsDeleting(true);
try {
const res = await fetch(`/api/projects/${projectId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/projects/${projectId}`, { method: 'DELETE' });
if (!res.ok) throw new Error('删除失败');
toast.success('项目已删除');
router.push('/projects');
@@ -172,7 +173,7 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
setIsEditing(true);
try {
const res = await fetch(`/api/projects/${projectId}`, {
const res = await fetchApi(`/api/projects/${projectId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(editForm),
@@ -199,7 +200,7 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
if (!deleteObjectiveId) return;
setIsDeletingObjective(true);
try {
const res = await fetch(`/api/objectives/${deleteObjectiveId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/objectives/${deleteObjectiveId}`, { method: 'DELETE' });
if (!res.ok) throw new Error('删除失败');
toast.success('目标已删除');
fetchData();
@@ -220,7 +221,7 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
const formData = new FormData(e.currentTarget);
try {
const res = await fetch(`/api/objectives/${editingObjective.id}`, {
const res = await fetchApi(`/api/objectives/${editingObjective.id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -246,7 +247,7 @@ export default function ProjectDetailPage({ projectId }: { projectId: string })
const handleTaskStatusChange = async (taskId: string, newStatus: string) => {
try {
const res = await fetch(`/api/tasks/${taskId}`, {
const res = await fetchApi(`/api/tasks/${taskId}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: newStatus }),

View File

@@ -18,6 +18,7 @@ import { PERIOD_TYPES, DIRECTION_LABELS } from '@/lib/constants';
import type { Objective, Metric, Template } from '@/types/database';
import { ArrowLeft, Loader2 } from 'lucide-react';
import { getErrorMessage } from '@/lib/error-utils';
import { fetchApi } from '@/lib/api-client';
const formSchema = z.object({
title: z.string().min(1, 'KR标题不能为空'),
@@ -72,9 +73,9 @@ export default function NewKRPage() {
useEffect(() => {
async function fetchData() {
const [objRes, metricsRes, templatesRes] = await Promise.all([
fetch(`/api/objectives?project_id=${projectId}`),
fetch('/api/metrics?active_only=true'),
fetch('/api/templates?active_only=true'),
fetchApi(`/api/objectives?project_id=${projectId}`),
fetchApi('/api/metrics?active_only=true'),
fetchApi('/api/templates?active_only=true'),
]);
if (objRes.ok) {
@@ -156,7 +157,7 @@ export default function NewKRPage() {
setIsSubmitting(true);
try {
const res = await fetch('/api/krs', {
const res = await fetchApi('/api/krs', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({

View File

@@ -15,6 +15,7 @@ import { useUser } from '@/components/user-context';
import { toast } from 'sonner';
import { ArrowLeft, Loader2 } from 'lucide-react';
import { getErrorMessage } from '@/lib/error-utils';
import { fetchApi } from '@/lib/api-client';
const formSchema = z.object({
title: z.string().min(1, '目标标题不能为空'),
@@ -54,7 +55,7 @@ export default function NewObjectivePage() {
setIsSubmitting(true);
try {
const res = await fetch('/api/objectives', {
const res = await fetchApi('/api/objectives', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({

View File

@@ -18,6 +18,7 @@ import { toast } from 'sonner';
import type { User } from '@/types/database';
import { ArrowLeft, Loader2 } from 'lucide-react';
import { getErrorMessage } from '@/lib/error-utils';
import { fetchApi } from '@/lib/api-client';
const formSchema = z.object({
name: z.string().min(1, '项目名称不能为空'),
@@ -48,12 +49,12 @@ export default function NewProjectPage() {
const onSubmit = async (values: FormValues) => {
setIsSubmitting(true);
try {
const res = await fetch('/api/projects', {
const res = await fetchApi('/api/projects', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
...values,
owner_id: currentUser?.id,
created_by: currentUser?.id,
}),
});

View File

@@ -8,6 +8,7 @@ import { StatusBadge, StatusDot } from '@/components/status-badge';
import { useUser } from '@/components/user-context';
import type { Project, User } from '@/types/database';
import { Plus, Users, Target, ArrowRight } from 'lucide-react';
import { fetchApi } from '@/lib/api-client';
interface ProjectWithRelations extends Project {
owner: User | null;
@@ -22,7 +23,7 @@ export default function ProjectsPage() {
useEffect(() => {
async function fetchProjects() {
try {
const res = await fetch('/api/projects');
const res = await fetchApi('/api/projects');
if (res.ok) {
const data = await res.json();
setProjects(data);

View File

@@ -4,6 +4,7 @@ import { useState } from 'react';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Target, Loader2, Sparkles, CheckCircle } from 'lucide-react';
import { fetchApi } from '@/lib/api-client';
interface InitWizardProps {
onComplete: () => void;
@@ -19,7 +20,7 @@ export function InitWizard({ onComplete }: InitWizardProps) {
setError(null);
try {
const res = await fetch('/api/seed', { method: 'POST' });
const res = await fetchApi('/api/seed', { method: 'POST' });
const data = await res.json();
if (!res.ok) {

View File

@@ -30,6 +30,7 @@ import {
AlertDialogTitle,
AlertDialogTrigger,
} from '@/components/ui/alert-dialog';
import { fetchApi } from '@/lib/api-client';
const taskSchema = z.object({
title: z.string().min(1, '计划标题不能为空'),
@@ -145,7 +146,7 @@ export function TaskEditDialog({
const url = task ? `/api/tasks/${task.id}` : '/api/tasks';
const method = task ? 'PATCH' : 'POST';
const taskRes = await fetch(url, {
const taskRes = await fetchApi(url, {
method,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -193,7 +194,7 @@ export function TaskEditDialog({
const localSteps = steps.filter(s => s.id.startsWith('temp-'));
if (localSteps.length > 0) {
await Promise.all(localSteps.map(step =>
fetch('/api/task-steps', {
fetchApi('/api/task-steps', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -223,7 +224,7 @@ export function TaskEditDialog({
try {
setIsDeletingTask(true);
await fetch(`/api/tasks/${task.id}`, { method: 'DELETE' });
await fetchApi(`/api/tasks/${task.id}`, { method: 'DELETE' });
toast.success('计划已删除');
onSuccess();
onOpenChange(false);
@@ -241,7 +242,7 @@ export function TaskEditDialog({
// If task exists, save step to DB immediately
if (task) {
try {
const res = await fetch('/api/task-steps', {
const res = await fetchApi('/api/task-steps', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -295,7 +296,7 @@ export function TaskEditDialog({
}
try {
const res = await fetch('/api/task-steps', {
const res = await fetchApi('/api/task-steps', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
@@ -320,7 +321,7 @@ export function TaskEditDialog({
}
try {
const res = await fetch(`/api/task-steps?id=${stepId}`, { method: 'DELETE' });
const res = await fetchApi(`/api/task-steps?id=${stepId}`, { method: 'DELETE' });
if (res.ok) {
setSteps(steps.filter(s => s.id !== stepId));
}

View File

@@ -2,6 +2,7 @@
import { createContext, useContext, useState, useEffect, useCallback, ReactNode } from 'react';
import type { User } from '@/types/database';
import { fetchApi } from '@/lib/api-client';
interface UserContextType {
currentUser: User | null;
@@ -26,7 +27,7 @@ export function UserProvider({ children }: { children: ReactNode }) {
const refreshUsers = useCallback(async () => {
try {
const res = await fetch('/api/users');
const res = await fetchApi('/api/users');
if (res.ok) {
const data = await res.json();
setUsers(data);
@@ -40,7 +41,7 @@ export function UserProvider({ children }: { children: ReactNode }) {
const refreshMe = useCallback(async () => {
try {
const meRes = await fetch('/api/auth/me', { cache: 'no-store' });
const meRes = await fetchApi('/api/auth/me', { cache: 'no-store' });
const meData = await meRes.json().catch(() => ({}));
const me = meData?.user as User | null | undefined;
@@ -109,7 +110,7 @@ export function UserProvider({ children }: { children: ReactNode }) {
setCurrentUser(null);
setIsAuthenticated(false);
setUsers([]);
fetch('/api/auth/logout', { method: 'POST' }).catch(() => {});
fetchApi('/api/auth/logout', { method: 'POST' }).catch(() => {});
}, []);
return (

22
lib/api-client.ts Normal file
View File

@@ -0,0 +1,22 @@
// 必须与 next.config.js 中的 basePath 保持一致
const BASE_PATH = '/ok-r';
/**
* 获取带 basePath 的完整 API URL
* @param path API 路径,例如 '/api/users'
*/
export function getApiUrl(path: string) {
if (path.startsWith('http')) return path;
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
return `${BASE_PATH}${normalizedPath}`;
}
/**
* 封装 fetch 请求,自动处理 basePath
* @param path API 路径,例如 '/api/users'
* @param init fetch 配置项
*/
export async function fetchApi(path: string, init?: RequestInit) {
const url = getApiUrl(path);
return fetch(url, init);
}

View File

@@ -1,6 +1,5 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'standalone', // 输出独立的目录
basePath: '/ok-r', // 部署到子路径时需要设置
eslint: {
ignoreDuringBuilds: true,

View File

@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -19,9 +23,19 @@
}
],
"paths": {
"@/*": ["./*"]
"@/*": [
"./*"
]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"dist/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}