-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
FUCK my LIFE: This deviates from the simple idea I had in mine for
uploads because I want to support image variants to resize original images into the desired size. I'm following a bit Rails ActiveStorage implementation but I saw they use polymorphic associations so I need to see how I can manage it in Drizzle. This issue has some nice options: drizzle-team/drizzle-orm#1051 (comment) I think is duable. Another consideration is in terms of adapters. Now is ultra harcoded to PostgreSQL + Drizzle. But if I would like to expand to MySQL I should do a kind of Adapter pattern like the one use Licia Auth or NextJS Auth. I like the one use Licia because looks simple enough. Under the hood all DB access is done with raw SQL which I think makes sense if I also want to decouple from Drizzle DSL. Not sure if it's worth it. In terms of API types I would like to keep something similar to what I had in previous commit where was something like const factory = AttachmentFactory({ dbAdapter: PostgrsqlAdapter({ client: db }) }) type Schema = typeof schema UserAttachment = factory.build<Shchema['users']>({ drive: disk, // DiskWrapper (filesystem or S3) table: schema['users'], // I would like something like this where relation is infered from // Drizzle schema relations // But this couple the thing with Drizzle which I'm kind of ok. // In this config also can go the variants config for the different // file sizes we want to generate. // In terms of variants Rails do on-deman variants when requesting // from the UI but it stores the variant after first request. // I'm not sure if I want to add Sharp (or something like it) to // support variants. Maybe this doesn't work in Vercel or Cloudflare // Edge. Pretty sure it doesn't // Other approach would to have a AWS Lambda that does the resize when // a file is addaded to the bucket. But this does the system DEV // friendly and also requires on the final user to implement the Lamda. I // can help here by implementing using IAC like SST ion // Both options have tradeoffs. attachments: [{ relation: 'avatar' }], }) const attachment = UserAttachment.new({ id: 'some-user-id' }) // Optional if I want to get the user from DB await user.getModel() // Now that we have the user model we have methods for add/delete/get/getUrl // This creates relations in DB // It also use Flydrive to store the file in Disk or S3 await attachment.addAvatar({ file: someFile })
- Loading branch information
1 parent
d056c50
commit c60475b
Showing
9 changed files
with
110 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
import { blobs } from '$/db/schema/attachments/blobs' | ||
import readfort from '$/db/schema/dbSchema' | ||
import { InferSelectModel, relations } from 'drizzle-orm' | ||
import { bigserial } from 'drizzle-orm/pg-core' | ||
|
||
export enum AttachableType { | ||
Users = 'users', | ||
} | ||
export const attachableEnum = readfort.enum('attachable_type', [ | ||
AttachableType.Users, | ||
]) | ||
|
||
export const attachments = readfort.table('attachments', { | ||
id: bigserial('id', { mode: 'number' }).notNull(), | ||
attachableId: bigserial('attachable_id', { mode: 'bigint' }).notNull(), | ||
attachableType: attachableEnum('attachable_type').notNull(), | ||
}) | ||
|
||
export const attachmentsRelations = relations(attachments, ({ many }) => ({ | ||
blobs: many(blobs), | ||
})) | ||
|
||
export type Attachment = InferSelectModel<typeof attachments> & { | ||
blobs: Blob[] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,27 @@ | ||
export { AttachmentFactory } from './AttachmentFactory' | ||
|
||
/* // Then, declare types for our dynamic methods */ | ||
/* type DynamicAttachmentMethods<T> = { */ | ||
/* [P in `add${Capitalize<string & T>}` | `remove${Capitalize<string & T>}` | `get${Capitalize<string & T>}` | `get${Capitalize<string & T>}Url`]: () => void; */ | ||
/* }; */ | ||
/**/ | ||
/* // Factory function to create an Attachment instance with dynamic methods */ | ||
/* function createAttachment<T extends string>(rel: T): Attachment & DynamicAttachmentMethods<T> { */ | ||
/* const attachment = new Attachment(rel); */ | ||
/**/ | ||
/* const baseMethodName = `${rel.charAt(0).toUpperCase()}${rel.substring(1)}`; */ | ||
/* attachment[`add${baseMethodName}`] = function() { */ | ||
/* console.log(`Add called for ${rel}`); */ | ||
/* }; */ | ||
/* attachment[`remove${baseMethodName}`] = function() { */ | ||
/* console.log(`Remove called for ${rel}`); */ | ||
/* }; */ | ||
/* attachment[`get${baseMethodName}`] = function() { */ | ||
/* console.log(`Get called for ${rel}`); */ | ||
/* }; */ | ||
/* attachment[`get${baseMethodName}Url`] = function() { */ | ||
/* console.log(`GetUrl called for ${rel}`); */ | ||
/* }; */ | ||
/**/ | ||
/* return attachment as Attachment & DynamicAttachmentMethods<T>; */ | ||
/* } */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters