Trying to write next-auth adapter

Aanthonyshew5/4/2023
blahblahblahrober AKA @Dan Kochetov helped me get most of the way to having a next-auth adapter done but, in the couple weeks I waited for a review, I came back and now the SQLite migration is betraying me.

See video. Starting from a clean slate, it's saying nothing to migrate and, when I run tests against my db.sqlite, I get back errors for no tables, kiddo. Pretty confused; seems like I'm not pushing any schema somehow?

Pull request if you want to look at code: https://github.com/nextauthjs/next-auth/pull/7165
I'm working in ./packages/adapter-drizzle-sqlite
ASAndrii Sherman5/4/2023
Wrong script used
ASAndrii Sherman5/4/2023
Need to have generate:sqlite
ASAndrii Sherman5/4/2023
And you have generate:mysql
ASAndrii Sherman5/4/2023
But will improve warning for this case
ASAndrii Sherman5/4/2023
It seems to be unclear at all what’s happening
Aanthonyshew5/4/2023
Oh, it still fails when it's right, generate:sqlte
Aanthonyshew5/4/2023
My b, I was doing science and forgot to switch that back in the video.
ASAndrii Sherman5/4/2023
so you are using pnpm build?
ASAndrii Sherman5/4/2023
I'll clone your PR and will try to reproduce
Aanthonyshew5/4/2023
Anything that invokes the generator will do it. pnpm generate-schema will have the same behavior.
ASAndrii Sherman5/4/2023
Looking at your PR generate-schema has generate:mysql script
So I guess the only right script is pnpm build
ASAndrii Sherman5/4/2023
or dev
Aanthonyshew5/4/2023
I haven't pushed the correction yet.
ASAndrii Sherman5/4/2023
got it
ASAndrii Sherman5/4/2023
I'll ping you back after checking it locally
Aanthonyshew5/4/2023
Gracias, papa.
Aanthonyshew5/4/2023
Just pushed a cleanup some of my science.
ASAndrii Sherman5/4/2023
ASAndrii Sherman5/4/2023
so I made a fork
ASAndrii Sherman5/4/2023
and run pnpm generate-schema
ASAndrii Sherman5/4/2023
if you are open for a call we can debug it on your end
ASAndrii Sherman5/4/2023
but it seems to work
ASAndrii Sherman5/4/2023
Aanthonyshew5/4/2023
Bless ittttttttt.
Aanthonyshew5/4/2023
That's just the worst outcome haha.
Aanthonyshew5/4/2023
Thanks for taking the time, legend. I'll go figure my life out.
ASAndrii Sherman5/4/2023
I can send you my laptop
Bbloberenober5/4/2023
And that's how Docker was born
Aanthonyshew5/4/2023
wut kind is it
LLiltripple_reid5/5/2023
this needs more attention, I really wouldn't want to pay 100 bucks for 5000 users on Clerk 😭
Aanthonyshew5/6/2023
How do I let Drizzle auto-assign a uuid? Or do I need to handle it in my code?
Bbloberenober5/6/2023
if it cannot be done via SQL, you can't for now
Bbloberenober5/6/2023
but we have a ticket for that
Bbloberenober5/6/2023
...ok, maybe we don't
let me create it
Aanthonyshew5/6/2023
Gotcha, thanks.

One last one and then I think I'm going to be home free:
I'm trying to give the maintainers the option to have a drizzle-adapter-all if they want. Essentially, an adapter that will accept any of the SQL flavors. But I'm getting this. Is this me being dumb or will is drizzle freaking out because I have multiple clients (client flavors?) in one workspace?
Ttacomanator5/7/2023
Would love to have this! for now I am always passing an empty id when inserting into a table like this:

const cuid2 = customType<{ data: string; notNull: true }>({
  dataType() {
    return "text";
  },
  toDriver(value): string {
    return value ? value : createId();
  },
});

const User = sqliteTable(
  "User",
  { id: cuid2("id").primaryKey() }
);

// adapter
async createUser(user) {
  return db
    .insert(User)
    .values({ ...user, id: "" })
    .returning()
    .get();
},
Aanthonyshew5/7/2023
Wow, fancy. I just did this. Is this naive? Using uuidv4 from the uuid npm package.
Ttacomanator5/7/2023
That works too. I needed something reusable and automatic for use with multiple models.
ASAndrii Sherman5/7/2023
I can suggest a bit of improvement here. May work

