Skip to content

Commit a4630d6

Browse files
Fix type issues
1 parent ce00bfe commit a4630d6

File tree

6 files changed

+118
-62
lines changed

6 files changed

+118
-62
lines changed

src/plugins/next-mocks/alias/cache/index.ts

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,25 @@
11
import { fn } from "@storybook/test";
2+
import type { Mock } from "vitest";
23

34
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
45
type Callback = (...args: any[]) => Promise<any>;
56

7+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
8+
type Procedure = (...args: any[]) => any;
9+
610
// mock utilities/overrides (as of Next v14.2.0)
7-
const revalidatePath = fn().mockName("next/cache::revalidatePath");
8-
const revalidateTag = fn().mockName("next/cache::revalidateTag");
9-
const unstable_cache = fn()
11+
const revalidatePath: Mock<Procedure> = fn().mockName(
12+
"next/cache::revalidatePath",
13+
);
14+
const revalidateTag: Mock<Procedure> = fn().mockName(
15+
"next/cache::revalidateTag",
16+
);
17+
const unstable_cache: Mock<Procedure> = fn()
1018
.mockName("next/cache::unstable_cache")
1119
.mockImplementation((cb: Callback) => cb);
12-
const unstable_noStore = fn().mockName("next/cache::unstable_noStore");
20+
const unstable_noStore: Mock<Procedure> = fn().mockName(
21+
"next/cache::unstable_noStore",
22+
);
1323

