Skip to content

Commit

Permalink
Prepare linter and TypeScript for docs. (#6804)
Browse files Browse the repository at this point in the history
### Description

For ESLint, this is just a setup PR that caps the number of warnings
we're willing to accept.

For TypeScript, I unfortunately need to fix a whole mess of errors to
make ESLint run. Rather than fix all the errors, I'm just throwing down
a bunch of any's to keep the PR small.

CLOSES TURBO-1941

---------

Co-authored-by: Josh Goldberg ✨ <git@joshuakgoldberg.com>
  • Loading branch information
anthonyshew and JoshuaKGoldberg committed Dec 16, 2023
1 parent 6bc7001 commit b9d62e6
Show file tree
Hide file tree
Showing 29 changed files with 270 additions and 339 deletions.
16 changes: 16 additions & 0 deletions docs/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
/** @type {import("eslint").Linter.Config} */
module.exports = {
root: true,
extends: ["@turbo/eslint-config/next"],
parser: "@typescript-eslint/parser",
parserOptions: {
project: true,
},
ignorePatterns: [
// Ignore dotfiles
".*.js",
],
rules: {
// Most of these rules should probably be on. Turning them off because they fail in many places
// and we need to set aside time to make them work.
"no-nested-ternary": "warn",
"no-await-in-loop": "warn",
"prefer-named-capture-group": "warn",
"@typescript-eslint/consistent-type-definitions": "warn",
"@typescript-eslint/no-unsafe-member-access": "warn",
"@typescript-eslint/no-non-null-assertion": "warn",
"@typescript-eslint/no-explicit-any": "warn",
"@typescript-eslint/no-floating-promises": "warn",
"@typescript-eslint/no-implied-eval": "warn",
Expand Down
6 changes: 3 additions & 3 deletions docs/components/ExamplesArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@ export function ExamplesArea({
.filter(({ featured }) => (filter === "featured" ? featured : true))
.sort((a, b) => a.name.localeCompare(b.name));

const withBoost = [];
const withTemplate = [];
const withoutTemplate = [];
const withBoost: Example[] = [];
const withTemplate: Example[] = [];
const withoutTemplate: Example[] = [];
sortedExamples.forEach((e) => {
if (e.boost) {
withBoost.push(e);
Expand Down
2 changes: 2 additions & 0 deletions docs/components/ExtraContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,6 @@ export default function ExtraContent() {
if (site === "repo") {
return <RemoteCacheCounter />;
}

return null;
}
2 changes: 1 addition & 1 deletion docs/components/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ export function FooterContent() {
<div className="mt-12 md:!mt-0">
<FooterHeader>Company</FooterHeader>
<ul className="mt-4 space-y-1.5 list-none ml-0" role="list">
{navigation.company(site).map((item) => (
{navigation.company(site!).map((item) => (
<li key={item.name}>
<FooterLink href={item.href}>{item.name}</FooterLink>
</li>
Expand Down
11 changes: 6 additions & 5 deletions docs/components/LogoContext/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ function MenuItem({
if (type === "copy") {
setCopied(true);
} else {
closeMenu();
closeMenu?.();
}
};

useEffect(() => {
if (copied) {
const timeout = setTimeout(() => {
setCopied(false);
closeMenu();
closeMenu?.();
}, 2000);
return () => {
clearTimeout(timeout);
Expand All @@ -63,7 +63,7 @@ function MenuItem({
);
if (type === "internal") {
return (
<Link className={classes} href={href} onClick={handleClick} {...other}>
<Link className={classes} href={href!} onClick={handleClick} {...other}>
{prefix}
{children}
</Link>
Expand Down Expand Up @@ -98,12 +98,13 @@ function MenuItem({
</button>
);
}
return null;
}

export function LogoContext() {
const [open, setOpen] = useState(false);
const site = useTurboSite();
const menu = useRef(null);
const site = useTurboSite()!;
const menu = useRef<any>(null);
const { theme = "dark" } = useTheme();

const toggleMenu = (e: MouseEvent<HTMLButtonElement>) => {
Expand Down
2 changes: 1 addition & 1 deletion docs/components/Tabs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const Tabs: FC<{
// Use SWR so all tabs with the same key can sync their states.
const { data, mutate } = useSWR(storageKey, (key) => {
try {
return JSON.parse(localStorage.getItem(key));
return JSON.parse(localStorage.getItem(key)!);
} catch (e) {
return null;
}
Expand Down
2 changes: 1 addition & 1 deletion docs/components/blog/Date.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { ReactNode } from "react";

function Date({
children,
update = null,
update = undefined,
}: {
children: ReactNode;
update?: string;
Expand Down
9 changes: 5 additions & 4 deletions docs/components/clients/Clients.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { ReactElement } from "react";
import React from "react";
import cn from "classnames";
import { users } from "./users";
Expand All @@ -12,8 +13,8 @@ export function Clients({
staticWidth?: boolean;
companyList?: string[];
}) {
const showcaseDark = [];
const showcaseLight = [];
const showcaseDark: ReactElement[] = [];
const showcaseLight: ReactElement[] = [];

function LogoWrapper({ className, children }) {
if (!staticWidth) return children;
Expand All @@ -38,15 +39,15 @@ export function Clients({
className="flex dark:hidden"
key={`${user.caption}-dark`}
>
<Logo isLink={linked} theme="dark" user={user} />
<Logo isLink={linked ?? false} theme="dark" user={user} />
</LogoWrapper>
);
showcaseLight.push(
<LogoWrapper
className="hidden dark:flex"
key={`${user.caption}-light`}
>
<Logo isLink={linked} theme="light" user={user} />
<Logo isLink={linked ?? false} theme="light" user={user} />
</LogoWrapper>
);
}
Expand Down
4 changes: 2 additions & 2 deletions docs/components/clients/Logo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ export function Logo({
"hidden dark:inline": theme !== "dark",
"dark:hidden inline": theme === "dark",
})}
height={numericHeight}
height={numericHeight!}
priority
src={user.image.replace(
"/logos",
theme === "light" ? "/logos/white" : "/logos/color"
)}
style={styles}
width={numericWidth}
width={numericWidth!}
/>
);

Expand Down
6 changes: 3 additions & 3 deletions docs/components/image/ThemedImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ interface ImageAttrs {
}

export interface ThemedImageProps {
title?: string;
dark?: ImageAttrs;
light?: ImageAttrs;
title: string;
dark: ImageAttrs;
light: ImageAttrs;
priority?: boolean;
}

Expand Down
2 changes: 1 addition & 1 deletion docs/components/pages/pack-home/PackBenchmarksGraph.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ function GraphTimer({
timer,
duration,
}: {
turbo: boolean;
turbo?: boolean;
timer: number;
duration: number;
}) {
Expand Down
6 changes: 3 additions & 3 deletions docs/content/features.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,15 @@ import BeakerIconLight from "../public/images/docs/shared/feature-icons/beaker-l

type NextImageSrc = Parameters<typeof Image>[0]["src"];

export type Feature = {
export interface Feature {
name: string;
description: string;
iconDark: NextImageSrc;
iconLight: NextImageSrc;
page: "all" | "home" | "docs";
};
}

export type Features = Array<Feature>;
export type Features = Feature[];

const REPO_FEATURES: Features = [
{
Expand Down
10 changes: 5 additions & 5 deletions docs/content/legacy-features.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Remove when docs is refactored to use the new icons (see ./features.ts)

import React from "react";
import type React from "react";
import {
ArrowsExpandIcon,
BeakerIcon,
Expand All @@ -12,16 +12,16 @@ import {
LightningBoltIcon,
RefreshIcon,
} from "@heroicons/react/outline";
import { IconType } from "../components/Icons";
import type { IconType } from "../components/Icons";

export type Feature = {
export interface Feature {
name: string;
description: React.ReactNode;
Icon: IconType;
page: "all" | "home" | "docs";
};
}

export type Features = Array<Feature>;
export type Features = Feature[];

const LEGACY_REPO_FEATURES: Features = [
{
Expand Down
5 changes: 4 additions & 1 deletion docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"dev": "next",
"start": "next start",
"build": "next build ",
"lint": "next lint",
"lint": "next lint --max-warnings 356",
"check-types": "tsc --noEmit",
"rss": "node scripts/generate-rss.js",
"schema": "turbo-types-generate ./public/schema.json",
Expand Down Expand Up @@ -47,7 +47,10 @@
"@types/node": "^20.10.4",
"@types/react": "^18",
"@types/react-dom": "^18",
"@typescript-eslint/parser": "^6.14.0",
"@typescript-eslint/eslint-plugin": "^6.14.0",
"autoprefixer": "10.4.16",
"eslint": "^8.55.0",
"csstype": "3.1.3",
"gray-matter": "^4.0.3",
"postcss": "8.4.32",
Expand Down
6 changes: 3 additions & 3 deletions docs/pages/api/og.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,16 @@ export default async function openGraphImage(
): Promise<ImageResponse> {
try {
const [fonts, bg] = await loadAssets();
const { searchParams } = new URL(req.url);
const { searchParams } = new URL(req.url!);

const type = searchParams.get("type");
const type = searchParams.get("type")!;

// Start with the default title for the type
let title = TITLE_FOR_TYPE[type];

// If there'sa a ?title=<title> query param, always prefer that.
if (searchParams.has("title")) {
title = searchParams.get("title").slice(0, 100);
title = searchParams.get("title")!.slice(0, 100);
}

return new ImageResponse(createElement(OGImage, { title, type, bg }), {
Expand Down
2 changes: 1 addition & 1 deletion docs/pages/api/signup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
};

try {
await fetch(TRAY_URL, {
await fetch(TRAY_URL!, {
method: "POST",
headers: {
"Content-Type": "application/json",
Expand Down
9 changes: 4 additions & 5 deletions docs/pages/repo/docs/getting-started/create-new.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ export const Button = ({ children, className, appName }: ButtonProps) => {
};
```

We've found our button!
We've found our button!

Everything inside this file will be able to be used by workspaces that depend on `@repo/ui/button`.
Everything inside this file will be able to be used by workspaces that depend on `@repo/ui/button`.

Any changes we make in this file will be shared across `web` and `docs`. Pretty cool!

Expand All @@ -237,7 +237,7 @@ We have two more workspaces to look at, `typescript-config` and `eslint-config`.
}
```

Here we see the name of the package is `@repo/typescript-config`.
Here we see the name of the package is `@repo/typescript-config`.

New, let's take a look in the `tsconfig.json` file located in our `web` app.

Expand All @@ -247,7 +247,7 @@ New, let's take a look in the `tsconfig.json` file located in our `web` app.
}
```

As you can see, we're importing `@repo/typescript-config/nextjs.json` directly into our `tsconfig.json` file.
As you can see, we're importing `@repo/typescript-config/nextjs.json` directly into our `tsconfig.json` file.

This pattern allows for a monorepo to share a single `tsconfig.json` across all its workspaces, reducing code duplication.

Expand Down Expand Up @@ -398,7 +398,6 @@ It had saved the logs from the previous run, so it just replayed them.

Let's try changing some code to see what happens. Make a change to a file inside `apps/docs`:


```diff filename="apps/docs/app/page.tsx"
import { Button } from "@repo/ui/button";
// ^^^^^^ ^^^^^^^^^^^^^^^
Expand Down
15 changes: 10 additions & 5 deletions docs/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,26 @@
{
"compilerOptions": {
"plugins": [
{
"name": "next"
}
],
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"skipLibCheck": true,
"strict": false,
"strictNullChecks": true,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "node",
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"allowJs": false,
"types": ["next"]
"allowJs": false
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
"exclude": ["node_modules"]
}
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
"devDependencies": {
"@taplo/cli": "^0.5.2",
"@types/react": "18.2.0",
"eslint": "^8.48.0",
"eslint": "^8.55.0",
"husky": "^8.0.0",
"lint-staged": "^13.1.0",
"next": "^13.0.6",
"npm-run-all": "^4.1.5",
"prettier": "^2.8.7",
"semver": "^7.3.8",
"typescript": "^4.9.4"
"typescript": "5.3.3"
},
"optionalDependencies": {
"rust": "nightly"
Expand Down
2 changes: 1 addition & 1 deletion packages/eslint-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
"version": "0.0.0",
"private": true,
"devDependencies": {
"@vercel/style-guide": "^5.0.0"
"@vercel/style-guide": "^5.1.0"
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 comment on commit b9d62e6

@vercel
Copy link

@vercel vercel bot commented on b9d62e6 Dec 16, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.