Skip to content

Commit 0bb5ee3

Browse files
fix: more errors
fix: even more issues
1 parent 31364b3 commit 0bb5ee3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+791
-559
lines changed

.eslintignore

-1
This file was deleted.

.eslintrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ module.exports = {
55
parserOptions: {
66
project: true,
77
},
8+
ignorePatterns: ["**/farcaster/generated/*.ts"],
89
};

packages/eslint-config/library.js

+2
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,11 @@ module.exports = {
3333
"@typescript-eslint/require-await": "warn",
3434
"@typescript-eslint/no-explicit-any": "warn",
3535
"@typescript-eslint/no-unnecessary-condition": "warn",
36+
"@typescript-eslint/consistent-type-imports": "error",
3637
"jest/expect-expect": "warn",
3738
"react/jsx-sort-props": "off",
3839
"unicorn/filename-case": "off",
3940
eqeqeq: "off",
41+
"no-await-in-loop": "off",
4042
},
4143
};

packages/frames.js/src/cloudflare-workers/index.test.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ describe("cloudflare workers adapter", () => {
77

88
it("correctly integrates with Cloudflare Workers", async () => {
99
const frames = lib.createFrames();
10-
const handler = frames(async (ctx) => {
10+
const handler = frames((ctx) => {
1111
expect(ctx.request.url).toBe("http://localhost:3000/");
1212

1313
return {
@@ -35,7 +35,7 @@ describe("cloudflare workers adapter", () => {
3535
},
3636
});
3737

38-
const handler = frames(async (ctx) => {
38+
const handler = frames((ctx) => {
3939
expect(ctx.state).toEqual({ test: false });
4040

4141
return {

packages/frames.js/src/cloudflare-workers/test.types.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
/* eslint-disable @typescript-eslint/require-await -- we want to test that handler supports async*/
12
import type { ExecutionContext, Request as CfRequest, ExportedHandlerFetchHandler } from '@cloudflare/workers-types';
23
import type { types } from '.';
34
import { createFrames } from '.';
@@ -41,6 +42,17 @@ framesWithExplicitStateAndEnv(async (ctx) => {
4142
ctx satisfies { initialState?: { test: boolean }; message?: unknown, pressedButton?: unknown; request: Request; };
4243
ctx satisfies { cf: { env: { secret: string }; ctx: ExecutionContext; req: CfRequest }}
4344

45+
return {
46+
image: 'http://test.png',
47+
};
48+
}) satisfies ExportedHandlerFetchHandler<{ secret: string }>;
49+
50+
const framesWithExplicitStateAndEnvNoPromiseHandler = createFrames<{ test: boolean }, { secret: string }>({});
51+
framesWithExplicitStateAndEnvNoPromiseHandler((ctx) => {
52+
ctx.state satisfies { test: boolean };
53+
ctx satisfies { initialState?: { test: boolean }; message?: unknown, pressedButton?: unknown; request: Request; };
54+
ctx satisfies { cf: { env: { secret: string }; ctx: ExecutionContext; req: CfRequest }}
55+
4456
return {
4557
image: 'http://test.png',
4658
};

packages/frames.js/src/core/components.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,6 @@ export type ButtonProps =
6363
| LinkButtonProps
6464
| TxButtonProps;
6565

66-
export const Button: React.FunctionComponent<ButtonProps> = () => {
66+
export function Button(_: ButtonProps): null {
6767
return null;
68-
};
68+
}

packages/frames.js/src/core/composeMiddleware.test.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ describe("composeMiddleware", () => {
1010
it("properly works with just one middleware", async () => {
1111
const context = { a: 1 };
1212

13-
const composedMiddleware = composeMiddleware<typeof context, any>([
14-
async (ctx, next) => {
13+
const composedMiddleware = composeMiddleware<typeof context, unknown>([
14+
(ctx, next) => {
1515
ctx.a = 2;
1616
return next();
1717
},
@@ -31,7 +31,10 @@ describe("composeMiddleware", () => {
3131
order: [],
3232
};
3333

34-
const composedMiddleware = composeMiddleware<typeof context, Promise<any>>([
34+
const composedMiddleware = composeMiddleware<
35+
typeof context,
36+
Promise<string> | string
37+
>([
3538
async (ctx: typeof context, next) => {
3639
ctx.order.push(1);
3740
const result = await next({
@@ -54,7 +57,7 @@ describe("composeMiddleware", () => {
5457

5558
return result;
5659
},
57-
async (ctx: typeof context) => {
60+
(ctx: typeof context) => {
5861
ctx.order.push(3);
5962

6063
expect(ctx).toMatchObject({ 1: true, 2: "test" });

packages/frames.js/src/core/composeMiddleware.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ export function composeMiddleware<TContext, TReturnType>(
2525
);
2626

2727
return (ctx) => {
28-
return composedMiddleware(ctx, (() => {}) as any);
28+
return composedMiddleware(ctx, (() => {
29+
return undefined;
30+
}) as () => TReturnType);
2931
};
3032
}

packages/frames.js/src/core/createFrames.test.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ describe("createFrames", () => {
1313
it("provides default properties on context based on default middleware and internal logic", async () => {
1414
const handler = createFrames();
1515

16-
const routeHandler = handler(async (ctx) => {
16+
const routeHandler = handler((ctx) => {
1717
expect(ctx.url).toBeInstanceOf(URL);
1818
expect(ctx.url.href).toBe("http://test.com/");
1919

@@ -32,7 +32,7 @@ describe("createFrames", () => {
3232
it("passes initialState to context", async () => {
3333
const handler = createFrames({ initialState: { test: true } });
3434

35-
const routeHandler = handler(async (ctx) => {
35+
const routeHandler = handler((ctx) => {
3636
expect(ctx.initialState).toEqual({ test: true });
3737
return redirect("http://test.com");
3838
});
@@ -54,7 +54,7 @@ describe("createFrames", () => {
5454
middleware: [customMiddleware],
5555
});
5656

57-
const routeHandler = handler(async (ctx) => {
57+
const routeHandler = handler((ctx) => {
5858
return redirect(ctx.custom);
5959
});
6060

@@ -75,7 +75,7 @@ describe("createFrames", () => {
7575
const handler = createFrames();
7676

7777
const routeHandler = handler(
78-
async (ctx) => {
78+
(ctx) => {
7979
return redirect(ctx.custom);
8080
},
8181
{
@@ -90,16 +90,28 @@ describe("createFrames", () => {
9090
});
9191

9292
it("works with parallel middleware", async () => {
93-
const middleware0 = async (context: any, next: any) => {
93+
const middleware0: FramesMiddleware<any, { test0: boolean }> = async (
94+
context,
95+
next
96+
) => {
9497
return next({ test0: true });
9598
};
96-
const middleware1 = async (context: any, next: any) => {
99+
const middleware1: FramesMiddleware<any, { test1: boolean }> = async (
100+
context,
101+
next
102+
) => {
97103
return next({ test1: true });
98104
};
99-
const middleware2 = async (context: any, next: any) => {
105+
const middleware2: FramesMiddleware<any, { test2: boolean }> = async (
106+
context,
107+
next
108+
) => {
100109
return next({ test2: true });
101110
};
102-
const middleware3 = async (context: any, next: any) => {
111+
const middleware3: FramesMiddleware<any, { test3: boolean }> = async (
112+
context,
113+
next
114+
) => {
103115
return next({ test3: true });
104116
};
105117

@@ -111,7 +123,7 @@ describe("createFrames", () => {
111123
],
112124
});
113125

114-
const routeHandler = handler(async (ctx) => {
126+
const routeHandler = handler((ctx) => {
115127
expect(ctx).toMatchObject({
116128
test0: true,
117129
test1: true,

packages/frames.js/src/core/createFrames.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { coreMiddleware } from "../middleware";
1+
import { coreMiddleware } from "../middleware/default";
22
import { stateMiddleware } from "../middleware/stateMiddleware";
33
import { composeMiddleware } from "./composeMiddleware";
44
import type {
@@ -21,7 +21,7 @@ export function createFrames<
2121
TState,
2222
typeof coreMiddleware,
2323
TMiddlewares,
24-
(req: Request) => Promise<Response>
24+
(req: Request) => Promise<Response> | Response
2525
> {
2626
const globalMiddleware: FramesMiddleware<TState, FramesContext<TState>>[] =
2727
middleware || [];
@@ -30,8 +30,10 @@ export function createFrames<
3030
* This function takes handler function that does the logic with the help of context and returns one of possible results
3131
*/
3232
return function createFramesRequestHandler(handler, options = {}) {
33-
const perRouteMiddleware: FramesMiddleware<any, FramesContext<TState>>[] =
34-
options && Array.isArray(options.middleware) ? options.middleware : [];
33+
const perRouteMiddleware: FramesMiddleware<
34+
JsonValue | undefined,
35+
FramesContext<TState>
36+
>[] = Array.isArray(options.middleware) ? options.middleware : [];
3537

3638
const composedMiddleware = composeMiddleware<
3739
FramesContext<TState>,

packages/frames.js/src/core/formatUrl.ts

+19-14
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@
2020
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
2121
// USE OR OTHER DEALINGS IN THE SOFTWARE.
2222

23-
import type { UrlObject } from "url";
24-
import type { ParsedUrlQuery } from "querystring";
23+
import type { UrlObject } from "node:url";
24+
import type { ParsedUrlQuery } from "node:querystring";
2525

2626
// function searchParamsToUrlQuery(searchParams: URLSearchParams): ParsedUrlQuery {
2727
// const query: ParsedUrlQuery = {};
@@ -44,16 +44,18 @@ function stringifyUrlQueryParam(param: unknown): string {
4444
typeof param === "boolean"
4545
) {
4646
return String(param);
47-
} else {
48-
return "";
4947
}
48+
49+
return "";
5050
}
5151

5252
function urlQueryToSearchParams(urlQuery: ParsedUrlQuery): URLSearchParams {
5353
const result = new URLSearchParams();
5454
Object.entries(urlQuery).forEach(([key, value]) => {
5555
if (Array.isArray(value)) {
56-
value.forEach((item) => result.append(key, stringifyUrlQueryParam(item)));
56+
value.forEach((item) => {
57+
result.append(key, stringifyUrlQueryParam(item));
58+
});
5759
} else {
5860
result.set(key, stringifyUrlQueryParam(value));
5961
}
@@ -74,22 +76,23 @@ function urlQueryToSearchParams(urlQuery: ParsedUrlQuery): URLSearchParams {
7476

7577
const slashedProtocols = /https?|ftp|gopher|file/;
7678

77-
export function formatUrl(urlObj: UrlObject) {
78-
let { auth, hostname } = urlObj;
79+
export function formatUrl(urlObj: UrlObject): string {
80+
let { auth } = urlObj;
81+
const { hostname } = urlObj;
7982
let protocol = urlObj.protocol || "";
8083
let pathname = urlObj.pathname || "";
8184
let hash = urlObj.hash || "";
8285
let query = urlObj.query || "";
8386
let host: string | false = false;
8487

85-
auth = auth ? encodeURIComponent(auth).replace(/%3A/i, ":") + "@" : "";
88+
auth = auth ? `${encodeURIComponent(auth).replace(/%3A/i, ":")}@` : "";
8689

8790
if (urlObj.host) {
8891
host = auth + urlObj.host;
8992
} else if (hostname) {
90-
host = auth + (~hostname.indexOf(":") ? `[${hostname}]` : hostname);
93+
host = auth + (hostname.includes(":") ? `[${hostname}]` : hostname);
9194
if (urlObj.port) {
92-
host += ":" + urlObj.port;
95+
host += `:${urlObj.port}`;
9396
}
9497
}
9598

@@ -105,14 +108,16 @@ export function formatUrl(urlObj: UrlObject) {
105108
urlObj.slashes ||
106109
((!protocol || slashedProtocols.test(protocol)) && host !== false)
107110
) {
108-
host = "//" + (host || "");
109-
if (pathname && pathname[0] !== "/") pathname = "/" + pathname;
111+
host = `//${host || ""}`;
112+
if (pathname && !pathname.startsWith("/")) {
113+
pathname = `/${pathname}`;
114+
}
110115
} else if (!host) {
111116
host = "";
112117
}
113118

114-
if (hash && hash[0] !== "#") hash = "#" + hash;
115-
if (search && search[0] !== "?") search = "?" + search;
119+
if (hash && !hash.startsWith("#")) hash = `#${hash}`;
120+
if (search && !search.startsWith("?")) search = `?${search}`;
116121

117122
pathname = pathname.replace(/[?#]/g, encodeURIComponent);
118123
search = search.replace("#", "%23");

packages/frames.js/src/core/redirect.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FrameRedirect } from "./types";
1+
import type { FrameRedirect } from "./types";
22

33
/**
44
* Creates a redirect with 302 as default status

packages/frames.js/src/core/test.types.tsx

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1+
/* eslint-disable @typescript-eslint/require-await -- we are checking compatibility with promises */
12
import type { types } from '.';
23
import { createFrames } from '.';
34

4-
type Handler = (req: Request) => Promise<Response>;
5+
type Handler = (req: Request) => Promise<Response> | Response;
56

67
const framesWithoutState = createFrames();
78
framesWithoutState(async (ctx) => {
@@ -41,6 +42,17 @@ framesWithExplicitStateAndEnv(async (ctx) => {
4142
ctx satisfies { initialState?: { test: boolean }; message?: unknown, pressedButton?: unknown; request: Request; };
4243

4344

45+
return {
46+
image: 'http://test.png',
47+
};
48+
}) satisfies Handler;
49+
50+
const framesWithExplicitStateAndEnvNoPromise = createFrames<{ test: boolean }>({});
51+
framesWithExplicitStateAndEnvNoPromise((ctx) => {
52+
ctx.state satisfies { test: boolean };
53+
ctx satisfies { initialState?: { test: boolean }; message?: unknown, pressedButton?: unknown; request: Request; };
54+
55+
4456
return {
4557
image: 'http://test.png',
4658
};

packages/frames.js/src/core/types.ts

+8-6
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ export type FrameHandlerFunction<
134134
> = (
135135
// we pass ctx.state here since it is made available internally by stateMiddleware but the inference would not work
136136
ctx: FramesContext<TState> & TFramesContext & { state: TState }
137-
) => Promise<FramesHandlerFunctionReturnType<TState>>;
137+
) =>
138+
| Promise<FramesHandlerFunctionReturnType<TState>>
139+
| FramesHandlerFunctionReturnType<TState>;
138140

139141
export type FramesContextFromMiddlewares<
140142
TMiddlewares extends
@@ -164,7 +166,7 @@ export type FramesRequestHandlerFunction<
164166
| FramesMiddleware<any, any>[]
165167
| undefined,
166168
TFrameMiddleware extends FramesMiddleware<any, any>[] | undefined,
167-
TRequestHandlerFunction extends Function,
169+
TRequestHandlerFunction extends (...args: any[]) => any,
168170
> = <
169171
TPerRouteMiddleware extends
170172
| FramesMiddleware<any, any>[]
@@ -173,13 +175,13 @@ export type FramesRequestHandlerFunction<
173175
handler: FrameHandlerFunction<
174176
TState,
175177
(TDefaultMiddleware extends undefined
176-
? {}
178+
? Record<string, any>
177179
: FramesContextFromMiddlewares<NonNullable<TDefaultMiddleware>>) &
178180
(TFrameMiddleware extends undefined
179-
? {}
181+
? Record<string, any>
180182
: FramesContextFromMiddlewares<NonNullable<TFrameMiddleware>>) &
181183
(TPerRouteMiddleware extends undefined
182-
? {}
184+
? Record<string, any>
183185
: FramesContextFromMiddlewares<NonNullable<TPerRouteMiddleware>>)
184186
>,
185187
options?: FramesRequestHandlerFunctionOptions<TPerRouteMiddleware>
@@ -210,7 +212,7 @@ export type CreateFramesFunctionDefinition<
210212
| readonly FramesMiddleware<any, any>[]
211213
| FramesMiddleware<any, any>[]
212214
| undefined,
213-
TRequestHandlerFunction extends Function,
215+
TRequestHandlerFunction extends (...args: any[]) => any,
214216
> = <
215217
TState extends JsonValue | undefined = JsonValue | undefined,
216218
TFrameMiddleware extends FramesMiddleware<any, any>[] | undefined = undefined,

0 commit comments

Comments
 (0)