1424
const cacheExports = {
1525
unstable_cache,
@@ -19,4 +29,3 @@ const cacheExports = {
1929
};
2030

2131
export default cacheExports;
22-
export { unstable_cache, revalidateTag, revalidatePath, unstable_noStore };

src/plugins/next-mocks/alias/headers/cookies.ts

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,36 @@
11
import { fn } from "@storybook/test";
2-
import { RequestCookies } from "next/dist/compiled/@edge-runtime/cookies/index.js";
2+
import {
3+
type RequestCookie,
4+
RequestCookies,
5+
} from "next/dist/compiled/@edge-runtime/cookies/index.js";
6+
import type { Mock } from "vitest";
37
import { headers } from "./index.js";
48

59
class RequestCookiesMock extends RequestCookies {
6-
get = fn(super.get.bind(this)).mockName("next/headers::cookies().get");
10+
get: Mock<
11+
(...args: [name: string] | [RequestCookie]) => RequestCookie | undefined
12+
> = fn(super.get.bind(this)).mockName("next/headers::cookies().get");
713

8-
getAll = fn(super.getAll.bind(this)).mockName(
9-
"next/headers::cookies().getAll",
10-
);
14+
getAll: Mock<
15+
(...args: [name: string] | [RequestCookie] | []) => RequestCookie[]
16+
> = fn(super.getAll.bind(this)).mockName("next/headers::cookies().getAll");
1117

12-
has = fn(super.has.bind(this)).mockName("next/headers::cookies().has");
18+
has: Mock<(name: string) => boolean> = fn(super.has.bind(this)).mockName(
19+
"next/headers::cookies().has",
20+
);
1321

14-
set = fn(super.set.bind(this)).mockName("next/headers::cookies().set");
22+
set: Mock<
23+
(...args: [key: string, value: string] | [options: RequestCookie]) => this
24+
> = fn(super.set.bind(this)).mockName("next/headers::cookies().set");
1525

16-
delete = fn(super.delete.bind(this)).mockName(
17-
"next/headers::cookies().delete",
18-
);
26+
delete: Mock<(names: string | string[]) => boolean | boolean[]> = fn(
27+
super.delete.bind(this),
28+
).mockName("next/headers::cookies().delete");
1929
}
2030

2131
let requestCookiesMock: RequestCookiesMock;
2232

23-
export const cookies = fn(() => {
33+
export const cookies: Mock<() => RequestCookiesMock> = fn(() => {
2434
if (!requestCookiesMock) {
2535
requestCookiesMock = new RequestCookiesMock(headers());
2636
}

src/plugins/next-mocks/alias/headers/headers.ts

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,52 @@
11
import { fn } from "@storybook/test";
22

33
import { HeadersAdapter } from "next/dist/server/web/spec-extension/adapters/headers.js";
4+
import type { Mock } from "vitest";
45

56
class HeadersAdapterMock extends HeadersAdapter {
67
constructor() {
78
super({});
89
}
910

10-
append = fn(super.append.bind(this)).mockName(
11-
"next/headers::headers().append",
12-
);
11+
append: Mock<(name: string, value: string) => void> = fn(
12+
super.append.bind(this),
13+
).mockName("next/headers::headers().append");
1314

14-
delete = fn(super.delete.bind(this)).mockName(
15+
delete: Mock<(name: string) => void> = fn(super.delete.bind(this)).mockName(
1516
"next/headers::headers().delete",
1617
);
1718

18-
get = fn(super.get.bind(this)).mockName("next/headers::headers().get");
19-
20-
has = fn(super.has.bind(this)).mockName("next/headers::headers().has");
19+
get: Mock<(name: string) => string | null> = fn(
20+
super.get.bind(this),
21+
).mockName("next/headers::headers().get");
2122

22-
set = fn(super.set.bind(this)).mockName("next/headers::headers().set");
23-
24-
forEach = fn(super.forEach.bind(this)).mockName(
25-
"next/headers::headers().forEach",
23+
has: Mock<(name: string) => boolean> = fn(super.has.bind(this)).mockName(
24+
"next/headers::headers().has",
2625
);
2726

28-
entries = fn(super.entries.bind(this)).mockName(
29-
"next/headers::headers().entries",
30-
);
31-
32-
keys = fn(super.keys.bind(this)).mockName("next/headers::headers().keys");
33-
34-
values = fn(super.values.bind(this)).mockName(
35-
"next/headers::headers().values",
36-
);
27+
set: Mock<(name: string, value: string) => void> = fn(
28+
super.set.bind(this),
29+
).mockName("next/headers::headers().set");
30+
31+
forEach: Mock<
32+
(
33+
callbackfn: (value: string, name: string, parent: Headers) => void,
34+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
35+
thisArg?: any,
36+
) => void
37+
> = fn(super.forEach.bind(this)).mockName("next/headers::headers().forEach");
38+
39+
entries: Mock<() => IterableIterator<[string, string]>> = fn(
40+
super.entries.bind(this),
41+
).mockName("next/headers::headers().entries");
42+
43+
keys: Mock<() => IterableIterator<string>> = fn(
44+
super.keys.bind(this),
45+
).mockName("next/headers::headers().keys");
46+
47+
values: Mock<() => IterableIterator<string>> = fn(
48+
super.values.bind(this),
49+
).mockName("next/headers::headers().values");
3750
}
3851

3952
let headersAdapterMock: HeadersAdapterMock;
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { fn } from "@storybook/test";
2+
import type { DraftMode } from "next/dist/client/components/draft-mode";
23
import * as originalHeaders from "next/dist/client/components/headers.js";
4+
import type { Mock } from "vitest";
35

46
// mock utilities/overrides (as of Next v14.2.0)
57
export { headers } from "./headers";
68
export { cookies } from "./cookies";
79

810
// passthrough mocks - keep original implementation but allow for spying
9-
const draftMode = fn(originalHeaders.draftMode).mockName("draftMode");
11+
const draftMode: Mock<() => DraftMode> = fn(originalHeaders.draftMode).mockName(
12+
"draftMode",
13+
);
1014
export { draftMode };

src/plugins/next-mocks/alias/navigation/index.ts

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { fn } from "@storybook/test";
33
import * as actual from "next/dist/client/components/navigation.js";
44
import { RedirectStatusCode } from "next/dist/client/components/redirect-status-code.js";
55
import { getRedirectError } from "next/dist/client/components/redirect.js";
6+
import type { AppRouterInstance } from "next/dist/shared/lib/app-router-context.shared-runtime";
67
import { NextjsRouterMocksNotAvailable } from "storybook/internal/preview-errors";
78

89
let navigationAPI: {
@@ -63,7 +64,9 @@ export const getRouter = () => {
6364
export * from "next/dist/client/components/navigation.js";
6465

6566
// mock utilities/overrides (as of Next v14.2.0)
66-
export const redirect = fn(
67+
export const redirect: Mock<
68+
(url: string, type?: actual.RedirectType) => never
69+
> = fn(
6770
(
6871
url: string,
6972
type: actual.RedirectType = actual.RedirectType.push,
@@ -72,7 +75,9 @@ export const redirect = fn(
7275
},
7376
).mockName("next/navigation::redirect");
7477

75-
export const permanentRedirect = fn(
78+
export const permanentRedirect: Mock<
79+
(url: string, type?: actual.RedirectType) => never
80+
> = fn(
7681
(
7782
url: string,
7883
type: actual.RedirectType = actual.RedirectType.push,
@@ -82,32 +87,38 @@ export const permanentRedirect = fn(
8287
).mockName("next/navigation::permanentRedirect");
8388

8489
// passthrough mocks - keep original implementation but allow for spying
85-
export const useSearchParams = fn(actual.useSearchParams).mockName(
86-
"next/navigation::useSearchParams",
87-
);
88-
export const usePathname = fn(actual.usePathname).mockName(
90+
export const useSearchParams: Mock<() => actual.ReadonlyURLSearchParams> = fn(
91+
actual.useSearchParams,
92+
).mockName("next/navigation::useSearchParams");
93+
export const usePathname: Mock<() => string> = fn(actual.usePathname).mockName(
8994
"next/navigation::usePathname",
9095
);
91-
export const useSelectedLayoutSegment = fn(
92-
actual.useSelectedLayoutSegment,
93-
).mockName("next/navigation::useSelectedLayoutSegment");
94-
export const useSelectedLayoutSegments = fn(
95-
actual.useSelectedLayoutSegments,
96-
).mockName("next/navigation::useSelectedLayoutSegments");
97-
export const useRouter = fn(actual.useRouter).mockName(
98-
"next/navigation::useRouter",
96+
export const useSelectedLayoutSegment: Mock<
97+
(parallelRouteKey?: string) => string | null
98+
> = fn(actual.useSelectedLayoutSegment).mockName(
99+
"next/navigation::useSelectedLayoutSegment",
100+
);
101+
export const useSelectedLayoutSegments: Mock<
102+
(parallelRouteKey?: string) => string[]
103+
> = fn(actual.useSelectedLayoutSegments).mockName(
104+
"next/navigation::useSelectedLayoutSegments",
99105
);
100-
export const useServerInsertedHTML = fn(actual.useServerInsertedHTML).mockName(
106+
export const useRouter: Mock<() => AppRouterInstance> = fn(
107+
actual.useRouter,
108+
).mockName("next/navigation::useRouter");
109+
export const useServerInsertedHTML: Mock<
110+
(callback: () => React.ReactNode) => void
111+
> = fn(actual.useServerInsertedHTML).mockName(
101112
"next/navigation::useServerInsertedHTML",
102113
);
103-
export const notFound = fn(actual.notFound).mockName(
114+
export const notFound: Mock<() => never> = fn(actual.notFound).mockName(
104115
"next/navigation::notFound",
105116
);
106117

107118
// Params, not exported by Next.js, is manually declared to avoid inference issues.
108119
interface Params {
109120
[key: string]: string | string[];
110121
}
111-
export const useParams = fn<[], Params>(actual.useParams).mockName(
112-
"next/navigation::useParams",
113-
);
122+
export const useParams: Mock<() => Params> = fn<[], Params>(
123+
actual.useParams,
124+
).mockName("next/navigation::useParams");

src/plugins/next-mocks/alias/router/index.ts

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
import type { Mock } from "@storybook/test";
22
import { fn } from "@storybook/test";
3+
import type { NextComponentType, NextPageContext } from "next";
34
import singletonRouter, * as originalRouter from "next/dist/client/router.js";
5+
import type {
6+
ExcludeRouterProps,
7+
WithRouterProps,
8+
} from "next/dist/client/with-router";
49
import type { NextRouter, SingletonRouter } from "next/router.js";
10+
import type { ComponentType } from "react";
511
import { NextjsRouterMocksNotAvailable } from "storybook/internal/preview-errors";
612

713
const defaultRouterState = {
@@ -133,9 +139,12 @@ export default singletonRouter;
133139

134140
// mock utilities/overrides (as of Next v14.2.0)
135141
// passthrough mocks - keep original implementation but allow for spying
136-
export const useRouter = fn(originalRouter.useRouter).mockName(
137-
"next/router::useRouter",
138-
);
139-
export const withRouter = fn(originalRouter.withRouter).mockName(
140-
"next/router::withRouter",
141-
);
142+
export const useRouter: Mock<() => NextRouter> = fn(
143+
originalRouter.useRouter,
144+
).mockName("next/router::useRouter");
145+
export const withRouter: Mock<
146+
(
147+
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
148+
ComposedComponent: NextComponentType<NextPageContext, any, WithRouterProps>,
149+
) => ComponentType<ExcludeRouterProps<WithRouterProps>>
150+
> = fn(originalRouter.withRouter).mockName("next/router::withRouter");

0 commit comments

Comments
 (0)