I would like to use Firebase Auth for authenticating users in my Cloudflare SvelteKit application. Unfortunately, firebase-admin
relies on Node.js APIs that don't exist in the Cloudflare worker runtime.
There is at least one library that has attempted to bridge this gap:
However, I have read through their code and found it difficult to understand. As this is authentication we're talking about, I want to be completely comfortable with the solution I choose, so I don't want to use this package.
Because of this, I'm creating a toolkit to use Firebase Auth inside of a Cloudflare Worker. I don't want an npm package dependency on firebase-admin
because the package alone is 13MB and the Cloudflare worker free tier only allows 3MB of memory. However, I do want to use their types for my interfaces so I can stay close to the firebase-admin
approach.
I have tried to do this by downloading firebase-admin
as a dev dependency, and then using the types inside of my library by re-exporting them from a types.ts
file:
import type {
DecodedIdToken,
UserRecord,
UserIdentifier,
GetUsersResult,
ListUsersResult,
CreateRequest,
UpdateRequest,
DeleteUsersResult,
} from "firebase-admin/auth";
export type {
DecodedIdToken,
UserRecord,
UserIdentifier,
GetUsersResult,
ListUsersResult,
CreateRequest,
UpdateRequest,
DeleteUsersResult,
};
I'm compiling my package with tsup
, with the following config:
import { defineConfig } from "tsup";
export default defineConfig({
entry: ["src/index.ts"],
format: ["esm"], // ESM only
dts: true, // generate .d.ts
sourcemap: true,
clean: true,
target: "esnext", // Cloudflare Workers = modern V8
minify: false, // optional, but not needed for a lib
});
However when I generate the dist
file I want to publish on npm
I get the following in the index.d.ts
:
export { CreateRequest, DecodedIdToken, DeleteUsersResult, GetUsersResult, ListUsersResult, UpdateRequest, UserIdentifier, UserRecord } from 'firebase-admin/auth';
Clearly, this is a dependency on firebase-admin/auth
which I don't want, I want the types themselves. Is there a way around this, or will I have to copy the type files myself?
TypeScript module bundlers such as tsup and zshy don't do anything special to recreate or export types from module source code. As you have found, they simply arrange to re-export exactly what your code imports. This is the easiest and most straight way to accomplish the task. They don't themselves try to make deep copies of all the requested types for export.
You mentioned that one workaround is to copy the type files into your project. You could do that, but you'd need to make sure you copy all the relevant files from all the referred dependency modules. firebase-admin types are not just defined in a single file. For example, consider the firebase-admin type named DeleteUsersResult
. That type depends on another type named FirebaseArrayIndexError
, which is defined in a different type file. So, the only way that you'd be able to fully re-create all of the types you want is to make sure you've copied all the type files and their dependency files from firebase-admin (and potentially, from other modules as well, depending on how deep the types a referenced). As you can imagine, manually copying all these types as they might change between versions could be a lot of work.
If you're using the zshy bundler, you might be able to modify it, or write some plugin, that does deeply copy any types you want to re-export and place them in a new file that doesn't need maintenance. From the zshy docs:
TypeScript's Compiler API provides dedicated hooks for performing such transforms (though they are criminally under-utilized).
ts.TransformerFactory
: Provides AST transformations to rewrite import/export extensions before module conversion
So maybe you could arrange to provide a transformer factory that's smart about TypeScript types to make deep copies of existing types so that you don't need their original definitions. Or maybe the author of zshy would be willing to add this as a feature if you file a feature request along with a description of the problem you're trying to solve.
(BTW, I applied zshy with the default configuration to your use case, and it currently does exactly what tsup does by re-exporting exactly what your code imports from firebase-admin).
But the bottom line here is that these TS bundlers simply aren't currently designed to make deep copies of types for re-export as your use case requires.