#Correct TypeScript from WorkerEntrypoint Binding

15 messages · Page 1 of 1 (latest)

quick rose
#

If I have this service below

export default class Users extends WorkerEntrypoint<Env> {
    async fetch() {
        return new Response(null, { status: 404 });
    }

    async list() {
        const adapter = new PrismaD1(this.env.DB);
        const prisma = new PrismaClient({ adapter });

        try {
            const users = await prisma.user.findMany();
            const result = JSON.stringify(users);
            return new Response(result);
        } catch (e) {
            if (e instanceof Prisma.PrismaClientKnownRequestError) {
                return Response.json({ e }, { status: 400 });
            }
            return Response.json({ e }, { status: 500 });
        }
    }
name = "users"
main = "src/index.ts"
compatibility_date = "2025-01-09"

When I consume this into another service provider it has in its toml

[[services]]
binding = "USERS"
service = "users"
entrypoint = "Users"

When I run wrangler types it generaties this type decleration file

// Generated by Wrangler by running `wrangler types`

interface Env {
    USERS: Fetcher;
}

However when I try to use this service it only shows two methods which are the reserved types connect and fetch

mighty comet
#

There's a separate type for RPC services, Service<Users> in this case, if you import type Users from './other.ts'

The way I usually have them would be USERS: Service<import('other-service').default> as inline type imports

quick rose
#

Oh intersting thanks @mighty comet !

Maybe this deserves its own question, but it is something I am struggling with when getting started to write out my next course on creating cloudflare workers.

I am wondering if it makes sense to continue with multiple wrangler directories for each service like in flipfeeds currently or do something like @cold cloak has in punderful-workflows creating multiple services in a single wrangler directory.

I feel like this is where they typing might also break down because technically they are not even in the same project making imports more difficult

mighty comet
#

I would do it in a very similar way to your setup

  • pnpm monorepo, each worker is a package
  • make the exported worker's type an export of the package
  • import them from workspace:^ in other packages - and this should work in the same repo as well as others, if you publish it to a (maybe private) registry
quick rose
#

How do you test things like this locally, I am finding it difficult to run workers concurrently with only my gateway being served at 8787. I "hardcoded" port into its pnpm dev command but maybe there is another way?

mighty comet
#

I believe the port config option in wrangler.toml/json is what you're looking for, I'd assign them something unique each

#

(insert obligatory testing in production joke)

#

and then an actual explanation, you can use gradual deployments, eg. upload your new version and deploy it to 0% of traffic, which you can override with a header for your own requests

dusty gull
mighty comet
#

sadly generics are not supported by the type generator right now, even though it would be super useful, and also something I've asked about in the past

dusty gull
#

Ye Unfortunately I found out the the hard way and monorepo did its own part in escalating the difficulty but finally after 2 days of typescript hell I got it working in acceptable manners 😄

cold cloak
#

Try something like this:

interface Env {
    UPLOADER: Fetcher<import("../autotranscriber/src/").Uploader>;
#

(Where that Uploader is the exported class name at that relative dir)

placid niche
#

Hello, I have similar problem, my 2 workerentrypoints live in a separate repo, when i bind them in my main application i get this build error on deploy.

RESOLVER: Service /* entrypoint Resolver from shortener-operator */;

When I try to access the rpc method I get compile error error TS2339: Property 'get' does not exist on type '{ fetch(input: URL | RequestInfo, init?: RequestInit<CfProperties<unknown>> | undefined): Promise<Response>; connect(address: string | SocketAddress, options?: SocketOptions | undefined): Socket; }'.

How can I approach this? Should I move my workers in the same repo or can I import the types from external(private) repo