#Fixing Cloudflare Pages typescript build

5 messages · Page 1 of 1 (latest)

kind swallow
#

Build errors:

src/lib/auth/index.ts:15:35 - error ts(2339): Property 'AUTH' does not exist on type 'Locals'.

15     const stored = await c.locals.AUTH.get(name);
                                     ~~~~

src/pages/api/add.json.ts:46:29 - error ts(2339): Property 'DB' does not exist on type 'Locals'.

46   const DB = context.locals.DB
                               ~~

src/pages/api/list.json.ts:4:23 - error ts(2339): Property 'DB' does not exist on type 'Locals'.

4   const DB = c.locals.DB

src/env.d.ts:

/// <reference types="astro/client" />

import type { KVNamespace, D1Database } from "@cloudflare/workers-types/experimental"

type ENV = {
  AUTH: KVNamespace;
  DB: D1Database;
};

type Runtime = import('@astrojs/cloudflare').AdvancedRuntime<ENV>;

declare namespace App {
  interface Locals extends Runtime {
  }
}

astro.config.mjs

import { defineConfig } from 'astro/config';

import cloudflare from "@astrojs/cloudflare";

// https://astro.build/config
export default defineConfig({
  output: "server",
  adapter: cloudflare({
    runtime: {
      mode: "local",
      type: "pages",
      bindings: {
        "DB": {
          type: "d1",
        },
        "AUTH": {
          type: "kv",
        }
      }
    }
  })
});

src/lib/auth/index.ts

import type { APIContext } from "astro"

export const apiAuth = async (c: APIContext) => {
    const reject = (status: number) => {
        return new Response(null, {
            status: status
        });
    }

    const auth = c.request.headers.get("Authorization");
    if (!auth) return reject(400);

    const [name, token] = auth.split(":");

    const stored = await c.locals.AUTH.get(name);

    if (stored !== token) return reject(401);
}
neat badgeBOT
#

Hi @kind swallow. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the provided information, it seems like the issue is related to TypeScript not recognizing the AUTH and DB properties on the Locals type. This could be due to the way the types are being extended in your src/env.d.ts file.

In your src/env.d.ts file, you're extending the Locals interface with the Runtime type. However, the Runtime type itself doesn't seem to include the AUTH and DB properties. Instead, you might want to extend the Locals interface directly with the ENV type, which includes these properties.

Here's how you can modify your src/env.d.ts file:

/// <reference types="astro/client" />

import type { KVNamespace, D1Database } from "@cloudflare/workers-types/experimental"

type ENV = {
  AUTH: KVNamespace;
  DB: D1Database;
};

declare namespace App {
  interface Locals extends ENV {
  }
}

This way, the Locals interface should now correctly include the AUTH and DB properties, and TypeScript should no longer complain about these properties not existing.

Please note that this solution is based on the provided information and assumes that the AUTH and DB properties are correctly set up in your astro.config.mjs file and that the @cloudflare/workers-types/experimental package provides the correct types for KVNamespace and D1Database.

Sources:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@kind swallow kapa.ai is still learning and improving, please let us know how it did by reacting below

kind swallow
#

The only useful part about this was the linked Github Issue.

Ultimately, my problem was having:

import type { AdvancedRuntime } from "@astrojs/cloudflare"
import type { KVNamespace, D1Database } from "@cloudflare/workers-types/experimental"

type ENV = {
  AUTH: KVNamespace;
  DB: D1Database;
}

declare namespace App {
  interface Locals extends AdvancedRuntime {
    runtime: AdvancedRuntime & { env: ENV };
  }
}

Instead of:

type AdvancedRuntime = import("@astrojs/cloudflare").AdvancedRuntime;

type D1Database = import("@cloudflare/workers-types/experimental").D1Database;
type KVNamespace = import("@cloudflare/workers-types/experimental").KVNamespace;

type ENV = {
  AUTH: KVNamespace;
  DB: D1Database;
}

declare namespace App {
  interface Locals extends AdvancedRuntime {
    runtime: AdvancedRuntime & { env: ENV };
  }
}

I don't really understand why, but thanks I guess.