// notNull in customType will be left false, because we always are
// generating it in toDriver
const cuid2 = customType<{ data: string; notNull: false }>({
  dataType() {
    return "text";
  },
  toDriver(value): string {
    return typeof value === 'undefined' ? createId() : value;
  },
});

const User = sqliteTable("User", {
  id: cuid2("id"),
  name: text("name").notNull(),
}, (t) => ({
  // need to define primary key here, so migration will create PK constraint
  // but type will be left nullable
  f: primaryKey(t.id)
}));

async createUser(user) {
  // id will be optional
  return db.insert(User).values(...user).returning().get();
};
ASAndrii Sherman5/7/2023
so no need for id: "" on insert
ASAndrii Sherman5/7/2023
I didn't test a real query, but it should work
Ttacomanator5/7/2023
wouldn't end up being a nullable column though?
ASAndrii Sherman5/7/2023
only in types. As long as id will be always generated by customType
ASAndrii Sherman5/7/2023
it means for insert function it can be nullable
ASAndrii Sherman5/7/2023
but for migration kit will use primary key for this field
ASAndrii Sherman5/7/2023
which is notNull on database layer
Ttacomanator5/7/2023
ah, I see, let me try it then!
ASAndrii Sherman5/7/2023
and tbh, I would never think of using customType for this case πŸ˜…
ASAndrii Sherman5/7/2023
it was smart
Ttacomanator5/7/2023
I don't know it was the first thing I grabbed for when I figured out that program generated default values were not yet supported ✌️

tried it, but one downside seems to be that all of the places in my code where I took for granted that id is not null now seem to think it could be null 🫒
ASAndrii Sherman5/7/2023
Maybe try this
ASAndrii Sherman5/7/2023
const cuid2 = customType<{ data: string; notNull: true, default: true }>({
ASAndrii Sherman5/7/2023
make it back notNull
ASAndrii Sherman5/7/2023
but default true
ASAndrii Sherman5/7/2023
and then you can put primary key back
ASAndrii Sherman5/7/2023
const User = sqliteTable("User", {
  id: cuid2("id").primaryKey(),
  name: text("name").notNull(),
});
ASAndrii Sherman5/7/2023
it will still work
ASAndrii Sherman5/7/2023
and default: true sounds much better
Ttacomanator5/7/2023
I think this is essentially what I tried in the past but couldn't get it to work, but let me try again!
Ttacomanator5/7/2023
Yeah, for some reason when I do it this way, it never seems to get to the toDriver method of the custom type
Ttacomanator5/7/2023
It seems like default: true causes it to bypass toDriver when the value is undefined, assuming that the database will take care of it?
ASAndrii Sherman5/7/2023
I'll check a code now
ASAndrii Sherman5/7/2023
it shouldn't
ASAndrii Sherman5/7/2023
because those are just types
ASAndrii Sherman5/7/2023
yeah, you are right
if value is undefined orm will bypass toDriver, because already know, that the value is null/db default
ASAndrii Sherman5/7/2023
but I don't think it should work this way
ASAndrii Sherman5/7/2023
toDriver should always intercept insert values
Ttacomanator5/7/2023
i had the same thought... then https://github.com/drizzle-team/drizzle-orm/issues/556 may not even be needed...
ASAndrii Sherman5/7/2023
It would be nice to have it, so you don't need to create customType
ASAndrii Sherman5/7/2023
it would be nice to make it both work as expected πŸ˜…
ASAndrii Sherman5/7/2023
will do that
ASAndrii Sherman5/7/2023
thanks for you investigations in this part. Was super helpful!
Ttacomanator5/7/2023
anytime thank you too!
Bbloberenober5/7/2023
uhhh
this is an error text I'm seeing for the first time in my life
will need to investigate
Bbloberenober5/7/2023
Did you try things from this thread? https://github.com/microsoft/TypeScript/issues/42873
Aanthonyshew5/7/2023
Yeah, I definitely made a spooky one, huh. πŸ™ƒ

i tried a couple different things to no avail. I eventually decided to just drop the β€œall” adapter since it barely makes sense to have anyway. Just pick the right flavor, duh.
ASAndrii Sherman5/7/2023
Today I've learned a new word: "avail"

thanks @anthonyshew
ASAndrii Sherman5/7/2023
yesterday it was "plethora"
NNeonCop5/14/2023
this is awesome work!!