refactor: replace relative paths with absolute ones in import statements

This commit is contained in:
zyachel 2023-01-28 22:09:27 +05:30
parent 20418b4c1f
commit 505ff4d839
37 changed files with 153 additions and 183 deletions

View file

@ -1,7 +1,6 @@
import { useContext } from 'react';
import { themeContext } from '../../context/theme-context';
import styles from '../../styles/modules/components/buttons/themeToggler.module.scss';
import { themeContext } from 'src/context/theme-context';
import styles from 'src/styles/modules/components/buttons/themeToggler.module.scss';
type Props = {
className: string;

View file

@ -1,9 +1,8 @@
import { ReactNode } from 'react';
import Link from 'next/link';
import Layout from '../../layouts/Layout';
import Meta from '../meta/Meta';
import styles from '../../styles/modules/components/error/error-info.module.scss';
import Layout from 'src/layouts/Layout';
import Meta from 'src/components/meta/Meta';
import styles from 'src/styles/modules/components/error/error-info.module.scss';
// for details regarding the svg, go to sadgnu.svg file
// description copied verbatim from https://www.gnu.org/graphics/sventsitsky-sadgnu.html

View file

@ -1,7 +1,7 @@
import { Companies } from '../../interfaces/shared/search';
import { Companies } from 'src/interfaces/shared/search';
import Link from 'next/link';
import styles from '../../styles/modules/components/find/company.module.scss';
import styles from 'src/styles/modules/components/find/company.module.scss';
type Props = {
company: Companies[0];

View file

@ -1,7 +1,6 @@
import { Keywords } from '../../interfaces/shared/search';
import Link from 'next/link';
import styles from '../../styles/modules/components/find/keyword.module.scss';
import { Keywords } from 'src/interfaces/shared/search';
import styles from 'src/styles/modules/components/find/keyword.module.scss';
type Props = {
keyword: Keywords[0];

View file

@ -1,8 +1,8 @@
import { People } from '../../interfaces/shared/search';
import Image from 'next/future/image';
import Link from 'next/link';
import { modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/find/person.module.scss';
import { People } from 'src/interfaces/shared/search';
import { modifyIMDbImg } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/find/person.module.scss';
type Props = {
person: People[0];
@ -21,7 +21,7 @@ const Person = ({ person }: Props) => {
/>
) : (
<svg className={styles.imgNA}>
<use href="/svg/sprite.svg#icon-image-slash" />
<use href='/svg/sprite.svg#icon-image-slash' />
</svg>
)}
</div>
@ -32,7 +32,7 @@ const Person = ({ person }: Props) => {
{person.aka && <p>{person.aka}</p>}
{person.jobCateogry && <p>{person.jobCateogry}</p>}
{(person.knownForTitle || person.knownInYear) && (
<ul className={styles.basicInfo} aria-label="quick facts">
<ul className={styles.basicInfo} aria-label='quick facts'>
{person.knownForTitle && <li>{person.knownForTitle}</li>}
{person.knownInYear && <li>{person.knownInYear}</li>}
</ul>

View file

@ -1,9 +1,8 @@
import { Titles } from '../../interfaces/shared/search';
import Image from 'next/future/image';
import Link from 'next/link';
import { modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/find/title.module.scss';
import { Titles } from 'src/interfaces/shared/search';
import { modifyIMDbImg } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/find/title.module.scss';
type Props = {
title: Titles[0];
@ -22,7 +21,7 @@ const Title = ({ title }: Props) => {
/>
) : (
<svg className={styles.imgNA}>
<use href="/svg/sprite.svg#icon-image-slash" />
<use href='/svg/sprite.svg#icon-image-slash' />
</svg>
)}
</div>
@ -30,7 +29,7 @@ const Title = ({ title }: Props) => {
<Link href={`/title/${title.id}`}>
<a className={`heading ${styles.heading}`}>{title.name}</a>
</Link>
<ul aria-label="quick facts" className={styles.basicInfo}>
<ul aria-label='quick facts' className={styles.basicInfo}>
{title.type && <li>{title.type}</li>}
{title.sAndE && <li>{title.sAndE}</li>}
{title.releaseYear && <li>{title.releaseYear}</li>}
@ -42,11 +41,11 @@ const Title = ({ title }: Props) => {
</p>
)}
{title.seriesId && (
<ul aria-label="quick series facts" className={styles.seriesInfo}>
<ul aria-label='quick series facts' className={styles.seriesInfo}>
{title.seriesType && <li>{title.seriesType}</li>}
<li>
<Link href={`/title/${title.seriesId}`}>
<a className="link">{title.seriesName}</a>
<a className='link'>{title.seriesName}</a>
</Link>
</li>
{title.seriesReleaseYear && <li>{title.seriesReleaseYear}</li>}

View file

@ -1,11 +1,10 @@
import Find from '../../interfaces/shared/search';
import Company from './Company';
import Person from './Person';
import Title from './Title';
import styles from '../../styles/modules/components/find/results.module.scss';
import Keyword from './Keyword';
import { getResTitleTypeHeading } from '../../utils/helpers';
import Find from 'src/interfaces/shared/search';
import { getResTitleTypeHeading } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/find/results.module.scss';
type Props = {
results: Find | null;
@ -43,11 +42,11 @@ const Results = ({ results, className, title }: Props) => {
return (
<article className={`${className} ${styles.results}`}>
<h1 className="heading heading__primary">Results for '{title}'</h1>
<h1 className='heading heading__primary'>Results for '{title}'</h1>
<div className={styles.results__list}>
{!!titles.length && (
<section className={styles.titles}>
<h2 className="heading heading__secondary">
<h2 className='heading heading__secondary'>
{titlesSectionHeading}
</h2>
<ul className={styles.titles__list}>
@ -59,7 +58,7 @@ const Results = ({ results, className, title }: Props) => {
)}
{!!people.length && (
<section className={styles.people}>
<h2 className="heading heading__secondary">People</h2>
<h2 className='heading heading__secondary'>People</h2>
<ul className={styles.people__list}>
{people.map(person => (
<Person person={person} key={person.id} />
@ -69,7 +68,7 @@ const Results = ({ results, className, title }: Props) => {
)}
{!!companies.length && (
<section className={styles.people}>
<h2 className="heading heading__secondary">Companies</h2>
<h2 className='heading heading__secondary'>Companies</h2>
<ul className={styles.people__list}>
{companies.map(company => (
<Company company={company} key={company.id} />
@ -79,7 +78,7 @@ const Results = ({ results, className, title }: Props) => {
)}
{!!keywords.length && (
<section className={styles.people}>
<h2 className="heading heading__secondary">Keywords</h2>
<h2 className='heading heading__secondary'>Keywords</h2>
<ul className={styles.people__list}>
{keywords.map(keyword => (
<Keyword keyword={keyword} key={keyword.id} />

View file

@ -1,10 +1,9 @@
import { useRouter } from 'next/router';
import { ChangeEventHandler, FormEventHandler, useRef, useState } from 'react';
import { cleanQueryStr } from '../../../utils/helpers';
import { resultTypes, resultTitleTypes } from '../../../utils/constants/find';
import styles from '../../../styles/modules/components/form/find.module.scss';
import { QueryTypes } from '../../../interfaces/shared/search';
import { useRouter } from 'next/router';
import { cleanQueryStr } from 'src/utils/helpers';
import { QueryTypes } from 'src/interfaces/shared/search';
import { resultTypes, resultTitleTypes } from 'src/utils/constants/find';
import styles from 'src/styles/modules/components/form/find.module.scss';
/**
* helper function to render similar radio btns. saves from boilerplate.
@ -19,11 +18,11 @@ const renderRadioBtns = (
return data.types.map(({ name, val }) => (
<p className={parentClass} key={val}>
<input
type="radio"
type='radio'
name={data.key}
id={`${data.key}:${val}`}
value={val}
className="visually-hidden"
className='visually-hidden'
/>
<label htmlFor={`${data.key}:${val}`}>{name}</label>
</p>
@ -66,30 +65,30 @@ const Form = ({ className }: Props) => {
return (
<form
action="/find"
action='/find'
onSubmit={submitHandler}
ref={formRef}
className={`${className} ${styles.form}`}
>
<p className="heading heading__primary">Search</p>
<p className='heading heading__primary'>Search</p>
<p className={styles.searchbar}>
<svg
className={`icon ${styles.searchbar__icon}`}
focusable="false"
aria-hidden="true"
role="img"
focusable='false'
aria-hidden='true'
role='img'
>
<use href="/svg/sprite.svg#icon-search"></use>
<use href='/svg/sprite.svg#icon-search'></use>
</svg>
<input
id="searchbar"
type="search"
name="q"
placeholder="movies, people..."
id='searchbar'
type='search'
name='q'
placeholder='movies, people...'
className={styles.searchbar__input}
/>
<label className="visually-hidden" htmlFor="searchbar">
<label className='visually-hidden' htmlFor='searchbar'>
Search for anything
</label>
</p>
@ -106,14 +105,14 @@ const Form = ({ className }: Props) => {
{renderRadioBtns(resultTitleTypes, styles.titleType)}
</fieldset>
<p className={styles.exact}>
<label htmlFor="exact">Exact Matches</label>
<input type="checkbox" name="exact" id="exact" value="true" />
<label htmlFor='exact'>Exact Matches</label>
<input type='checkbox' name='exact' id='exact' value='true' />
</p>
<div className={styles.buttons}>
<button type="reset" className={styles.button}>
<button type='reset' className={styles.button}>
Clear
</button>
<button type="submit" className={styles.button}>
<button type='submit' className={styles.button}>
Submit
</button>
</div>

View file

@ -1,4 +1,4 @@
import styles from '../../styles/modules/components/loaders/progress-bar.module.scss';
import styles from 'src/styles/modules/components/loaders/progress-bar.module.scss';
const ProgressBar = () => {
return <span className={styles.progress} role='progressbar'></span>;

View file

@ -1,15 +1,14 @@
import { Fragment } from 'react';
import Image from 'next/future/image';
import Link from 'next/link';
import { Basic } from 'src/interfaces/shared/title';
import {
formatNumber,
formatTime,
getProxiedIMDbImgUrl,
modifyIMDbImg,
} from '../../utils/helpers';
import { Basic } from '../../interfaces/shared/title';
import styles from '../../styles/modules/components/title/basic.module.scss';
} from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/basic.module.scss';
type Props = {
className: string;

View file

@ -1,9 +1,8 @@
import Image from 'next/future/image';
import Link from 'next/link';
import { Cast } from '../../interfaces/shared/title';
import { modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/cast.module.scss';
import { Cast } from 'src/interfaces/shared/title';
import { modifyIMDbImg } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/cast.module.scss';
type Props = {
className: string;

View file

@ -1,7 +1,6 @@
import Link from 'next/link';
import { Fragment } from 'react';
import { DidYouKnow } from '../../interfaces/shared/title';
import styles from '../../styles/modules/components/title/did-you-know.module.scss';
import { DidYouKnow } from 'src/interfaces/shared/title';
import styles from 'src/styles/modules/components/title/did-you-know.module.scss';
type Props = {
data: DidYouKnow;

View file

@ -1,9 +1,8 @@
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Info } from '../../interfaces/shared/title';
import { formatMoney, formatTime } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/info.module.scss';
import { Info } from 'src/interfaces/shared/title';
import { formatMoney, formatTime } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/info.module.scss';
type Props = {
info: Info;

View file

@ -1,9 +1,8 @@
import Image from 'next/future/image';
import Link from 'next/link';
import { Media } from '../../interfaces/shared/title';
import { getProxiedIMDbImgUrl, modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/media.module.scss';
import { Media } from 'src/interfaces/shared/title';
import { getProxiedIMDbImgUrl, modifyIMDbImg } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/media.module.scss';
type Props = {
className: string;

View file

@ -1,8 +1,8 @@
import Image from 'next/future/image';
import Link from 'next/link';
import { MoreLikeThis } from '../../interfaces/shared/title';
import { formatNumber, modifyIMDbImg } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/more-like-this.module.scss';
import { MoreLikeThis } from 'src/interfaces/shared/title';
import { formatNumber, modifyIMDbImg } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/more-like-this.module.scss';
type Props = {
className: string;

View file

@ -1,8 +1,8 @@
import { useRouter } from 'next/router';
import Link from 'next/link';
import { Reviews } from '../../interfaces/shared/title';
import { formatNumber } from '../../utils/helpers';
import styles from '../../styles/modules/components/title/reviews.module.scss';
import { Reviews } from 'src/interfaces/shared/title';
import { formatNumber } from 'src/utils/helpers';
import styles from 'src/styles/modules/components/title/reviews.module.scss';
type Props = {
reviews: Reviews;

View file

@ -1,5 +1,5 @@
import React, { useState, createContext, ReactNode } from 'react';
import { isLocalStorageAvailable } from '../utils/helpers';
import { isLocalStorageAvailable } from 'src/utils/helpers';
const getInitialTheme = () => {
// for server-side rendering, as window isn't availabe there

View file

@ -1,4 +1,7 @@
import { ResultMetaTitleTypes, ResultMetaTypes } from '../shared/search';
import {
ResultMetaTitleTypes,
ResultMetaTypes,
} from 'src/interfaces/shared/search';
export default interface RawFind {
props: {

View file

@ -1,5 +1,5 @@
import cleanFind from '../../utils/cleaners/find';
import { resultTitleTypes, resultTypes } from '../../utils/constants/find';
import cleanFind from 'src/utils/cleaners/find';
import { resultTitleTypes, resultTypes } from 'src/utils/constants/find';
type BasicSearch = ReturnType<typeof cleanFind>;
export type { BasicSearch as default };

View file

@ -1,5 +1,5 @@
import cleanTitle from '../../utils/cleaners/title';
import title from '../../utils/fetchers/title';
import cleanTitle from 'src/utils/cleaners/title';
import title from 'src/utils/fetchers/title';
export type AxiosTitleRes = Awaited<ReturnType<typeof title>>;

View file

@ -1,10 +1,8 @@
import { FC } from 'react';
import Link from 'next/link';
import { useRouter } from 'next/router';
import styles from '../styles/modules/layout/footer.module.scss';
const Footer: FC = () => {
const Footer = () => {
const { pathname } = useRouter();
const className = (link: string) =>
pathname === link ? styles.nav__linkActive : styles.nav__link;

View file

@ -1,9 +1,8 @@
import { ReactNode } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import ThemeToggler from '../components/buttons/ThemeToggler';
import styles from '../styles/modules/layout/header.module.scss';
import ThemeToggler from 'src/components/buttons/ThemeToggler';
import styles from 'src/styles/modules/layout/header.module.scss';
type Props = { full?: boolean; children?: ReactNode };

View file

@ -1,4 +1,4 @@
import ErrorInfo from '../components/error/ErrorInfo';
import ErrorInfo from 'src/components/error/ErrorInfo';
const Error404 = () => {
return <ErrorInfo message='Not found, sorry.' statusCode={404} />;

View file

@ -1,4 +1,4 @@
import ErrorInfo from '../components/error/ErrorInfo';
import ErrorInfo from 'src/components/error/ErrorInfo';
const Error500 = () => {
return <ErrorInfo message='Server messed up, sorry.' statusCode={500} />;

View file

@ -1,10 +1,9 @@
import type { AppProps } from 'next/app';
import usePageLoading from '../hooks/usePageLoading';
import ProgressBar from '../components/loaders/ProgressBar';
import ErrorBoundary from '../components/error/ErrorBoundary';
import ThemeProvider from '../context/theme-context';
import '../styles/main.scss';
import { AppProps } from 'next/app';
import ProgressBar from 'src/components/loaders/ProgressBar';
import ErrorBoundary from 'src/components/error/ErrorBoundary';
import ThemeProvider from 'src/context/theme-context';
import usePageLoading from 'src/hooks/usePageLoading';
import 'src/styles/main.scss';
const ModifiedApp = ({ Component, pageProps }: AppProps) => {
const { isPageLoading, key } = usePageLoading();

View file

@ -1,9 +1,7 @@
/* eslint-disable react/no-unescaped-entities */
import Link from 'next/link';
import Meta from '../../components/meta/Meta';
import Layout from '../../layouts/Layout';
import styles from '../../styles/modules/pages/about/about.module.scss';
import Meta from 'src/components/meta/Meta';
import Layout from 'src/layouts/Layout';
import styles from 'src/styles/modules/pages/about/about.module.scss';
const About = () => {
return (

View file

@ -1,6 +1,6 @@
import { NextApiRequest, NextApiResponse } from 'next';
import redis from '../../utils/redis';
import axiosInstance from '../../utils/axiosInstance';
import redis from 'src/utils/redis';
import axiosInstance from 'src/utils/axiosInstance';
const getCleanReqHeaders = (headers: NextApiRequest['headers']) => ({
...(headers.accept && { accept: headers.accept }),

View file

@ -1,7 +1,6 @@
import Meta from '../../components/meta/Meta';
import Layout from '../../layouts/Layout';
import styles from '../../styles/modules/pages/contact/contact.module.scss';
import Meta from 'src/components/meta/Meta';
import Layout from 'src/layouts/Layout';
import styles from 'src/styles/modules/pages/contact/contact.module.scss';
const Contact = () => {
return (

View file

@ -1,17 +1,14 @@
import { GetServerSideProps } from 'next';
import Layout from '../../layouts/Layout';
import ErrorInfo from '../../components/error/ErrorInfo';
import Meta from '../../components/meta/Meta';
import Results from '../../components/find';
import basicSearch from '../../utils/fetchers/basicSearch';
import Form from '../../components/forms/find';
import Find, { FindQueryParams } from '../../interfaces/shared/search';
import { AppError } from '../../interfaces/shared/error';
import { cleanQueryStr } from '../../utils/helpers';
import styles from '../../styles/modules/pages/find/find.module.scss';
import Layout from 'src/layouts/Layout';
import ErrorInfo from 'src/components/error/ErrorInfo';
import Meta from 'src/components/meta/Meta';
import Results from 'src/components/find';
import Form from 'src/components/forms/find';
import Find, { FindQueryParams } from 'src/interfaces/shared/search';
import { AppError } from 'src/interfaces/shared/error';
import basicSearch from 'src/utils/fetchers/basicSearch';
import { cleanQueryStr } from 'src/utils/helpers';
import styles from 'src/styles/modules/pages/find/find.module.scss';
type Props =
| { data: { title: string; results: Find }; error: null }

View file

@ -1,7 +1,7 @@
import Meta from '../../components/meta/Meta';
import Layout from '../../layouts/Layout';
import packageInfo from '../../../package.json';
import styles from '../../styles/modules/pages/privacy/privacy.module.scss';
import Meta from 'src/components/meta/Meta';
import Layout from 'src/layouts/Layout';
import packageInfo from 'src/../package.json';
import styles from 'src/styles/modules/pages/privacy/privacy.module.scss';
const Privacy = () => {
return (

View file

@ -1,27 +1,16 @@
// external
import { GetServerSideProps, GetStaticProps, GetStaticPaths } from 'next'
import { GetServerSideProps, GetStaticProps, GetStaticPaths } from 'next';
import Head from 'next/head';
import { useRouter } from 'next/router';
// local
import Meta from '../../../components/meta/Meta';
import Layout from '../../../layouts/Layout';
import ErrorInfo from '../../../components/error/ErrorInfo';
import {
Basic,
Cast,
DidYouKnow,
Info,
Media,
MoreLikeThis,
Reviews,
} from '../../../components/title';
// misc
import Title from '../../../interfaces/shared/title';
import { AppError } from '../../../interfaces/shared/error';
import title from '../../../utils/fetchers/title';
import { getProxiedIMDbImgUrl } from '../../../utils/helpers';
// styles
import styles from '../../../styles/modules/pages/title/title.module.scss';
import Meta from 'src/components/meta/Meta';
import Layout from 'src/layouts/Layout';
import ErrorInfo from 'src/components/error/ErrorInfo';
// prettier-ignore
import { Basic, Cast, DidYouKnow, Info, Media, MoreLikeThis, Reviews } from 'src/components/title';
import Title from 'src/interfaces/shared/title';
import { AppError } from 'src/interfaces/shared/error';
import title from 'src/utils/fetchers/title';
import { getProxiedIMDbImgUrl } from 'src/utils/helpers';
import styles from 'src/styles/modules/pages/title/title.module.scss';
type Props = { data: Title; error: null } | { error: AppError; data: null };
@ -49,7 +38,7 @@ const TitleInfo = ({ data, error }: Props) => {
/>
<Head>
<meta
title="og:image"
title='og:image'
content={
data.basic.poster?.url
? getProxiedIMDbImgUrl(data.basic.poster?.url)
@ -73,23 +62,23 @@ const TitleInfo = ({ data, error }: Props) => {
};
// TO-DO: make a getServerSideProps wrapper for handling errors
export const getServerSideProps: GetServerSideProps = async (ctx) => {
const titleId = ctx.params!.titleId as string
export const getServerSideProps: GetServerSideProps = async ctx => {
const titleId = ctx.params!.titleId as string;
try {
const data = await title(titleId)
const data = await title(titleId);
return { props: { data, error: null } }
return { props: { data, error: null } };
} catch (error: any) {
const { message, statusCode } = error
ctx.res.statusCode = statusCode
ctx.res.statusMessage = message
const { message, statusCode } = error;
ctx.res.statusCode = statusCode;
ctx.res.statusMessage = message;
return { props: { error: { message, statusCode }, data: null } }
}
return { props: { error: { message, statusCode }, data: null } };
}
};
export default TitleInfo
export default TitleInfo;
// could've used getStaticProps instead of getServerSideProps, but meh.
/*

View file

@ -1,4 +1,4 @@
import RawFind from '../../interfaces/misc/rawFind';
import RawFind from 'src/interfaces/misc/rawFind';
const formatSAndE = (
season: string | undefined,

View file

@ -1,5 +1,5 @@
import RawTitle from '../../interfaces/misc/rawTitle';
import { formatDate } from '../helpers';
import RawTitle from 'src/interfaces/misc/rawTitle';
import { formatDate } from 'src/utils/helpers';
const cleanTitle = (rawData: RawTitle) => {
const {

View file

@ -1,10 +1,8 @@
// external deps
import * as cheerio from 'cheerio';
// local files
import axiosInstance from '../axiosInstance';
import { AppError } from '../helpers';
import RawFind from '../../interfaces/misc/rawFind';
import cleanFind from '../cleaners/find';
import RawFind from 'src/interfaces/misc/rawFind';
import axiosInstance from 'src/utils/axiosInstance';
import { AppError } from 'src/utils/helpers';
import cleanFind from 'src/utils/cleaners/find';
const basicSearch = async (queryStr: string) => {
try {

View file

@ -1,11 +1,8 @@
// external deps
import * as cheerio from 'cheerio';
// local files
import axiosInstance from '../axiosInstance';
import cleanTitle from '../cleaners/title';
import { AppError } from '../helpers';
// interfaces
import RawTitle from '../../interfaces/misc/rawTitle';
import RawTitle from 'src/interfaces/misc/rawTitle';
import axiosInstance from 'src/utils/axiosInstance';
import cleanTitle from 'src/utils/cleaners/title';
import { AppError } from 'src/utils/helpers';
const title = async (titleId: string) => {
try {

View file

@ -1,7 +1,7 @@
import {
ResultMetaTitleTypes,
ResultMetaTypes,
} from '../interfaces/shared/search';
} from 'src/interfaces/shared/search';
import { resultTitleTypes } from './constants/find';
export const formatTime = (timeInSecs: number) => {

View file

@ -13,7 +13,11 @@
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true
"incremental": true,
"baseUrl": ".",
"paths": {
"src": ["src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"exclude": ["node_modules", "dev"]