import { relations, sql } from 'drizzle-orm'; import { mysqlTable, int, text, tinyint, datetime, varchar, unique, timestamp, mysqlEnum, index, type AnyMySqlColumn } from 'drizzle-orm/mysql-core'; export const auditLog = mysqlTable('audit_log', { id: int('id').autoincrement().notNull(), action: text('action').notNull(), content: text('content'), actor_ip: text('actor_ip'), actor_ua: text('actor_ua'), flagged: tinyint('flagged').default(0).notNull(), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), actorId: int('actorId').references(() => user.id, { onDelete: 'set null' }) }); export const document = mysqlTable('document', { id: int('id').autoincrement().notNull(), title: text('title').notNull(), slug: text('slug').notNull(), body: text('body').notNull(), authorId: int('authorId').references(() => user.id), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }); export const oauth2Client = mysqlTable( 'o_auth2_client', { id: int('id').autoincrement().notNull(), client_id: varchar('client_id', { length: 36 }).notNull(), client_secret: text('client_secret').notNull(), title: varchar('title', { length: 255 }).notNull(), description: text('description'), scope: text('scope'), grants: text('grants').default('authorization_code').notNull(), activated: tinyint('activated').default(0).notNull(), verified: tinyint('verified').default(0).notNull(), confidential: tinyint('confidential').default(1).notNull(), pictureId: int('pictureId').references(() => upload.id, { onDelete: 'set null' }), ownerId: int('ownerId').references(() => user.id, { onDelete: 'set null' }), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }, (table) => { return { IDX_e9d16c213910ad57bd05e97b42: unique('IDX_e9d16c213910ad57bd05e97b42').on(table.client_id) }; } ); export type OAuth2Client = typeof oauth2Client.$inferSelect; export type NewOAuth2Client = typeof oauth2Client.$inferInsert; export const oauth2ClientManager = mysqlTable('o_auth2_client_manager', { id: int('id').autoincrement().notNull(), clientId: int('clientId') .references(() => oauth2Client.id, { onDelete: 'cascade' }) .notNull(), userId: int('userId') .references(() => user.id, { onDelete: 'cascade' }) .notNull(), issuerId: int('issuerId').references(() => user.id, { onDelete: 'set null' }), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }); export const oauth2ClientAuthorization = mysqlTable('o_auth2_client_authorization', { id: int('id').autoincrement().notNull(), scope: text('scope'), expires_at: timestamp('expires_at', { mode: 'date' }), clientId: int('clientId').references(() => oauth2Client.id, { onDelete: 'cascade' }), userId: int('userId').references(() => user.id, { onDelete: 'cascade' }), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), current: tinyint('current').default(1).notNull() }); export type OAuth2ClientAuthorization = typeof oauth2ClientAuthorization.$inferSelect; export type NewOAuth2ClientAuthorization = typeof oauth2ClientAuthorization.$inferInsert; export const oauth2ClientUrl = mysqlTable('o_auth2_client_url', { id: int('id').autoincrement().notNull(), url: varchar('url', { length: 255 }).notNull(), type: mysqlEnum('type', ['redirect_uri', 'terms', 'privacy', 'website']).notNull(), created_at: timestamp('created_at', { fsp: 6, mode: 'date' }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: timestamp('updated_at', { fsp: 6, mode: 'date' }) .default(sql`current_timestamp(6)`) .notNull(), clientId: int('clientId').references(() => oauth2Client.id, { onDelete: 'cascade' }) }); export type OAuth2ClientUrl = typeof oauth2ClientUrl.$inferSelect; export type NewOAuth2ClientUrl = typeof oauth2ClientUrl.$inferInsert; export const oauth2Token = mysqlTable('o_auth2_token', { id: int('id').autoincrement().notNull(), type: mysqlEnum('type', ['code', 'device_code', 'access_token', 'refresh_token']).notNull(), token: text('token').notNull(), scope: text('scope'), expires_at: timestamp('expires_at', { mode: 'date' }) .default(sql`current_timestamp()`) .notNull(), userId: int('userId').references(() => user.id, { onDelete: 'cascade' }), clientId: int('clientId').references(() => oauth2Client.id, { onDelete: 'cascade' }), nonce: text('nonce'), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), pcke: text('pcke') }); export type OAuth2Token = typeof oauth2Token.$inferSelect; export type NewOAuth2Token = typeof oauth2Token.$inferInsert; export const privilege = mysqlTable('privilege', { id: int('id').autoincrement().notNull(), name: text('name').notNull(), clientId: int('clientId').references(() => oauth2Client.id, { onDelete: 'cascade' }), automatic: tinyint('automatic').default(0).notNull() }); export type Privilege = typeof privilege.$inferSelect; export const upload = mysqlTable('upload', { id: int('id').autoincrement().notNull(), original_name: varchar('original_name', { length: 255 }).notNull(), mimetype: varchar('mimetype', { length: 255 }).notNull(), file: varchar('file', { length: 255 }).notNull(), uploaderId: int('uploaderId').references((): AnyMySqlColumn => user.id, { onDelete: 'set null', onUpdate: 'cascade' }), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }); export type Upload = typeof upload.$inferSelect; export const user = mysqlTable( 'user', { id: int('id').autoincrement().notNull(), uuid: varchar('uuid', { length: 36 }).notNull(), username: varchar('username', { length: 26 }).notNull(), email: varchar('email', { length: 255 }).notNull(), display_name: varchar('display_name', { length: 32 }).notNull(), password: text('password'), activated: tinyint('activated').default(0).notNull(), activity_at: timestamp('activity_at', { mode: 'date' }) .default(sql`current_timestamp()`) .notNull(), pictureId: int('pictureId').references((): AnyMySqlColumn => upload.id, { onDelete: 'set null', onUpdate: 'cascade' }), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull(), updated_at: datetime('updated_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }, (table) => { return { IDX_a95e949168be7b7ece1a2382fe: unique('IDX_a95e949168be7b7ece1a2382fe').on(table.uuid), IDX_78a916df40e02a9deb1c4b75ed: unique('IDX_78a916df40e02a9deb1c4b75ed').on(table.username), IDX_e12875dfb3b1d92d7d7c5377e2: unique('IDX_e12875dfb3b1d92d7d7c5377e2').on(table.email) }; } ); export type User = typeof user.$inferSelect; export type NewUser = typeof user.$inferInsert; export const userPrivilegesPrivilege = mysqlTable( 'user_privileges_privilege', { userId: int('userId') .notNull() .references(() => user.id, { onDelete: 'cascade', onUpdate: 'cascade' }), privilegeId: int('privilegeId') .notNull() .references(() => privilege.id, { onDelete: 'cascade', onUpdate: 'cascade' }) }, (table) => { return { IDX_0664a7ff494a1859a09014c0f1: index('IDX_0664a7ff494a1859a09014c0f1').on(table.userId), IDX_e71171f4ed20bc8564a1819d0b: index('IDX_e71171f4ed20bc8564a1819d0b').on(table.privilegeId) }; } ); export const userToken = mysqlTable('user_token', { id: int('id').autoincrement().notNull(), token: text('token').notNull(), type: mysqlEnum('type', [ 'generic', 'activation', 'deactivation', 'password', 'login', 'gdpr', 'totp', 'public_key', 'invite', 'recovery' ]).notNull(), expires_at: timestamp('expires_at', { mode: 'date' }), userId: int('userId').references(() => user.id, { onDelete: 'cascade' }), nonce: text('nonce'), metadata: text('metadata'), created_at: datetime('created_at', { mode: 'date', fsp: 6 }) .default(sql`current_timestamp(6)`) .notNull() }); export type UserToken = typeof userToken.$inferSelect; export type NewUserToken = typeof userToken.$inferInsert; export const auditLogRelations = relations(auditLog, ({ one }) => ({ user: one(user, { fields: [auditLog.actorId], references: [user.id] }) })); export const userRelations = relations(user, ({ one, many }) => ({ audit_logs: many(auditLog), documents: many(document), o_auth2_clients: many(oauth2Client), o_auth2_client_authorizations: many(oauth2ClientAuthorization), o_auth2_tokens: many(oauth2Token), uploads: many(upload, { relationName: 'upload_uploaderId_user_id' }), upload: one(upload, { fields: [user.pictureId], references: [upload.id], relationName: 'user_pictureId_upload_id' }), user_privileges_privileges: many(userPrivilegesPrivilege), user_tokens: many(userToken) })); export const documentRelations = relations(document, ({ one }) => ({ user: one(user, { fields: [document.authorId], references: [user.id] }) })); export const oauth2ClientRelations = relations(oauth2Client, ({ one, many }) => ({ user: one(user, { fields: [oauth2Client.ownerId], references: [user.id] }), upload: one(upload, { fields: [oauth2Client.pictureId], references: [upload.id] }), o_auth2_client_authorizations: many(oauth2ClientAuthorization), o_auth2_client_urls: many(oauth2ClientUrl), o_auth2_tokens: many(oauth2Token), o_auth2_managers: many(oauth2ClientManager) })); export const oauth2ClientManagerRelations = relations(oauth2ClientManager, ({ one }) => ({ user: one(user, { fields: [oauth2ClientManager.userId], references: [user.id] }), issuer: one(user, { fields: [oauth2ClientManager.issuerId], references: [user.id] }), o_auth2_client: one(oauth2Client, { fields: [oauth2ClientManager.clientId], references: [oauth2Client.id] }) })); export const uploadRelations = relations(upload, ({ one, many }) => ({ o_auth2_clients: many(oauth2Client), user: one(user, { fields: [upload.uploaderId], references: [user.id], relationName: 'upload_uploaderId_user_id' }), users: many(user, { relationName: 'user_pictureId_upload_id' }) })); export const oauth2ClientAuthorizationRelations = relations( oauth2ClientAuthorization, ({ one }) => ({ user: one(user, { fields: [oauth2ClientAuthorization.userId], references: [user.id] }), o_auth2_client: one(oauth2Client, { fields: [oauth2ClientAuthorization.clientId], references: [oauth2Client.id] }) }) ); export const oauth2ClientUrlRelations = relations(oauth2ClientUrl, ({ one }) => ({ o_auth2_client: one(oauth2Client, { fields: [oauth2ClientUrl.clientId], references: [oauth2Client.id] }) })); export const oauth2TokenRelations = relations(oauth2Token, ({ one }) => ({ o_auth2_client: one(oauth2Client, { fields: [oauth2Token.clientId], references: [oauth2Client.id] }), user: one(user, { fields: [oauth2Token.userId], references: [user.id] }) })); export const userPrivilegesPrivilegeRelations = relations(userPrivilegesPrivilege, ({ one }) => ({ user: one(user, { fields: [userPrivilegesPrivilege.userId], references: [user.id] }), privilege: one(privilege, { fields: [userPrivilegesPrivilege.privilegeId], references: [privilege.id] }) })); export const privilegeRelations = relations(privilege, ({ one, many }) => ({ user_privileges_privileges: many(userPrivilegesPrivilege), o_auth2_client: one(oauth2Client, { fields: [privilege.clientId], references: [oauth2Client.id] }) })); export const userTokenRelations = relations(userToken, ({ one }) => ({ user: one(user, { fields: [userToken.userId], references: [user.id] }) }));